[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |