[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
Wed Nov 16 18:42:34 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 2d0aafcf6a2a05ec10f1ee78f85e45ce852d5631
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              | 131 ++++++++++++++++++++----------------
 src/arch/x86/include/arch/acpigen.h |  17 +++++
 2 files changed, 91 insertions(+), 57 deletions(-)

diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c
index 31b8dac..516701b 100644
--- a/src/arch/x86/acpigen.c
+++ b/src/arch/x86/acpigen.c
@@ -1168,89 +1168,106 @@ void acpigen_write_return_byte(uint8_t arg)
 	acpigen_write_byte(arg);
 }
 
-/*
- * 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.
- *
- * Arguments passed into _DSM method:
- * Arg0 = UUID
- * Arg1 = Revision
- * Arg2 = Function index
- * Arg3 = Function specific arguments
- *
- * 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 })
- * 	}
- * }
- */
+void acpigen_write_return_integer(uint64_t arg)
+{
+	acpigen_emit_byte(RETURN_OP);
+	acpigen_write_integer(arg);
+}
+
+void acpigen_write_return_string(const char *arg)
+{
+	acpigen_emit_byte(RETURN_OP);
+	acpigen_write_string(arg);
+}
+
 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 572ae6c..642b957 100644
--- a/src/arch/x86/include/arch/acpigen.h
+++ b/src/arch/x86/include/arch/acpigen.h
@@ -144,6 +144,23 @@ 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_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);
+void acpigen_write_return_integer(uint64_t arg);
+void acpigen_write_return_string(const char *arg);
 void acpigen_write_len_f(void);
 void acpigen_pop_len(void);
 void acpigen_set_current(char *curr);



More information about the coreboot-gerrit mailing list