On 05/18/12 05:07, Kevin O'Connor wrote: > On Tue, May 15, 2012 at 12:46:25PM +0200, Gerd Hoffmann wrote: >> 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 <[email protected]> > [...] >> diff --git a/src/acpi.c b/src/acpi.c >> index 30888b9..a13298d 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 >> + u64 *pcimem = malloc_high(sizeof(*pcimem) * 6); >> + pcimem[0] = pcimem_start; >> + pcimem[1] = pcimem_end - 1; >> + pcimem[2] = pcimem_end - pcimem_start - 1; >> + pcimem[3] = pcimem64_start; >> + pcimem[4] = pcimem64_end - 1; >> + pcimem[5] = pcimem64_end - pcimem64_start - 1; > > I think we should really define a struct here instead of an array - > that should make it more obvious what's going on. > > -Kevin
Done, also created a virtual device in the dsdt to access those fields so we have a single place in the dsdt we have to keep in sync with acpi.h in case we are going to add more stuff there (as discussed for s3). Comments? [ for review only, guess we want pin down the w2k8 issue before committing, although that one is less critical than the winxp issue as it triggers only in case something is actually mapped high ... ] cheers, Gerd
>From 581045edb168717c7f5691be1af5f75d35c3ebf5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann <[email protected]> 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 <[email protected]> --- 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; 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 - 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
_______________________________________________ SeaBIOS mailing list [email protected] http://www.seabios.org/mailman/listinfo/seabios
