[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] hvmloader: allocate ACPI tables as we go



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1307118117 -3600
# Node ID 396b11c69144ee43b43f3c892e2a620bde74d4ad
# Parent  d5097672d125b5d43fc621e603042dcf8b16cb2c
hvmloader: allocate ACPI tables as we go

Rather than building the tables twice, once purely to figure out the
size, just allocate each individual table as we go.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---


diff -r d5097672d125 -r 396b11c69144 tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Fri Jun 03 17:21:40 2011 +0100
+++ b/tools/firmware/hvmloader/acpi/build.c     Fri Jun 03 17:21:57 2011 +0100
@@ -68,12 +68,21 @@
     return (inb(0x88) == 0x1F);
 }
 
-static int construct_madt(struct acpi_20_madt *madt)
+static struct acpi_20_madt *construct_madt(void)
 {
+    struct acpi_20_madt           *madt;
     struct acpi_20_madt_intsrcovr *intsrcovr;
     struct acpi_20_madt_ioapic    *io_apic;
     struct acpi_20_madt_lapic     *lapic;
-    int i, offset = 0;
+    int i, sz;
+
+    sz  = sizeof(struct acpi_20_madt);
+    sz += sizeof(struct acpi_20_madt_intsrcovr) * 16;
+    sz += sizeof(struct acpi_20_madt_ioapic);
+    sz += sizeof(struct acpi_20_madt_lapic) * nr_processor_objects;
+
+    madt = mem_alloc(sz, 16);
+    if (!madt) return NULL;
 
     memset(madt, 0, sizeof(*madt));
     madt->header.signature    = ACPI_2_0_MADT_SIGNATURE;
@@ -85,7 +94,6 @@
     madt->header.creator_revision = ACPI_CREATOR_REVISION;
     madt->lapic_addr = LAPIC_BASE_ADDRESS;
     madt->flags      = ACPI_PCAT_COMPAT;
-    offset += sizeof(*madt);
 
     intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1);
     for ( i = 0; i < 16; i++ )
@@ -113,7 +121,6 @@
             continue;
         }
 
-        offset += sizeof(*intsrcovr);
         intsrcovr++;
     }
 
@@ -123,7 +130,6 @@
     io_apic->length      = sizeof(*io_apic);
     io_apic->ioapic_id   = IOAPIC_ID;
     io_apic->ioapic_addr = IOAPIC_BASE_ADDRESS;
-    offset += sizeof(*io_apic);
 
     lapic = (struct acpi_20_madt_lapic *)(io_apic + 1);
     madt_lapic0_addr = (uint32_t)lapic;
@@ -138,20 +144,23 @@
         lapic->flags = ((i < hvm_info->nr_vcpus) &&
                         test_bit(i, hvm_info->vcpu_online)
                         ? ACPI_LOCAL_APIC_ENABLED : 0);
-        offset += sizeof(*lapic);
         lapic++;
     }
 
-    madt->header.length = offset;
-    set_checksum(madt, offsetof(struct acpi_header, checksum), offset);
+    madt->header.length = (unsigned char *)lapic - (unsigned char *)madt;
+    set_checksum(madt, offsetof(struct acpi_header, checksum),
+                 madt->header.length);
     madt_csum_addr = (uint32_t)&madt->header.checksum;
 
-    return align16(offset);
+    return madt;
 }
 
-static int construct_hpet(struct acpi_20_hpet *hpet)
+static struct acpi_20_hpet *construct_hpet(void)
 {
-    int offset;
+    struct acpi_20_hpet *hpet;
+
+    hpet = mem_alloc(sizeof(*hpet), 16);
+    if (!hpet) return NULL;
 
     memset(hpet, 0, sizeof(*hpet));
     hpet->header.signature    = ACPI_2_0_HPET_SIGNATURE;
@@ -163,20 +172,20 @@
     hpet->header.creator_revision = ACPI_CREATOR_REVISION;
     hpet->timer_block_id      = 0x8086a201;
     hpet->addr.address        = ACPI_HPET_ADDRESS;
-    offset = sizeof(*hpet);
 
-    hpet->header.length = offset;
-    set_checksum(hpet, offsetof(struct acpi_header, checksum), offset);
-
-    return offset;
+    hpet->header.length = sizeof(*hpet);
+    set_checksum(hpet, offsetof(struct acpi_header, checksum),
+                 hpet->header.length = sizeof(*hpet));
+    return hpet;
 }
 
-static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
+static int construct_secondary_tables(unsigned long *table_ptrs)
 {
-    int offset = 0, nr_tables = 0;
+    int nr_tables = 0;
     struct acpi_20_madt *madt;
     struct acpi_20_hpet *hpet;
     struct acpi_20_tcpa *tcpa;
+    unsigned char *ssdt;
     static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};
     uint16_t *tis_hdr;
     void *lasa;
