summaryrefslogtreecommitdiff
path: root/src/arch/x86/acpigen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/acpigen.c')
-rw-r--r--src/arch/x86/acpigen.c119
1 files changed, 62 insertions, 57 deletions
diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c
index 5447752823..8ebdd0982c 100644
--- a/src/arch/x86/acpigen.c
+++ b/src/arch/x86/acpigen.c
@@ -1180,11 +1180,50 @@ void acpigen_write_return_string(const char *arg)
acpigen_write_string(arg);
}
+void acpigen_write_dsm(const char *uuid, void (**callbacks)(void *),
+ size_t count, void *arg)
+{
+ struct dsm_uuid id = DSM_UUID(uuid, callbacks, count, arg);
+ acpigen_write_dsm_uuid_arr(&id, 1);
+}
+
+static void acpigen_write_dsm_uuid(struct dsm_uuid *id)
+{
+ size_t i;
+
+ /* If (LEqual (Local0, ToUUID(uuid))) */
+ acpigen_write_if();
+ acpigen_emit_byte(LEQUAL_OP);
+ acpigen_emit_byte(LOCAL0_OP);
+ acpigen_write_uuid(id->uuid);
+
+ /* ToInteger (Arg2, Local1) */
+ acpigen_write_to_integer(ARG2_OP, LOCAL1_OP);
+
+ for (i = 0; i < id->count; i++) {
+ /* If (LEqual (Local1, i)) */
+ acpigen_write_if_lequal_op_int(LOCAL1_OP, i);
+
+ /* Callback to write if handler. */
+ if (id->callbacks[i])
+ id->callbacks[i](id->arg);
+
+ acpigen_pop_len(); /* If */
+ }
+
+ /* Default case: Return (Buffer (One) { 0x0 }) */
+ acpigen_write_return_singleton_buffer(0x0);
+
+ acpigen_pop_len(); /* If (LEqual (Local0, ToUUID(uuid))) */
+
+}
+
/*
* Generate ACPI AML code for _DSM method.
- * This function takes as input uuid for the device, set of callbacks and
- * argument to pass into the callbacks. Callbacks should ensure that Local0 and
- * Local1 are left untouched. Use of Local2-Local7 is permitted in callbacks.
+ * This function takes as input array of uuid for the device, set of callbacks
+ * and argument to pass into the callbacks. Callbacks should ensure that Local0
+ * and Local1 are left untouched. Use of Local2-Local7 is permitted in
+ * callbacks.
*
* Arguments passed into _DSM method:
* Arg0 = UUID
@@ -1194,26 +1233,26 @@ void acpigen_write_return_string(const char *arg)
*
* AML code generated would look like:
* Method (_DSM, 4, Serialized) {
- * ToBuffer (Arg0, Local0)
- * If (LEqual (Local0, ToUUID(uuid))) {
- * ToInteger (Arg2, Local1)
- * If (LEqual (Local1, 0)) {
- * <acpigen by callback[0]>
- * } Else {
- * ...
- * If (LEqual (Local1, n)) {
- * <acpigen by callback[n]>
- * } Else {
- * Return (Buffer (One) { 0x0 })
- * }
- * }
- * } Else {
- * Return (Buffer (One) { 0x0 })
- * }
+ * ToBuffer (Arg0, Local0)
+ * If (LEqual (Local0, ToUUID(uuid))) {
+ * ToInteger (Arg2, Local1)
+ * If (LEqual (Local1, 0)) {
+ * <acpigen by callback[0]>
+ * }
+ * ...
+ * If (LEqual (Local1, n)) {
+ * <acpigen by callback[n]>
+ * }
+ * Return (Buffer (One) { 0x0 })
+ * }
+ * ...
+ * If (LEqual (Local0, ToUUID(uuidn))) {
+ * ...
+ * }
+ * Return (Buffer (One) { 0x0 })
* }
*/
-void acpigen_write_dsm(const char *uuid, void (*callbacks[])(void *),
- size_t count, void *arg)
+void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count)
{
size_t i;
@@ -1223,46 +1262,12 @@ void acpigen_write_dsm(const char *uuid, void (*callbacks[])(void *),
/* ToBuffer (Arg0, Local0) */
acpigen_write_to_buffer(ARG0_OP, LOCAL0_OP);
- /* If (LEqual (Local0, ToUUID(uuid))) */
- acpigen_write_if();
- acpigen_emit_byte(LEQUAL_OP);
- acpigen_emit_byte(LOCAL0_OP);
- acpigen_write_uuid(uuid);
-
- /* ToInteger (Arg2, Local1) */
- acpigen_write_to_integer(ARG2_OP, LOCAL1_OP);
- acpigen_write_debug_op(LOCAL1_OP);
-
- for (i = 0; i < count; i++) {
- /* If (Lequal (Local1, i)) */
- acpigen_write_if_lequal_op_int(LOCAL1_OP, i);
-
- /* Callback to write if handler. */
- if (callbacks[i])
- callbacks[i](arg);
-
- acpigen_pop_len(); /* If */
-
- /* Else */
- acpigen_write_else();
- }
-
- /* Default case: Return (Buffer (One) { 0x0 }) */
- acpigen_write_return_singleton_buffer(0x0);
-
- /* Pop lengths for all the else clauses. */
for (i = 0; i < count; i++)
- acpigen_pop_len();
-
- acpigen_pop_len(); /* If (LEqual (Local0, ToUUID(uuid))) */
-
- /* Else */
- acpigen_write_else();
+ acpigen_write_dsm_uuid(&ids[i]);
- /* Return (Buffer (One) { 0x0 }) */
+ /* Return (Buffer (One) { 0x0 }) */
acpigen_write_return_singleton_buffer(0x0);
- acpigen_pop_len(); /* Else */
acpigen_pop_len(); /* Method _DSM */
}