⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 build.c

📁 xen虚拟机源代码安装包
💻 C
字号:
/* * Copyright (c) 2004, Intel Corporation. * Copyright (c) 2006, Keir Fraser, XenSource Inc. * * 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 "acpi2_0.h"#include "ssdt_tpm.h"#include "../config.h"#include "../util.h"#define align16(sz)        (((sz) + 15) & ~15)#define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))extern struct acpi_20_rsdp Rsdp;extern struct acpi_20_rsdt Rsdt;extern struct acpi_20_xsdt Xsdt;extern struct acpi_20_fadt Fadt;extern struct acpi_20_facs Facs;extern unsigned char AmlCode[];extern int DsdtLen;static void set_checksum(    void *table, uint32_t checksum_offset, uint32_t length){    uint8_t *p, sum = 0;    p = table;    p[checksum_offset] = 0;    while ( length-- )        sum = sum + *p++;    p = table;    p[checksum_offset] = -sum;}static int uart_exists(uint16_t uart_base){    uint16_t ier = uart_base + 1;    uint8_t a, b, c;    a = inb(ier);    outb(ier, 0);    b = inb(ier);    outb(ier, 0xf);    c = inb(ier);    outb(ier, a);    return ((b == 0) && (c == 0xf));}static int hpet_exists(unsigned long hpet_base){    uint32_t hpet_id = *(uint32_t *)hpet_base;    return ((hpet_id >> 16) == 0x8086);}static int construct_bios_info_table(uint8_t *buf){    struct bios_info *bios_info = (struct bios_info *)buf;    memset(bios_info, 0, sizeof(*bios_info));    bios_info->com1_present = uart_exists(0x3f8);    bios_info->com2_present = uart_exists(0x2f8);    bios_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS);    bios_info->pci_min = PCI_MEMBASE;    bios_info->pci_len = PCI_MEMSIZE;    bios_info->xen_pfiob = 0xdead;    return align16(sizeof(*bios_info));}static int construct_madt(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;    memset(madt, 0, sizeof(*madt));    madt->header.signature    = ACPI_2_0_MADT_SIGNATURE;    madt->header.revision     = ACPI_2_0_MADT_REVISION;    fixed_strcpy(madt->header.oem_id, ACPI_OEM_ID);    fixed_strcpy(madt->header.oem_table_id, ACPI_OEM_TABLE_ID);    madt->header.oem_revision = ACPI_OEM_REVISION;    madt->header.creator_id   = ACPI_CREATOR_ID;    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++ )    {        memset(intsrcovr, 0, sizeof(*intsrcovr));        intsrcovr->type   = ACPI_INTERRUPT_SOURCE_OVERRIDE;        intsrcovr->length = sizeof(*intsrcovr);        intsrcovr->source = i;        if ( i == 0 )        {            /* ISA IRQ0 routed to IOAPIC GSI 2. */            intsrcovr->gsi    = 2;            intsrcovr->flags  = 0x0;        }        else if ( PCI_ISA_IRQ_MASK & (1U << i) )        {            /* PCI: active-low level-triggered. */            intsrcovr->gsi    = i;            intsrcovr->flags  = 0xf;        }        else        {            /* No need for a INT source override structure. */            continue;        }        offset += sizeof(*intsrcovr);        intsrcovr++;    }    io_apic = (struct acpi_20_madt_ioapic *)intsrcovr;    memset(io_apic, 0, sizeof(*io_apic));    io_apic->type        = ACPI_IO_APIC;    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);    for ( i = 0; i < get_vcpu_nr(); i++ )    {        memset(lapic, 0, sizeof(*lapic));        lapic->type    = ACPI_PROCESSOR_LOCAL_APIC;        lapic->length  = sizeof(*lapic);        /* Processor ID must match processor-object IDs in the DSDT. */        lapic->acpi_processor_id = i;        lapic->apic_id = LAPIC_ID(i);        lapic->flags   = ACPI_LOCAL_APIC_ENABLED;        offset += sizeof(*lapic);        lapic++;    }    madt->header.length = offset;    set_checksum(madt, offsetof(struct acpi_header, checksum), offset);    return align16(offset);}static int construct_hpet(struct acpi_20_hpet *hpet){    int offset;    memset(hpet, 0, sizeof(*hpet));    hpet->header.signature    = ACPI_2_0_HPET_SIGNATURE;    hpet->header.revision     = ACPI_2_0_HPET_REVISION;    fixed_strcpy(hpet->header.oem_id, ACPI_OEM_ID);    fixed_strcpy(hpet->header.oem_table_id, ACPI_OEM_TABLE_ID);    hpet->header.oem_revision = ACPI_OEM_REVISION;    hpet->header.creator_id   = ACPI_CREATOR_ID;    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;}static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs){    int offset = 0, nr_tables = 0;    struct acpi_20_madt *madt;    struct acpi_20_hpet *hpet;    struct acpi_20_tcpa *tcpa;    static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};    uint16_t *tis_hdr;    /* MADT. */    if ( (get_vcpu_nr() > 1) || get_apic_mode() )    {        madt = (struct acpi_20_madt *)&buf[offset];        offset += construct_madt(madt);        table_ptrs[nr_tables++] = (unsigned long)madt;    }    /* HPET. */    if ( hpet_exists(ACPI_HPET_ADDRESS) )    {        hpet = (struct acpi_20_hpet *)&buf[offset];        offset += construct_hpet(hpet);        table_ptrs[nr_tables++] = (unsigned long)hpet;    }    /* TPM TCPA and SSDT. */    tis_hdr = (uint16_t *)0xFED40F00;    if ( (tis_hdr[0] == tis_signature[0]) &&         (tis_hdr[1] == tis_signature[1]) &&         (tis_hdr[2] == tis_signature[2]) )    {        memcpy(&buf[offset], AmlCode_TPM, sizeof(AmlCode_TPM));        table_ptrs[nr_tables++] = (unsigned long)&buf[offset];        offset += align16(sizeof(AmlCode_TPM));        tcpa = (struct acpi_20_tcpa *)&buf[offset];        memset(tcpa, 0, sizeof(*tcpa));        offset += align16(sizeof(*tcpa));        table_ptrs[nr_tables++] = (unsigned long)tcpa;        tcpa->header.signature = ACPI_2_0_TCPA_SIGNATURE;        tcpa->header.length    = sizeof(*tcpa);        tcpa->header.revision  = ACPI_2_0_TCPA_REVISION;        fixed_strcpy(tcpa->header.oem_id, ACPI_OEM_ID);        fixed_strcpy(tcpa->header.oem_table_id, ACPI_OEM_TABLE_ID);        tcpa->header.oem_revision = ACPI_OEM_REVISION;        tcpa->header.creator_id   = ACPI_CREATOR_ID;        tcpa->header.creator_revision = ACPI_CREATOR_REVISION;        tcpa->lasa = e820_malloc(ACPI_2_0_TCPA_LAML_SIZE);        if ( tcpa->lasa )        {            tcpa->laml = ACPI_2_0_TCPA_LAML_SIZE;            memset((char *)(unsigned long)tcpa->lasa, 0, tcpa->laml);            set_checksum(tcpa,                         offsetof(struct acpi_header, checksum),                         tcpa->header.length);        }    }    table_ptrs[nr_tables] = 0;    return align16(offset);}static void __acpi_build_tables(uint8_t *buf, int *low_sz, int *high_sz){    struct acpi_20_rsdp *rsdp;    struct acpi_20_rsdt *rsdt;    struct acpi_20_xsdt *xsdt;    struct acpi_20_fadt *fadt;    struct acpi_10_fadt *fadt_10;    struct acpi_20_facs *facs;    unsigned char       *dsdt;    unsigned long        secondary_tables[16];    int                  offset = 0, i;    /*     * Fill in high-memory data structures, starting at @buf.     */    facs = (struct acpi_20_facs *)&buf[offset];    memcpy(facs, &Facs, sizeof(struct acpi_20_facs));    offset += align16(sizeof(struct acpi_20_facs));    dsdt = (unsigned char *)&buf[offset];    memcpy(dsdt, &AmlCode, DsdtLen);    offset += align16(DsdtLen);    /*     * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2     * or above properly, notably Windows 2000, which tries to copy FADT     * into a 116 bytes buffer thus causing an overflow. The solution is to     * link the higher revision FADT with the XSDT only and introduce a     * 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];    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;    fadt_10->firmware_ctrl = (unsigned long)facs;    set_checksum(fadt_10,                 offsetof(struct acpi_header, checksum),                 sizeof(struct acpi_10_fadt));    fadt = (struct acpi_20_fadt *)&buf[offset];    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;    fadt->x_firmware_ctrl = (unsigned long)facs;    set_checksum(fadt,                 offsetof(struct acpi_header, checksum),                 sizeof(struct acpi_20_fadt));    offset += construct_secondary_tables(&buf[offset], secondary_tables);    xsdt = (struct acpi_20_xsdt *)&buf[offset];    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];    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 *)ACPI_PHYSICAL_ADDRESS;    offset = 0;    offset += construct_bios_info_table(&buf[offset]);    rsdp = (struct acpi_20_rsdp *)&buf[offset];    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,                 offsetof(struct acpi_10_rsdp, checksum),                 sizeof(struct acpi_10_rsdp));    set_checksum(rsdp,                 offsetof(struct acpi_20_rsdp, extended_checksum),                 sizeof(struct acpi_20_rsdp));    *low_sz = offset;}void acpi_build_tables(void){    int high_sz, low_sz;    uint8_t *buf;    /* Find out size of high-memory ACPI data area. */    buf = (uint8_t *)&_end;    __acpi_build_tables(buf, &low_sz, &high_sz);    memset(buf, 0, high_sz);    /* Allocate data area and set up ACPI tables there. */    buf = (uint8_t *)e820_malloc(high_sz);    __acpi_build_tables(buf, &low_sz, &high_sz);    printf(" - Lo data: %08lx-%08lx\n"           " - Hi data: %08lx-%08lx\n",           (unsigned long)ACPI_PHYSICAL_ADDRESS,           (unsigned long)ACPI_PHYSICAL_ADDRESS + low_sz - 1,           (unsigned long)buf, (unsigned long)buf + high_sz - 1);}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -