From ec2e3e479af0dc66041ae3b599b7df93b10160b9 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Tue, 3 Nov 2020 15:19:08 -0800 Subject: acpigen: Add more useful helper functions acpigen_write_debug_namestr() - Debug = NAME acpigen_write_return_namestr() - Return (NAME) acpigen_set_package_op_element_int() - Set package pointer element DeRefOf (PKG[ELEM]) = INT acpigen_get_package_element() - Get package (not pointer) element dest_op = PKG[ELEM] acpigen_set_package_element_int() - Set package element to integer PKG[ELEM] = INT acpigen_set_package_element_namestr() - Set package element to namestr PKG[ELEM] = NAME acpigen_write_delay_until_namestr_int() - Delay while waiting for register to equal expected value. BUG=b:160996445 Signed-off-by: Duncan Laurie Change-Id: I9b20a23872b7d4a50f03761032426ffbb722b9ee Reviewed-on: https://review.coreboot.org/c/coreboot/+/47196 Reviewed-by: Furquan Shaikh Reviewed-by: Tim Wawrzynczak Tested-by: build bot (Jenkins) --- src/acpi/acpigen.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) (limited to 'src/acpi/acpigen.c') diff --git a/src/acpi/acpigen.c b/src/acpi/acpigen.c index 4a7dfc9325..244ac548c9 100644 --- a/src/acpi/acpigen.c +++ b/src/acpi/acpigen.c @@ -342,7 +342,7 @@ void acpigen_write_scope(const char *name) void acpigen_get_package_op_element(uint8_t package_op, unsigned int element, uint8_t dest_op) { - /* = DeRefOf ([ = DeRefOf ([]) */ acpigen_write_store(); acpigen_emit_byte(DEREF_OP); acpigen_emit_byte(INDEX_OP); @@ -352,6 +352,52 @@ void acpigen_get_package_op_element(uint8_t package_op, unsigned int element, ui acpigen_emit_byte(dest_op); } +void acpigen_set_package_op_element_int(uint8_t package_op, unsigned int element, uint64_t src) +{ + /* DeRefOf ([]) = */ + acpigen_write_store(); + acpigen_write_integer(src); + acpigen_emit_byte(DEREF_OP); + acpigen_emit_byte(INDEX_OP); + acpigen_emit_byte(package_op); + acpigen_write_integer(element); + acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */ +} + +void acpigen_get_package_element(const char *package, unsigned int element, uint8_t dest_op) +{ + /* = [] */ + acpigen_write_store(); + acpigen_emit_byte(INDEX_OP); + acpigen_emit_namestring(package); + acpigen_write_integer(element); + acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */ + acpigen_emit_byte(dest_op); +} + +void acpigen_set_package_element_int(const char *package, unsigned int element, uint64_t src) +{ + /* [] = */ + acpigen_write_store(); + acpigen_write_integer(src); + acpigen_emit_byte(INDEX_OP); + acpigen_emit_namestring(package); + acpigen_write_integer(element); + acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */ +} + +void acpigen_set_package_element_namestr(const char *package, unsigned int element, + const char *src) +{ + /* [] = */ + acpigen_write_store(); + acpigen_emit_namestring(src); + acpigen_emit_byte(INDEX_OP); + acpigen_emit_namestring(package); + acpigen_write_integer(element); + acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */ +} + void acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len) { /* @@ -1320,6 +1366,14 @@ void acpigen_write_debug_op(uint8_t op) acpigen_emit_ext_op(DEBUG_OP); } +/* Store (str, DEBUG) */ +void acpigen_write_debug_namestr(const char *str) +{ + acpigen_write_store(); + acpigen_emit_namestring(str); + acpigen_emit_ext_op(DEBUG_OP); +} + void acpigen_write_if(void) { acpigen_emit_byte(IF_OP); @@ -1455,6 +1509,12 @@ void acpigen_write_return_integer(uint64_t arg) acpigen_write_integer(arg); } +void acpigen_write_return_namestr(const char *arg) +{ + acpigen_emit_byte(RETURN_OP); + acpigen_emit_namestring(arg); +} + void acpigen_write_return_string(const char *arg) { acpigen_emit_byte(RETURN_OP); @@ -2098,3 +2158,35 @@ void acpigen_write_xpss_object(const struct acpi_xpss_sw_pstate *pstate_values, acpigen_pop_len(); } + +/* Delay up to wait_ms until provided namestr matches expected value. */ +void acpigen_write_delay_until_namestr_int(uint32_t wait_ms, const char *name, uint64_t value) +{ + uint32_t wait_ms_segment = 1; + uint32_t segments = wait_ms; + + /* Sleep in 16ms segments if delay is more than 32ms. */ + if (wait_ms > 32) { + wait_ms_segment = 16; + segments = wait_ms / 16; + } + + acpigen_write_store_int_to_op(segments, LOCAL7_OP); + acpigen_emit_byte(WHILE_OP); + acpigen_write_len_f(); + acpigen_emit_byte(LGREATER_OP); + acpigen_emit_byte(LOCAL7_OP); + acpigen_emit_byte(ZERO_OP); + + /* If name is not provided then just delay in a loop. */ + if (name) { + acpigen_write_if_lequal_namestr_int(name, value); + acpigen_emit_byte(BREAK_OP); + acpigen_pop_len(); /* If */ + } + + acpigen_write_sleep(wait_ms_segment); + acpigen_emit_byte(DECREMENT_OP); + acpigen_emit_byte(LOCAL7_OP); + acpigen_pop_len(); /* While */ +} -- cgit v1.2.3