[SeaBIOS] [PATCH 5/6] update dsdt ressources at runtime

Gleb Natapov gleb at redhat.com
Tue May 22 11:57:38 CEST 2012


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 at 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))
> >> +                  + 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 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 at 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 at 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))
> +                  + 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
> SeaBIOS at seabios.org
> http://www.seabios.org/mailman/listinfo/seabios


--
			Gleb.



More information about the SeaBIOS mailing list