Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt.c =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt.c @@ -0,0 +1,59 @@ +/* + * acpi_ssdt.c: Append SSDT ACPI entries to the XSDT table. + * + * Copyright (c) 2006, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ +#include "../acpi/acpi2_0.h" +#include "util.h" +#include "acpi_utils.h" +#include "acpi_xsdt.h" + + +#include "acpi_ssdt_tpm.h" +static int acpi_ssdt_tpm_tis_probe(unsigned char *acpi_start, + unsigned char **freemem, + unsigned char *limit) +{ + int success = 1; /* not successful means 'out of memory' */ + unsigned char *addr; + /* check TPM_DID, TPM_VID, TPM_RID in ioemu/hw/tpm_tis.c */ + uint16_t tis_did_vid_rid[] = {0x0001, 0x0001, 0x0001}; + + /* probe for TIS interface ... */ + if (memcmp((char *)(0xFED40000 + 0xF00), + tis_did_vid_rid, + sizeof(tis_did_vid_rid)) == 0) { + puts("TIS is available\n"); + addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, + AmlCode_TPM, sizeof(AmlCode_TPM)); + if (addr == NULL) + success = 0; + } + return success; +} + + +/* + * Call functions that probe for devices and have them register their + * SSDT entries. + */ +void acpi_ssdt_update(unsigned char *acpi_start, + unsigned long acpi_size, + unsigned char *limit, + unsigned char **freemem) +{ + acpi_ssdt_tpm_tis_probe(acpi_start, freemem, limit); +} Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt.h =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt.h @@ -0,0 +1,14 @@ +/* + * acpi_xsdt.h: Handling of SSDT entries. + * + * Copyright (c) 2006, IBM Corporation. + */ +#ifndef ACPI_SSDT_H +#define ACPI_SSDT_H + +void acpi_ssdt_update(unsigned char *acpi_start, + unsigned long acpi_size, + unsigned char *limit, + unsigned char **freemem); + +#endif Index: root/xen-unstable.hg/tools/firmware/hvmloader/hvmloader.c =================================================================== --- root.orig/xen-unstable.hg/tools/firmware/hvmloader/hvmloader.c +++ root/xen-unstable.hg/tools/firmware/hvmloader/hvmloader.c @@ -26,6 +26,7 @@ #include "hypercall.h" #include "util.h" #include "smbios.h" +#include "acpi_ssdt.h" #include #include @@ -195,12 +196,18 @@ main(void) puts("Loading ACPI ...\n"); acpi_madt_update((unsigned char *) acpi); if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) { + unsigned char *freemem = (unsigned char *) + (ACPI_PHYSICAL_ADDRESS + sizeof(acpi)); /* * Make sure acpi table does not overlap rombios * currently acpi less than 8K will be OK. */ memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi)); + acpi_ssdt_update((unsigned char *)ACPI_PHYSICAL_ADDRESS, + sizeof(acpi), + (unsigned char *)0xF0000, + &freemem); } } Index: root/xen-unstable.hg/tools/firmware/hvmloader/Makefile =================================================================== --- root.orig/xen-unstable.hg/tools/firmware/hvmloader/Makefile +++ root/xen-unstable.hg/tools/firmware/hvmloader/Makefile @@ -40,13 +40,29 @@ OBJCOPY = objcopy CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR) -SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c +vpath iasl $(PATH) + +SRCS = hvmloader.c \ + acpi_madt.c \ + acpi_ssdt.c \ + acpi_utils.c \ + acpi_xsdt.c \ + mp_tables.c \ + util.c \ + smbios.c OBJS = $(patsubst %.c,%.o,$(SRCS)) +SSDT_SRCS = acpi_ssdt_tpm.h .PHONY: all all: hvmloader -hvmloader: roms.h $(SRCS) +acpi_ssdt_tpm.h: acpi_ssdt_tpm.asl + $(MAKE) iasl + iasl -tc $^ + cat acpi_ssdt_tpm.hex | sed "s/AmlCode/AmlCode_TPM/" > $@ + rm -rf acpi_ssdt_tpm.hex + +hvmloader: roms.h $(SSDT_SRCS) $(SRCS) $(CC) $(CFLAGS) -c $(SRCS) $(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS) $(OBJCOPY) hvmloader.tmp hvmloader @@ -59,6 +75,18 @@ roms.h: ../rombios/BIOS-bochs-latest ../ sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h sh ./mkhex acpi ../acpi/acpi.bin >> roms.h +iasl: + @echo + @echo "ACPI ASL compiler(iasl) is needed" + @echo "Download Intel ACPI CA" + @echo "If wget failed, please download and compile manually from" + @echo "http://developer.intel.com/technology/iapc/acpi/downloads.htm" + @echo + wget $(IASL_URL) + tar xzf $(IASL_VER).tar.gz + make -C $(IASL_VER)/compiler + $(INSTALL_PROG) $(IASL_VER)/compiler/iasl /usr/bin/iasl + .PHONY: clean clean: rm -f roms.h acpi.h Index: root/xen-unstable.hg/tools/firmware/acpi/acpi2_0.h =================================================================== --- root.orig/xen-unstable.hg/tools/firmware/acpi/acpi2_0.h +++ root/xen-unstable.hg/tools/firmware/acpi/acpi2_0.h @@ -111,7 +111,7 @@ typedef struct { // // The maximum number of entrys in RSDT or XSDT // -#define ACPI_MAX_NUM_TABLES 2 +#define ACPI_MAX_NUM_TABLES 5 // // Root System Description Table (RSDT) Index: root/xen-unstable.hg/tools/firmware/acpi/acpi_build.c =================================================================== --- root.orig/xen-unstable.hg/tools/firmware/acpi/acpi_build.c +++ root/xen-unstable.hg/tools/firmware/acpi/acpi_build.c @@ -105,6 +105,7 @@ UpdateTable( * Caculate the checksum */ { + int i; // RSDP Update table->Rsdp->RsdtAddress = (uint32_t)(ACPI_PHYSICAL_ADDRESS+ table->RsdtOffset); @@ -132,6 +133,9 @@ UpdateTable( FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum), table->Rsdt->Header.Length ); + + for (i = 2; i < ACPI_MAX_NUM_TABLES; i++) + table->Rsdt->Entry[i] = 0; //XSDT Update table->Xsdt->Entry[0] = (uint64_t)(ACPI_PHYSICAL_ADDRESS + @@ -145,6 +149,10 @@ UpdateTable( table->Xsdt->Header.Length ); + for (i = 2; i < ACPI_MAX_NUM_TABLES; i++) + table->Xsdt->Entry[i] = 0; + + // FADT Update table->Fadt->Dsdt = (uint32_t)(ACPI_PHYSICAL_ADDRESS + table->DsdtOffset); Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_madt.c =================================================================== --- root.orig/xen-unstable.hg/tools/firmware/hvmloader/acpi_madt.c +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_madt.c @@ -21,6 +21,7 @@ #include "../acpi/acpi2_0.h" #include "../acpi/acpi_madt.h" #include "util.h" +#include "acpi_utils.h" #include #define NULL ((void*)0) @@ -115,21 +116,6 @@ acpi_madt_get_madt(unsigned char *acpi_s return madt; } -static void -set_checksum(void *start, int checksum_offset, int len) -{ - unsigned char sum = 0; - unsigned char *ptr; - - ptr = start; - ptr[checksum_offset] = 0; - while (len--) - sum += *ptr++; - - ptr = start; - ptr[checksum_offset] = -sum; -} - static int acpi_madt_set_local_apics( int nr_vcpu, Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt_tpm.asl =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt_tpm.asl @@ -0,0 +1,29 @@ +//**********************************************************************// +//* +//* Copyright (c) 2006, IBM Corporation. +//* +//* This program is free software; you can redistribute it and/or modify it +//* under the terms and conditions of the GNU General Public License, +//* version 2, as published by the Free Software Foundation. +//* +//* This program is distributed in the hope it will be useful, but WITHOUT +//* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +//* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +//* more details. +//* +//* You should have received a copy of the GNU General Public License along with +//* this program; if not, write to the Free Software Foundation, Inc., 59 Temple +//* Place - Suite 330, Boston, MA 02111-1307 USA. + +//* SSDT for TPM TIS Interface for Xen with Qemu device model + +DefinitionBlock ("SSDT_TPM.aml", "SSDT", 1, "IBM","xen", 2006) +{ + Device (TPM) { + Name (_HID, EisaId ("PNP0C31")) + Name (_CRS, ResourceTemplate () + { + Memory32Fixed (ReadWrite, 0xFED40000, 0x5000,) + }) + } +} \ No newline at end of file Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_utils.c =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_utils.c @@ -0,0 +1,33 @@ +/* + * Commonly used ACPI utility functions. + * + * Yu Ke, ke.yu@xxxxxxxxx + * Copyright (c) 2005, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ + +void set_checksum(void *start, int checksum_offset, int len) +{ + unsigned char sum = 0; + unsigned char *ptr; + + ptr = start; + ptr[checksum_offset] = 0; + while (len--) + sum += *ptr++; + + ptr = start; + ptr[checksum_offset] = -sum; +} Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_utils.h =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_utils.h @@ -0,0 +1,29 @@ +/* + * Commonly used ACPI utility functions. + * + * Yu Ke, ke.yu@xxxxxxxxx + * Copyright (c) 2005, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef ACPI_UTILS_H +#define ACPI_UTILS_H + +#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field))) + +#define NULL ((void*)0) + +void set_checksum(void *start, int checksum_offset, int len); + +#endif Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt_tpm.h =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_ssdt_tpm.h @@ -0,0 +1,25 @@ +/* + * + * Intel ACPI Component Architecture + * ASL Optimizing Compiler version 20060707 [Sep 11 2006] + * Copyright (C) 2000 - 2006 Intel Corporation + * Supports ACPI Specification Revision 3.0a + * + * Compilation of "acpi_ssdt_tpm.asl" - Mon Oct 30 11:28:27 2006 + * + * C source code output + * + */ +unsigned char AmlCode_TPM[] = +{ + 0x53,0x53,0x44,0x54,0x4C,0x00,0x00,0x00, /* 00000000 "SSDTL..." */ + 0x01,0x6D,0x49,0x42,0x4D,0x00,0x00,0x00, /* 00000008 ".mIBM..." */ + 0x78,0x65,0x6E,0x00,0x00,0x00,0x00,0x00, /* 00000010 "xen....." */ + 0xD6,0x07,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x07,0x07,0x06,0x20,0x5B,0x82,0x26,0x54, /* 00000020 "... [.&T" */ + 0x50,0x4D,0x5F,0x08,0x5F,0x48,0x49,0x44, /* 00000028 "PM_._HID" */ + 0x0C,0x41,0xD0,0x0C,0x31,0x08,0x5F,0x43, /* 00000030 ".A..1._C" */ + 0x52,0x53,0x11,0x11,0x0A,0x0E,0x86,0x09, /* 00000038 "RS......" */ + 0x00,0x01,0x00,0x00,0xD4,0xFE,0x00,0x50, /* 00000040 ".......P" */ + 0x00,0x00,0x79,0x00, +}; Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_xsdt.c =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_xsdt.c @@ -0,0 +1,89 @@ +/* + * acpi_xsdt.c: Handling of XSDT entries. + * + * Copyright (c) 2006, IBM Corporation. + * Copyright (c) 2005, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ +#include "../acpi/acpi2_0.h" +#include "util.h" +#include "acpi_utils.h" +#include "acpi_xsdt.h" + + +/* Get the XSDT table */ +ACPI_2_0_XSDT *acpi_xsdt_get(unsigned char *acpi_start) +{ + ACPI_2_0_RSDP *rsdp = NULL; + ACPI_2_0_XSDT *xsdt = NULL; + + rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS)); + if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) { + puts("Bad RSDP signature\n"); + return NULL; + } + + xsdt= (ACPI_2_0_XSDT *) + (acpi_start + rsdp->XsdtAddress - ACPI_PHYSICAL_ADDRESS); + if (xsdt->Header.Signature != ACPI_2_0_XSDT_SIGNATURE) { + puts("Bad XSDT signature\n"); + return NULL; + } + return xsdt; +} + +/* + add an entry to the xdst table entry pointers + copy the given ssdt data to the current available memory at + freemem, if it does not exceed the limit + */ +unsigned char *acpi_xsdt_add_entry(unsigned char *acpi_start, + unsigned char **freemem, + unsigned char *limit, + unsigned char *table, unsigned int table_size) +{ + ACPI_2_0_XSDT *xsdt = acpi_xsdt_get(acpi_start); + int found = 0, i = 0; + unsigned char *addr = NULL; + + /* get empty slot in the Xsdt table */ + while (i < ACPI_MAX_NUM_TABLES) { + if (xsdt->Entry[i] == 0) { + found = 1; + break; + } + i++; + } + + if (found) { + /* memory below hard limit ? */ + if (*freemem + table_size <= limit) { + puts("Copying SSDT entry!\n"); + addr = *freemem; + memcpy(addr, table, table_size); + xsdt->Entry[i] = (long)addr; + *freemem += table_size; + /* update the XSDT table */ + xsdt->Header.Length = + sizeof(ACPI_TABLE_HEADER) + + (i + 1) * sizeof(uint64_t); + set_checksum(xsdt, + FIELD_OFFSET(ACPI_TABLE_HEADER, + Checksum), + xsdt->Header.Length); + } + } + return addr; +} Index: root/xen-unstable.hg/tools/firmware/hvmloader/acpi_xsdt.h =================================================================== --- /dev/null +++ root/xen-unstable.hg/tools/firmware/hvmloader/acpi_xsdt.h @@ -0,0 +1,16 @@ +/* + * acpi_xsdt.h: Handling of XSDT entries. + * + * Copyright (c) 2006, IBM Corporation. + */ +#ifndef ACPI_XSDT_H +#define ACPI_XSDT_H + +ACPI_2_0_XSDT *acpi_xsdt_get(unsigned char *acpi_start); +unsigned char *acpi_xsdt_add_entry(unsigned char *acpi_start, + unsigned char **freemem, + unsigned char *limit, + unsigned char *table, + unsigned int table_size); + +#endif