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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -1199,21 +1238,21 @@ void acpigen_write_return_string(const char *arg)
|
|||
* 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 })
|
||||
* }
|
||||
* ...
|
||||
* If (LEqual (Local0, ToUUID(uuidn))) {
|
||||
* ...
|
||||
* }
|
||||
* } Else {
|
||||
* 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 }) */
|
||||
acpigen_write_return_singleton_buffer(0x0);
|
||||
|
||||
acpigen_pop_len(); /* Else */
|
||||
acpigen_pop_len(); /* Method _DSM */
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -235,8 +249,9 @@ void acpigen_write_return_byte(uint8_t arg);
|
|||
* argument to pass into the callbacks. Callbacks should ensure that Local0 and
|
||||
* 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);
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue