Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


f4aaac130728b6406bfad32802ca5c2b76de4151
[palacios.git] / palacios / include / palacios / vmm_multiboot.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2015, The V3VEE Project <http://www.v3vee.org> 
11  * All rights reserved.
12  *
13  * Author: Peter Dinda <pdinda@northwestern.edu>
14  *
15  * This is free software.  You are permitted to use,
16  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
17  */
18
19
20 #ifndef __VMM_MULTIBOOT_H
21 #define __VMM_MULTIBOOT_H
22
23
24 #ifdef __V3VEE__ 
25
26 #include <palacios/vmm_types.h>
27
28
29 /******************************************************************
30      Data contained in the ELF file we will attempt to boot  
31 ******************************************************************/
32
33 #define ELF_MAGIC    0x464c457f
34 #define MB2_MAGIC    0xe85250d6
35
36 typedef struct mb_header {
37     uint32_t magic;
38     uint32_t arch; 
39 #define ARCH_X86 0
40     uint32_t headerlen;
41     uint32_t checksum;
42 } __attribute__((packed)) mb_header_t;
43
44 typedef struct mb_tag {
45     uint16_t type;
46     uint16_t flags;
47     uint32_t size;
48 } __attribute__((packed)) mb_tag_t;
49
50 #define MB_TAG_INFO    1
51 typedef struct mb_info_req {
52     mb_tag_t tag;
53     uint32_t types[0];
54 } __attribute__((packed)) mb_info_t;
55
56
57 typedef uint32_t u_virt, u_phys;
58
59 #define MB_TAG_ADDRESS 2
60 typedef struct mb_addr {
61     mb_tag_t tag;
62     u_virt   header_addr;
63     u_virt   load_addr;
64     u_virt   load_end_addr;
65     u_virt   bss_end_addr;
66 } __attribute__((packed)) mb_addr_t;
67
68 #define MB_TAG_ENTRY 3
69 typedef struct mb_entry {
70     mb_tag_t tag;
71     u_virt   entry_addr;
72 } __attribute__((packed)) mb_entry_t;
73
74 #define MB_TAG_FLAGS 4
75 typedef struct mb_flags {
76     mb_tag_t tag;
77     uint32_t console_flags;
78 } __attribute__((packed)) mb_flags_t;
79
80 #define MB_TAG_FRAMEBUF 5
81 typedef struct mb_framebuf {
82     mb_tag_t tag;
83     uint32_t width;
84     uint32_t height;
85     uint32_t depth;
86 } __attribute__((packed)) mb_framebuf_t;
87
88 #define MB_TAG_MODALIGN 6
89 typedef struct mb_modalign {
90     mb_tag_t tag;
91     uint32_t size;
92 } __attribute__((packed)) mb_modalign_t;
93
94
95 // For HVM, which can use a pure 64 bit variant
96 // version of multiboot.  The existence of
97 // this tag indicates that this special mode is
98 // requested
99 #define MB_TAG_MB64_HRT           0xf00d
100 typedef struct mb_mb64_hrt {
101     mb_tag_t       tag;
102     uint64_t       hrt_flags;
103     // whether this kernel is relocable
104 #define MB_TAG_MB64_HRT_FLAG_RELOC      0x1
105     // How to map the memory in the initial PTs
106     // highest set bit wins
107 #define MB_TAG_MB64_HRT_FLAG_MAP_4KB    0x100
108 #define MB_TAG_MB64_HRT_FLAG_MAP_2MB    0x200
109 #define MB_TAG_MB64_HRT_FLAG_MAP_1GB    0x400
110 #define MB_TAG_MB64_HRT_FLAG_MAP_512GB  0x800
111
112     // How much physical address space to map in the
113     // initial page tables (bytes)
114     // 
115     uint64_t       max_mem_to_map;
116     // offset of the GVA->GPA mappings (GVA of GPA 0)
117     uint64_t       gva_offset;
118     // 64 bit entry address (=0 to use entry tag (which will be offset by gva_offset))
119     uint64_t       gva_entry;
120     // desired address of the page the VMM, HRT, and ROS share
121     // for communication.  "page" here a 4 KB quantity
122     uint64_t       comm_page_gpa;
123     // desired interrupt vector that should be used for upcalls
124     // the default for this is 255
125     uint8_t        hrt_int_vector;
126     uint8_t        reserved[7];
127     
128 } __attribute__((packed)) mb_mb64_hrt_t;
129
130 typedef struct mb_data {
131     mb_header_t   *header;
132     mb_info_t     *info;
133     mb_addr_t     *addr;
134     mb_entry_t    *entry;
135     mb_flags_t    *flags;
136     mb_framebuf_t *framebuf;
137     mb_modalign_t *modalign;
138     mb_mb64_hrt_t *mb64_hrt;
139 } mb_data_t;
140
141
142
143 // We are not doing:
144 //
145 // - BIOS Boot Device
146 // - Modules
147 // - ELF symbols
148 // - Boot Loader name
149 // - APM table
150 // - VBE info
151 // - Framebuffer info
152 //
153
154
155
156 /******************************************************************
157      Data we will pass to the kernel via rbx
158 ******************************************************************/
159
160 #define MB2_INFO_MAGIC    0x36d76289
161
162
163 typedef struct mb_info_header {
164     uint32_t  totalsize;
165     uint32_t  reserved;
166 } __attribute__((packed)) mb_info_header_t;
167
168 // A tag of type 0, size 8 indicates last value
169 //
170 typedef struct mb_info_tag {
171     uint32_t  type;
172     uint32_t  size;
173 } __attribute__((packed)) mb_info_tag_t;
174
175
176 #define MB_INFO_MEM_TAG  4
177 typedef struct mb_info_mem {
178     mb_info_tag_t tag;
179     uint32_t  mem_lower; // 0..640K in KB 
180     uint32_t  mem_upper; // in KB to first hole - 1 MB
181 } __attribute__((packed)) mb_info_mem_t;
182
183 #define MB_INFO_CMDLINE_TAG  1
184 // note alignment of 8 bytes required for each... 
185 typedef struct mb_info_cmdline {
186     mb_info_tag_t tag;
187     uint32_t  size;      // includes zero termination
188     uint8_t   string[];  // zero terminated
189 } __attribute__((packed)) mb_info_cmdline_t;
190
191
192 #define MEM_RAM   1
193 #define MEM_ACPI  3
194 #define MEM_RESV  4
195
196 typedef struct mb_info_memmap_entry {
197     uint64_t  base_addr;
198     uint64_t  length;
199     uint32_t  type;
200     uint32_t  reserved;
201 } __attribute__((packed)) mb_info_memmap_entry_t;
202
203 #define MB_INFO_MEMMAP_TAG  6
204 // note alignment of 8 bytes required for each... 
205 typedef struct mb_info_memmap {
206     mb_info_tag_t tag;
207     uint32_t  entry_size;     // multiple of 8
208     uint32_t  entry_version;  // 0
209     mb_info_memmap_entry_t  entries[];
210 } __attribute__((packed)) mb_info_memmap_t;
211
212 #define MB_INFO_HRT_TAG 0xf00df00d
213 typedef struct mb_info_hrt {
214     mb_info_tag_t  tag;
215     // apic ids are 0..num_apics-1
216     // ioapics follow
217     // apic and ioapic addresses are the well known places
218     uint32_t       total_num_apics;
219     // first apic the HRT owns (HRT core 0)
220     uint32_t       first_hrt_apic_id;
221     // can the HRT use an ioapic?
222     uint32_t       have_hrt_ioapic;
223     // if so, this is the first entry on the
224     // ioapic that can be used by the HRT
225     uint32_t       first_hrt_ioapic_entry;
226     // CPU speed
227     uint64_t       cpu_freq_khz;
228     // copy of the HRT flags from the kernel (indicating 
229     // page table mapping type, position independence, etc.
230     // these reflect how it has actually been mapped
231     uint64_t       hrt_flags;
232     // the amount of physical address space that has been mapped
233     // initially. 
234     uint64_t       max_mem_mapped; 
235     // The first physical address the HRT should
236     // (nominally) use.   Physical addresses below this are
237     // visible to the ROS
238     uint64_t       first_hrt_gpa;
239     // Where the intial boot state starts in the physical address
240     // space.   This includes INT HANDLER,IDT,GDT,TSS, PAGETABLES,
241     // and MBINFO, but not the scratch stacks
242     // This is essentially the content of CR3 - 1 page on boot
243     uint64_t       boot_state_gpa;
244     // Where GPA 0 is mapped in the virtual address space
245     uint64_t       gva_offset;   
246
247     // Typically:
248     //     first_hrt_vaddr==first_hrt_paddr => no address space coalescing
249     //     first_hrt_vaddr>first_hrt_paddr => address space coalescing
250     // For example, first_hrt_vaddr might be set to the start of linux kernel
251     // This then allows us to coalesce user portion of the address space of 
252     // a linux process and the HRT
253     // for communication.  "page" here a 4 KB quantity
254
255     // address of the page the VMM, HRT, and ROS share
256     uint64_t       comm_page_gpa;
257     // interrupt vector used to upcall to HRT (==0 if none)
258     // downcalls are done with HVM hypercall 0xf00df00d
259     uint8_t        hrt_int_vector;
260     uint8_t        reserved[7];
261 } __attribute__((packed)) mb_info_hrt_t;
262
263
264
265
266 struct v3_vm_multiboot {
267     uint8_t   is_multiboot;
268     struct v3_cfg_file *mb_file;
269     mb_data_t mb_data;
270     // GPA where we put the MB record, GDT, TSS, etc
271     // The kernel load address and size are as in mb_data
272     void     *mb_data_gpa; 
273 };
274
275 // There is no core structure for
276 // multiboot capability
277
278
279 struct v3_xml;
280
281 int v3_init_multiboot();
282 int v3_deinit_multiboot();
283
284 int v3_init_multiboot_vm(struct v3_vm_info *vm, struct v3_xml *config);
285 int v3_deinit_multiboot_vm(struct v3_vm_info *vm);
286
287 int v3_init_multiboot_core(struct guest_info *core);
288 int v3_deinit_multiboot_core(struct guest_info *core);
289
290 int v3_setup_multiboot_vm_for_boot(struct v3_vm_info *vm);
291 int v3_setup_multiboot_core_for_boot(struct guest_info *core);
292
293 int v3_handle_multiboot_reset(struct guest_info *core);
294
295 // The following are utility functions that HVM builds on
296 int      v3_parse_multiboot_header(struct v3_cfg_file *file, mb_data_t *result);
297 int      v3_write_multiboot_kernel(struct v3_vm_info *vm, mb_data_t *mb, struct v3_cfg_file *file, 
298                                    void *base, uint64_t limit);
299 // The multiboot table is prepared from the perspective of the given
300 // core - this allows it to be generated appropriately for ROS and HRT cores
301 // when used in an HVM
302 uint64_t v3_build_multiboot_table(struct guest_info *core, uint8_t *dest, uint64_t size);
303
304 #endif /* ! __V3VEE__ */
305
306
307 #endif