@@ -184,22 +193,23 @@
     /* MADT. */
     if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
     {
-        madt = (struct acpi_20_madt *)&buf[offset];
-        offset += construct_madt(madt);
+        madt = construct_madt();
+        if (!madt) return -1;
         table_ptrs[nr_tables++] = (unsigned long)madt;
     }
 
     /* HPET. Always included in DSDT, so always include it here too. */
     /* (And it's unconditionally required by Windows SVVP tests.) */
-    hpet = (struct acpi_20_hpet *)&buf[offset];
-    offset += construct_hpet(hpet);
+    hpet = construct_hpet();
+    if (!hpet) return -1;
     table_ptrs[nr_tables++] = (unsigned long)hpet;
 
-    if ( battery_port_exists() ) 
+    if ( battery_port_exists() )
     {
-        table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
-        memcpy(&buf[offset], ssdt_pm, sizeof(ssdt_pm));
-        offset += align16(sizeof(ssdt_pm));
+        ssdt = mem_alloc(sizeof(ssdt_pm), 16);
+        if (!ssdt) return -1;
+        memcpy(ssdt, ssdt_pm, sizeof(ssdt_pm));
+        table_ptrs[nr_tables++] = (unsigned long)ssdt;
     }
 
     /* TPM TCPA and SSDT. */
@@ -208,13 +218,14 @@
          (tis_hdr[1] == tis_signature[1]) &&
          (tis_hdr[2] == tis_signature[2]) )
     {
-        memcpy(&buf[offset], ssdt_tpm, sizeof(ssdt_tpm));
-        table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
-        offset += align16(sizeof(ssdt_tpm));
+        ssdt = mem_alloc(sizeof(ssdt_tpm), 16);
+        if (!ssdt) return -1;
+        memcpy(ssdt, ssdt_tpm, sizeof(ssdt_tpm));
+        table_ptrs[nr_tables++] = (unsigned long)ssdt;
 
-        tcpa = (struct acpi_20_tcpa *)&buf[offset];
+        tcpa = mem_alloc(sizeof(struct acpi_20_tcpa), 16);
+        if (!tcpa) return -1;
         memset(tcpa, 0, sizeof(*tcpa));
-        offset += align16(sizeof(*tcpa));
         table_ptrs[nr_tables++] = (unsigned long)tcpa;
 
         tcpa->header.signature = ACPI_2_0_TCPA_SIGNATURE;
@@ -225,7 +236,7 @@
         tcpa->header.oem_revision = ACPI_OEM_REVISION;
         tcpa->header.creator_id   = ACPI_CREATOR_ID;
         tcpa->header.creator_revision = ACPI_CREATOR_REVISION;
-        if ( (lasa = mem_alloc(ACPI_2_0_TCPA_LAML_SIZE, 0)) != NULL )
+        if ( (lasa = mem_alloc(ACPI_2_0_TCPA_LAML_SIZE, 16)) != NULL )
         {
             tcpa->lasa = virt_to_phys(lasa);
             tcpa->laml = ACPI_2_0_TCPA_LAML_SIZE;
@@ -237,12 +248,10 @@
     }
 
     table_ptrs[nr_tables] = 0;
-    return align16(offset);
+    return nr_tables;
 }
 
-static void __acpi_build_tables(unsigned int physical,
-                                uint8_t *buf,
-                                int *low_sz, int *high_sz)
+void acpi_build_tables(unsigned int physical)
 {
     struct acpi_20_rsdp *rsdp;
     struct acpi_20_rsdt *rsdt;
@@ -252,27 +261,28 @@
     struct acpi_20_facs *facs;
     unsigned char       *dsdt;
     unsigned long        secondary_tables[16];
-    int                  offset = 0, i;
+    int                  nr_secondaries, i;
 
     /*
      * Fill in high-memory data structures, starting at @buf.
      */
 
-    facs = (struct acpi_20_facs *)&buf[offset];
+    facs = mem_alloc(sizeof(struct acpi_20_facs), 16);
+    if (!facs) goto oom;
     memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
-    offset += align16(sizeof(struct acpi_20_facs));
 
-    dsdt = (unsigned char *)&buf[offset];
     if ( hvm_info->nr_vcpus <= 15 )
     {
+        dsdt = mem_alloc(dsdt_15cpu_len, 16);
+        if (!dsdt) goto oom;
         memcpy(dsdt, &dsdt_15cpu, dsdt_15cpu_len);
-        offset += align16(dsdt_15cpu_len);
         nr_processor_objects = 15;
     }
     else
     {
+        dsdt = mem_alloc(dsdt_anycpu_len, 16);
+        if (!dsdt) goto oom;
         memcpy(dsdt, &dsdt_anycpu, dsdt_anycpu_len);
-        offset += align16(dsdt_anycpu_len);
         nr_processor_objects = HVM_MAX_VCPUS;
     }
 
@@ -284,9 +294,9 @@
      * compatible revision 1 FADT that is linked with the RSDT. Refer to:
      *     http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt
      */
-    fadt_10 = (struct acpi_10_fadt *)&buf[offset];
+    fadt_10 = mem_alloc(sizeof(struct acpi_10_fadt), 16);
+    if (!fadt_10) goto oom;
     memcpy(fadt_10, &Fadt, sizeof(struct acpi_10_fadt));
-    offset += align16(sizeof(struct acpi_10_fadt));
     fadt_10->header.length = sizeof(struct acpi_10_fadt);
     fadt_10->header.revision = ACPI_1_0_FADT_REVISION;
     fadt_10->dsdt          = (unsigned long)dsdt;
@@ -295,9 +305,9 @@
                  offsetof(struct acpi_header, checksum),
                  sizeof(struct acpi_10_fadt));
 
