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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2015, The V3VEE Project <http://www.v3vee.org>
11 * All rights reserved.
13 * Author: Peter Dinda <pdinda@northwestern.edu>
15 * This is free software. You are permitted to use,
16 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #ifndef __VMM_MULTIBOOT_H
21 #define __VMM_MULTIBOOT_H
26 #include <palacios/vmm_types.h>
29 /******************************************************************
30 Data contained in the ELF file we will attempt to boot
31 ******************************************************************/
33 #define ELF_MAGIC 0x464c457f
34 #define MB2_MAGIC 0xe85250d6
36 typedef struct mb_header {
42 } __attribute__((packed)) mb_header_t;
44 typedef struct mb_tag {
48 } __attribute__((packed)) mb_tag_t;
51 typedef struct mb_info_req {
54 } __attribute__((packed)) mb_info_t;
57 typedef uint32_t u_virt, u_phys;
59 #define MB_TAG_ADDRESS 2
60 typedef struct mb_addr {
66 } __attribute__((packed)) mb_addr_t;
68 #define MB_TAG_ENTRY 3
69 typedef struct mb_entry {
72 } __attribute__((packed)) mb_entry_t;
74 #define MB_TAG_FLAGS 4
75 typedef struct mb_flags {
77 uint32_t console_flags;
78 } __attribute__((packed)) mb_flags_t;
80 #define MB_TAG_FRAMEBUF 5
81 typedef struct mb_framebuf {
86 } __attribute__((packed)) mb_framebuf_t;
88 #define MB_TAG_MODALIGN 6
89 typedef struct mb_modalign {
92 } __attribute__((packed)) mb_modalign_t;
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
99 #define MB_TAG_MB64_HRT 0xf00d
100 typedef struct mb_mb64_hrt {
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
112 // How much physical address space to map in the
113 // initial page tables (bytes)
115 uint64_t max_mem_to_map;
116 // offset of the GVA->GPA mappings (GVA of GPA 0)
118 // 64 bit entry address (=0 to use entry tag (which will be offset by gva_offset))
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;
128 } __attribute__((packed)) mb_mb64_hrt_t;
130 typedef struct mb_data {
136 mb_framebuf_t *framebuf;
137 mb_modalign_t *modalign;
138 mb_mb64_hrt_t *mb64_hrt;
145 // - BIOS Boot Device
148 // - Boot Loader name
151 // - Framebuffer info
156 /******************************************************************
157 Data we will pass to the kernel via rbx
158 ******************************************************************/
160 #define MB2_INFO_MAGIC 0x36d76289
163 typedef struct mb_info_header {
166 } __attribute__((packed)) mb_info_header_t;
168 // A tag of type 0, size 8 indicates last value
170 typedef struct mb_info_tag {
173 } __attribute__((packed)) mb_info_tag_t;
176 #define MB_INFO_MEM_TAG 4
177 typedef struct mb_info_mem {
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;
183 #define MB_INFO_CMDLINE_TAG 1
184 // note alignment of 8 bytes required for each...
185 typedef struct mb_info_cmdline {
187 uint32_t size; // includes zero termination
188 uint8_t string[]; // zero terminated
189 } __attribute__((packed)) mb_info_cmdline_t;
196 typedef struct mb_info_memmap_entry {
201 } __attribute__((packed)) mb_info_memmap_entry_t;
203 #define MB_INFO_MEMMAP_TAG 6
204 // note alignment of 8 bytes required for each...
205 typedef struct mb_info_memmap {
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;
212 #define MB_INFO_HRT_TAG 0xf00df00d
213 typedef struct mb_info_hrt {
215 // apic ids are 0..num_apics-1
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;
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
232 // the amount of physical address space that has been mapped
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
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
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;
261 } __attribute__((packed)) mb_info_hrt_t;
266 struct v3_vm_multiboot {
267 uint8_t is_multiboot;
268 struct v3_cfg_file *mb_file;
270 // GPA where we put the MB record, GDT, TSS, etc
271 // The kernel load address and size are as in mb_data
275 // There is no core structure for
276 // multiboot capability
281 int v3_init_multiboot();
282 int v3_deinit_multiboot();
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);
287 int v3_init_multiboot_core(struct guest_info *core);
288 int v3_deinit_multiboot_core(struct guest_info *core);
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);
293 int v3_handle_multiboot_reset(struct guest_info *core);
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);
304 #endif /* ! __V3VEE__ */