ia64/xen-unstable

annotate tools/firmware/hvmloader/hvmloader.c @ 16747:bf828db8d017

hvm: Extboot support for Xen

This patch adds extboot to Xen. It should be pretty harmless as the
moment because it's never enabled. extboot allows arbitrary block
devices to be used to boot guests including SCSI and PV disks. I've
tested it with both Windows and Linux guests in QEMU.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 17 16:39:14 2008 +0000 (2008-01-17)
parents 0814fb0f8a4d
children 824ffb1efa9c
rev   line source
kaf24@8708 1 /*
kaf24@8708 2 * hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader.
kaf24@8708 3 *
kaf24@8708 4 * Leendert van Doorn, leendert@watson.ibm.com
kaf24@8708 5 * Copyright (c) 2005, International Business Machines Corporation.
kaf24@8708 6 *
kfraser@12554 7 * Copyright (c) 2006, Keir Fraser, XenSource Inc.
kfraser@12554 8 *
kaf24@8708 9 * This program is free software; you can redistribute it and/or modify it
kaf24@8708 10 * under the terms and conditions of the GNU General Public License,
kaf24@8708 11 * version 2, as published by the Free Software Foundation.
kaf24@8708 12 *
kaf24@8708 13 * This program is distributed in the hope it will be useful, but WITHOUT
kaf24@8708 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kaf24@8708 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kaf24@8708 16 * more details.
kaf24@8708 17 *
kaf24@8708 18 * You should have received a copy of the GNU General Public License along with
kaf24@8708 19 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
kaf24@8708 20 * Place - Suite 330, Boston, MA 02111-1307 USA.
kaf24@8708 21 */
kfraser@14959 22
kaf24@8708 23 #include "roms.h"
kfraser@14959 24 #include "acpi/acpi2_0.h"
kfraser@10976 25 #include "hypercall.h"
kfraser@10976 26 #include "util.h"
kfraser@12548 27 #include "config.h"
kaf24@12571 28 #include "apic_regs.h"
kfraser@12554 29 #include "pci_regs.h"
keir@15303 30 #include "e820.h"
kfraser@10976 31 #include <xen/version.h>
kfraser@11081 32 #include <xen/hvm/params.h>
kaf24@8708 33
kaf24@8708 34 asm(
kfraser@12548 35 " .text \n"
kfraser@12548 36 " .globl _start \n"
kfraser@12548 37 "_start: \n"
kfraser@14373 38 /* C runtime kickoff. */
kfraser@12548 39 " cld \n"
kfraser@12548 40 " cli \n"
kfraser@14373 41 " movl $stack_top,%esp \n"
kfraser@14373 42 " movl %esp,%ebp \n"
keir@16440 43 " movl %eax,initial_eax \n"
kfraser@14373 44 " call main \n"
kfraser@14373 45 /* Relocate real-mode trampoline to 0x0. */
kfraser@14373 46 " mov $trampoline_start,%esi \n"
kfraser@14373 47 " xor %edi,%edi \n"
kfraser@14373 48 " mov $trampoline_end,%ecx \n"
kfraser@14373 49 " sub %esi,%ecx \n"
kfraser@14373 50 " rep movsb \n"
kfraser@14373 51 /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */
kfraser@12548 52 " lgdt gdt_desr \n"
kfraser@14373 53 " mov $0x0010,%ax \n"
kfraser@14373 54 " mov %ax,%ds \n"
kfraser@14373 55 " mov %ax,%es \n"
kfraser@14373 56 " mov %ax,%fs \n"
kfraser@14373 57 " mov %ax,%gs \n"
kfraser@14373 58 " mov %ax,%ss \n"
kfraser@14391 59 /* Initialise all 32-bit GPRs to zero. */
kfraser@14391 60 " xor %eax,%eax \n"
kfraser@14391 61 " xor %ebx,%ebx \n"
kfraser@14391 62 " xor %ecx,%ecx \n"
kfraser@14391 63 " xor %edx,%edx \n"
kfraser@14391 64 " xor %esp,%esp \n"
kfraser@14391 65 " xor %ebp,%ebp \n"
kfraser@14391 66 " xor %esi,%esi \n"
kfraser@14391 67 " xor %edi,%edi \n"
kfraser@14373 68 /* Enter real mode, reload all segment registers and IDT. */
kfraser@14391 69 " ljmp $0x8,$0x0 \n"
kfraser@14373 70 "trampoline_start: .code16 \n"
kfraser@14373 71 " mov %eax,%cr0 \n"
kfraser@14373 72 " ljmp $0,$1f-trampoline_start\n"
kfraser@14391 73 "1: mov %ax,%ds \n"
kfraser@14373 74 " mov %ax,%es \n"
kfraser@14373 75 " mov %ax,%fs \n"
kfraser@14373 76 " mov %ax,%gs \n"
kfraser@14373 77 " mov %ax,%ss \n"
kfraser@14373 78 " lidt 1f-trampoline_start \n"
kfraser@14373 79 " ljmp $0xf000,$0xfff0 \n"
kfraser@14373 80 "1: .word 0x3ff,0,0 \n"
kfraser@14373 81 "trampoline_end: .code32 \n"
kfraser@12548 82 " \n"
kfraser@12548 83 "gdt_desr: \n"
kfraser@12548 84 " .word gdt_end - gdt - 1 \n"
kfraser@12548 85 " .long gdt \n"
kfraser@12548 86 " \n"
kfraser@12548 87 " .align 8 \n"
kfraser@12548 88 "gdt: \n"
kfraser@12548 89 " .quad 0x0000000000000000 \n"
kfraser@14373 90 " .quad 0x00009a000000ffff \n" /* Ring 0 code, base 0 limit 0xffff */
kfraser@14373 91 " .quad 0x000092000000ffff \n" /* Ring 0 data, base 0 limit 0xffff */
kfraser@12548 92 "gdt_end: \n"
kfraser@12548 93 " \n"
kfraser@12548 94 " .bss \n"
kfraser@12548 95 " .align 8 \n"
kfraser@12548 96 "stack: \n"
kfraser@12548 97 " .skip 0x4000 \n"
kfraser@12548 98 "stack_top: \n"
kfraser@12548 99 );
kaf24@8708 100
keir@16440 101 static unsigned int initial_eax;
keir@16440 102
kfraser@14959 103 void create_mp_tables(void);
kfraser@14959 104 int hvm_write_smbios_tables(void);
kaf24@8708 105
kfraser@10976 106 static int
kaf24@8708 107 cirrus_check(void)
kaf24@8708 108 {
kfraser@12548 109 outw(0x3C4, 0x9206);
kfraser@12548 110 return inb(0x3C5) == 0x12;
kaf24@8708 111 }
kaf24@8708 112
kfraser@10976 113 static int
kaf24@8708 114 check_amd(void)
kaf24@8708 115 {
kfraser@12548 116 char id[12];
kaf24@8708 117
kfraser@12548 118 __asm__ __volatile__ (
kfraser@12548 119 "cpuid"
kfraser@12548 120 : "=b" (*(int *)(&id[0])),
kfraser@12548 121 "=c" (*(int *)(&id[8])),
kfraser@12548 122 "=d" (*(int *)(&id[4]))
kfraser@12548 123 : "a" (0) );
kfraser@12548 124 return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
kaf24@8708 125 }
kaf24@8708 126
keir@16440 127 static int
keir@16440 128 use_vmxassist(void)
keir@16440 129 {
keir@16440 130 return !check_amd() && !initial_eax;
keir@16440 131 }
keir@16440 132
kfraser@10976 133 static void
kfraser@10976 134 wrmsr(uint32_t idx, uint64_t v)
kfraser@10976 135 {
kfraser@12548 136 __asm__ __volatile__ (
kfraser@12548 137 "wrmsr"
kfraser@12548 138 : : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) );
kfraser@10976 139 }
kfraser@10976 140
kfraser@10976 141 static void
kfraser@10976 142 init_hypercalls(void)
kfraser@10976 143 {
kfraser@12548 144 uint32_t eax, ebx, ecx, edx;
kfraser@12548 145 unsigned long i;
kfraser@12554 146 char signature[13];
kfraser@12548 147 xen_extraversion_t extraversion;
kfraser@10976 148
kfraser@12548 149 cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
kfraser@10976 150
kfraser@12548 151 *(uint32_t *)(signature + 0) = ebx;
kfraser@12548 152 *(uint32_t *)(signature + 4) = ecx;
kfraser@12548 153 *(uint32_t *)(signature + 8) = edx;
kfraser@12548 154 signature[12] = '\0';
kfraser@10976 155
kfraser@12548 156 if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
kfraser@12548 157 {
kfraser@12554 158 printf("FATAL: Xen hypervisor not detected\n");
kfraser@12548 159 __asm__ __volatile__( "ud2" );
kfraser@12548 160 }
kfraser@10976 161
kfraser@12554 162 /* Fill in hypercall transfer pages. */
kfraser@12548 163 cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
kfraser@12548 164 for ( i = 0; i < eax; i++ )
kfraser@12548 165 wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
kfraser@12548 166
kfraser@12554 167 /* Print version information. */
kfraser@12554 168 cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
kfraser@12548 169 hypercall_xen_version(XENVER_extraversion, extraversion);
kfraser@12554 170 printf("Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);
kfraser@10976 171 }
kfraser@10976 172
kfraser@12548 173 static void apic_setup(void)
kaf24@8708 174 {
kaf24@12571 175 /* Set the IOAPIC ID to tha static value used in the MP/ACPI tables. */
kaf24@12571 176 ioapic_write(0x00, IOAPIC_ID);
kaf24@8708 177
kaf24@12571 178 /* Set up Virtual Wire mode. */
kaf24@12571 179 lapic_write(APIC_SPIV, APIC_SPIV_APIC_ENABLED | 0xFF);
kaf24@12571 180 lapic_write(APIC_LVT0, APIC_MODE_EXTINT << 8);
kaf24@12571 181 lapic_write(APIC_LVT1, APIC_MODE_NMI << 8);
kaf24@8708 182 }
kaf24@8708 183
kfraser@12554 184 static void pci_setup(void)
kfraser@12554 185 {
kfraser@12554 186 uint32_t devfn, bar_reg, bar_data, bar_sz, cmd;
kfraser@12554 187 uint32_t *base, io_base = 0xc000, mem_base = HVM_BELOW_4G_MMIO_START;
kfraser@12554 188 uint16_t class, vendor_id, device_id;
kfraser@12554 189 unsigned int bar, pin, link, isa_irq;
kfraser@12554 190
kfraser@12554 191 /* Program PCI-ISA bridge with appropriate link routes. */
kfraser@15581 192 isa_irq = 0;
kfraser@15581 193 for ( link = 0; link < 4; link++ )
kfraser@12554 194 {
kfraser@15581 195 do { isa_irq = (isa_irq + 1) & 15;
kfraser@15581 196 } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) );
kfraser@12554 197 pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq);
kfraser@12554 198 printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq);
kfraser@12554 199 }
kfraser@12554 200
kfraser@12554 201 /* Program ELCR to match PCI-wired IRQs. */
kfraser@12554 202 outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0));
kfraser@12554 203 outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8));
kfraser@12554 204
kfraser@12554 205 /* Scan the PCI bus and map resources. */
kfraser@12554 206 for ( devfn = 0; devfn < 128; devfn++ )
kfraser@12554 207 {
kfraser@12554 208 class = pci_readw(devfn, PCI_CLASS_DEVICE);
kfraser@12554 209 vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
kfraser@12554 210 device_id = pci_readw(devfn, PCI_DEVICE_ID);
kfraser@12554 211 if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
kfraser@12554 212 continue;
kfraser@12554 213
kfraser@12554 214 ASSERT((devfn != PCI_ISA_DEVFN) ||
kfraser@12554 215 ((vendor_id == 0x8086) && (device_id == 0x7000)));
kfraser@12554 216
kfraser@12554 217 switch ( class )
kfraser@12554 218 {
kfraser@12554 219 case 0x0680:
kfraser@12554 220 ASSERT((vendor_id == 0x8086) && (device_id == 0x7113));
kfraser@12554 221 /*
kfraser@12554 222 * PIIX4 ACPI PM. Special device with special PCI config space.
kfraser@12554 223 * No ordinary BARs.
kfraser@12554 224 */
kfraser@12554 225 pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */
kfraser@12554 226 pci_writew(devfn, 0x22, 0x0000);
kfraser@12554 227 pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */
kfraser@12554 228 pci_writew(devfn, 0x3d, 0x0001);
kfraser@12554 229 break;
kfraser@12554 230 case 0x0101:
kfraser@12554 231 /* PIIX3 IDE */
kfraser@12554 232 ASSERT((vendor_id == 0x8086) && (device_id == 0x7010));
kfraser@12554 233 pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */
kfraser@12554 234 pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */
kfraser@12554 235 /* fall through */
kfraser@12554 236 default:
kfraser@12554 237 /* Default memory mappings. */
kfraser@12554 238 for ( bar = 0; bar < 7; bar++ )
kfraser@12554 239 {
kfraser@12554 240 bar_reg = PCI_BASE_ADDRESS_0 + 4*bar;
kfraser@12554 241 if ( bar == 6 )
kfraser@12554 242 bar_reg = PCI_ROM_ADDRESS;
kfraser@12554 243
kfraser@12554 244 bar_data = pci_readl(devfn, bar_reg);
kfraser@12554 245
kfraser@12554 246 pci_writel(devfn, bar_reg, ~0);
kfraser@12554 247 bar_sz = pci_readl(devfn, bar_reg);
kfraser@12554 248 if ( bar_sz == 0 )
kfraser@12554 249 continue;
kfraser@12554 250
kfraser@12554 251 if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
kfraser@12554 252 PCI_BASE_ADDRESS_SPACE_MEMORY )
kfraser@12554 253 {
kfraser@12554 254 base = &mem_base;
kfraser@12554 255 bar_sz &= PCI_BASE_ADDRESS_MEM_MASK;
kfraser@12554 256 bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;
kfraser@12554 257 }
kfraser@12554 258 else
kfraser@12554 259 {
kfraser@12554 260 base = &io_base;
kfraser@12554 261 bar_sz &= PCI_BASE_ADDRESS_IO_MASK & 0xffff;
kfraser@12554 262 bar_data &= ~PCI_BASE_ADDRESS_IO_MASK;
kfraser@12554 263 }
kfraser@12554 264 bar_sz &= ~(bar_sz - 1);
kfraser@12554 265
kfraser@12554 266 *base = (*base + bar_sz - 1) & ~(bar_sz - 1);
kfraser@12554 267 bar_data |= *base;
kfraser@12554 268 *base += bar_sz;
kfraser@12554 269
kfraser@12554 270 pci_writel(devfn, bar_reg, bar_data);
kfraser@12554 271 printf("pci dev %02x:%x bar %02x size %08x: %08x\n",
kfraser@12554 272 devfn>>3, devfn&7, bar_reg, bar_sz, bar_data);
kfraser@12554 273
kfraser@12554 274 /* Now enable the memory or I/O mapping. */
kfraser@12554 275 cmd = pci_readw(devfn, PCI_COMMAND);
kfraser@12554 276 if ( (bar_reg == PCI_ROM_ADDRESS) ||
kfraser@12554 277 ((bar_data & PCI_BASE_ADDRESS_SPACE) ==
kfraser@12554 278 PCI_BASE_ADDRESS_SPACE_MEMORY) )
kfraser@12554 279 cmd |= PCI_COMMAND_MEMORY;
kfraser@12554 280 else
kfraser@12554 281 cmd |= PCI_COMMAND_IO;
kfraser@12554 282 pci_writew(devfn, PCI_COMMAND, cmd);
kfraser@12554 283 }
kfraser@12554 284 break;
kfraser@12554 285 }
kfraser@12554 286
kfraser@12554 287 /* Map the interrupt. */
kfraser@12554 288 pin = pci_readb(devfn, PCI_INTERRUPT_PIN);
kfraser@12554 289 if ( pin != 0 )
kfraser@12554 290 {
kfraser@12554 291 /* This is the barber's pole mapping used by Xen. */
kfraser@12554 292 link = ((pin - 1) + (devfn >> 3)) & 3;
kfraser@12554 293 isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link);
kfraser@12554 294 pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq);
kfraser@12554 295 printf("pci dev %02x:%x INT%c->IRQ%u\n",
kfraser@12554 296 devfn>>3, devfn&7, 'A'+pin-1, isa_irq);
kfraser@12554 297 }
kfraser@12554 298 }
kfraser@12554 299 }
kfraser@12554 300
keir@14449 301 /*
keir@14449 302 * If the network card is in the boot order, load the Etherboot option ROM.
keir@14449 303 * Read the boot order bytes from CMOS and check if any of them are 0x4.
keir@14449 304 */
keir@14449 305 static int must_load_nic(void)
Tim@13140 306 {
Tim@13140 307 uint8_t boot_order;
Tim@13140 308
keir@14449 309 /* Read CMOS register 0x3d (boot choices 0 and 1). */
keir@14449 310 boot_order = cmos_inb(0x3d);
keir@14449 311 if ( ((boot_order & 0xf) == 0x4) || ((boot_order & 0xf0) == 0x40) )
Tim@13140 312 return 1;
keir@14449 313
keir@14449 314 /* Read CMOS register 0x38 (boot choice 2 and FDD test flag). */
keir@14449 315 boot_order = cmos_inb(0x38);
keir@14449 316 return ((boot_order & 0xf0) == 0x40);
keir@14449 317 }
keir@14449 318
keir@16747 319 static int must_load_extboot(void)
keir@16747 320 {
keir@16747 321 return (inb(0x404) == 1);
keir@16747 322 }
keir@16747 323
keir@14449 324 /* Replace possibly erroneous memory-size CMOS fields with correct values. */
keir@14449 325 static void cmos_write_memory_size(void)
keir@14449 326 {
keir@15303 327 struct e820entry *map = HVM_E820;
keir@15303 328 int i, nr = *HVM_E820_NR;
keir@14449 329 uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0;
keir@14449 330
keir@14449 331 for ( i = 0; i < nr; i++ )
keir@14449 332 if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) )
keir@14449 333 break;
keir@14449 334
keir@14449 335 if ( i != nr )
keir@14449 336 {
keir@14449 337 alt_mem = ext_mem = map[i].addr + map[i].size;
keir@14449 338 ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
keir@14449 339 if ( ext_mem > 0xffff )
keir@14449 340 ext_mem = 0xffff;
keir@14449 341 alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
keir@14449 342 }
keir@14449 343
keir@14877 344 /* All BIOSes: conventional memory (CMOS *always* reports 640kB). */
keir@14449 345 cmos_outb(0x15, (uint8_t)(base_mem >> 0));
keir@14449 346 cmos_outb(0x16, (uint8_t)(base_mem >> 8));
keir@14449 347
keir@14449 348 /* All BIOSes: extended memory (1kB chunks above 1MB). */
keir@14449 349 cmos_outb(0x17, (uint8_t)( ext_mem >> 0));
keir@14449 350 cmos_outb(0x18, (uint8_t)( ext_mem >> 8));
keir@14449 351 cmos_outb(0x30, (uint8_t)( ext_mem >> 0));
keir@14449 352 cmos_outb(0x31, (uint8_t)( ext_mem >> 8));
keir@14449 353
keir@14449 354 /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */
keir@14449 355 cmos_outb(0x34, (uint8_t)( alt_mem >> 0));
keir@14449 356 cmos_outb(0x35, (uint8_t)( alt_mem >> 8));
Tim@13140 357 }
Tim@13140 358
kfraser@12548 359 int main(void)
kfraser@12548 360 {
kfraser@14959 361 int acpi_sz = 0, vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
keir@16747 362 int extboot_sz = 0;
kaf24@12574 363
kfraser@12554 364 printf("HVM Loader\n");
kfraser@12548 365
kfraser@12548 366 init_hypercalls();
kfraser@12548 367
kfraser@12554 368 printf("Writing SMBIOS tables ...\n");
kfraser@14959 369 smbios_sz = hvm_write_smbios_tables();
kfraser@12548 370
kfraser@12554 371 printf("Loading ROMBIOS ...\n");
kfraser@14959 372 rombios_sz = sizeof(rombios);
kfraser@14959 373 if ( rombios_sz > 0x10000 )
kfraser@14959 374 rombios_sz = 0x10000;
kfraser@14959 375 memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz);
kaf24@13656 376 highbios_setup();
kfraser@12548 377
kfraser@12548 378 apic_setup();
kfraser@12554 379 pci_setup();
kaf24@12574 380
kfraser@12600 381 if ( (get_vcpu_nr() > 1) || get_apic_mode() )
kaf24@12574 382 create_mp_tables();
kfraser@12548 383
kfraser@12548 384 if ( cirrus_check() )
kfraser@12548 385 {
kfraser@12554 386 printf("Loading Cirrus VGABIOS ...\n");
kfraser@12548 387 memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
kfraser@12548 388 vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
kfraser@14959 389 vgabios_sz = sizeof(vgabios_cirrusvga);
kfraser@12548 390 }
kfraser@12548 391 else
kfraser@12548 392 {
kfraser@12554 393 printf("Loading Standard VGABIOS ...\n");
kfraser@12548 394 memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
kfraser@12548 395 vgabios_stdvga, sizeof(vgabios_stdvga));
kfraser@14959 396 vgabios_sz = sizeof(vgabios_stdvga);
kfraser@12548 397 }
kfraser@12548 398
Tim@13140 399 if ( must_load_nic() )
Tim@13140 400 {
Tim@13140 401 printf("Loading ETHERBOOT ...\n");
Tim@13140 402 memcpy((void *)ETHERBOOT_PHYSICAL_ADDRESS,
Tim@13140 403 etherboot, sizeof(etherboot));
kfraser@14959 404 etherboot_sz = sizeof(etherboot);
Tim@13140 405 }
Tim@13140 406
keir@16747 407 if ( must_load_extboot() )
keir@16747 408 {
keir@16747 409 printf("Loading EXTBOOT ...\n");
keir@16747 410 memcpy((void *)EXTBOOT_PHYSICAL_ADDRESS,
keir@16747 411 extboot, sizeof(extboot));
keir@16747 412 extboot_sz = sizeof(extboot);
keir@16747 413 }
keir@16747 414
kfraser@14959 415 if ( get_acpi_enabled() )
kfraser@12548 416 {
kfraser@12554 417 printf("Loading ACPI ...\n");
kaf24@12574 418 acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS);
kfraser@12634 419 ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
kfraser@12548 420 }
kfraser@12548 421
keir@14449 422 cmos_write_memory_size();
keir@14449 423
kfraser@14959 424 printf("BIOS map:\n");
kfraser@14959 425 if ( vgabios_sz )
kfraser@14959 426 printf(" %05x-%05x: VGA BIOS\n",
kfraser@14959 427 VGABIOS_PHYSICAL_ADDRESS,
kfraser@14959 428 VGABIOS_PHYSICAL_ADDRESS + vgabios_sz - 1);
kfraser@14959 429 if ( etherboot_sz )
kfraser@14959 430 printf(" %05x-%05x: Etherboot ROM\n",
kfraser@14959 431 ETHERBOOT_PHYSICAL_ADDRESS,
kfraser@14959 432 ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1);
keir@16747 433 if ( extboot_sz )
keir@16747 434 printf(" %05x-%05x: Extboot ROM\n",
keir@16747 435 EXTBOOT_PHYSICAL_ADDRESS,
keir@16747 436 EXTBOOT_PHYSICAL_ADDRESS + extboot_sz - 1);
keir@16440 437 if ( use_vmxassist() )
kfraser@14959 438 printf(" %05x-%05x: VMXAssist\n",
kfraser@14959 439 VMXASSIST_PHYSICAL_ADDRESS,
kfraser@14959 440 VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1);
kfraser@14959 441 if ( smbios_sz )
kfraser@14959 442 printf(" %05x-%05x: SMBIOS tables\n",
kfraser@14959 443 SMBIOS_PHYSICAL_ADDRESS,
kfraser@14959 444 SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1);
kfraser@14959 445 if ( acpi_sz )
kfraser@14959 446 printf(" %05x-%05x: ACPI tables\n",
kfraser@14959 447 ACPI_PHYSICAL_ADDRESS,
kfraser@14959 448 ACPI_PHYSICAL_ADDRESS + acpi_sz - 1);
kfraser@14959 449 if ( rombios_sz )
kfraser@14959 450 printf(" %05x-%05x: Main BIOS\n",
kfraser@14959 451 ROMBIOS_PHYSICAL_ADDRESS,
kfraser@14959 452 ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
kfraser@14959 453
keir@16440 454 if ( use_vmxassist() )
kfraser@12548 455 {
kfraser@12554 456 printf("Loading VMXAssist ...\n");
kfraser@12548 457 memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
kfraser@12548 458 vmxassist, sizeof(vmxassist));
kfraser@12548 459
kfraser@12554 460 printf("VMX go ...\n");
kfraser@12548 461 __asm__ __volatile__(
kfraser@12548 462 "jmp *%%eax"
kfraser@12548 463 : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
kfraser@12548 464 );
kfraser@12548 465 }
kfraser@12548 466
kfraser@14373 467 printf("Invoking ROMBIOS ...\n");
kfraser@12548 468 return 0;
kfraser@12548 469 }
kfraser@12548 470
kfraser@12548 471 /*
kfraser@12548 472 * Local variables:
kfraser@12548 473 * mode: C
kfraser@12548 474 * c-set-style: "BSD"
kfraser@12548 475 * c-basic-offset: 4
kfraser@12548 476 * tab-width: 4
kfraser@12548 477 * indent-tabs-mode: nil
kfraser@12548 478 * End:
kfraser@12548 479 */