[coreboot-gerrit] Patch set updated for coreboot: arch/x86/acpigen: Write DSM method with multiple UUID's

Naresh Solanki (naresh.solanki@intel.com) gerrit at coreboot.org
Thu Nov 17 13:12:33 CET 2016


Naresh Solanki (naresh.solanki at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17424

-gerrit

commit e3b0fa878c97e1955989ff9f10f9b5e99d986f49
Author: Naresh G Solanki <naresh.solanki at intel.com>
Date:   Tue Nov 15 10:13:15 2016 +0530

    arch/x86/acpigen: Write DSM method with multiple UUID's
    
    Enable generic way of writing DSM method which can write acpi table for
    multiple UUID's.
    
    Change-Id: Ic1fbdc0647e8fdc50ffa407887feb19a63cb48e4
    Signed-off-by: Naresh G Solanki <naresh.solanki at intel.com>
---
 src/arch/x86/acpigen.c              | 119 +++++++++++++++++++++++-------------
 src/arch/x86/include/arch/acpigen.h |  15 +++++
 2 files changed, 93 insertions(+), 41 deletions(-)

diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c
index 5447752..c1d9c8b 100644
--- a/src/arch/x86/acpigen.c
+++ b/src/arch/x86/acpigen.c
@@ -1194,75 +1194,112 @@ 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]>
+ *		} Else {
+ *			...
+ *			If (LEqual (Local1, n)) {
+ *				<acpigen by callback[n]>
+ *			} Else {
+ *				Return (Buffer (One) { 0x0 })
+ *			}
+ *		}
+ *	} Else {
+ *		Return (Buffer (One) { 0x0 })
+ *	}
  * }
  */
 void acpigen_write_dsm(const char *uuid, void (*callbacks[])(void *),
 		       size_t count, void *arg)
 {
-	size_t i;
-
-	/* Method (_DSM, 4, Serialized) */
-	acpigen_write_method_serialized("_DSM", 0x4);
+	struct dsm_uuid id = DSM_UUID(uuid, callbacks, count, arg);
+	acpigen_write_dsm_uuid_arr(&id, 1);
+}
 
-	/* ToBuffer (Arg0, Local0) */
-	acpigen_write_to_buffer(ARG0_OP, LOCAL0_OP);
+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(uuid);
+	acpigen_write_uuid(id->uuid);
 
-	/*   ToInteger (Arg2, Local1) */
+	/* 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)) */
+	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 (callbacks[i])
-			callbacks[i](arg);
+		/* Callback to write if handler. */
+		if (id->callbacks[i])
+			id->callbacks[i](id->arg);
 
 		acpigen_pop_len();	/* If */
-
-		/*   Else */
-		acpigen_write_else();
 	}
 
-	/*   Default case: Return (Buffer (One) { 0x0 }) */
+	/* 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();
+}
+
+/*
+ * Generate ACPI AML code for _DSM method.
+ * 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 = array of UUID
+ * Arg1 = count
+ *
+ * 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]>
+ *		}
+ *		...
+ *		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_uuid_arr(struct dsm_uuid *ids, size_t count)
+{
+	size_t i;
+
+	/* Method (_DSM, 4, Serialized) */
+	acpigen_write_method_serialized("_DSM", 0x4);
+
+	/* ToBuffer (Arg0, Local0) */
+	acpigen_write_to_buffer(ARG0_OP, LOCAL0_OP);
+
+	for (i = 0; i < count; i++)
+		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 */
 }
 
diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h
index dcd8fb7..015b54a 100644
--- a/src/arch/x86/include/arch/acpigen.h
+++ b/src/arch/x86/include/arch/acpigen.h
@@ -144,6 +144,20 @@ struct opregion {
 	unsigned long regionlen;
 };
 
+#define DSM_UUID(DSM_UUID, DSM_CALLBACKS, DSM_COUNT, DSM_ARG) \
+	{ .uuid = DSM_UUID, \
+	.callbacks = DSM_CALLBACKS, \
+	.count = DSM_COUNT, \
+	.arg = DSM_ARG, \
+	}
+
+struct dsm_uuid {
+	const char *uuid;
+	void (**callbacks)(void *);
+	size_t count;
+	void *arg;
+};
+
 void acpigen_write_return_integer(uint64_t arg);
 void acpigen_write_return_string(const char *arg);
 void acpigen_write_len_f(void);
@@ -237,6 +251,7 @@ void acpigen_write_return_byte(uint8_t arg);
  */
 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);
 /*
  * Generate ACPI AML code for OperationRegion
  * This function takes input region name, region space, region offset & region



More information about the coreboot-gerrit mailing list