>From 581045edb168717c7f5691be1af5f75d35c3ebf5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 15 May 2012 10:38:05 +0200 Subject: [PATCH] update dsdt ressources at runtime 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 --- src/acpi-dsdt.dsl | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/acpi.c | 28 ++++++++++++++++++- src/acpi.h | 9 ++++++ 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl index 4bdc268..3e3999a 100644 --- a/src/acpi-dsdt.dsl +++ b/src/acpi-dsdt.dsl @@ -61,6 +61,38 @@ DefinitionBlock ( /**************************************************************** + * Data area filled by seabios (see acpi.h, struct bfld) + ****************************************************************/ + + Scope(\_SB) { + Device(BFLD) { + External (\_SB.BDAT) + Field(\_SB.BDAT, QWordAcc, NoLock, Preserve) { + P0S, 64, + P0E, 64, + P0L, 64, + P1S, 64, + P1E, 64, + P1L, 64, + } + Field(\_SB.BDAT, DWordAcc, NoLock, Preserve) { + P0SL, 64, + P0SH, 64, + P0EL, 64, + P0EH, 64, + P0LL, 64, + P0LH, 64, + P1SL, 64, + P1SH, 64, + P1EL, 64, + P1EH, 64, + P1LL, 64, + P1LH, 64, + } + } + } + +/**************************************************************** * PCI Bus definition ****************************************************************/ @@ -132,7 +164,7 @@ DefinitionBlock ( B0EJ, 32, } - Name (_CRS, ResourceTemplate () + Name (CRES, ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x0000, // Address Space Granularity @@ -174,8 +206,49 @@ 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) + { + DBUG("pci0 _crs: enter") + + /* 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 (\_SB.BFLD.P0SL, PS32) + Store (\_SB.BFLD.P0EL, PE32) + Store (\_SB.BFLD.P0LL, PL32) + + If (LAnd(LEqual(\_SB.BFLD.P1SL, 0x00), + LEqual(\_SB.BFLD.P1SH, 0x00))) { + DBUG("pci0 _crs: 32bit") + Return (CRES) + } Else { + DBUG("pci0 _crs: 64bit") + /* 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 (\_SB.BFLD.P1S, PS64) + Store (\_SB.BFLD.P1E, PE64) + Store (\_SB.BFLD.P1L, PL64) + /* add window and return result */ + ConcatenateResTemplate (CRES, CR64, Local0) + DBUG("pci0 _crs: done") + Return (Local0) + } + } } } diff --git a/src/acpi.c b/src/acpi.c index 30888b9..5c3aaec 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; ip0s = pcimem_start; + bfld->p0e = pcimem_end - 1; + bfld->p0l = pcimem_end - pcimem_start - 1; + bfld->p1s = pcimem64_start; + bfld->p1e = pcimem64_end - 1; + bfld->p1l = pcimem64_end - pcimem64_start - 1; + + // 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 -- 1.7.1