All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Campbell <ian.campbell@citrix.com>
To: xen-devel@lists.xensource.com
Cc: Ian Campbell <ian.campbell@citrix.com>
Subject: [PATCH 2 of 4] hvmloader: allocate ACPI tables as we go
Date: Thu, 2 Jun 2011 16:07:53 +0100	[thread overview]
Message-ID: <34a70784084d146ea4dd.1307027273@cosworth.uk.xensource.com> (raw)
In-Reply-To: <patchbomb.1307027271@cosworth.uk.xensource.com>

# HG changeset patch
# User Ian Campbell <ian.campbell@citrix.com>
# Date 1307026861 -3600
# Node ID 34a70784084d146ea4ddc5d4a63eade67a6045f6
# Parent  1f07d98d624ec828bd6483425adf204521175833
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@citrix.com>

diff -r 1f07d98d624e -r 34a70784084d tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c	Thu Jun 02 16:00:37 2011 +0100
+++ b/tools/firmware/hvmloader/acpi/build.c	Thu Jun 02 16:01:01 2011 +0100
@@ -68,12 +68,21 @@ static uint8_t battery_port_exists(void)
     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 @@ static int construct_madt(struct acpi_20
     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 @@ static int construct_madt(struct acpi_20
             continue;
         }
 
-        offset += sizeof(*intsrcovr);
         intsrcovr++;
     }
 
@@ -123,7 +130,6 @@ static int construct_madt(struct acpi_20
     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 @@ static int construct_madt(struct acpi_20
         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 @@ static int construct_hpet(struct acpi_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 @@ static int construct_secondary_tables(ui
     /* 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 @@ static int construct_secondary_tables(ui
          (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 @@ static int construct_secondary_tables(ui
         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 @@ static int construct_secondary_tables(ui
     }
 
     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 @@ static void __acpi_build_tables(unsigned
     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 @@ static void __acpi_build_tables(unsigned
      * 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 @@ static void __acpi_build_tables(unsigned
                  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 @@ static void __acpi_build_tables(unsigned
                  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 @@ static void __acpi_build_tables(unsigned
                  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);
 }
 
 /*

  parent reply	other threads:[~2011-06-02 15:07 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-02 15:07 [PATCH 0 of 4] hvmloader: ACPI clean/fix-ups Ian Campbell
2011-06-02 15:07 ` [PATCH 1 of 4] hvmloader: reduce minimum allocation alignment from 1024 bytes to 16 Ian Campbell
2011-06-02 15:07 ` Ian Campbell [this message]
2011-06-02 15:07 ` [PATCH 3 of 4] hvmloader: removed unused/incorrect define Ian Campbell
2011-06-02 15:07 ` [PATCH 4 of 4] hvmloader: reinstate datastructure shared with DSDT in SeaBIOS case Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=34a70784084d146ea4dd.1307027273@cosworth.uk.xensource.com \
    --to=ian.campbell@citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.