Duncan Laurie has uploaded this change for review.

View Change

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 <dlaurie@google.com>
Change-Id: I9b20a23872b7d4a50f03761032426ffbb722b9ee
---
M src/acpi/acpigen.c
M src/include/acpi/acpigen.h
2 files changed, 115 insertions(+), 2 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/96/47196/1
diff --git a/src/acpi/acpigen.c b/src/acpi/acpigen.c
index 7b72584..2a37148 100644
--- a/src/acpi/acpigen.c
+++ b/src/acpi/acpigen.c
@@ -340,7 +340,7 @@

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);
@@ -350,6 +350,52 @@
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)
{
/*
@@ -1318,6 +1364,14 @@
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);
@@ -1453,6 +1507,12 @@
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);
@@ -2095,3 +2155,35 @@

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 6360614..15af019 100644
--- a/src/include/acpi/acpigen.h
+++ b/src/include/acpi/acpigen.h
@@ -286,6 +286,7 @@
};

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_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 @@

/*
* 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 @@
*/
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

To view, visit change 47196. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I9b20a23872b7d4a50f03761032426ffbb722b9ee
Gerrit-Change-Number: 47196
Gerrit-PatchSet: 1
Gerrit-Owner: Duncan Laurie <dlaurie@chromium.org>
Gerrit-MessageType: newchange