Write the pci window location to memory and add a pointer to the SSDT (BDAT region). Turn \SB.PCI0._CRS into a method which looks up the information there and updates the ressources accordingly.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/acpi-dsdt.dsl | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/acpi.c | 28 ++++++++++++++++++++++- src/acpi.h | 9 +++++++ 3 files changed, 98 insertions(+), 4 deletions(-)
diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl index 4bdc268..5305ff9 100644 --- a/src/acpi-dsdt.dsl +++ b/src/acpi-dsdt.dsl @@ -59,7 +59,6 @@ DefinitionBlock ( } }
- /**************************************************************** * PCI Bus definition ****************************************************************/ @@ -132,7 +131,7 @@ DefinitionBlock ( B0EJ, 32, }
- Name (_CRS, ResourceTemplate () + Name (CRES, ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x0000, // Address Space Granularity @@ -174,8 +173,68 @@ DefinitionBlock ( 0xFEBFFFFF, // Address Range Maximum 0x00000000, // Address Translation Offset 0x1EC00000, // Address Length - ,, , AddressRangeMemory, TypeStatic) + ,, PW32, AddressRangeMemory, TypeStatic) }) + Name (CR64, ResourceTemplate () + { + QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, + 0x00000000, // Address Space Granularity + 0x8000000000, // Address Range Minimum + 0xFFFFFFFFFF, // Address Range Maximum + 0x00000000, // Address Translation Offset + 0x8000000000, // Address Length + ,, PW64, AddressRangeMemory, TypeStatic) + }) + 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, + } + + /* 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) + + If (LAnd(LEqual(P1SL, 0x00), LEqual(P1SH, 0x00))) { + 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) + } + } } }
diff --git a/src/acpi.c b/src/acpi.c index 5387183..365267b 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -415,7 +415,8 @@ build_ssdt(void) int length = ((1+3+4) + (acpi_cpus * SD_SIZEOF) + (1+2+5+(12*acpi_cpus)) - + (6+2+1+(1*acpi_cpus))); + + (6+2+1+(1*acpi_cpus)) + + 17); u8 *ssdt = malloc_high(sizeof(struct acpi_table_header) + length); if (! ssdt) { warn_noalloc(); @@ -477,6 +478,31 @@ build_ssdt(void) for (i=0; i<acpi_cpus; i++) *(ssdt_ptr++) = (i < CountCPUs) ? 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_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1);
//hexdump(ssdt, ssdt_ptr - ssdt); diff --git a/src/acpi.h b/src/acpi.h index e01315a..cb21561 100644 --- a/src/acpi.h +++ b/src/acpi.h @@ -98,4 +98,13 @@ 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; + #endif // acpi.h