ia64/xen-unstable
changeset 12574:4d07411c517a
[HVM] Dynamically build ACPI-table data block.
Only emit MP tables and MADT for multi-processor guests.
Signed-off-by: Keir Fraser <keir@xensource.com>
Only emit MP tables and MADT for multi-processor guests.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@localhost.localdomain |
---|---|
date | Sun Nov 26 17:37:28 2006 +0000 (2006-11-26) |
parents | 91951de7592c |
children | 25cb51eed511 |
files | tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/acpi/Makefile tools/firmware/hvmloader/acpi/acpi2_0.h tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/acpi/gen.c tools/firmware/hvmloader/acpi/static_tables.c tools/firmware/hvmloader/acpi_madt.c tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/util.c tools/firmware/hvmloader/util.h |
line diff
1.1 --- a/tools/firmware/hvmloader/Makefile Sun Nov 26 17:35:00 2006 +0000 1.2 +++ b/tools/firmware/hvmloader/Makefile Sun Nov 26 17:37:28 2006 +0000 1.3 @@ -40,25 +40,27 @@ OBJCOPY = objcopy 1.4 CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float 1.5 LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR) 1.6 1.7 -SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c acpi_utils.c 1.8 +SRCS = hvmloader.c mp_tables.c util.c smbios.c acpi_utils.c 1.9 OBJS = $(patsubst %.c,%.o,$(SRCS)) 1.10 1.11 .PHONY: all 1.12 all: hvmloader 1.13 1.14 -hvmloader: roms.h $(SRCS) 1.15 +hvmloader: roms.h acpi/acpi.a $(SRCS) 1.16 $(CC) $(CFLAGS) -c $(SRCS) 1.17 - $(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS) 1.18 + $(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS) acpi/acpi.a 1.19 $(OBJCOPY) hvmloader.tmp hvmloader 1.20 rm -f hvmloader.tmp 1.21 1.22 +.PHONY: acpi/acpi.a 1.23 +acpi/acpi.a: 1.24 + $(MAKE) -C acpi 1.25 + 1.26 roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin 1.27 - $(MAKE) -C acpi 1.28 sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h 1.29 sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h 1.30 sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h 1.31 sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h 1.32 - sh ./mkhex acpi acpi/acpi.bin >> roms.h 1.33 1.34 .PHONY: clean 1.35 clean:
2.1 --- a/tools/firmware/hvmloader/acpi/Makefile Sun Nov 26 17:35:00 2006 +0000 2.2 +++ b/tools/firmware/hvmloader/acpi/Makefile Sun Nov 26 17:37:28 2006 +0000 2.3 @@ -15,21 +15,20 @@ 2.4 # Place - Suite 330, Boston, MA 02111-1307 USA. 2.5 # 2.6 2.7 +override XEN_TARGET_ARCH = x86_32 2.8 XEN_ROOT = ../../../.. 2.9 +CFLAGS := -I. -I.. -I$(XEN_ROOT)/tools/libxc 2.10 include $(XEN_ROOT)/tools/Rules.mk 2.11 2.12 -HOSTCFLAGS += -I. -I.. -I$(XEN_ROOT)/tools/libxc 2.13 - 2.14 -C_SRC = build.c dsdt.c gen.c static_tables.c 2.15 +C_SRC = build.c dsdt.c static_tables.c 2.16 H_SRC = $(wildcard *.h) 2.17 -ACPI_GEN = acpigen 2.18 -ACPI_BIN = acpi.bin 2.19 +OBJS = $(patsubst %.c,%.o,$(C_SRC)) 2.20 2.21 IASL_VER = acpica-unix-20050513 2.22 IASL_URL = http://developer.intel.com/technology/iapc/acpi/downloads/$(IASL_VER).tar.gz 2.23 2.24 vpath iasl $(PATH) 2.25 -all:$(ACPI_BIN) 2.26 +all: acpi.a 2.27 2.28 dsdt.c: dsdt.asl 2.29 $(MAKE) iasl 2.30 @@ -50,14 +49,13 @@ iasl: 2.31 make -C $(IASL_VER)/compiler 2.32 $(INSTALL_PROG) $(IASL_VER)/compiler/iasl /usr/bin/iasl 2.33 2.34 -$(ACPI_GEN): $(C_SRC) $(H_SRC) 2.35 - $(HOSTCC) -o $(ACPI_GEN) $(HOSTCFLAGS) $(C_SRC) 2.36 +acpi.a: $(OBJS) 2.37 + $(AR) rc $@ $(OBJS) 2.38 2.39 -$(ACPI_BIN): $(ACPI_GEN) 2.40 - ./$(ACPI_GEN) $(ACPI_BIN) 2.41 +%.o: %.c $(H_SRC) 2.42 + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< 2.43 2.44 clean: 2.45 - rm -rf *.o $(ACPI_GEN) $(ACPI_BIN) $(IASL_VER) 2.46 - rm -rf $(IASL_VER).tar.gz 2.47 + rm -rf *.a *.o $(IASL_VER) $(IASL_VER).tar.gz 2.48 2.49 install: all
3.1 --- a/tools/firmware/hvmloader/acpi/acpi2_0.h Sun Nov 26 17:35:00 2006 +0000 3.2 +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Sun Nov 26 17:37:28 2006 +0000 3.3 @@ -249,7 +249,7 @@ struct acpi_20_facs { 3.4 /* 3.5 * Multiple APIC Description Table header definition (MADT). 3.6 */ 3.7 -struct acpi_20_madt_header { 3.8 +struct acpi_20_madt { 3.9 struct acpi_header header; 3.10 uint32_t lapic_addr; 3.11 uint32_t flags; 3.12 @@ -316,13 +316,6 @@ struct acpi_20_madt_intsrcovr { 3.13 uint16_t flags; 3.14 }; 3.15 3.16 -struct acpi_20_madt { 3.17 - struct acpi_20_madt_header header; 3.18 - struct acpi_20_madt_intsrcovr intsrcovr[4]; 3.19 - struct acpi_20_madt_ioapic io_apic[1]; 3.20 - struct acpi_20_madt_lapic lapic[32]; 3.21 -}; 3.22 - 3.23 /* 3.24 * Table Signatures. 3.25 */ 3.26 @@ -338,7 +331,7 @@ struct acpi_20_madt { 3.27 3.28 #define ACPI_PHYSICAL_ADDRESS 0xEA000 3.29 3.30 -void AcpiBuildTable(uint8_t *buf); 3.31 +int acpi_build_tables(uint8_t *); 3.32 3.33 #endif /* _ACPI_2_0_H_ */ 3.34
4.1 --- a/tools/firmware/hvmloader/acpi/build.c Sun Nov 26 17:35:00 2006 +0000 4.2 +++ b/tools/firmware/hvmloader/acpi/build.c Sun Nov 26 17:37:28 2006 +0000 4.3 @@ -1,233 +1,196 @@ 4.4 /* 4.5 * Copyright (c) 2004, Intel Corporation. 4.6 + * Copyright (c) 2006, Keir Fraser, XenSource Inc. 4.7 * 4.8 * This program is free software; you can redistribute it and/or modify it 4.9 - * under the terms and conditions of the GNU General Public License, 4.10 - * version 2, as published by the Free Software Foundation. 4.11 + * under the terms and conditions of the GNU General Public License, version 4.12 + * 2, as published by the Free Software Foundation. 4.13 * 4.14 - * This program is distributed in the hope it will be useful, but WITHOUT 4.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 4.17 - * more details. 4.18 + * This program is distributed in the hope it will be useful, but WITHOUT ANY 4.19 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 4.20 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 4.21 + * details. 4.22 * 4.23 * You should have received a copy of the GNU General Public License along with 4.24 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 4.25 * Place - Suite 330, Boston, MA 02111-1307 USA. 4.26 - * 4.27 */ 4.28 4.29 #include "acpi2_0.h" 4.30 +#include "../config.h" 4.31 +#include "../util.h" 4.32 4.33 extern struct acpi_20_rsdp Rsdp; 4.34 extern struct acpi_20_rsdt Rsdt; 4.35 extern struct acpi_20_xsdt Xsdt; 4.36 extern struct acpi_20_fadt Fadt; 4.37 -extern struct acpi_20_madt Madt; 4.38 extern struct acpi_20_facs Facs; 4.39 -extern unsigned char *AmlCode; 4.40 +extern unsigned char AmlCode[]; 4.41 extern int DsdtLen; 4.42 4.43 +static void set_checksum( 4.44 + void *table, uint32_t checksum_offset, uint32_t length) 4.45 +{ 4.46 + uint8_t *p, sum = 0; 4.47 4.48 -typedef struct _ACPI_TABLE_ALL{ 4.49 - struct acpi_20_rsdp *Rsdp; 4.50 - struct acpi_20_rsdt *Rsdt; 4.51 - struct acpi_20_xsdt *Xsdt; 4.52 - struct acpi_20_fadt *Fadt; 4.53 - struct acpi_20_madt *Madt; 4.54 - struct acpi_20_facs *Facs; 4.55 - unsigned char *Dsdt; 4.56 - uint32_t RsdpOffset; 4.57 - uint32_t RsdtOffset; 4.58 - uint32_t XsdtOffset; 4.59 - uint32_t FadtOffset; 4.60 - uint32_t MadtOffset; 4.61 - uint32_t FacsOffset; 4.62 - uint32_t DsdtOffset; 4.63 -}ACPI_TABLE_ALL; 4.64 + p = table; 4.65 + p[checksum_offset] = 0; 4.66 4.67 -static 4.68 -void 4.69 -MemCopy(void* src, void* dst, int len){ 4.70 + while ( length-- ) 4.71 + sum = sum + *p++; 4.72 4.73 - uint8_t* src0=src; 4.74 - uint8_t* dst0=dst; 4.75 - 4.76 - while(len--){ 4.77 - *(dst0++)=*(src0++); 4.78 - } 4.79 + p = table; 4.80 + p[checksum_offset] = -sum; 4.81 } 4.82 4.83 -static 4.84 -void 4.85 -SetCheckSum( 4.86 - void* Table, 4.87 - uint32_t ChecksumOffset, 4.88 - uint32_t Length 4.89 - ) 4.90 -/* 4.91 - * Routine Description: 4.92 - * Calculate Checksum and store the result in the checksum 4.93 - * filed of the table 4.94 - * 4.95 - * INPUT: 4.96 - * Table: Start pointer of table 4.97 - * ChecksumOffset: Offset of checksum field in the table 4.98 - * Length: Length of Table 4.99 - */ 4.100 +int construct_madt(struct acpi_20_madt *madt) 4.101 { 4.102 - uint8_t Sum = 0; 4.103 - uint8_t *Ptr; 4.104 + struct acpi_20_madt_intsrcovr *intsrcovr; 4.105 + struct acpi_20_madt_ioapic *io_apic; 4.106 + struct acpi_20_madt_lapic *lapic; 4.107 + int i, offset = 0; 4.108 + 4.109 + memset(madt, 0, sizeof(*madt)); 4.110 + madt->header.signature = ACPI_2_0_MADT_SIGNATURE; 4.111 + madt->header.revision = ACPI_2_0_MADT_REVISION; 4.112 + strncpy(madt->header.oem_id, "INTEL ", 6); 4.113 + madt->header.oem_table_id = ACPI_OEM_TABLE_ID; 4.114 + madt->header.oem_revision = ACPI_OEM_REVISION; 4.115 + madt->header.creator_id = ACPI_CREATOR_ID; 4.116 + madt->header.creator_revision = ACPI_CREATOR_REVISION; 4.117 + madt->lapic_addr = LAPIC_BASE_ADDRESS; 4.118 + madt->flags = ACPI_PCAT_COMPAT; 4.119 + offset += sizeof(*madt); 4.120 + 4.121 + intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1); 4.122 + for ( i = 0; i < 16; i++ ) 4.123 + { 4.124 + if ( !(PCI_ISA_IRQ_MASK & (1U << i)) ) 4.125 + continue; 4.126 4.127 - Ptr=Table; 4.128 - Ptr[ChecksumOffset]=0; 4.129 - while (Length--) { 4.130 - Sum = (uint8_t)(Sum + (*Ptr++)); 4.131 + /* PCI: active-low level-triggered */ 4.132 + memset(intsrcovr, 0, sizeof(*intsrcovr)); 4.133 + intsrcovr->type = ACPI_INTERRUPT_SOURCE_OVERRIDE; 4.134 + intsrcovr->length = sizeof(*intsrcovr); 4.135 + intsrcovr->source = i; 4.136 + intsrcovr->gsi = i; 4.137 + intsrcovr->flags = 0xf; 4.138 + 4.139 + offset += sizeof(*intsrcovr); 4.140 + intsrcovr++; 4.141 } 4.142 - 4.143 - Ptr = Table; 4.144 - Ptr[ChecksumOffset] = (uint8_t) (0xff - Sum + 1); 4.145 + 4.146 + io_apic = (struct acpi_20_madt_ioapic *)intsrcovr; 4.147 + memset(io_apic, 0, sizeof(*io_apic)); 4.148 + io_apic->type = ACPI_IO_APIC; 4.149 + io_apic->length = sizeof(*io_apic); 4.150 + io_apic->ioapic_id = IOAPIC_ID; 4.151 + io_apic->ioapic_addr = IOAPIC_BASE_ADDRESS; 4.152 + offset += sizeof(*io_apic); 4.153 + 4.154 + lapic = (struct acpi_20_madt_lapic *)io_apic; 4.155 + for ( i = 0; i < get_vcpu_nr(); i++ ) 4.156 + { 4.157 + memset(lapic, 0, sizeof(*lapic)); 4.158 + lapic->type = ACPI_PROCESSOR_LOCAL_APIC; 4.159 + lapic->length = sizeof(*lapic); 4.160 + lapic->acpi_processor_id = i; 4.161 + lapic->apic_id = i; 4.162 + lapic->flags = ACPI_LOCAL_APIC_ENABLED; 4.163 + offset += sizeof(*lapic); 4.164 + lapic++; 4.165 + } 4.166 + 4.167 + madt->header.length = offset; 4.168 + set_checksum(madt, offsetof(struct acpi_header, checksum), offset); 4.169 + 4.170 + return offset; 4.171 } 4.172 4.173 -// 4.174 -// FIELD_OFFSET - returns the byte offset to a field within a structure 4.175 -// 4.176 -#define FIELD_OFFSET(TYPE,Field) ((uint32_t)(&(((TYPE *) 0)->Field))) 4.177 - 4.178 -static 4.179 -void 4.180 -UpdateTable( 4.181 - ACPI_TABLE_ALL *table 4.182 - ) 4.183 /* 4.184 - * Update the ACPI table: 4.185 - * fill in the actuall physical address of RSDT, XSDT, FADT, MADT, FACS 4.186 - * Caculate the checksum 4.187 + * Copy all the ACPI table to buffer. 4.188 + * Buffer layout: FACS, DSDT, FADT, MADT, XSDT, RSDT, RSDP. 4.189 */ 4.190 +int acpi_build_tables(uint8_t *buf) 4.191 { 4.192 - // RSDP Update 4.193 - table->Rsdp->rsdt_address = (uint32_t)(ACPI_PHYSICAL_ADDRESS+ 4.194 - table->RsdtOffset); 4.195 - table->Rsdp->xsdt_address = (uint64_t)(ACPI_PHYSICAL_ADDRESS+ 4.196 - table->XsdtOffset); 4.197 - SetCheckSum(table->Rsdp, 4.198 - FIELD_OFFSET(struct acpi_10_rsdp, checksum), 4.199 - sizeof(struct acpi_10_rsdp) 4.200 - ); 4.201 - SetCheckSum(table->Rsdp, 4.202 - FIELD_OFFSET(struct acpi_20_rsdp, 4.203 - extended_checksum), 4.204 - sizeof(struct acpi_20_rsdp) 4.205 - ); 4.206 + struct acpi_20_rsdp *rsdp; 4.207 + struct acpi_20_rsdt *rsdt; 4.208 + struct acpi_20_xsdt *xsdt; 4.209 + struct acpi_20_fadt *fadt; 4.210 + struct acpi_20_madt *madt = 0; 4.211 + struct acpi_20_facs *facs; 4.212 + unsigned char *dsdt; 4.213 + int offset = 0, nr_vcpus = get_vcpu_nr(); 4.214 + 4.215 +#define inc_offset(sz) (offset = (offset + (sz) + 15) & ~15) 4.216 +#define requires_madt() (nr_vcpus > 1) 4.217 4.218 - 4.219 - //RSDT Update 4.220 - table->Rsdt->entry[0] = (uint32_t)(ACPI_PHYSICAL_ADDRESS + 4.221 - table->FadtOffset); 4.222 - table->Rsdt->entry[1] = (uint32_t)(ACPI_PHYSICAL_ADDRESS + 4.223 - table->MadtOffset); 4.224 - table->Rsdt->header.length = sizeof (struct acpi_header) + 4.225 - 2*sizeof(uint32_t); 4.226 - SetCheckSum(table->Rsdt, 4.227 - FIELD_OFFSET(struct acpi_header, checksum), 4.228 - table->Rsdt->header.length 4.229 - ); 4.230 + facs = (struct acpi_20_facs *)&buf[offset]; 4.231 + memcpy(facs, &Facs, sizeof(struct acpi_20_facs)); 4.232 + inc_offset(sizeof(struct acpi_20_facs)); 4.233 + 4.234 + dsdt = (unsigned char *)&buf[offset]; 4.235 + memcpy(dsdt, &AmlCode, DsdtLen); 4.236 + inc_offset(DsdtLen); 4.237 4.238 - //XSDT Update 4.239 - table->Xsdt->entry[0] = (uint64_t)(ACPI_PHYSICAL_ADDRESS + 4.240 - table->FadtOffset); 4.241 - table->Xsdt->entry[1] = (uint64_t)(ACPI_PHYSICAL_ADDRESS + 4.242 - table->MadtOffset); 4.243 - table->Xsdt->header.length = sizeof (struct acpi_header) + 4.244 - 2*sizeof(uint64_t); 4.245 - SetCheckSum(table->Xsdt, 4.246 - FIELD_OFFSET(struct acpi_header, checksum), 4.247 - table->Xsdt->header.length 4.248 - ); 4.249 + fadt = (struct acpi_20_fadt *)&buf[offset]; 4.250 + memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt)); 4.251 + inc_offset(sizeof(struct acpi_20_fadt)); 4.252 + fadt->dsdt = (unsigned long)dsdt; 4.253 + fadt->x_dsdt = (unsigned long)dsdt; 4.254 + fadt->firmware_ctrl = (unsigned long)facs; 4.255 + fadt->x_firmware_ctrl = (unsigned long)facs; 4.256 + set_checksum(fadt, 4.257 + offsetof(struct acpi_header, checksum), 4.258 + sizeof(struct acpi_20_fadt)); 4.259 4.260 - // FADT Update 4.261 - table->Fadt->dsdt = (uint32_t)(ACPI_PHYSICAL_ADDRESS + 4.262 - table->DsdtOffset); 4.263 - table->Fadt->x_dsdt = (uint64_t)(ACPI_PHYSICAL_ADDRESS + 4.264 - table->DsdtOffset); 4.265 - table->Fadt->firmware_ctrl = (uint32_t)(ACPI_PHYSICAL_ADDRESS + 4.266 - table->FacsOffset); 4.267 - table->Fadt->x_firmware_ctrl = (uint64_t)(ACPI_PHYSICAL_ADDRESS + 4.268 - table->FacsOffset); 4.269 - SetCheckSum(table->Fadt, 4.270 - FIELD_OFFSET(struct acpi_header, checksum), 4.271 - sizeof(struct acpi_20_fadt) 4.272 - ); 4.273 - 4.274 - // MADT update 4.275 - SetCheckSum(table->Madt, 4.276 - FIELD_OFFSET(struct acpi_header, checksum), 4.277 - sizeof(struct acpi_20_madt) 4.278 - ); 4.279 -} 4.280 + if ( requires_madt() ) 4.281 + { 4.282 + madt = (struct acpi_20_madt *)&buf[offset]; 4.283 + inc_offset(construct_madt(madt)); 4.284 + } 4.285 4.286 -void 4.287 -AcpiBuildTable(uint8_t* buf) 4.288 -/* 4.289 - * Copy all the ACPI table to buffer 4.290 - * Buffer Layout: 4.291 - * FACS 4.292 - * RSDP 4.293 - * RSDT 4.294 - * XSDT 4.295 - * FADT 4.296 - * MADT 4.297 - * DSDT 4.298 - * 4.299 - */ 4.300 -{ 4.301 - ACPI_TABLE_ALL table; 4.302 - int offset=0; 4.303 + xsdt = (struct acpi_20_xsdt *)&buf[offset]; 4.304 + memcpy(xsdt, &Xsdt, sizeof(struct acpi_20_xsdt)); 4.305 + inc_offset(sizeof(struct acpi_20_xsdt)); 4.306 + xsdt->entry[0] = (unsigned long)fadt; 4.307 + xsdt->header.length = sizeof(struct acpi_header) + sizeof(uint64_t); 4.308 + if ( requires_madt() ) 4.309 + { 4.310 + xsdt->entry[1] = (unsigned long)madt; 4.311 + xsdt->header.length += sizeof(uint64_t); 4.312 + } 4.313 + set_checksum(xsdt, 4.314 + offsetof(struct acpi_header, checksum), 4.315 + xsdt->header.length); 4.316 4.317 - // FACS: should be 64-bit alignment 4.318 - // so it is put at the start of buffer 4.319 - // as the buffer is 64 bit alignment 4.320 - table.FacsOffset = offset; 4.321 - table.Facs = (struct acpi_20_facs *)(&buf[offset]); 4.322 - MemCopy(&Facs, table.Facs, sizeof(struct acpi_20_facs)); 4.323 - offset += sizeof(struct acpi_20_facs); 4.324 - 4.325 - // RSDP 4.326 - table.RsdpOffset = offset; 4.327 - table.Rsdp = (struct acpi_20_rsdp *)(&buf[offset]); 4.328 - MemCopy(&Rsdp, table.Rsdp, sizeof(struct acpi_20_rsdp)); 4.329 - offset += sizeof(struct acpi_20_rsdp); 4.330 + rsdt = (struct acpi_20_rsdt *)&buf[offset]; 4.331 + memcpy(rsdt, &Rsdt, sizeof(struct acpi_20_rsdt)); 4.332 + inc_offset(sizeof(struct acpi_20_rsdt)); 4.333 + rsdt->entry[0] = (unsigned long)fadt; 4.334 + rsdt->header.length = sizeof(struct acpi_header) + sizeof(uint32_t); 4.335 + if ( requires_madt() ) 4.336 + { 4.337 + rsdt->entry[1] = (unsigned long)madt; 4.338 + rsdt->header.length += sizeof(uint32_t); 4.339 + } 4.340 + set_checksum(rsdt, 4.341 + offsetof(struct acpi_header, checksum), 4.342 + rsdt->header.length); 4.343 4.344 - // RSDT 4.345 - table.RsdtOffset = offset; 4.346 - table.Rsdt = (struct acpi_20_rsdt *)(&buf[offset]); 4.347 - MemCopy(&Rsdt, table.Rsdt, sizeof(struct acpi_20_rsdt)); 4.348 - offset += sizeof(struct acpi_20_rsdt); 4.349 - 4.350 - // XSDT 4.351 - table.XsdtOffset = offset; 4.352 - table.Xsdt = (struct acpi_20_xsdt *)(&buf[offset]); 4.353 - MemCopy(&Xsdt, table.Xsdt, sizeof(struct acpi_20_xsdt)); 4.354 - offset += sizeof(struct acpi_20_xsdt); 4.355 - 4.356 - // FADT 4.357 - table.FadtOffset = offset; 4.358 - table.Fadt = (struct acpi_20_fadt *)(&buf[offset]); 4.359 - MemCopy(&Fadt, table.Fadt, sizeof(struct acpi_20_fadt)); 4.360 - offset += sizeof(struct acpi_20_fadt); 4.361 - 4.362 - // MADT 4.363 - table.MadtOffset = offset; 4.364 - table.Madt = (struct acpi_20_madt*)(&buf[offset]); 4.365 - MemCopy(&Madt, table.Madt, sizeof(struct acpi_20_madt)); 4.366 - offset += sizeof(struct acpi_20_madt); 4.367 + rsdp = (struct acpi_20_rsdp *)&buf[offset]; 4.368 + memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp)); 4.369 + inc_offset(sizeof(struct acpi_20_rsdp)); 4.370 + rsdp->rsdt_address = (unsigned long)rsdt; 4.371 + rsdp->xsdt_address = (unsigned long)xsdt; 4.372 + set_checksum(rsdp, 4.373 + offsetof(struct acpi_10_rsdp, checksum), 4.374 + sizeof(struct acpi_10_rsdp)); 4.375 + set_checksum(rsdp, 4.376 + offsetof(struct acpi_20_rsdp, extended_checksum), 4.377 + sizeof(struct acpi_20_rsdp)); 4.378 4.379 - // DSDT 4.380 - table.DsdtOffset = offset; 4.381 - table.Dsdt = (unsigned char *)(&buf[offset]); 4.382 - MemCopy(&AmlCode, table.Dsdt, DsdtLen); 4.383 - offset += DsdtLen; 4.384 - 4.385 - UpdateTable(&table); 4.386 + return offset; 4.387 } 4.388 4.389 /*
5.1 --- a/tools/firmware/hvmloader/acpi/gen.c Sun Nov 26 17:35:00 2006 +0000 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,55 +0,0 @@ 5.4 -/* 5.5 - * Copyright (c) 2004, Intel Corporation. 5.6 - * 5.7 - * This program is free software; you can redistribute it and/or modify it 5.8 - * under the terms and conditions of the GNU General Public License, 5.9 - * version 2, as published by the Free Software Foundation. 5.10 - * 5.11 - * This program is distributed in the hope it will be useful, but WITHOUT 5.12 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.13 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 5.14 - * more details. 5.15 - * 5.16 - * You should have received a copy of the GNU General Public License along with 5.17 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 5.18 - * Place - Suite 330, Boston, MA 02111-1307 USA. 5.19 - * 5.20 - */ 5.21 -#include "acpi2_0.h" 5.22 -#include <stdio.h> 5.23 -#include <stdlib.h> 5.24 -#include <unistd.h> 5.25 - 5.26 -#define USAGE "Usage: acpi_gen filename \n" \ 5.27 - " generage acpitable and write to the binary \n" \ 5.28 - " filename - the binary name\n" 5.29 - 5.30 -#define ACPI_TABLE_SIZE (8*1024) 5.31 - 5.32 -int main(int argc, char **argv) 5.33 -{ 5.34 - char *filename; 5.35 - char buf[ACPI_TABLE_SIZE] = { 0 }; 5.36 - FILE *f; 5.37 - 5.38 - if (argc < 2) { 5.39 - fprintf(stderr,"%s",USAGE); 5.40 - exit(1); 5.41 - } 5.42 - 5.43 - filename = argv[1]; 5.44 - 5.45 - if ((f = fopen(filename, "w+")) == NULL) { 5.46 - fprintf(stderr,"Can not open %s", filename); 5.47 - exit(1); 5.48 - } 5.49 - 5.50 - AcpiBuildTable((uint8_t *)buf); 5.51 - 5.52 - if (fwrite(buf, ACPI_TABLE_SIZE, 1, f) < 1) { 5.53 - fprintf(stderr,"Can not write to %s\n", filename); 5.54 - exit(1); 5.55 - } 5.56 - 5.57 - return 0; 5.58 -}
6.1 --- a/tools/firmware/hvmloader/acpi/static_tables.c Sun Nov 26 17:35:00 2006 +0000 6.2 +++ b/tools/firmware/hvmloader/acpi/static_tables.c Sun Nov 26 17:37:28 2006 +0000 6.3 @@ -21,78 +21,6 @@ 6.4 #include <xen/hvm/ioreq.h> 6.5 6.6 /* 6.7 - * Multiple APIC Description Table (MADT). 6.8 - */ 6.9 - 6.10 -struct acpi_20_madt Madt = { 6.11 - .header = { 6.12 - .header = { 6.13 - .signature = ACPI_2_0_MADT_SIGNATURE, 6.14 - .length = sizeof(struct acpi_20_madt), 6.15 - .revision = ACPI_2_0_MADT_REVISION, 6.16 - .oem_id = ACPI_OEM_ID, 6.17 - .oem_table_id = ACPI_OEM_TABLE_ID, 6.18 - .oem_revision = ACPI_OEM_REVISION, 6.19 - .creator_id = ACPI_CREATOR_ID, 6.20 - .creator_revision = ACPI_CREATOR_REVISION 6.21 - }, 6.22 - .lapic_addr = LAPIC_BASE_ADDRESS, 6.23 - .flags = ACPI_PCAT_COMPAT 6.24 - }, 6.25 - 6.26 - .intsrcovr = { 6.27 - [0] = { 6.28 - .type = ACPI_INTERRUPT_SOURCE_OVERRIDE, 6.29 - .length = sizeof(struct acpi_20_madt_intsrcovr), 6.30 - .source = 5, 6.31 - .gsi = 5, 6.32 - .flags = 0xf /* PCI: active-low level-triggered */ 6.33 - }, 6.34 - [1] = { 6.35 - .type = ACPI_INTERRUPT_SOURCE_OVERRIDE, 6.36 - .length = sizeof(struct acpi_20_madt_intsrcovr), 6.37 - .source = 6, 6.38 - .gsi = 6, 6.39 - .flags = 0xf /* PCI: active-low level-triggered */ 6.40 - }, 6.41 - [2] = { 6.42 - .type = ACPI_INTERRUPT_SOURCE_OVERRIDE, 6.43 - .length = sizeof(struct acpi_20_madt_intsrcovr), 6.44 - .source = 10, 6.45 - .gsi = 10, 6.46 - .flags = 0xf /* PCI: active-low level-triggered */ 6.47 - }, 6.48 - [3] = { 6.49 - .type = ACPI_INTERRUPT_SOURCE_OVERRIDE, 6.50 - .length = sizeof(struct acpi_20_madt_intsrcovr), 6.51 - .source = 11, 6.52 - .gsi = 11, 6.53 - .flags = 0xf /* PCI: active-low level-triggered */ 6.54 - } 6.55 - }, 6.56 - 6.57 - /* IO APIC */ 6.58 - .io_apic = { 6.59 - [0] = { 6.60 - .type = ACPI_IO_APIC, 6.61 - .length = sizeof(struct acpi_20_madt_ioapic), 6.62 - .ioapic_id = IOAPIC_ID, 6.63 - .ioapic_addr = IOAPIC_BASE_ADDRESS 6.64 - } 6.65 - }, 6.66 - 6.67 - /* Local APIC entries for up to 32 processors. */ 6.68 - .lapic = { 6.69 - [0] = { 6.70 - .type = ACPI_PROCESSOR_LOCAL_APIC, 6.71 - .length = sizeof(struct acpi_20_madt_lapic), 6.72 - .flags = ACPI_LOCAL_APIC_ENABLED 6.73 - } 6.74 - } 6.75 -}; 6.76 - 6.77 - 6.78 -/* 6.79 * Firmware ACPI Control Structure (FACS). 6.80 */ 6.81
7.1 --- a/tools/firmware/hvmloader/acpi_madt.c Sun Nov 26 17:35:00 2006 +0000 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,164 +0,0 @@ 7.4 -/* 7.5 - * acpi_madt.c: Update ACPI MADT table for multiple processor guest. 7.6 - * 7.7 - * Yu Ke, ke.yu@intel.com 7.8 - * Copyright (c) 2005, Intel Corporation. 7.9 - * 7.10 - * This program is free software; you can redistribute it and/or modify it 7.11 - * under the terms and conditions of the GNU General Public License, 7.12 - * version 2, as published by the Free Software Foundation. 7.13 - * 7.14 - * This program is distributed in the hope it will be useful, but WITHOUT 7.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 7.17 - * more details. 7.18 - * 7.19 - * You should have received a copy of the GNU General Public License along with 7.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 7.21 - * Place - Suite 330, Boston, MA 02111-1307 USA. 7.22 - */ 7.23 - 7.24 -#include "acpi/acpi2_0.h" 7.25 -#include "util.h" 7.26 -#include "acpi_utils.h" 7.27 -#include <xen/hvm/hvm_info_table.h> 7.28 - 7.29 -#define NULL ((void*)0) 7.30 - 7.31 -static struct hvm_info_table *table = NULL; 7.32 - 7.33 -static int validate_hvm_info(struct hvm_info_table *t) 7.34 -{ 7.35 - char signature[] = "HVM INFO"; 7.36 - uint8_t *ptr = (uint8_t *)t; 7.37 - uint8_t sum = 0; 7.38 - int i; 7.39 - 7.40 - /* strncmp(t->signature, "HVM INFO", 8) */ 7.41 - for ( i = 0; i < 8; i++ ) 7.42 - { 7.43 - if ( signature[i] != t->signature[i] ) 7.44 - { 7.45 - printf("Bad hvm info signature\n"); 7.46 - return 0; 7.47 - } 7.48 - } 7.49 - 7.50 - for ( i = 0; i < t->length; i++ ) 7.51 - sum += ptr[i]; 7.52 - 7.53 - return (sum == 0); 7.54 -} 7.55 - 7.56 -/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */ 7.57 -struct hvm_info_table *get_hvm_info_table(void) 7.58 -{ 7.59 - struct hvm_info_table *t; 7.60 - 7.61 - if ( table != NULL ) 7.62 - return table; 7.63 - 7.64 - t = (struct hvm_info_table *)HVM_INFO_PADDR; 7.65 - 7.66 - if ( !validate_hvm_info(t) ) 7.67 - { 7.68 - printf("Bad hvm info table\n"); 7.69 - return NULL; 7.70 - } 7.71 - 7.72 - table = t; 7.73 - 7.74 - return table; 7.75 -} 7.76 - 7.77 -int get_vcpu_nr(void) 7.78 -{ 7.79 - struct hvm_info_table *t = get_hvm_info_table(); 7.80 - return (t ? t->nr_vcpus : 1); /* default 1 vcpu */ 7.81 -} 7.82 - 7.83 -int get_acpi_enabled(void) 7.84 -{ 7.85 - struct hvm_info_table *t = get_hvm_info_table(); 7.86 - return (t ? t->acpi_enabled : 0); /* default no acpi */ 7.87 -} 7.88 - 7.89 - 7.90 -static void * 7.91 -acpi_madt_get_madt(unsigned char *acpi_start) 7.92 -{ 7.93 - struct acpi_20_rsdt *rsdt; 7.94 - struct acpi_20_madt *madt; 7.95 - 7.96 - rsdt = acpi_rsdt_get(acpi_start); 7.97 - if ( rsdt == NULL ) 7.98 - return NULL; 7.99 - 7.100 - madt = (struct acpi_20_madt *)(acpi_start + rsdt->entry[1] - 7.101 - ACPI_PHYSICAL_ADDRESS); 7.102 - if ( madt->header.header.signature != ACPI_2_0_MADT_SIGNATURE ) 7.103 - { 7.104 - printf("Bad MADT signature \n"); 7.105 - return NULL; 7.106 - } 7.107 - 7.108 - return madt; 7.109 -} 7.110 - 7.111 -static int 7.112 -acpi_madt_set_local_apics( 7.113 - int nr_vcpu, 7.114 - struct acpi_20_madt *madt) 7.115 -{ 7.116 - int i; 7.117 - 7.118 - if ( (nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt ) 7.119 - return -1; 7.120 - 7.121 - for ( i = 0; i < nr_vcpu; i++ ) 7.122 - { 7.123 - madt->lapic[i].type = ACPI_PROCESSOR_LOCAL_APIC; 7.124 - madt->lapic[i].length = sizeof(struct acpi_20_madt_lapic); 7.125 - madt->lapic[i].acpi_processor_id = i; 7.126 - madt->lapic[i].apic_id = i; 7.127 - madt->lapic[i].flags = 1; 7.128 - } 7.129 - 7.130 - madt->header.header.length = 7.131 - sizeof(struct acpi_20_madt) - 7.132 - (MAX_VIRT_CPUS - nr_vcpu) * sizeof(struct acpi_20_madt_lapic); 7.133 - 7.134 - return 0; 7.135 -} 7.136 - 7.137 -#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field))) 7.138 - 7.139 -int acpi_madt_update(unsigned char *acpi_start) 7.140 -{ 7.141 - int rc; 7.142 - struct acpi_20_madt *madt; 7.143 - 7.144 - madt = acpi_madt_get_madt(acpi_start); 7.145 - if ( !madt ) 7.146 - return -1; 7.147 - 7.148 - rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt); 7.149 - if ( rc != 0 ) 7.150 - return rc; 7.151 - 7.152 - set_checksum( 7.153 - madt, FIELD_OFFSET(struct acpi_header, checksum), 7.154 - madt->header.header.length); 7.155 - 7.156 - return 0; 7.157 -} 7.158 - 7.159 -/* 7.160 - * Local variables: 7.161 - * mode: C 7.162 - * c-set-style: "BSD" 7.163 - * c-basic-offset: 4 7.164 - * tab-width: 4 7.165 - * indent-tabs-mode: nil 7.166 - * End: 7.167 - */
8.1 --- a/tools/firmware/hvmloader/hvmloader.c Sun Nov 26 17:35:00 2006 +0000 8.2 +++ b/tools/firmware/hvmloader/hvmloader.c Sun Nov 26 17:37:28 2006 +0000 8.3 @@ -74,10 +74,7 @@ asm( 8.4 "stack_top: \n" 8.5 ); 8.6 8.7 -extern int get_acpi_enabled(void); 8.8 -extern int acpi_madt_update(unsigned char* acpi_start); 8.9 extern void create_mp_tables(void); 8.10 -struct hvm_info_table *get_hvm_info_table(void); 8.11 8.12 static int 8.13 cirrus_check(void) 8.14 @@ -285,6 +282,9 @@ static void pci_setup(void) 8.15 8.16 int main(void) 8.17 { 8.18 + int acpi_sz; 8.19 + uint8_t *freemem; 8.20 + 8.21 printf("HVM Loader\n"); 8.22 8.23 init_hypercalls(); 8.24 @@ -297,7 +297,9 @@ int main(void) 8.25 8.26 apic_setup(); 8.27 pci_setup(); 8.28 - create_mp_tables(); 8.29 + 8.30 + if ( get_vcpu_nr() > 1 ) 8.31 + create_mp_tables(); 8.32 8.33 if ( cirrus_check() ) 8.34 { 8.35 @@ -315,22 +317,13 @@ int main(void) 8.36 if ( get_acpi_enabled() != 0 ) 8.37 { 8.38 printf("Loading ACPI ...\n"); 8.39 - acpi_madt_update((unsigned char *) acpi); 8.40 - if ( (ACPI_PHYSICAL_ADDRESS + sizeof(acpi)) <= 0xF0000 ) 8.41 - { 8.42 - unsigned char *freemem = (unsigned char *) 8.43 - (ACPI_PHYSICAL_ADDRESS + sizeof(acpi)); 8.44 - /* 8.45 - * Make sure acpi table does not overlap rombios 8.46 - * currently acpi less than 8K will be OK. 8.47 - */ 8.48 - memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, 8.49 - sizeof(acpi)); 8.50 - acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS, 8.51 - sizeof(acpi), 8.52 - (unsigned char *)0xF0000, 8.53 - &freemem); 8.54 - } 8.55 + acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS); 8.56 + freemem = (uint8_t *)ACPI_PHYSICAL_ADDRESS + acpi_sz; 8.57 + ASSERT(freemem <= (uint8_t *)0xF0000); 8.58 + acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS, 8.59 + freemem - (uint8_t *)ACPI_PHYSICAL_ADDRESS, 8.60 + (unsigned char *)0xF0000, 8.61 + &freemem); 8.62 } 8.63 8.64 if ( check_amd() )
9.1 --- a/tools/firmware/hvmloader/util.c Sun Nov 26 17:35:00 2006 +0000 9.2 +++ b/tools/firmware/hvmloader/util.c Sun Nov 26 17:37:28 2006 +0000 9.3 @@ -23,6 +23,7 @@ 9.4 #include "config.h" 9.5 #include <stdint.h> 9.6 #include <xenctrl.h> 9.7 +#include <xen/hvm/hvm_info_table.h> 9.8 9.9 void outb(uint16_t addr, uint8_t val) 9.10 { 9.11 @@ -487,6 +488,62 @@ void __bug(char *file, int line) 9.12 __asm__ __volatile__ ( "ud2" ); 9.13 } 9.14 9.15 +static int validate_hvm_info(struct hvm_info_table *t) 9.16 +{ 9.17 + char signature[] = "HVM INFO"; 9.18 + uint8_t *ptr = (uint8_t *)t; 9.19 + uint8_t sum = 0; 9.20 + int i; 9.21 + 9.22 + /* strncmp(t->signature, "HVM INFO", 8) */ 9.23 + for ( i = 0; i < 8; i++ ) 9.24 + { 9.25 + if ( signature[i] != t->signature[i] ) 9.26 + { 9.27 + printf("Bad hvm info signature\n"); 9.28 + return 0; 9.29 + } 9.30 + } 9.31 + 9.32 + for ( i = 0; i < t->length; i++ ) 9.33 + sum += ptr[i]; 9.34 + 9.35 + return (sum == 0); 9.36 +} 9.37 + 9.38 +static struct hvm_info_table *get_hvm_info_table(void) 9.39 +{ 9.40 + static struct hvm_info_table *table; 9.41 + struct hvm_info_table *t; 9.42 + 9.43 + if ( table != NULL ) 9.44 + return table; 9.45 + 9.46 + t = (struct hvm_info_table *)HVM_INFO_PADDR; 9.47 + 9.48 + if ( !validate_hvm_info(t) ) 9.49 + { 9.50 + printf("Bad hvm info table\n"); 9.51 + return NULL; 9.52 + } 9.53 + 9.54 + table = t; 9.55 + 9.56 + return table; 9.57 +} 9.58 + 9.59 +int get_vcpu_nr(void) 9.60 +{ 9.61 + struct hvm_info_table *t = get_hvm_info_table(); 9.62 + return (t ? t->nr_vcpus : 1); /* default 1 vcpu */ 9.63 +} 9.64 + 9.65 +int get_acpi_enabled(void) 9.66 +{ 9.67 + struct hvm_info_table *t = get_hvm_info_table(); 9.68 + return (t ? t->acpi_enabled : 0); /* default no acpi */ 9.69 +} 9.70 + 9.71 /* 9.72 * Local variables: 9.73 * mode: C
10.1 --- a/tools/firmware/hvmloader/util.h Sun Nov 26 17:35:00 2006 +0000 10.2 +++ b/tools/firmware/hvmloader/util.h Sun Nov 26 17:37:28 2006 +0000 10.3 @@ -3,6 +3,9 @@ 10.4 10.5 #include <stdarg.h> 10.6 10.7 +#undef offsetof 10.8 +#define offsetof(t, m) ((unsigned long)&((t *)0)->m) 10.9 + 10.10 extern void __assert_failed(char *assertion, char *file, int line) 10.11 __attribute__((noreturn)); 10.12 #define ASSERT(p) \ 10.13 @@ -40,8 +43,9 @@ void pci_write(uint32_t devfn, uint32_t 10.14 void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, 10.15 uint32_t *ecx, uint32_t *edx); 10.16 10.17 -/* Return number of vcpus. */ 10.18 +/* HVM-builder info. */ 10.19 int get_vcpu_nr(void); 10.20 +int get_acpi_enabled(void); 10.21 10.22 /* String and memory functions */ 10.23 int strcmp(const char *cs, const char *ct);