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;
198 typedef struct mb_info_memmap_entry {
203 } __attribute__((packed)) mb_info_memmap_entry_t;
205 #define MB_INFO_MEMMAP_TAG 6
206 // note alignment of 8 bytes required for each...
207 typedef struct mb_info_memmap {
209 uint32_t entry_size; // multiple of 8
210 uint32_t entry_version; // 0
211 mb_info_memmap_entry_t entries[];
212 } __attribute__((packed)) mb_info_memmap_t;
214 #define MB_INFO_HRT_TAG 0xf00df00d
215 typedef struct mb_info_hrt {
217 // apic ids are 0..num_apics-1
219 // apic and ioapic addresses are the well known places
220 uint32_t total_num_apics;
221 // first apic the HRT owns (HRT core 0)
222 uint32_t first_hrt_apic_id;
223 // can the HRT use an ioapic?
224 uint32_t have_hrt_ioapic;
225 // if so, this is the first entry on the
226 // ioapic that can be used by the HRT
227 uint32_t first_hrt_ioapic_entry;
229 uint64_t cpu_freq_khz;
230 // copy of the HRT flags from the kernel (indicating
231 // page table mapping type, position independence, etc.
232 // these reflect how it has actually been mapped
234 // the amount of physical address space that has been mapped
236 uint64_t max_mem_mapped;
237 // The first physical address the HRT should
238 // (nominally) use. Physical addresses below this are
239 // visible to the ROS
240 uint64_t first_hrt_gpa;
241 // Where the intial boot state starts in the physical address
242 // space. This includes INT HANDLER,IDT,GDT,TSS, PAGETABLES,
243 // and MBINFO, but not the scratch stacks
244 // This is essentially the content of CR3 - 1 page on boot
245 uint64_t boot_state_gpa;
246 // Where GPA 0 is mapped in the virtual address space
250 // first_hrt_vaddr==first_hrt_paddr => no address space coalescing
251 // first_hrt_vaddr>first_hrt_paddr => address space coalescing
252 // For example, first_hrt_vaddr might be set to the start of linux kernel
253 // This then allows us to coalesce user portion of the address space of
254 // a linux process and the HRT
255 // for communication. "page" here a 4 KB quantity
257 // address of the page the VMM, HRT, and ROS share
258 uint64_t comm_page_gpa;
259 // interrupt vector used to upcall to HRT (==0 if none)
260 // downcalls are done with HVM hypercall 0xf00df00d
261 uint8_t hrt_int_vector;
263 } __attribute__((packed)) mb_info_hrt_t;
268 struct v3_vm_multiboot {
269 uint8_t is_multiboot;
270 struct v3_cfg_file *mb_file;
272 // GPA where we put the MB record, GDT, TSS, etc
273 // The kernel load address and size are as in mb_data
277 // There is no core structure for
278 // multiboot capability
283 int v3_init_multiboot();
284 int v3_deinit_multiboot();
286 int v3_init_multiboot_vm(struct v3_vm_info *vm, struct v3_xml *config);
287 int v3_deinit_multiboot_vm(struct v3_vm_info *vm);
289 int v3_init_multiboot_core(struct guest_info *core);
290 int v3_deinit_multiboot_core(struct guest_info *core);
292 int v3_setup_multiboot_vm_for_boot(struct v3_vm_info *vm);
293 int v3_setup_multiboot_core_for_boot(struct guest_info *core);
295 int v3_handle_multiboot_reset(struct guest_info *core);
297 // The following are utility functions that HVM builds on
298 int v3_parse_multiboot_header(struct v3_cfg_file *file, mb_data_t *result);
299 int v3_write_multiboot_kernel(struct v3_vm_info *vm, mb_data_t *mb, struct v3_cfg_file *file,
300 void *base, uint64_t limit);
301 // The multiboot table is prepared from the perspective of the given
302 // core - this allows it to be generated appropriately for ROS and HRT cores
303 // when used in an HVM
304 uint64_t v3_build_multiboot_table(struct guest_info *core, uint8_t *dest, uint64_t size);
306 #endif /* ! __V3VEE__ */