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

📄 hvmloader.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * hvmloader.c: HVM bootloader. * * Leendert van Doorn, leendert@watson.ibm.com * Copyright (c) 2005, International Business Machines 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 "roms.h"#include "acpi/acpi2_0.h"#include "hypercall.h"#include "util.h"#include "config.h"#include "apic_regs.h"#include "pci_regs.h"#include "e820.h"#include "option_rom.h"#include <xen/version.h>#include <xen/hvm/params.h>asm (    "    .text                       \n"    "    .globl _start               \n"    "_start:                         \n"    /* C runtime kickoff. */    "    cld                         \n"    "    cli                         \n"    "    movl $stack_top,%esp        \n"    "    movl %esp,%ebp              \n"    "    call main                   \n"    /* Relocate real-mode trampoline to 0x0. */    "    mov  $trampoline_start,%esi \n"    "    xor  %edi,%edi              \n"    "    mov  $trampoline_end,%ecx   \n"    "    sub  %esi,%ecx              \n"    "    rep  movsb                  \n"    /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */    "    lgdt gdt_desr               \n"    "    mov  $0x0010,%ax            \n"    "    mov  %ax,%ds                \n"    "    mov  %ax,%es                \n"    "    mov  %ax,%fs                \n"    "    mov  %ax,%gs                \n"    "    mov  %ax,%ss                \n"    /* Initialise all 32-bit GPRs to zero. */    "    xor  %eax,%eax              \n"    "    xor  %ebx,%ebx              \n"    "    xor  %ecx,%ecx              \n"    "    xor  %edx,%edx              \n"    "    xor  %esp,%esp              \n"    "    xor  %ebp,%ebp              \n"    "    xor  %esi,%esi              \n"    "    xor  %edi,%edi              \n"    /* Enter real mode, reload all segment registers and IDT. */    "    ljmp $0x8,$0x0              \n"    "trampoline_start: .code16       \n"    "    mov  %eax,%cr0              \n"    "    ljmp $0,$1f-trampoline_start\n"    "1:  mov  %ax,%ds                \n"    "    mov  %ax,%es                \n"    "    mov  %ax,%fs                \n"    "    mov  %ax,%gs                \n"    "    mov  %ax,%ss                \n"    "    lidt 1f-trampoline_start    \n"    "    ljmp $0xf000,$0xfff0        \n"    "1:  .word 0x3ff,0,0             \n"    "trampoline_end:   .code32       \n"    "                                \n"    "gdt_desr:                       \n"    "    .word gdt_end - gdt - 1     \n"    "    .long gdt                   \n"    "                                \n"    "    .align 8                    \n"    "gdt:                            \n"    "    .quad 0x0000000000000000    \n"    "    .quad 0x00009a000000ffff    \n" /* Ring 0 code, base 0 limit 0xffff */    "    .quad 0x000092000000ffff    \n" /* Ring 0 data, base 0 limit 0xffff */    "gdt_end:                        \n"    "                                \n"    "    .bss                        \n"    "    .align    8                 \n"    "stack:                          \n"    "    .skip    0x4000             \n"    "stack_top:                      \n"    "    .text                       \n"    );static enum { VGA_none, VGA_std, VGA_cirrus } virtual_vga = VGA_none;static voidinit_hypercalls(void){    uint32_t eax, ebx, ecx, edx;    unsigned long i;    char signature[13];    xen_extraversion_t extraversion;    cpuid(0x40000000, &eax, &ebx, &ecx, &edx);    *(uint32_t *)(signature + 0) = ebx;    *(uint32_t *)(signature + 4) = ecx;    *(uint32_t *)(signature + 8) = edx;    signature[12] = '\0';    BUG_ON(strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002));    /* Fill in hypercall transfer pages. */    cpuid(0x40000002, &eax, &ebx, &ecx, &edx);    for ( i = 0; i < eax; i++ )        wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);    /* Print version information. */    cpuid(0x40000001, &eax, &ebx, &ecx, &edx);    hypercall_xen_version(XENVER_extraversion, extraversion);    printf("Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);}static void apic_setup(void){    /* Set the IOAPIC ID to tha static value used in the MP/ACPI tables. */    ioapic_write(0x00, IOAPIC_ID);    /* Set up Virtual Wire mode. */    lapic_write(APIC_SPIV, APIC_SPIV_APIC_ENABLED | 0xFF);    lapic_write(APIC_LVT0, APIC_MODE_EXTINT << 8);    lapic_write(APIC_LVT1, APIC_MODE_NMI    << 8);}static void pci_setup(void){    uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd;    uint16_t class, vendor_id, device_id;    unsigned int bar, pin, link, isa_irq;    /* Resources assignable to PCI devices via BARs. */    struct resource {        uint32_t base, max;    } *resource;    struct resource mem_resource = { PCI_MEMBASE, PCI_MEMBASE + PCI_MEMSIZE };    struct resource io_resource  = { 0xc000, 0x10000 };    /* Create a list of device BARs in descending order of size. */    struct bars {        uint32_t devfn, bar_reg, bar_sz;    } *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS;    unsigned int i, nr_bars = 0;    /* Program PCI-ISA bridge with appropriate link routes. */    isa_irq = 0;    for ( link = 0; link < 4; link++ )    {        do { isa_irq = (isa_irq + 1) & 15;        } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) );        pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq);        printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq);    }    /* Program ELCR to match PCI-wired IRQs. */    outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0));    outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8));    /* Scan the PCI bus and map resources. */    for ( devfn = 0; devfn < 128; devfn++ )    {        class     = pci_readw(devfn, PCI_CLASS_DEVICE);        vendor_id = pci_readw(devfn, PCI_VENDOR_ID);        device_id = pci_readw(devfn, PCI_DEVICE_ID);        if ( (vendor_id == 0xffff) && (device_id == 0xffff) )            continue;        ASSERT((devfn != PCI_ISA_DEVFN) ||               ((vendor_id == 0x8086) && (device_id == 0x7000)));        switch ( class )        {        case 0x0300:            if ( (vendor_id == 0x1234) && (device_id == 0x1111) )                virtual_vga = VGA_std;            if ( (vendor_id == 0x1013) && (device_id == 0xb8) )                virtual_vga = VGA_cirrus;            break;        case 0x0680:            /* PIIX4 ACPI PM. Special device with special PCI config space. */            ASSERT((vendor_id == 0x8086) && (device_id == 0x7113));            pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */            pci_writew(devfn, 0x22, 0x0000);            pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */            pci_writew(devfn, 0x3d, 0x0001);            break;        case 0x0101:            if ( vendor_id == 0x8086 )            {                /* Intel ICHs since PIIX3: enable IDE legacy mode. */                pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */                pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */            }            break;        }        /* Map the I/O memory and port resources. */        for ( bar = 0; bar < 7; bar++ )        {            bar_reg = PCI_BASE_ADDRESS_0 + 4*bar;            if ( bar == 6 )                bar_reg = PCI_ROM_ADDRESS;            bar_data = pci_readl(devfn, bar_reg);            pci_writel(devfn, bar_reg, ~0);            bar_sz = pci_readl(devfn, bar_reg);            pci_writel(devfn, bar_reg, bar_data);            if ( bar_sz == 0 )                continue;            bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) ==                        PCI_BASE_ADDRESS_SPACE_MEMORY) ?                       PCI_BASE_ADDRESS_MEM_MASK :                       (PCI_BASE_ADDRESS_IO_MASK & 0xffff));            bar_sz &= ~(bar_sz - 1);            for ( i = 0; i < nr_bars; i++ )                if ( bars[i].bar_sz < bar_sz )                    break;            if ( i != nr_bars )                memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars));            bars[i].devfn   = devfn;            bars[i].bar_reg = bar_reg;            bars[i].bar_sz  = bar_sz;            nr_bars++;        }        /* Map the interrupt. */        pin = pci_readb(devfn, PCI_INTERRUPT_PIN);        if ( pin != 0 )        {            /* This is the barber's pole mapping used by Xen. */            link = ((pin - 1) + (devfn >> 3)) & 3;            isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link);            pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq);            printf("pci dev %02x:%x INT%c->IRQ%u\n",                   devfn>>3, devfn&7, 'A'+pin-1, isa_irq);        }    }    /* Assign iomem and ioport resources in descending order of size. */    for ( i = 0; i < nr_bars; i++ )    {        devfn   = bars[i].devfn;        bar_reg = bars[i].bar_reg;        bar_sz  = bars[i].bar_sz;        bar_data = pci_readl(devfn, bar_reg);        if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==             PCI_BASE_ADDRESS_SPACE_MEMORY )        {            resource = &mem_resource;            bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;        }        else        {

⌨️ 快捷键说明

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