Message ID | 20120504153725.GA6782@morn.localdomain |
---|---|
State | New |
Headers | show |
On Fri, May 04, 2012 at 11:37:25AM -0400, Kevin O'Connor wrote: > On Fri, May 04, 2012 at 10:46:00AM -0400, Kevin O'Connor wrote: > > On Fri, May 04, 2012 at 04:01:56PM +0200, Gerd Hoffmann wrote: > > > On 05/04/12 15:18, Kevin O'Connor wrote: > > > > On Fri, May 04, 2012 at 10:21:22AM +0200, Gerd Hoffmann wrote: > > > >> Hi, > > > >> > > > >> This patch series makes the PCI I/O windows runtime-configurable via > > > >> qemu firmware config interface. Main advantage is that we can size and > > > >> shuffle around the PCI i/O windows according to the amount of memory the > > > >> virtual machine has. We don't need a hole for 64bit PCI bars, we can > > > >> just map them above the main memory. The hole for 32bit PCI bars can be > > > >> enlarged for guests with less than 3.5 GB of memory. > > > > > > > > Why pass in a PCI IO range through fw_cfg if SeaBIOS can figure out an > > > > acceptable range from the amount of memory in the machine? > > > > > > Suggestions on how to update the pci host bridge windows in the dsdt then? > > > > Perhaps malloc_high() a struct with the info you need and then create > > an OperationRegion() in the dynamically generated SSDT with the > > address of the struct. > > I played with this a little and came up with the below as an example. > IMO that is much better than reading fw_cfg from AML. fw_cfg wasn't meant to be touched while OS is running. Another option is to patch the DSDT directly. We have the infrastructure for that in place. > -Kevin > > > diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl > index 4a18617..960f9fb 100644 > --- a/src/acpi-dsdt.dsl > +++ b/src/acpi-dsdt.dsl > @@ -132,7 +132,7 @@ DefinitionBlock ( > B0EJ, 32, > } > > - Name (_CRS, ResourceTemplate () > + Name (CRES, ResourceTemplate () > { > WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, > 0x0000, // Address Space Granularity > @@ -183,6 +183,18 @@ DefinitionBlock ( > 0x8000000000, // Address Length > ,, , AddressRangeMemory, TypeStatic) > }) > + Method (_CRS, 0) > + { > + External (\_SB.BDAT) > + Field(\_SB.BDAT, DWordAcc, NoLock, Preserve) { > + VAL1, 32, > + VAL2, 32, > + } > + DBUG("Got") > + DBUG(VAL1) > + DBUG(VAL2) > + Return (CRES) > + } > } > } > > diff --git a/src/acpi.c b/src/acpi.c > index 30888b9..3e0d4da 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,26 @@ build_ssdt(void) > for (i=0; i<acpi_cpus; i++) > *(ssdt_ptr++) = (i < CountCPUs) ? 0x01 : 0x00; > > + // XXX > + u32 *myval = malloc_high(sizeof(*myval) * 2); > + myval[0] = 0x1234abcd; > + myval[1] = 0xdcba8976; > + > + // 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)myval; > + ssdt_ptr += 4; > + *(ssdt_ptr++) = 0x0C; // DWordPrefix > + *(u32*)ssdt_ptr = sizeof(*myval)*2; > + ssdt_ptr += 4; > + > build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1); > > //hexdump(ssdt, ssdt_ptr - ssdt); -- Gleb.
diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl index 4a18617..960f9fb 100644 --- a/src/acpi-dsdt.dsl +++ b/src/acpi-dsdt.dsl @@ -132,7 +132,7 @@ DefinitionBlock ( B0EJ, 32, } - Name (_CRS, ResourceTemplate () + Name (CRES, ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x0000, // Address Space Granularity @@ -183,6 +183,18 @@ DefinitionBlock ( 0x8000000000, // Address Length ,, , AddressRangeMemory, TypeStatic) }) + Method (_CRS, 0) + { + External (\_SB.BDAT) + Field(\_SB.BDAT, DWordAcc, NoLock, Preserve) { + VAL1, 32, + VAL2, 32, + } + DBUG("Got") + DBUG(VAL1) + DBUG(VAL2) + Return (CRES) + } } } diff --git a/src/acpi.c b/src/acpi.c index 30888b9..3e0d4da 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,26 @@ build_ssdt(void) for (i=0; i<acpi_cpus; i++) *(ssdt_ptr++) = (i < CountCPUs) ? 0x01 : 0x00; + // XXX + u32 *myval = malloc_high(sizeof(*myval) * 2); + myval[0] = 0x1234abcd; + myval[1] = 0xdcba8976; + + // 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)myval; + ssdt_ptr += 4; + *(ssdt_ptr++) = 0x0C; // DWordPrefix + *(u32*)ssdt_ptr = sizeof(*myval)*2; + ssdt_ptr += 4; + build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1); //hexdump(ssdt, ssdt_ptr - ssdt);