ia64/xen-unstable

changeset 12620:5c47222b60dc

[HVMLOADER] acpi: Implement an acpi_rsdp_get() function that searches
for the RSDP in memory (up to the BIOS) rather than calculating its
start address. Recent changes seem to have moved the RSDP to another
location in memory so that I received 'BAD RSPD signature' messages.
I have also fixed some other possible issues related to return codes
and alignment of ACPI entries.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kfraser@localhost.localdomain
date Tue Nov 28 13:53:12 2006 +0000 (2006-11-28)
parents 4666710bfc55
children 1c51c580dc05
files tools/firmware/hvmloader/acpi_utils.c
line diff
     1.1 --- a/tools/firmware/hvmloader/acpi_utils.c	Tue Nov 28 13:50:32 2006 +0000
     1.2 +++ b/tools/firmware/hvmloader/acpi_utils.c	Tue Nov 28 13:53:12 2006 +0000
     1.3 @@ -85,7 +85,8 @@ static void acpi_tpm_tis_probe(unsigned 
     1.4          return;
     1.5  
     1.6      /* legacy systems need an RSDT entry */
     1.7 -    acpi_rsdt_add_entry_pointer(acpi_start, addr);
     1.8 +    if ( acpi_rsdt_add_entry_pointer(acpi_start, addr) != 1 )
     1.9 +        return;
    1.10  
    1.11      /* add ACPI TCPA table */
    1.12      addr = acpi_xsdt_add_entry(acpi_start, freemem, limit,
    1.13 @@ -108,7 +109,8 @@ static void acpi_tpm_tis_probe(unsigned 
    1.14                       tcpa->header.length);
    1.15      }
    1.16  
    1.17 -    acpi_rsdt_add_entry_pointer(acpi_start, addr);
    1.18 +    if ( acpi_rsdt_add_entry_pointer(acpi_start, addr) != 1 )
    1.19 +        return;
    1.20  }
    1.21  
    1.22  
    1.23 @@ -125,17 +127,51 @@ void acpi_update(unsigned char *acpi_sta
    1.24  }
    1.25  
    1.26  
    1.27 +/*
    1.28 + * Search for the RSDP in memory below the BIOS
    1.29 + */
    1.30 +struct acpi_20_rsdp *acpi_rsdp_get(unsigned char *acpi_start)
    1.31 +{
    1.32 +    int offset = 0;
    1.33 +    int found = 0;
    1.34 +    static int displayed = 0;
    1.35 +    struct acpi_20_rsdp *rsdp;
    1.36 +
    1.37 +    while ( &acpi_start[offset] < (unsigned char *)0xf0000 )
    1.38 +    {
    1.39 +        rsdp = (struct acpi_20_rsdp *)&acpi_start[offset];
    1.40 +        if ( rsdp->signature == ACPI_2_0_RSDP_SIGNATURE )
    1.41 +        {
    1.42 +            found = 1;
    1.43 +            break;
    1.44 +        }
    1.45 +        offset += 0x10;
    1.46 +    }
    1.47 +    
    1.48 +    if ( !found )
    1.49 +        rsdp = NULL;
    1.50 +
    1.51 +    if ( !displayed )
    1.52 +    {
    1.53 +        if ( rsdp )
    1.54 +            printf("Found RSDP at %lx\n",(long)rsdp);
    1.55 +        else
    1.56 +            printf("ERROR: RSDP was not found\n");
    1.57 +        displayed = 1;
    1.58 +    }
    1.59 +
    1.60 +    return rsdp;
    1.61 +}
    1.62 +
    1.63 +
    1.64  struct acpi_20_rsdt *acpi_rsdt_get(unsigned char *acpi_start)
    1.65  {
    1.66      struct acpi_20_rsdp *rsdp;
    1.67      struct acpi_20_rsdt *rsdt;
    1.68  
    1.69 -    rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs));
    1.70 -    if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE )
    1.71 -    {
    1.72 -        printf("Bad RSDP signature\n");
    1.73 +    rsdp = acpi_rsdp_get(acpi_start);
    1.74 +    if (!rsdp)
    1.75          return NULL;
    1.76 -    }
    1.77  
    1.78      rsdt = (struct acpi_20_rsdt *)
    1.79          (acpi_start + rsdp->rsdt_address - ACPI_PHYSICAL_ADDRESS);
    1.80 @@ -189,12 +225,9 @@ struct acpi_20_xsdt *acpi_xsdt_get(unsig
    1.81      struct acpi_20_rsdp *rsdp;
    1.82      struct acpi_20_xsdt *xsdt;
    1.83  
    1.84 -    rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs));
    1.85 -    if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE )
    1.86 -    {
    1.87 -        printf("Bad RSDP signature\n");
    1.88 +    rsdp = acpi_rsdp_get(acpi_start);
    1.89 +    if (!rsdp)
    1.90          return NULL;
    1.91 -    }
    1.92  
    1.93      xsdt = (struct acpi_20_xsdt *)
    1.94          (acpi_start + rsdp->xsdt_address - ACPI_PHYSICAL_ADDRESS);
    1.95 @@ -272,10 +305,10 @@ static unsigned char *acpi_xsdt_add_entr
    1.96          /* memory below hard limit ? */
    1.97          if ( (*freemem + table_size) <= limit )
    1.98          {
    1.99 -            printf("Copying SSDT entry\n");
   1.100              addr = *freemem;
   1.101              memcpy(addr, table, table_size);
   1.102 -            *freemem += table_size;
   1.103 +            printf("Copied dyn. ACPI entry to %lx\n",(long)addr);
   1.104 +            *freemem += ((table_size + 0xf) & ~0xf);
   1.105  
   1.106              acpi_xsdt_add_entry_pointer(acpi_start, addr);
   1.107          }