ia64/xen-unstable

annotate tools/firmware/hvmloader/hvmloader.c @ 14959:5754173c3d81

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