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@intel.com> Reviewed-on: https://review.coreboot.org/17424 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik <subrata.banik@intel.com> Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
c36fa6433e
commit
ab77cd4785
|
@ -1180,11 +1180,50 @@ void acpigen_write_return_string(const char *arg)
|
||||||
acpigen_write_string(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.
|
* Generate ACPI AML code for _DSM method.
|
||||||
* This function takes as input uuid for the device, set of callbacks and
|
* This function takes as input array of uuid for the device, set of callbacks
|
||||||
* argument to pass into the callbacks. Callbacks should ensure that Local0 and
|
* and argument to pass into the callbacks. Callbacks should ensure that Local0
|
||||||
* Local1 are left untouched. Use of Local2-Local7 is permitted in callbacks.
|
* and Local1 are left untouched. Use of Local2-Local7 is permitted in
|
||||||
|
* callbacks.
|
||||||
*
|
*
|
||||||
* Arguments passed into _DSM method:
|
* Arguments passed into _DSM method:
|
||||||
* Arg0 = UUID
|
* Arg0 = UUID
|
||||||
|
@ -1194,26 +1233,26 @@ void acpigen_write_return_string(const char *arg)
|
||||||
*
|
*
|
||||||
* AML code generated would look like:
|
* AML code generated would look like:
|
||||||
* Method (_DSM, 4, Serialized) {
|
* Method (_DSM, 4, Serialized) {
|
||||||
* ToBuffer (Arg0, Local0)
|
* ToBuffer (Arg0, Local0)
|
||||||
* If (LEqual (Local0, ToUUID(uuid))) {
|
* If (LEqual (Local0, ToUUID(uuid))) {
|
||||||
* ToInteger (Arg2, Local1)
|
* ToInteger (Arg2, Local1)
|
||||||
* If (LEqual (Local1, 0)) {
|
* If (LEqual (Local1, 0)) {
|
||||||
* <acpigen by callback[0]>
|
* <acpigen by callback[0]>
|
||||||
* } Else {
|
* }
|
||||||
* ...
|
* ...
|
||||||
* If (LEqual (Local1, n)) {
|
* If (LEqual (Local1, n)) {
|
||||||
* <acpigen by callback[n]>
|
* <acpigen by callback[n]>
|
||||||
* } Else {
|
* }
|
||||||
* Return (Buffer (One) { 0x0 })
|
* Return (Buffer (One) { 0x0 })
|
||||||
* }
|
* }
|
||||||
* }
|
* ...
|
||||||
* } Else {
|
* If (LEqual (Local0, ToUUID(uuidn))) {
|
||||||
* Return (Buffer (One) { 0x0 })
|
* ...
|
||||||
* }
|
* }
|
||||||
|
* Return (Buffer (One) { 0x0 })
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
void acpigen_write_dsm(const char *uuid, void (*callbacks[])(void *),
|
void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count)
|
||||||
size_t count, void *arg)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -1223,46 +1262,12 @@ void acpigen_write_dsm(const char *uuid, void (*callbacks[])(void *),
|
||||||
/* ToBuffer (Arg0, Local0) */
|
/* ToBuffer (Arg0, Local0) */
|
||||||
acpigen_write_to_buffer(ARG0_OP, LOCAL0_OP);
|
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++)
|
for (i = 0; i < count; i++)
|
||||||
acpigen_pop_len();
|
acpigen_write_dsm_uuid(&ids[i]);
|
||||||
|
|
||||||
acpigen_pop_len(); /* If (LEqual (Local0, ToUUID(uuid))) */
|
/* Return (Buffer (One) { 0x0 }) */
|
||||||
|
|
||||||
/* Else */
|
|
||||||
acpigen_write_else();
|
|
||||||
|
|
||||||
/* Return (Buffer (One) { 0x0 }) */
|
|
||||||
acpigen_write_return_singleton_buffer(0x0);
|
acpigen_write_return_singleton_buffer(0x0);
|
||||||
|
|
||||||
acpigen_pop_len(); /* Else */
|
|
||||||
acpigen_pop_len(); /* Method _DSM */
|
acpigen_pop_len(); /* Method _DSM */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,20 @@ struct opregion {
|
||||||
unsigned long regionlen;
|
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_integer(uint64_t arg);
|
||||||
void acpigen_write_return_string(const char *arg);
|
void acpigen_write_return_string(const char *arg);
|
||||||
void acpigen_write_len_f(void);
|
void acpigen_write_len_f(void);
|
||||||
|
@ -235,8 +249,9 @@ void acpigen_write_return_byte(uint8_t arg);
|
||||||
* argument to pass into the callbacks. Callbacks should ensure that Local0 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.
|
* Local1 are left untouched. Use of Local2-Local7 is permitted in callbacks.
|
||||||
*/
|
*/
|
||||||
void acpigen_write_dsm(const char *uuid, void (*callbacks[])(void *),
|
void acpigen_write_dsm(const char *uuid, void (**callbacks)(void *),
|
||||||
size_t count, void *arg);
|
size_t count, void *arg);
|
||||||
|
void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);
|
||||||
/*
|
/*
|
||||||
* Generate ACPI AML code for OperationRegion
|
* Generate ACPI AML code for OperationRegion
|
||||||
* This function takes input region name, region space, region offset & region
|
* This function takes input region name, region space, region offset & region
|
||||||
|
|
Loading…
Reference in New Issue