These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / seabios / src / fw / xen.c
1 // Xen HVM support
2 //
3 // Copyright (C) 2011 Citrix Systems.
4 //
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
6
7 #include "config.h" // CONFIG_XEN
8 #include "e820map.h" // e820_add
9 #include "hw/serialio.h" // DebugOutputPort
10 #include "malloc.h" // memalign_high
11 #include "memmap.h" // PAGE_SIZE
12 #include "output.h" // dprintf
13 #include "paravirt.h" // PlatformRunningOn
14 #include "string.h" // memcpy
15 #include "util.h" // copy_acpi_rsdp
16 #include "x86.h" // cpuid
17 #include "xen.h" // xen_extraversion_t
18
19 #define INFO_PHYSICAL_ADDRESS 0x00001000
20
21 u32 xen_cpuid_base = 0;
22 unsigned long xen_hypercall_page = 0;
23
24 struct xen_seabios_info {
25     char signature[14]; /* XenHVMSeaBIOS\0 */
26     u8 length;     /* Length of this struct */
27     u8 checksum;   /* Set such that the sum over bytes 0..length == 0 */
28     /*
29      * Physical address of an array of tables_nr elements.
30      *
31      * Each element is a 32 bit value contianing the physical address
32      * of a BIOS table.
33      */
34     u32 tables;
35     u32 tables_nr;
36     /*
37      * Physical address of the e820 table, contains e820_nr entries.
38      */
39     u32 e820;
40     u32 e820_nr;
41 } PACKED;
42
43 static void validate_info(struct xen_seabios_info *t)
44 {
45     if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) )
46         panic("Bad Xen info signature\n");
47
48     if ( t->length < sizeof(struct xen_seabios_info) )
49         panic("Bad Xen info length\n");
50
51     if (checksum(t, t->length) != 0)
52         panic("Bad Xen info checksum\n");
53 }
54
55 void xen_preinit(void)
56 {
57     u32 base, eax, ebx, ecx, edx;
58     char signature[13];
59
60     if (!CONFIG_XEN)
61         return;
62
63     for (base = 0x40000000; base < 0x40010000; base += 0x100) {
64         cpuid(base, &eax, &ebx, &ecx, &edx);
65         memcpy(signature + 0, &ebx, 4);
66         memcpy(signature + 4, &ecx, 4);
67         memcpy(signature + 8, &edx, 4);
68         signature[12] = 0;
69
70         dprintf(9, "Found hypervisor signature \"%s\" at %x\n",
71                 signature, base);
72         if (strcmp(signature, "XenVMMXenVMM") == 0) {
73             /* Set debug_io_port first, so the following messages work. */
74             DebugOutputPort = 0xe9;
75             debug_banner();
76             dprintf(1, "\nFound Xen hypervisor signature at %x\n", base);
77             if ((eax - base) < 2)
78                 panic("Insufficient Xen cpuid leaves. eax=%x at base %x\n",
79                       eax, base);
80             xen_cpuid_base = base;
81             break;
82         }
83     }
84     if (!xen_cpuid_base) {
85         dprintf(1, "No Xen hypervisor found.\n");
86         return;
87     }
88     PlatformRunningOn = PF_QEMU|PF_XEN;
89 }
90
91 static int hypercall_xen_version( int cmd, void *arg)
92 {
93     return _hypercall2(int, xen_version, cmd, arg);
94 }
95
96 /* Fill in hypercall transfer pages. */
97 void xen_hypercall_setup(void)
98 {
99     u32 eax, ebx, ecx, edx;
100     xen_extraversion_t extraversion;
101     unsigned long i;
102
103     if (!runningOnXen())
104         return;
105
106     cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx);
107
108     xen_hypercall_page = (unsigned long)memalign_high(PAGE_SIZE, eax*PAGE_SIZE);
109     if (!xen_hypercall_page)
110         panic("unable to allocate Xen hypercall page\n");
111
112     dprintf(1, "Allocated Xen hypercall page at %lx\n", xen_hypercall_page);
113     for ( i = 0; i < eax; i++ )
114         wrmsr(ebx, xen_hypercall_page + (i << 12) + i);
115
116     /* Print version information. */
117     cpuid(xen_cpuid_base + 1, &eax, &ebx, &ecx, &edx);
118     hypercall_xen_version(XENVER_extraversion, extraversion);
119     dprintf(1, "Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);
120 }
121
122 void xen_biostable_setup(void)
123 {
124     struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS;
125     void **tables = (void*)info->tables;
126     int i;
127
128     dprintf(1, "xen: copy BIOS tables...\n");
129     for (i=0; i<info->tables_nr; i++)
130         copy_table(tables[i]);
131
132     find_acpi_features();
133 }
134
135 void xen_ramsize_preinit(void)
136 {
137     int i;
138     struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS;
139     struct e820entry *e820 = (struct e820entry *)info->e820;
140     validate_info(info);
141
142     dprintf(1, "xen: copy e820...\n");
143
144     for (i = 0; i < info->e820_nr; i++) {
145         struct e820entry *e = &e820[i];
146         e820_add(e->start, e->size, e->type);
147     }
148 }