This patch changes SeaBIOS to pass the PCI regions via a dynamically updated SSDT instead of via the BDAT memory reference system. This change will likely make it easier to port the ACPI tables to QEMU.
This patch has only been lightly tested.
Gerd - I know you ran various tests when originally introducing the BDAT system. Do you recall what test cases you used?
-Kevin
Kevin O'Connor (2): Rename src/ssdt-susp.dsl to src/ssdt-misc.dsl. acpi: Eliminate BDAT parameter passing to DSDT code.
Makefile | 2 +- src/acpi-dsdt-pci-crs.dsl | 61 +++++++++++++++++------------------------------ src/acpi.c | 47 +++++++++++++----------------------- src/acpi.h | 9 ------- src/ssdt-misc.dsl | 58 ++++++++++++++++++++++++++++++++++++++++++++ src/ssdt-susp.dsl | 38 ----------------------------- tools/acpi_extract.py | 17 ++++++++++++- 7 files changed, 114 insertions(+), 118 deletions(-) create mode 100644 src/ssdt-misc.dsl delete mode 100644 src/ssdt-susp.dsl
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- src/acpi.c | 8 ++++---- src/ssdt-misc.dsl | 38 ++++++++++++++++++++++++++++++++++++++ src/ssdt-susp.dsl | 38 -------------------------------------- 4 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 src/ssdt-misc.dsl delete mode 100644 src/ssdt-susp.dsl
diff --git a/Makefile b/Makefile index 1ce2f79..ada8fa5 100644 --- a/Makefile +++ b/Makefile @@ -220,7 +220,7 @@ $(OUT)%.hex: src/%.dsl ./tools/acpi_extract_preprocess.py ./tools/acpi_extract.p $(Q)$(PYTHON) ./tools/acpi_extract.py $(OUT)$*.lst > $(OUT)$*.off $(Q)cat $(OUT)$*.off > $@
-$(OUT)acpi.o: $(OUT)acpi-dsdt.hex $(OUT)ssdt-proc.hex $(OUT)ssdt-pcihp.hex $(OUT)ssdt-susp.hex $(OUT)q35-acpi-dsdt.hex +$(OUT)acpi.o: $(OUT)acpi-dsdt.hex $(OUT)ssdt-proc.hex $(OUT)ssdt-pcihp.hex $(OUT)ssdt-misc.hex $(OUT)q35-acpi-dsdt.hex
################ Kconfig rules
diff --git a/src/acpi.c b/src/acpi.c index 195dc88..658ca50 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -439,7 +439,7 @@ encodeLen(u8 *ssdt_ptr, int length, int bytes) #define SSDT_SIGNATURE 0x54445353 // SSDT #define SSDT_HEADER_LENGTH 36
-#include "ssdt-susp.hex" +#include "ssdt-misc.hex" #include "ssdt-pcihp.hex"
#define PCI_RMV_BASE 0xae0c @@ -496,7 +496,7 @@ static void* build_ssdt(void) { int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs; - int length = (sizeof(ssdp_susp_aml) // _S3_ / _S4_ / _S5_ + int length = (sizeof(ssdp_misc_aml) // _S3_ / _S4_ / _S5_ + (1+3+4) // Scope(_SB_) + (acpi_cpus * PROC_SIZEOF) // procs + (1+2+5+(12*acpi_cpus)) // NTFY @@ -518,14 +518,14 @@ build_ssdt(void) if (!sys_states || sys_state_size != 6) sys_states = (char[]){128, 0, 0, 129, 128, 128};
- memcpy(ssdt_ptr, ssdp_susp_aml, sizeof(ssdp_susp_aml)); + memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml)); if (!(sys_states[3] & 128)) ssdt_ptr[acpi_s3_name[0]] = 'X'; if (!(sys_states[4] & 128)) ssdt_ptr[acpi_s4_name[0]] = 'X'; else ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt[acpi_s4_pkg[0] + 3] = sys_states[4] & 127; - ssdt_ptr += sizeof(ssdp_susp_aml); + ssdt_ptr += sizeof(ssdp_misc_aml);
// build Scope(_SB_) header *(ssdt_ptr++) = 0x10; // ScopeOp diff --git a/src/ssdt-misc.dsl b/src/ssdt-misc.dsl new file mode 100644 index 0000000..f0a8df3 --- /dev/null +++ b/src/ssdt-misc.dsl @@ -0,0 +1,38 @@ +ACPI_EXTRACT_ALL_CODE ssdp_misc_aml + +DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) +{ + +/**************************************************************** + * Suspend + ****************************************************************/ + + Scope() { + /* + * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes: + * must match piix4 emulation. + */ + + ACPI_EXTRACT_NAME_STRING acpi_s3_name + Name(_S3, Package(0x04) { + One, /* PM1a_CNT.SLP_TYP */ + One, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + ACPI_EXTRACT_NAME_STRING acpi_s4_name + ACPI_EXTRACT_PKG_START acpi_s4_pkg + Name(_S4, Package(0x04) { + 0x2, /* PM1a_CNT.SLP_TYP */ + 0x2, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + Name(_S5, Package(0x04) { + Zero, /* PM1a_CNT.SLP_TYP */ + Zero, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + } +} diff --git a/src/ssdt-susp.dsl b/src/ssdt-susp.dsl deleted file mode 100644 index ca9428f..0000000 --- a/src/ssdt-susp.dsl +++ /dev/null @@ -1,38 +0,0 @@ -ACPI_EXTRACT_ALL_CODE ssdp_susp_aml - -DefinitionBlock ("ssdt-susp.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) -{ - -/**************************************************************** - * Suspend - ****************************************************************/ - - Scope() { - /* - * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes: - * must match piix4 emulation. - */ - - ACPI_EXTRACT_NAME_STRING acpi_s3_name - Name(_S3, Package(0x04) { - One, /* PM1a_CNT.SLP_TYP */ - One, /* PM1b_CNT.SLP_TYP */ - Zero, /* reserved */ - Zero /* reserved */ - }) - ACPI_EXTRACT_NAME_STRING acpi_s4_name - ACPI_EXTRACT_PKG_START acpi_s4_pkg - Name(_S4, Package(0x04) { - 0x2, /* PM1a_CNT.SLP_TYP */ - 0x2, /* PM1b_CNT.SLP_TYP */ - Zero, /* reserved */ - Zero /* reserved */ - }) - Name(_S5, Package(0x04) { - Zero, /* PM1a_CNT.SLP_TYP */ - Zero, /* PM1b_CNT.SLP_TYP */ - Zero, /* reserved */ - Zero /* reserved */ - }) - } -}
The "BDAT" construct is the only ACPI mechanism that relies on SeaBIOS reserved memory. Replace it with the SSDT based template system.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/acpi-dsdt-pci-crs.dsl | 61 +++++++++++++++++------------------------------ src/acpi.c | 39 ++++++++++-------------------- src/acpi.h | 9 ------- src/ssdt-misc.dsl | 20 ++++++++++++++++ tools/acpi_extract.py | 17 ++++++++++++- 5 files changed, 71 insertions(+), 75 deletions(-)
diff --git a/src/acpi-dsdt-pci-crs.dsl b/src/acpi-dsdt-pci-crs.dsl index 802eebc..d421891 100644 --- a/src/acpi-dsdt-pci-crs.dsl +++ b/src/acpi-dsdt-pci-crs.dsl @@ -56,52 +56,35 @@ Scope(_SB.PCI0) { })
Method(_CRS, 0) { - /* see see acpi.h, struct bfld */ - External(BDAT, OpRegionObj) - Field(BDAT, QWordAcc, NoLock, Preserve) { - P0S, 64, - P0E, 64, - P0L, 64, - P1S, 64, - P1E, 64, - P1L, 64, - } - Field(BDAT, DWordAcc, NoLock, Preserve) { - P0SL, 32, - P0SH, 32, - P0EL, 32, - P0EH, 32, - P0LL, 32, - P0LH, 32, - P1SL, 32, - P1SH, 32, - P1EL, 32, - P1EH, 32, - P1LL, 32, - P1LH, 32, - } + /* Fields provided by dynamically created ssdt */ + External(P0S, IntObj) + External(P0E, IntObj) + External(P1V, IntObj) + External(P1S, BuffObj) + External(P1E, BuffObj) + External(P1L, BuffObj)
/* fixup 32bit pci io window */ CreateDWordField(CRES, _SB.PCI0.PW32._MIN, PS32) CreateDWordField(CRES, _SB.PCI0.PW32._MAX, PE32) CreateDWordField(CRES, _SB.PCI0.PW32._LEN, PL32) - Store(P0SL, PS32) - Store(P0EL, PE32) - Store(P0LL, PL32) + Store(P0S, PS32) + Store(P0E, PE32) + Store(Add(Subtract(P0E, P0S), 1), PL32)
- If (LAnd(LEqual(P1SL, 0x00), LEqual(P1SH, 0x00))) { + If (LEqual(P1V, Zero)) { Return (CRES) - } Else { - /* fixup 64bit pci io window */ - CreateQWordField(CR64, _SB.PCI0.PW64._MIN, PS64) - CreateQWordField(CR64, _SB.PCI0.PW64._MAX, PE64) - CreateQWordField(CR64, _SB.PCI0.PW64._LEN, PL64) - Store(P1S, PS64) - Store(P1E, PE64) - Store(P1L, PL64) - /* add window and return result */ - ConcatenateResTemplate(CRES, CR64, Local0) - Return (Local0) } + + /* fixup 64bit pci io window */ + CreateQWordField(CR64, _SB.PCI0.PW64._MIN, PS64) + CreateQWordField(CR64, _SB.PCI0.PW64._MAX, PE64) + CreateQWordField(CR64, _SB.PCI0.PW64._LEN, PL64) + Store(P1S, PS64) + Store(P1E, PE64) + Store(P1L, PL64) + /* add window and return result */ + ConcatenateResTemplate(CRES, CR64, Local0) + Return (Local0) } } diff --git a/src/acpi.c b/src/acpi.c index 658ca50..98a5d40 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -501,7 +501,6 @@ build_ssdt(void) + (acpi_cpus * PROC_SIZEOF) // procs + (1+2+5+(12*acpi_cpus)) // NTFY + (6+2+1+(1*acpi_cpus)) // CPON - + 17 // BDAT + (1+3+4) // Scope(PCI0) + ((PCI_SLOTS - 1) * PCIHP_SIZEOF) // slots + (1+2+5+(12*(PCI_SLOTS - 1)))); // PCNT @@ -525,6 +524,19 @@ build_ssdt(void) ssdt_ptr[acpi_s4_name[0]] = 'X'; else ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt[acpi_s4_pkg[0] + 3] = sys_states[4] & 127; + + // store pci io windows + *(u32*)&ssdt_ptr[acpi_pci32_start[0]] = pcimem_start; + *(u32*)&ssdt_ptr[acpi_pci32_end[0]] = pcimem_end - 1; + if (pcimem64_start) { + ssdt_ptr[acpi_pci64_valid[0]] = 1; + *(u64*)&ssdt_ptr[acpi_pci64_start[0]] = pcimem64_start; + *(u64*)&ssdt_ptr[acpi_pci64_end[0]] = pcimem64_end - 1; + *(u64*)&ssdt_ptr[acpi_pci64_length[0]] = pcimem64_end - pcimem64_start; + } else { + ssdt_ptr[acpi_pci64_valid[0]] = 0; + } + ssdt_ptr += sizeof(ssdp_misc_aml);
// build Scope(_SB_) header @@ -562,31 +574,6 @@ build_ssdt(void) for (i=0; i<acpi_cpus; i++) *(ssdt_ptr++) = (apic_id_is_present(i)) ? 0x01 : 0x00;
- // store pci io windows: start, end, length - // this way we don't have to do the math in the dsdt - struct bfld *bfld = malloc_high(sizeof(struct bfld)); - bfld->p0s = pcimem_start; - bfld->p0e = pcimem_end - 1; - bfld->p0l = pcimem_end - pcimem_start; - bfld->p1s = pcimem64_start; - bfld->p1e = pcimem64_end - 1; - bfld->p1l = pcimem64_end - pcimem64_start; - - // build "OperationRegion(BDAT, SystemMemory, 0x12345678, 0x87654321)" - *(ssdt_ptr++) = 0x5B; // ExtOpPrefix - *(ssdt_ptr++) = 0x80; // OpRegionOp - *(ssdt_ptr++) = 'B'; - *(ssdt_ptr++) = 'D'; - *(ssdt_ptr++) = 'A'; - *(ssdt_ptr++) = 'T'; - *(ssdt_ptr++) = 0x00; // SystemMemory - *(ssdt_ptr++) = 0x0C; // DWordPrefix - *(u32*)ssdt_ptr = (u32)bfld; - ssdt_ptr += 4; - *(ssdt_ptr++) = 0x0C; // DWordPrefix - *(u32*)ssdt_ptr = sizeof(struct bfld); - ssdt_ptr += 4; - // build Scope(PCI0) opcode *(ssdt_ptr++) = 0x10; // ScopeOp ssdt_ptr = encodeLen(ssdt_ptr, length - (ssdt_ptr - ssdt), 3); diff --git a/src/acpi.h b/src/acpi.h index 6289953..7fbd082 100644 --- a/src/acpi.h +++ b/src/acpi.h @@ -113,15 +113,6 @@ struct fadt_descriptor_rev1 #endif } PACKED;
-struct bfld { - u64 p0s; /* pci window 0 (below 4g) - start */ - u64 p0e; /* pci window 0 (below 4g) - end */ - u64 p0l; /* pci window 0 (below 4g) - length */ - u64 p1s; /* pci window 1 (above 4g) - start */ - u64 p1e; /* pci window 1 (above 4g) - end */ - u64 p1l; /* pci window 1 (above 4g) - length */ -} PACKED; - /* PCI fw r3.0 MCFG table. */ /* Subtable */ struct acpi_mcfg_allocation { diff --git a/src/ssdt-misc.dsl b/src/ssdt-misc.dsl index f0a8df3..679422b 100644 --- a/src/ssdt-misc.dsl +++ b/src/ssdt-misc.dsl @@ -4,6 +4,26 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) {
/**************************************************************** + * PCI memory ranges + ****************************************************************/ + + Scope() { + ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start + Name(P0S, 0x12345678) + ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end + Name(P0E, 0x12345678) + ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid + Name(P1V, 0x12) + ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start + Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) + ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end + Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) + ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length + Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) + } + + +/**************************************************************** * Suspend ****************************************************************/
diff --git a/tools/acpi_extract.py b/tools/acpi_extract.py index dd3ccfd..ab8ced6 100755 --- a/tools/acpi_extract.py +++ b/tools/acpi_extract.py @@ -128,6 +128,15 @@ def aml_name_string(offset): offset += 1 return offset;
+# Given data offset, find 8 byte buffer offset +def aml_data_buffer8(offset): + #0x08 NameOp NameString DataRef + expect = [0x11, 0x0B, 0x0A, 0x08] + if (aml[offset:offset+4] != expect): + die( "Name offset 0x%x: expected %s actual %s" % + (offset, aml[offset:offset+4], expect)) + return offset + len(expect) + # Given data offset, find dword const offset def aml_data_dword_const(offset): #0x08 NameOp NameString DataRef @@ -152,6 +161,10 @@ def aml_data_byte_const(offset): (offset, aml[offset])); return offset + 1;
+# Find name'd buffer8 +def aml_name_buffer8(offset): + return aml_data_buffer8(aml_name_string(offset) + 4) + # Given name offset, find dword const offset def aml_name_dword_const(offset): return aml_data_dword_const(aml_name_string(offset) + 4) @@ -283,7 +296,9 @@ for i in range(len(asl)): die("%s directive used more than once" % directive) output[array] = aml continue - if (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"): + if (directive == "ACPI_EXTRACT_NAME_BUFFER8"): + offset = aml_name_buffer8(offset) + elif (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"): offset = aml_name_dword_const(offset) elif (directive == "ACPI_EXTRACT_NAME_WORD_CONST"): offset = aml_name_word_const(offset)
On 03/07/13 04:04, Kevin O'Connor wrote:
This patch changes SeaBIOS to pass the PCI regions via a dynamically updated SSDT instead of via the BDAT memory reference system. This change will likely make it easier to port the ACPI tables to QEMU.
This patch has only been lightly tested.
Looks good to me & survived my testing.
Gerd - I know you ran various tests when originally introducing the BDAT system. Do you recall what test cases you used?
(1) boot winxp -- must not BSOD at boot. (2) boot linux guest, check the 32bit io window is recognized correctly (boot messages, /proc/iomem). (3) boot linux with xxl pci bar: "qemu -vga qxl -global qxl-vga.vram64_size_mb=2048" seabios should map 64bit pci bar(s) above 4G and enable the 64bit window. Verify via seabios log, lspci, /proc/iomem, boot messages.
cheers, Gerd
On Fri, Mar 08, 2013 at 11:11:42AM +0100, Gerd Hoffmann wrote:
On 03/07/13 04:04, Kevin O'Connor wrote:
This patch changes SeaBIOS to pass the PCI regions via a dynamically updated SSDT instead of via the BDAT memory reference system. This change will likely make it easier to port the ACPI tables to QEMU.
This patch has only been lightly tested.
Looks good to me & survived my testing.
Thanks. I pushed this series.
-Kevin