On Tue, May 22, 2012 at 11:55:02AM +0200, Gerd Hoffmann wrote:
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 kraxel@redhat.com
[...]
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))
u8 *ssdt = malloc_high(sizeof(struct acpi_table_header) + length); if (! ssdt) { warn_noalloc();+ 17);
@@ -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 S3 I just patch the value directly and do not see the reason to complicated it.
[ 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 kraxel@redhat.com 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 kraxel@redhat.com
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))
u8 *ssdt = malloc_high(sizeof(struct acpi_table_header) + length); if (! ssdt) { warn_noalloc();+ 17);
@@ -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 SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
-- Gleb.