1 /*
2  * hvmloader.c: HVM bootloader.
3  *
4  * Leendert van Doorn, leendert@watson.ibm.com
5  * Copyright (c) 2005, International Business Machines Corporation.
6  *
7  * Copyright (c) 2006, Keir Fraser, XenSource Inc.
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms and conditions of the GNU General Public License,
11  * version 2, as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along with
19  * this program; If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "util.h"
23 #include "hypercall.h"
24 #include "config.h"
25 #include "pci_regs.h"
26 #include "apic_regs.h"
27 #include "vnuma.h"
28 #include <acpi2_0.h>
29 #include <xen/version.h>
30 #include <xen/hvm/params.h>
31 #include <xen/arch-x86/hvm/start_info.h>
32 
33 const struct hvm_start_info *hvm_start_info;
34 
35 asm (
36     "    .text                       \n"
37     "    .globl _start               \n"
38     "_start:                         \n"
39     /* C runtime kickoff. */
40     "    cld                         \n"
41     "    cli                         \n"
42     "    lgdt gdt_desr               \n"
43     "    mov  $"STR(SEL_DATA32)",%ax \n"
44     "    mov  %ax,%ds                \n"
45     "    mov  %ax,%es                \n"
46     "    mov  %ax,%fs                \n"
47     "    mov  %ax,%gs                \n"
48     "    mov  %ax,%ss                \n"
49     "    ljmp $"STR(SEL_CODE32)",$1f \n"
50     "1:  movl $stack_top,%esp        \n"
51     "    movl %esp,%ebp              \n"
52     /* store HVM start info ptr */
53     "    mov  %ebx, hvm_start_info   \n"
54     "    call main                   \n"
55     /* Relocate real-mode trampoline to 0x0. */
56     "    mov  $trampoline_start,%esi \n"
57     "    xor  %edi,%edi              \n"
58     "    mov  $trampoline_end,%ecx   \n"
59     "    sub  %esi,%ecx              \n"
60     "    rep  movsb                  \n"
61     /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */
62     "    mov  $"STR(SEL_DATA16)",%ax \n"
63     "    mov  %ax,%ds                \n"
64     "    mov  %ax,%es                \n"
65     "    mov  %ax,%fs                \n"
66     "    mov  %ax,%gs                \n"
67     "    mov  %ax,%ss                \n"
68     /* Initialise all 32-bit GPRs to zero. */
69     "    xor  %eax,%eax              \n"
70     "    xor  %ebx,%ebx              \n"
71     "    xor  %ecx,%ecx              \n"
72     "    xor  %edx,%edx              \n"
73     "    xor  %esp,%esp              \n"
74     "    xor  %ebp,%ebp              \n"
75     "    xor  %esi,%esi              \n"
76     "    xor  %edi,%edi              \n"
77     /* Enter real mode, reload all segment registers and IDT. */
78     "    ljmp $"STR(SEL_CODE16)",$0x0\n"
79     "trampoline_start: .code16       \n"
80     "    mov  %eax,%cr0              \n"
81     "    ljmp $0,$1f-trampoline_start\n"
82     "1:  mov  %ax,%ds                \n"
83     "    mov  %ax,%es                \n"
84     "    mov  %ax,%fs                \n"
85     "    mov  %ax,%gs                \n"
86     "    mov  %ax,%ss                \n"
87     "    lidt 1f-trampoline_start    \n"
88     "    ljmp $0xf000,$0xfff0        \n"
89     "1:  .word 0x3ff,0,0             \n"
90     "trampoline_end:   .code32       \n"
91     "                                \n"
92     "gdt_desr:                       \n"
93     "    .word gdt_end - gdt - 1     \n"
94     "    .long gdt                   \n"
95     "                                \n"
96     "    .align 8                    \n"
97     "gdt:                            \n"
98     "    .quad 0x0000000000000000    \n"
99     "    .quad 0x008f9a000000ffff    \n" /* Ring 0 16b code, base 0 limit 4G */
100     "    .quad 0x008f92000000ffff    \n" /* Ring 0 16b data, base 0 limit 4G */
101     "    .quad 0x00cf9a000000ffff    \n" /* Ring 0 32b code, base 0 limit 4G */
102     "    .quad 0x00cf92000000ffff    \n" /* Ring 0 32b data, base 0 limit 4G */
103     "    .quad 0x00af9a000000ffff    \n" /* Ring 0 64b code */
104     "gdt_end:                        \n"
105     "                                \n"
106     "    .bss                        \n"
107     "    .align    8                 \n"
108     "stack:                          \n"
109     "    .skip    0x4000             \n"
110     "stack_top:                      \n"
111     "    .text                       \n"
112     );
113 
114 unsigned long scratch_start = SCRATCH_PHYSICAL_ADDRESS;
115 
116 uint32_t ioapic_base_address = 0xfec00000;
117 uint8_t ioapic_version;
118 
119 bool acpi_enabled;
120 
init_hypercalls(void)121 static void init_hypercalls(void)
122 {
123     uint32_t eax, ebx, ecx, edx;
124     unsigned long i;
125     char signature[13];
126     xen_extraversion_t extraversion;
127     uint32_t base;
128 
129     for ( base = 0x40000000; base < 0x40010000; base += 0x100 )
130     {
131         cpuid(base, &eax, &ebx, &ecx, &edx);
132 
133         *(uint32_t *)(signature + 0) = ebx;
134         *(uint32_t *)(signature + 4) = ecx;
135         *(uint32_t *)(signature + 8) = edx;
136         signature[12] = '\0';
137 
138         if ( !strcmp("XenVMMXenVMM", signature) )
139             break;
140     }
141 
142     BUG_ON(strcmp("XenVMMXenVMM", signature) || ((eax - base) < 2));
143 
144     /* Fill in hypercall transfer pages. */
145     cpuid(base + 2, &eax, &ebx, &ecx, &edx);
146     for ( i = 0; i < eax; i++ )
147         wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
148 
149     /* Print version information. */
150     cpuid(base + 1, &eax, &ebx, &ecx, &edx);
151     hypercall_xen_version(XENVER_extraversion, extraversion);
152     printf("Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);
153 }
154 
155 /* Replace possibly erroneous memory-size CMOS fields with correct values. */
cmos_write_memory_size(void)156 static void cmos_write_memory_size(void)
157 {
158     uint32_t base_mem = 640, ext_mem, alt_mem;
159 
160     alt_mem = ext_mem = hvm_info->low_mem_pgend << PAGE_SHIFT;
161     ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
162     if ( ext_mem > 0xffff )
163         ext_mem = 0xffff;
164     alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
165 
166     /* All BIOSes: conventional memory (CMOS *always* reports 640kB). */
167     cmos_outb(0x15, (uint8_t)(base_mem >> 0));
168     cmos_outb(0x16, (uint8_t)(base_mem >> 8));
169 
170     /* All BIOSes: extended memory (1kB chunks above 1MB). */
171     cmos_outb(0x17, (uint8_t)( ext_mem >> 0));
172     cmos_outb(0x18, (uint8_t)( ext_mem >> 8));
173     cmos_outb(0x30, (uint8_t)( ext_mem >> 0));
174     cmos_outb(0x31, (uint8_t)( ext_mem >> 8));
175 
176     /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */
177     cmos_outb(0x34, (uint8_t)( alt_mem >> 0));
178     cmos_outb(0x35, (uint8_t)( alt_mem >> 8));
179 }
180 
181 /*
182  * Set up an empty TSS area for virtual 8086 mode to use. Its content is
183  * going to be managed by Xen, but zero fill it just in case.
184  */
init_vm86_tss(void)185 static void init_vm86_tss(void)
186 {
187 /*
188  * Have the TSS cover the ISA port range, which makes it
189  * - 104 bytes base structure
190  * - 32 bytes interrupt redirection bitmap
191  * - 128 bytes I/O bitmap
192  * - one trailing byte
193  * or a total of to 265 bytes. As it needs to be a multiple of the requested
194  * alignment, this ends up requiring 384 bytes.
195  */
196 #define TSS_SIZE (3 * 128)
197     void *tss;
198 
199     tss = mem_alloc(TSS_SIZE, 128);
200     memset(tss, 0, TSS_SIZE);
201     hvm_param_set(HVM_PARAM_VM86_TSS_SIZED,
202                   ((uint64_t)TSS_SIZE << 32) | virt_to_phys(tss));
203     printf("vm86 TSS at %08lx\n", virt_to_phys(tss));
204 #undef TSS_SIZE
205 }
206 
apic_setup(void)207 static void apic_setup(void)
208 {
209     /*
210      * This would the The Right Thing To Do (tm), if only qemu negotiated
211      * with Xen where the IO-APIC actually sits (which is currently hard
212      * coded in Xen and can't be controlled externally). Uncomment this code
213      * once that changed.
214     ioapic_base_address |= (pci_readb(PCI_ISA_DEVFN, 0x80) & 0x3f) << 10;
215      */
216     ioapic_version = ioapic_read(0x01) & 0xff;
217 
218     /* Set the IOAPIC ID to the static value used in the MP/ACPI tables. */
219     ioapic_write(0x00, IOAPIC_ID);
220 
221     /* NMIs are delivered direct to the BSP. */
222     lapic_write(APIC_SPIV, APIC_SPIV_APIC_ENABLED | 0xFF);
223     lapic_write(APIC_LVT0, (APIC_MODE_EXTINT << 8) | APIC_LVT_MASKED);
224     lapic_write(APIC_LVT1, APIC_MODE_NMI << 8);
225 
226     /* 8259A ExtInts are delivered through IOAPIC pin 0 (Virtual Wire Mode). */
227     ioapic_write(0x10, APIC_DM_EXTINT);
228     ioapic_write(0x11, SET_APIC_ID(LAPIC_ID(0)));
229 }
230 
231 struct bios_info {
232     const char *key;
233     const struct bios_config *bios;
234 } bios_configs[] = {
235 #ifdef ENABLE_ROMBIOS
236     { "rombios", &rombios_config, },
237 #endif
238     { "seabios", &seabios_config, },
239     { "ovmf", &ovmf_config, },
240     { NULL, NULL }
241 };
242 
detect_bios(void)243 static const struct bios_config *detect_bios(void)
244 {
245     const struct bios_info *b;
246     const char *bios;
247 
248     bios = xenstore_read("hvmloader/bios", "rombios");
249 
250     for ( b = &bios_configs[0]; b->key != NULL; b++ )
251         if ( !strcmp(bios, b->key) )
252             return b->bios;
253 
254     printf("Unknown BIOS %s, no ROM image found\n", bios);
255     BUG();
256     return NULL;
257 }
258 
acpi_enable_sci(void)259 static void acpi_enable_sci(void)
260 {
261     uint8_t pm1a_cnt_val;
262 
263 #define PIIX4_SMI_CMD_IOPORT 0xb2
264 #define PIIX4_ACPI_ENABLE    0xf1
265 
266     /*
267      * PIIX4 emulation in QEMU has SCI_EN=0 by default. We have no legacy
268      * SMM implementation, so give ACPI control to the OSPM immediately.
269      */
270     pm1a_cnt_val = inb(ACPI_PM1A_CNT_BLK_ADDRESS_V1);
271     if ( !(pm1a_cnt_val & ACPI_PM1C_SCI_EN) )
272         outb(PIIX4_SMI_CMD_IOPORT, PIIX4_ACPI_ENABLE);
273 
274     pm1a_cnt_val = inb(ACPI_PM1A_CNT_BLK_ADDRESS_V1);
275     BUG_ON(!(pm1a_cnt_val & ACPI_PM1C_SCI_EN));
276 }
277 
get_module_entry(const struct hvm_start_info * info,const char * name)278 const struct hvm_modlist_entry *get_module_entry(
279     const struct hvm_start_info *info,
280     const char *name)
281 {
282     const struct hvm_modlist_entry *modlist =
283         (struct hvm_modlist_entry *)(uintptr_t)info->modlist_paddr;
284     unsigned int i;
285 
286     if ( !modlist ||
287          info->modlist_paddr > UINTPTR_MAX ||
288          (UINTPTR_MAX - (uintptr_t)info->modlist_paddr) / sizeof(*modlist)
289          < info->nr_modules )
290         return NULL;
291 
292     for ( i = 0; i < info->nr_modules; i++ )
293     {
294         char *module_name = (char*)(uintptr_t)modlist[i].cmdline_paddr;
295 
296         /* Skip if the module or its cmdline is missing. */
297         if ( !module_name || !modlist[i].paddr )
298             continue;
299 
300         /* Skip if the cmdline cannot be read. */
301         if ( modlist[i].cmdline_paddr > UINTPTR_MAX ||
302              (modlist[i].cmdline_paddr + strlen(name)) > UINTPTR_MAX )
303             continue;
304 
305         if ( !strcmp(name, module_name) )
306         {
307             if ( modlist[i].paddr > UINTPTR_MAX ||
308                  modlist[i].size > UINTPTR_MAX ||
309                  (modlist[i].paddr + modlist[i].size - 1) > UINTPTR_MAX )
310             {
311                 printf("Cannot load \"%s\" from 0x"PRIllx" (0x"PRIllx")\n",
312                        name, PRIllx_arg(modlist[i].paddr),
313                        PRIllx_arg(modlist[i].size));
314                 BUG();
315             }
316             return &modlist[i];
317         }
318     }
319 
320     return NULL;
321 }
322 
main(void)323 int main(void)
324 {
325     const struct bios_config *bios;
326     const struct hvm_modlist_entry *bios_module;
327 
328     /* Initialise hypercall stubs with RET, rendering them no-ops. */
329     memset((void *)HYPERCALL_PHYSICAL_ADDRESS, 0xc3 /* RET */, PAGE_SIZE);
330 
331     printf("HVM Loader\n");
332     BUG_ON(hvm_start_info->magic != XEN_HVM_START_MAGIC_VALUE);
333 
334     init_hypercalls();
335 
336     memory_map_setup();
337 
338     xenbus_setup();
339 
340     bios = detect_bios();
341     printf("System requested %s\n", bios->name);
342 
343     printf("CPU speed is %u MHz\n", get_cpu_mhz());
344 
345     apic_setup();
346     pci_setup();
347 
348     smp_initialise();
349 
350     perform_tests();
351 
352     if ( bios->bios_info_setup )
353         bios->bios_info_setup();
354 
355     if ( bios->create_smbios_tables )
356     {
357         printf("Writing SMBIOS tables ...\n");
358         bios->create_smbios_tables();
359     }
360 
361     printf("Loading %s ...\n", bios->name);
362     bios_module = get_module_entry(hvm_start_info, "firmware");
363     if ( bios_module )
364     {
365         uint32_t paddr = bios_module->paddr;
366 
367         bios->bios_load(bios, (void *)paddr, bios_module->size, NULL);
368     }
369 #ifdef ENABLE_ROMBIOS
370     else if ( bios == &rombios_config )
371     {
372         const struct hvm_modlist_entry *ipxe;
373         uint32_t paddr = 0;
374 
375         ipxe = get_module_entry(hvm_start_info, "ipxe");
376         if ( ipxe )
377             paddr = ipxe->paddr;
378         bios->bios_load(bios, NULL, 0, (void *)paddr);
379     }
380 #endif
381     else
382     {
383         /*
384          * If there is no BIOS module supplied and if there is no embeded BIOS
385          * image, then we failed. Only rombios might have an embedded bios blob.
386          */
387         printf("no BIOS ROM image found\n");
388         BUG();
389     }
390 
391     if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
392     {
393         if ( bios->create_mp_tables )
394             bios->create_mp_tables();
395         if ( bios->create_pir_tables )
396             bios->create_pir_tables();
397     }
398 
399     if ( bios->load_roms )
400         bios->load_roms();
401 
402     acpi_enabled = !strncmp(xenstore_read("platform/acpi", "1"), "1", 1);
403 
404     if ( acpi_enabled )
405     {
406         init_vnuma_info();
407 
408         if ( bios->acpi_build_tables )
409         {
410             printf("Loading ACPI ...\n");
411             bios->acpi_build_tables();
412         }
413 
414         acpi_enable_sci();
415 
416         hvm_param_set(HVM_PARAM_ACPI_IOPORTS_LOCATION, 1);
417     }
418 
419     init_vm86_tss();
420 
421     cmos_write_memory_size();
422 
423     printf("BIOS map:\n");
424     if ( SCRATCH_PHYSICAL_ADDRESS != scratch_start )
425         printf(" %05x-%05lx: Scratch space\n",
426                SCRATCH_PHYSICAL_ADDRESS, scratch_start);
427     printf(" %05x-%05x: Main BIOS\n",
428            bios->bios_address,
429            bios->bios_address + bios->image_size - 1);
430 
431     if ( bios->e820_setup )
432         bios->e820_setup();
433 
434     if ( bios->bios_info_finish )
435         bios->bios_info_finish();
436 
437     xenbus_shutdown();
438 
439     printf("Invoking %s ...\n", bios->name);
440     return 0;
441 }
442 
443 /*
444  * Local variables:
445  * mode: C
446  * c-file-style: "BSD"
447  * c-basic-offset: 4
448  * tab-width: 4
449  * indent-tabs-mode: nil
450  * End:
451  */
452