<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/20547">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">arch/x86/acpigen: Add generator for _ROM<br><br>Add a common generator for method _ROM.<br>To be used with graphic devices.<br>The data has to be placed in system memory and has to be<br>a multiple of 4096.<br><br>Change-Id: Ie118b15257295b7133c8e585c0fd5218249dec8d<br>Signed-off-by: Patrick Rudolph <siro@das-labor.org><br>---<br>M src/arch/x86/acpigen.c<br>M src/arch/x86/include/arch/acpigen.h<br>2 files changed, 217 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/47/20547/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c<br>index f9690b3..d00c4bd 100644<br>--- a/src/arch/x86/acpigen.c<br>+++ b/src/arch/x86/acpigen.c<br>@@ -1295,6 +1295,215 @@<br> acpigen_pop_len(); /* Method _DSM */<br> }<br> <br>+/*<br>+ * Generate ACPI AML code for _ROM method.<br>+ * This function takes as input ROM data and ROM length.<br>+ * The ROM length has to be multiple of 4096 and has to be less<br>+ * than the current implementation limit of 0x40000.<br>+ *<br>+ * Arguments passed into _DSM method:<br>+ * Arg0 = Offset in Bytes<br>+ * Arg1 = Bytes to return<br>+ *<br>+ * AML code generated would look like:<br>+ * Method (_ROM, 2, Serialized) {<br>+ * ToBuffer (Arg0, Local0)<br>+ * ToBuffer (Arg1, Local1)<br>+ *<br>+ * OperationRegion("ROMS", SYSTEMMEMORY, current, entries * 0x10000)<br>+ * Field (ROMS, AnyAcc, NoLock, Preserve)<br>+ * {<br>+ * Offset (0),<br>+ * RBF0, 0x80000<br>+ * RBF1, 0x80000<br>+ * RBF2, 0x80000<br>+ * RBF3, 0x80000<br>+ * }<br>+ *<br>+ * If (LGreater (LOCAL1_OP, 0x1000))<br>+ * {<br>+ * Store (0x1000, Local1)<br>+ * }<br>+ *<br>+ * If (LGreater (LOCAL0_OP, 0x10000))<br>+ * {<br>+ * Return(Buffer(Local1){0})<br>+ * }<br>+ *<br>+ * Multiply (Local1, 0x08, Local3)<br>+ * Name (ROM1, Buffer (0x80000) {0})<br>+ * Name (ROM2, Buffer (Local1) {0})<br>+ *<br>+ * If (LLess (LOCAL0_OP, 0x10000))<br>+ * {<br>+ * Store (RBFx, ROM1)<br>+ * Subtract (Local0, 0, Local0)<br>+ * }<br>+ *<br>+ * Multiply (Local0, 0x08, Local2)<br>+ * CreateField (ROM1, Local2, Local3, TMPB)<br>+ * Store (TMPB, ROM2)<br>+ * Return (ROM2)<br>+ * }<br>+ */<br>+<br>+void acpigen_write_rom(void *bios, size_t length)<br>+{<br>+ struct fieldlist l[] = {<br>+ FIELDLIST_OFFSET(0),<br>+ FIELDLIST_NAMESTR("RBF0", 0x80000),<br>+ FIELDLIST_NAMESTR("RBF1", 0x80000),<br>+ FIELDLIST_NAMESTR("RBF2", 0x80000),<br>+ FIELDLIST_NAMESTR("RBF3", 0x80000),<br>+ };<br>+ ASSERT(bios)<br>+ ASSERT(length)<br>+ ASSERT(!(length & 0xfff))<br>+<br>+ /* Split ROM into smaller chunks */<br>+ size_t entries = DIV_ROUND_UP(length, 0x10000);<br>+ ASSERT(entries <= (ARRAY_SIZE(l) - 1))<br>+<br>+ /* Method (_ROM, 2) */<br>+ acpigen_write_method("_ROM", 2);<br>+<br>+ /* OperationRegion("ROMS", SYSTEMMEMORY, current, entries * 0x10000) */<br>+ struct opregion opreg = OPREGION("ROMS", SYSTEMMEMORY,<br>+ (u32)(uintptr_t)bios, entries * 0x10000);<br>+ acpigen_write_opregion(&opreg);<br>+<br>+ /* Field (ROMS, AnyAcc, NoLock, Preserve)<br>+ * {<br>+ * Offset (0),<br>+ * RBF0, 0x80000<br>+ * RBF1, 0x80000<br>+ * RBF2, 0x80000<br>+ * RBF3, 0x80000<br>+ * } */<br>+ acpigen_write_field(opreg.name, l, ARRAY_SIZE(l), FIELD_ANYACC |<br>+ FIELD_NOLOCK | FIELD_PRESERVE);<br>+<br>+ /* ToBuffer (Arg0, Local0) */<br>+ acpigen_write_to_buffer(ARG0_OP, LOCAL0_OP);<br>+<br>+ /* ToBuffer (Arg1, Local1) */<br>+ acpigen_write_to_buffer(ARG1_OP, LOCAL1_OP);<br>+<br>+ /* ACPI SPEC requires to return at maximum 4KiB */<br>+ /* If (LGreater (LOCAL1_OP, 0x1000)) */<br>+ acpigen_write_if();<br>+ acpigen_emit_byte(LGREATER_OP);<br>+ acpigen_emit_byte(LOCAL1_OP);<br>+ acpigen_write_integer(0x1000);<br>+<br>+ /* Store (0x1000, Local1) */<br>+ acpigen_write_store();<br>+ acpigen_write_integer(0x1000);<br>+ acpigen_emit_byte(LOCAL1_OP);<br>+<br>+ /* Pop if */<br>+ acpigen_pop_len();<br>+<br>+ /* If (LGreater (LOCAL0_OP, length)) */<br>+ acpigen_write_if();<br>+ acpigen_emit_byte(LGREATER_OP);<br>+ acpigen_emit_byte(LOCAL0_OP);<br>+ acpigen_write_integer(length);<br>+<br>+ /* Return(Buffer(Local1){0}) */<br>+ acpigen_emit_byte(RETURN_OP);<br>+ acpigen_emit_byte(BUFFER_OP);<br>+ acpigen_write_len_f();<br>+ acpigen_emit_byte(LOCAL1_OP);<br>+ acpigen_emit_byte(0);<br>+ acpigen_pop_len();<br>+<br>+ /* Pop if */<br>+ acpigen_pop_len();<br>+<br>+ /* Multiply (Local1, 0x08, Local3) */<br>+ acpigen_emit_byte(MULTIPLY_OP);<br>+ acpigen_emit_byte(LOCAL1_OP);<br>+ acpigen_write_integer(0x08);<br>+ acpigen_emit_byte(LOCAL3_OP);<br>+<br>+ /* Name (ROM1, Buffer (0x80000) {0}) */<br>+ acpigen_write_name("ROM1");<br>+ acpigen_emit_byte(BUFFER_OP);<br>+ acpigen_write_len_f();<br>+ acpigen_write_integer(0x80000);<br>+ acpigen_emit_byte(0);<br>+ acpigen_pop_len();<br>+<br>+ /* Name (ROM2, Buffer (Local1) {0}) */<br>+ acpigen_write_name("ROM2");<br>+ acpigen_emit_byte(BUFFER_OP);<br>+ acpigen_write_len_f();<br>+ acpigen_emit_byte(LOCAL1_OP);<br>+ acpigen_emit_byte(0);<br>+ acpigen_pop_len();<br>+<br>+ for (size_t i = 0; i < entries; i++) {<br>+ const char name[5] = {'R', 'B', 'F', '0' + i, 0};<br>+<br>+ /* If (LLess (LOCAL0_OP, 0x10000 * (i + 1))) */<br>+ acpigen_write_if();<br>+ acpigen_emit_byte(LLESS_OP);<br>+ acpigen_emit_byte(LOCAL0_OP);<br>+ acpigen_write_integer(0x10000 * (i + 1));<br>+<br>+ /* Store (RBFx, ROM1) */<br>+ acpigen_write_store();<br>+ acpigen_emit_namestring(name);<br>+ acpigen_emit_namestring("ROM1");<br>+<br>+ /* Subtract (Local0, 0x10000 * i, Local0) */<br>+ acpigen_emit_byte(SUBTRACT_OP);<br>+ acpigen_emit_byte(LOCAL0_OP);<br>+ acpigen_write_integer(0x10000 * i);<br>+ acpigen_emit_byte(LOCAL0_OP);<br>+<br>+ /* Pop if */<br>+ acpigen_pop_len();<br>+<br>+ if ((i + 1) < entries) {<br>+ /* else */<br>+ acpigen_write_else();<br>+ }<br>+ }<br>+<br>+ for (size_t i = 0; i < entries - 1; i++) {<br>+ /* Pop else */<br>+ acpigen_pop_len();<br>+ }<br>+<br>+ /* Multiply (Local0, 0x08, Local2) */<br>+ acpigen_emit_byte(MULTIPLY_OP);<br>+ acpigen_emit_byte(LOCAL0_OP);<br>+ acpigen_write_integer(0x08);<br>+ acpigen_emit_byte(LOCAL2_OP);<br>+<br>+ /* CreateField (ROM1, Local2, Local3, TMPB) */<br>+ acpigen_emit_ext_op(CREATEFIELD_OP);<br>+ acpigen_emit_namestring("ROM1");<br>+ acpigen_emit_byte(LOCAL2_OP);<br>+ acpigen_emit_byte(LOCAL3_OP);<br>+ acpigen_emit_namestring("TMPB");<br>+<br>+ /* Store (TMPB, ROM2) */<br>+ acpigen_write_store();<br>+ acpigen_emit_namestring("TMPB");<br>+ acpigen_emit_namestring("ROM2");<br>+<br>+ /* Return (ROM2) */<br>+ acpigen_emit_byte(RETURN_OP);<br>+ acpigen_emit_namestring("ROM2");<br>+<br>+ /* Pop method */<br>+ acpigen_pop_len();<br>+}<br>+<br>+<br> /* Soc-implemented functions -- weak definitions. */<br> int __attribute__((weak)) acpigen_soc_read_rx_gpio(unsigned int gpio_num)<br> {<br>diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h<br>index 37d0d55..a7c3e56 100644<br>--- a/src/arch/x86/include/arch/acpigen.h<br>+++ b/src/arch/x86/include/arch/acpigen.h<br>@@ -260,6 +260,14 @@<br> void acpigen_write_dsm(const char *uuid, void (**callbacks)(void *),<br> size_t count, void *arg);<br> void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);<br>+<br>+/*<br>+ * Generate ACPI AML code for _ROM method.<br>+ * This function takes as input ROM data and ROM length.<br>+ * The ROM length has to be multiple of 4096 and has to be less<br>+ * than the current implementation limit of 0x40000.<br>+ */<br>+void acpigen_write_rom(void *bios, size_t length);<br> /*<br> * Generate ACPI AML code for OperationRegion<br> * This function takes input region name, region space, region offset & region<br></pre><p>To view, visit <a href="https://review.coreboot.org/20547">change 20547</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/20547"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ie118b15257295b7133c8e585c0fd5218249dec8d </div>
<div style="display:none"> Gerrit-Change-Number: 20547 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <siro@das-labor.org> </div>