ia64/xen-unstable

annotate tools/firmware/hvmloader/hvmloader.c @ 10893:2e3b121662dc

[HVM][SVM] Change the calling convention for SVM VMMCALLs so
that they don't conflict with the hypercall calling convention.
Signed-off-by: Steven Smith <ssmith@xensource.com>
author kfraser@localhost.localdomain
date Tue Aug 01 17:28:19 2006 +0100 (2006-08-01)
parents ae245d35457b
children 49dcd838b7df
rev   line source
kaf24@8708 1 /*
kaf24@8708 2 * hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader.
kaf24@8708 3 *
kaf24@8708 4 * A quicky so that we can boot rom images as if they were a Linux kernel.
kaf24@8708 5 * This code will copy the rom images (ROMBIOS/VGABIOS/VM86) into their
kaf24@8708 6 * respective spaces and transfer control to VM86 to execute the BIOSes.
kaf24@8708 7 *
kaf24@8708 8 * Leendert van Doorn, leendert@watson.ibm.com
kaf24@8708 9 * Copyright (c) 2005, International Business Machines Corporation.
kaf24@8708 10 *
kaf24@8708 11 * This program is free software; you can redistribute it and/or modify it
kaf24@8708 12 * under the terms and conditions of the GNU General Public License,
kaf24@8708 13 * version 2, as published by the Free Software Foundation.
kaf24@8708 14 *
kaf24@8708 15 * This program is distributed in the hope it will be useful, but WITHOUT
kaf24@8708 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kaf24@8708 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kaf24@8708 18 * more details.
kaf24@8708 19 *
kaf24@8708 20 * You should have received a copy of the GNU General Public License along with
kaf24@8708 21 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
kaf24@8708 22 * Place - Suite 330, Boston, MA 02111-1307 USA.
kaf24@8708 23 */
kaf24@8708 24 #include "roms.h"
kaf24@8708 25 #include "../acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */
kaf24@10575 26 #include <xen/hvm/hvm_info_table.h>
kaf24@8708 27
kaf24@8708 28 /* memory map */
kaf24@8708 29 #define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
kaf24@8708 30 #define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000
kaf24@8708 31 #define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000
kaf24@8708 32
kaf24@8708 33 /* invoke SVM's paged realmode support */
kfraser@10893 34 #define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
kaf24@8708 35
kaf24@8708 36 /*
kaf24@8708 37 * C runtime start off
kaf24@8708 38 */
kaf24@8708 39 asm(
kaf24@8708 40 " .text \n"
kaf24@8708 41 " .globl _start \n"
kaf24@8708 42 "_start: \n"
kaf24@8708 43 " cld \n"
kaf24@8708 44 " cli \n"
kaf24@8708 45 " lgdt gdt_desr \n"
kaf24@8708 46 " movl $stack_top, %esp \n"
kaf24@8708 47 " movl %esp, %ebp \n"
kaf24@8708 48 " call main \n"
kaf24@8708 49 " jmp halt \n"
kaf24@8708 50 " \n"
kaf24@8708 51 "gdt_desr: \n"
kaf24@8708 52 " .word gdt_end - gdt - 1 \n"
kaf24@8708 53 " .long gdt \n"
kaf24@8708 54 " \n"
kaf24@8708 55 " .align 8 \n"
kaf24@8708 56 "gdt: \n"
kaf24@8708 57 " .quad 0x0000000000000000 \n"
kaf24@8708 58 " .quad 0x00CF92000000FFFF \n"
kaf24@8708 59 " .quad 0x00CF9A000000FFFF \n"
kaf24@8708 60 "gdt_end: \n"
kaf24@8708 61 " \n"
kaf24@8708 62 "halt: \n"
kaf24@8708 63 " sti \n"
kaf24@8708 64 " jmp . \n"
kaf24@8708 65 " \n"
kaf24@8708 66 " .bss \n"
kaf24@8708 67 " .align 8 \n"
kaf24@8708 68 "stack: \n"
kaf24@8708 69 " .skip 0x4000 \n"
kaf24@8708 70 "stack_top: \n"
kaf24@8708 71 );
kaf24@8708 72
kaf24@8708 73 extern int get_acpi_enabled(void);
kaf24@8708 74 extern int acpi_madt_update(unsigned char* acpi_start);
kaf24@10575 75 extern void create_mp_tables(void);
kaf24@10575 76 struct hvm_info_table *get_hvm_info_table(void);
kaf24@8708 77
kaf24@8708 78 static inline void
kaf24@8708 79 outw(unsigned short addr, unsigned short val)
kaf24@8708 80 {
kaf24@8708 81 __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
kaf24@8708 82 }
kaf24@8708 83
kaf24@8708 84 static inline void
kaf24@8708 85 outb(unsigned short addr, unsigned char val)
kaf24@8708 86 {
kaf24@8708 87 __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
kaf24@8708 88 }
kaf24@8708 89
kaf24@8708 90 static inline unsigned char
kaf24@8708 91 inb(unsigned short addr)
kaf24@8708 92 {
kaf24@8708 93 unsigned char val;
kaf24@8708 94
kaf24@8708 95 __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
kaf24@8708 96 return val;
kaf24@8708 97 }
kaf24@8708 98
kaf24@8708 99 void *
kaf24@8708 100 memcpy(void *dest, const void *src, unsigned n)
kaf24@8708 101 {
kaf24@8708 102 int t0, t1, t2;
kaf24@8708 103
kaf24@8708 104 __asm__ __volatile__(
kaf24@8708 105 "cld\n"
kaf24@8708 106 "rep; movsl\n"
kaf24@8708 107 "testb $2,%b4\n"
kaf24@8708 108 "je 1f\n"
kaf24@8708 109 "movsw\n"
kaf24@8708 110 "1: testb $1,%b4\n"
kaf24@8708 111 "je 2f\n"
kaf24@8708 112 "movsb\n"
kaf24@8708 113 "2:"
kaf24@8708 114 : "=&c" (t0), "=&D" (t1), "=&S" (t2)
kaf24@8708 115 : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
kaf24@8708 116 : "memory"
kaf24@8708 117 );
kaf24@8708 118 return dest;
kaf24@8708 119 }
kaf24@8708 120
kaf24@8708 121 int
kaf24@8708 122 puts(const char *s)
kaf24@8708 123 {
kaf24@8708 124 while (*s)
kaf24@8708 125 outb(0xE9, *s++);
kaf24@8708 126 return 0;
kaf24@8708 127 }
kaf24@8708 128
kaf24@8708 129 int
kaf24@8708 130 cirrus_check(void)
kaf24@8708 131 {
kaf24@8708 132 outw(0x3C4, 0x9206);
kaf24@8708 133 return inb(0x3C5) == 0x12;
kaf24@8708 134 }
kaf24@8708 135
kfraser@10893 136 int
kfraser@10893 137 vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
kaf24@8708 138 {
kaf24@8708 139 int eax;
kaf24@8708 140
kaf24@8708 141 __asm__ __volatile__(
kaf24@8708 142 ".byte 0x0F,0x01,0xD9"
kaf24@8708 143 : "=a" (eax)
kfraser@10893 144 : "a"(function),
kaf24@8708 145 "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi)
kaf24@8708 146 );
kaf24@8708 147 return eax;
kaf24@8708 148 }
kaf24@8708 149
kaf24@8708 150 int
kaf24@8708 151 check_amd(void)
kaf24@8708 152 {
kaf24@8708 153 char id[12];
kaf24@8708 154
kaf24@8708 155 __asm__ __volatile__(
kaf24@8708 156 "cpuid"
kaf24@8708 157 : "=b" (*(int *)(&id[0])),
kaf24@8708 158 "=c" (*(int *)(&id[8])),
kaf24@8708 159 "=d" (*(int *)(&id[4]))
kaf24@8708 160 : "a" (0)
kaf24@8708 161 );
kaf24@8708 162 return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
kaf24@8708 163 }
kaf24@8708 164
kaf24@8708 165 int
kaf24@8708 166 main(void)
kaf24@8708 167 {
kaf24@10575 168 struct hvm_info_table *t = get_hvm_info_table();
kaf24@10575 169
kaf24@8708 170 puts("HVM Loader\n");
kaf24@8708 171
kaf24@8708 172 puts("Loading ROMBIOS ...\n");
kaf24@8708 173 memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
kaf24@10575 174 if (t->apic_enabled)
kaf24@10575 175 create_mp_tables();
kaf24@10575 176
kaf24@8708 177 if (cirrus_check()) {
kaf24@8708 178 puts("Loading Cirrus VGABIOS ...\n");
kaf24@8708 179 memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
kaf24@8708 180 vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
kaf24@8708 181 } else {
kaf24@8708 182 puts("Loading Standard VGABIOS ...\n");
kaf24@8708 183 memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
kaf24@8708 184 vgabios_stdvga, sizeof(vgabios_stdvga));
kaf24@8708 185 }
kaf24@8708 186
kaf24@8708 187 if (get_acpi_enabled() != 0) {
kaf24@8708 188 puts("Loading ACPI ...\n");
kaf24@8708 189 acpi_madt_update((unsigned char *) acpi);
kaf24@8708 190 if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
kaf24@8708 191 /*
kaf24@8708 192 * Make sure acpi table does not overlap rombios
kaf24@8708 193 * currently acpi less than 8K will be OK.
kaf24@8708 194 */
kaf24@8708 195 memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi,
kaf24@8708 196 sizeof(acpi));
kaf24@8708 197 }
kaf24@8708 198 }
kaf24@8708 199
kaf24@8708 200 if (check_amd()) {
kaf24@8708 201 /* AMD implies this is SVM */
kaf24@8708 202 puts("SVM go ...\n");
kfraser@10893 203 vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
kaf24@8708 204 } else {
kaf24@8708 205 puts("Loading VMXAssist ...\n");
kaf24@8708 206 memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
kaf24@8708 207 vmxassist, sizeof(vmxassist));
kaf24@8708 208
kaf24@8708 209 puts("VMX go ...\n");
kaf24@8708 210 __asm__ __volatile__(
kaf24@8708 211 "jmp *%%eax"
kaf24@8708 212 : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
kaf24@8708 213 );
kaf24@8708 214 }
kaf24@8708 215
kaf24@8708 216 puts("Failed to invoke ROMBIOS\n");
kaf24@8708 217 return 0;
kaf24@8708 218 }
kaf24@8708 219