-    fadt = (struct acpi_20_fadt *)&buf[offset];
+    fadt = mem_alloc(sizeof(struct acpi_20_fadt), 16);
+    if (!fadt) goto oom;
     memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
-    offset += align16(sizeof(struct acpi_20_fadt));
     fadt->dsdt   = (unsigned long)dsdt;
     fadt->x_dsdt = (unsigned long)dsdt;
     fadt->firmware_ctrl   = (unsigned long)facs;
@@ -306,42 +316,42 @@
                  offsetof(struct acpi_header, checksum),
                  sizeof(struct acpi_20_fadt));
 
-    offset += construct_secondary_tables(&buf[offset], secondary_tables);
+    nr_secondaries = construct_secondary_tables(secondary_tables);
+    if ( nr_secondaries < 0 )
+        goto oom;
 
-    xsdt = (struct acpi_20_xsdt *)&buf[offset];
+    xsdt = mem_alloc(sizeof(struct acpi_20_xsdt)+
+                     sizeof(uint64_t)*nr_secondaries,
+                     16);
+    if (!xsdt) goto oom;
     memcpy(xsdt, &Xsdt, sizeof(struct acpi_header));
     xsdt->entry[0] = (unsigned long)fadt;
     for ( i = 0; secondary_tables[i]; i++ )
         xsdt->entry[i+1] = secondary_tables[i];
     xsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint64_t);
-    offset += align16(xsdt->header.length);
     set_checksum(xsdt,
                  offsetof(struct acpi_header, checksum),
                  xsdt->header.length);
 
-    rsdt = (struct acpi_20_rsdt *)&buf[offset];
+    rsdt = mem_alloc(sizeof(struct acpi_20_rsdt)+
+                     sizeof(uint32_t)*nr_secondaries,
+                     16);
+    if (!rsdt) goto oom;
     memcpy(rsdt, &Rsdt, sizeof(struct acpi_header));
     rsdt->entry[0] = (unsigned long)fadt_10;
     for ( i = 0; secondary_tables[i]; i++ )
         rsdt->entry[i+1] = secondary_tables[i];
     rsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint32_t);
-    offset += align16(rsdt->header.length);
     set_checksum(rsdt,
                  offsetof(struct acpi_header, checksum),
                  rsdt->header.length);
 
-    *high_sz = offset;
-
     /*
      * Fill in low-memory data structures: bios_info_table and RSDP.
      */
-    buf = (uint8_t *)physical;
-    offset = 0;
-
-    rsdp = (struct acpi_20_rsdp *)&buf[offset];
+    rsdp = (struct acpi_20_rsdp *)physical;
 
     memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp));
-    offset += align16(sizeof(struct acpi_20_rsdp));
     rsdp->rsdt_address = (unsigned long)rsdt;
     rsdp->xsdt_address = (unsigned long)xsdt;
     set_checksum(rsdp,
@@ -351,27 +361,11 @@
                  offsetof(struct acpi_20_rsdp, extended_checksum),
                  sizeof(struct acpi_20_rsdp));
 
-    *low_sz = offset;
-}
+    return;
 
-void acpi_build_tables(unsigned int physical)
-{
-    int high_sz, low_sz;
-    uint8_t *buf;
+oom:
+    printf("unable to build ACPI tables: out of memory\n");
 
-    /* Find out size of high-memory ACPI data area. */
-    buf = (uint8_t *)&_end;
-    __acpi_build_tables(physical, buf, &low_sz, &high_sz);
-    memset(buf, 0, high_sz);
-
-    /* Allocate data area and set up ACPI tables there. */
-    buf = mem_alloc(high_sz, 0);
-    __acpi_build_tables(physical, buf, &low_sz, &high_sz);
-
-    printf(" - Lo data: %08x-%08x\n"
-           " - Hi data: %08lx-%08lx\n",
-           physical, physical + low_sz - 1,
-           (unsigned long)buf, (unsigned long)buf + high_sz - 1);
 }
 
 /*

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.