diff options
-rw-r--r-- | src/acpi/acpigen.c | 94 | ||||
-rw-r--r-- | src/include/acpi/acpigen.h | 23 |
2 files changed, 115 insertions, 2 deletions
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) { - /* <dest_op> = DeRefOf (<package_op>[<element]) */ + /* <dest_op> = DeRefOf (<package_op>[<element>]) */ 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 (<package>[<element>]) = <src> */ + 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) +{ + /* <dest_op> = <package>[<element>] */ + 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) +{ + /* <package>[<element>] = <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) +{ + /* <package>[<element>] = <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 */ +} diff --git a/src/include/acpi/acpigen.h b/src/include/acpi/acpigen.h index 6360614c71..15af0192a3 100644 --- a/src/include/acpi/acpigen.h +++ b/src/include/acpi/acpigen.h @@ -286,6 +286,7 @@ struct cppc_config { }; void acpigen_write_return_integer(uint64_t arg); +void acpigen_write_return_namestr(const char *arg); void acpigen_write_return_string(const char *arg); void acpigen_write_len_f(void); void acpigen_pop_len(void); @@ -374,6 +375,7 @@ void acpigen_write_xor(uint8_t arg1, uint8_t arg2, uint8_t res); void acpigen_write_and(uint8_t arg1, uint8_t arg2, uint8_t res); void acpigen_write_not(uint8_t arg, uint8_t res); void acpigen_write_debug_string(const char *str); +void acpigen_write_debug_namestr(const char *str); void acpigen_write_debug_integer(uint64_t val); void acpigen_write_debug_op(uint8_t op); void acpigen_write_if(void); @@ -466,7 +468,7 @@ int get_cst_entries(acpi_cstate_t **); /* * Get element from package into specified destination op: - * <dest_op> = DeRefOf (<package_op>[<element]) + * <dest_op> = DeRefOf (<package_op>[<element>]) * * Example: * acpigen_get_package_op_element(ARG0_OP, 0, LOCAL0_OP) @@ -474,6 +476,25 @@ int get_cst_entries(acpi_cstate_t **); */ void acpigen_get_package_op_element(uint8_t package_op, unsigned int element, uint8_t dest_op); +/* Set element of package op to specified op: DeRefOf (<package>[<element>]) = <src> */ +void acpigen_set_package_op_element_int(uint8_t package_op, unsigned int element, uint64_t src); + +/* Get element from package to specified op: <dest_op> = <package>[<element>] */ +void acpigen_get_package_element(const char *package, unsigned int element, uint8_t dest_op); + +/* Set element of package to specified op: <package>[<element>] = <src> */ +void acpigen_set_package_element_int(const char *package, unsigned int element, uint64_t src); + +/* Set element of package to specified namestr: <package>[<element>] = <src> */ +void acpigen_set_package_element_namestr(const char *package, unsigned int element, + const char *src); + +/* + * Delay up to wait_ms milliseconds until the provided name matches the expected value. + * If wait_ms is >= 32ms then it will wait in 16ms chunks. This function uses LOCAL7_OP. + */ +void acpigen_write_delay_until_namestr_int(uint32_t wait_ms, const char *name, uint64_t value); + /* * Soc-implemented functions for generating ACPI AML code for GPIO handling. All * these functions are expected to use only Local5, Local6 and Local7 |