arch/x86/acpigen: Fix corner case in _ROM generator
In case the Option ROM isn't a multiple of 4KiB the last buffer was truncated to prevent a buffer overrun. But tests on nouveau showed that nouveau expects a buffer that has the requested size and is zero padded instead. Always return a buffer with requested size and zero pad the remaining bytes. Fixes nouveau on Lenovo W520 with Option ROM not being multiple of 4 KiB. Change-Id: I3f0ecc42a21945f66eb67f73e511bd516acf0fa9 Signed-off-by: Patrick Rudolph <siro@das-labor.org> Reviewed-on: https://review.coreboot.org/25999 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Rikken <nico@nicorikken.eu> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Naresh Solanki <naresh.solanki@intel.com>
This commit is contained in:
parent
892e9f6030
commit
65cbbe77ac
|
@ -1342,6 +1342,10 @@ void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count)
|
||||||
* Generate ACPI AML code for _ROM method.
|
* Generate ACPI AML code for _ROM method.
|
||||||
* This function takes as input ROM data and ROM length.
|
* This function takes as input ROM data and ROM length.
|
||||||
*
|
*
|
||||||
|
* The ACPI spec isn't clear about what should happen at the end of the
|
||||||
|
* ROM. Tests showed that it shouldn't truncate, but fill the remaining
|
||||||
|
* bytes in the returned buffer with zeros.
|
||||||
|
*
|
||||||
* Arguments passed into _DSM method:
|
* Arguments passed into _DSM method:
|
||||||
* Arg0 = Offset in Bytes
|
* Arg0 = Offset in Bytes
|
||||||
* Arg1 = Bytes to return
|
* Arg1 = Bytes to return
|
||||||
|
@ -1367,6 +1371,8 @@ void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count)
|
||||||
* Store (0x1000, Local1)
|
* Store (0x1000, Local1)
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
* Store (Local1, Local3)
|
||||||
|
*
|
||||||
* If (LGreater (Local0, 0x10000))
|
* If (LGreater (Local0, 0x10000))
|
||||||
* {
|
* {
|
||||||
* Return(Buffer(Local1){0})
|
* Return(Buffer(Local1){0})
|
||||||
|
@ -1381,7 +1387,7 @@ void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count)
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* Name (ROM1, Buffer (Local1) {0})
|
* Name (ROM1, Buffer (Local3) {0})
|
||||||
*
|
*
|
||||||
* Multiply (Local0, 0x08, Local0)
|
* Multiply (Local0, 0x08, Local0)
|
||||||
* Multiply (Local1, 0x08, Local1)
|
* Multiply (Local1, 0x08, Local1)
|
||||||
|
@ -1443,6 +1449,11 @@ void acpigen_write_rom(void *bios, const size_t length)
|
||||||
/* Pop if */
|
/* Pop if */
|
||||||
acpigen_pop_len();
|
acpigen_pop_len();
|
||||||
|
|
||||||
|
/* Store (Local1, Local3) */
|
||||||
|
acpigen_write_store();
|
||||||
|
acpigen_emit_byte(LOCAL1_OP);
|
||||||
|
acpigen_emit_byte(LOCAL3_OP);
|
||||||
|
|
||||||
/* If (LGreater (Local0, length)) */
|
/* If (LGreater (Local0, length)) */
|
||||||
acpigen_write_if();
|
acpigen_write_if();
|
||||||
acpigen_emit_byte(LGREATER_OP);
|
acpigen_emit_byte(LGREATER_OP);
|
||||||
|
@ -1489,11 +1500,11 @@ void acpigen_write_rom(void *bios, const size_t length)
|
||||||
/* Pop if */
|
/* Pop if */
|
||||||
acpigen_pop_len();
|
acpigen_pop_len();
|
||||||
|
|
||||||
/* Name (ROM1, Buffer (Local1) {0}) */
|
/* Name (ROM1, Buffer (Local3) {0}) */
|
||||||
acpigen_write_name("ROM1");
|
acpigen_write_name("ROM1");
|
||||||
acpigen_emit_byte(BUFFER_OP);
|
acpigen_emit_byte(BUFFER_OP);
|
||||||
acpigen_write_len_f();
|
acpigen_write_len_f();
|
||||||
acpigen_emit_byte(LOCAL1_OP);
|
acpigen_emit_byte(LOCAL3_OP);
|
||||||
acpigen_emit_byte(0);
|
acpigen_emit_byte(0);
|
||||||
acpigen_pop_len();
|
acpigen_pop_len();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue