e820map: move over to the new size scheme
[akaros.git] / user / vmm / include / vmm / vmm.h
1 /* Copyright (c) 2015 Google Inc.
2  * Ron Minnich <rminnich@google.com>
3  * See LICENSE for details.
4  *
5  * VMM.h */
6
7 #pragma once
8
9 #include <ros/vmm.h>
10 #include <vmm/sched.h>
11 #include <vmm/linux_bootparam.h>
12 #include <parlib/stdio.h>
13 #include <libelf.h>
14
15 // We need to reserve an area of the low 4G for thinks like tables, APIC, and
16 // so on. So far, 256 MiB has been more than enough, so ...
17 #define MiB 0x100000ull
18 #define MinMemory (16*MiB)
19 #define GiB (0x40000000ULL)
20 #define _4GiB (0x100000000ULL)
21 // BIOS conventions from 1978 make it smart to reserve the low 64k
22 #define LOW64K 65536
23 // The RESERVED area is for all the random junk like devices, ACPI, etc.
24 // We just give it the top 1 GiB of the 32-bit address space, which
25 // nicely translates to one GiB PTE.
26 #define RESERVED 0xC0000000ULL
27 #define RESERVEDSIZE (_4GiB - RESERVED)
28 // Start the VM at 16 MiB, a standard number for 64 bit kernels on amd64
29 #define KERNSTART 0x1000000
30
31 #define VM_PAGE_FAULT                   14
32
33 // APIC Guest Physical Address, a well known constant.
34 #define APIC_GPA                        0xfee00000ULL
35
36 /* The listing of VIRTIO MMIO devices. We currently only expect to have 2,
37  * console and network. Only the console is fully implemented right now.*/
38 enum {
39         VIRTIO_MMIO_CONSOLE_DEV,
40         VIRTIO_MMIO_NETWORK_DEV,
41         VIRTIO_MMIO_BLOCK_DEV,
42
43         /* This should always be the last entry. */
44         VIRTIO_MMIO_MAX_NUM_DEV,
45 };
46
47 /* Structure to encapsulate all of the bookkeeping for a VM. */
48 struct virtual_machine {
49         struct guest_thread                     **gths;
50         unsigned int                            nr_gpcs;
51         /* up_gpcs should not need synchronization. only the BSP should be making
52          * startup vmcalls. For security's sake we might still want to lock in the
53          * future. TODO(ganshun)
54          * up_gpcs refers to the number of guest pcores that have
55          * been started so far. */
56         unsigned int                            up_gpcs;
57         struct vmm_gpcore_init          *gpcis;
58         bool                                            vminit;
59
60         /* TODO: put these in appropriate structures.  e.g., virtio things in
61          * something related to virtio.  low4k in something related to the guest's
62          * memory. */
63         uint8_t                                         *low4k;
64         struct virtio_mmio_dev          *virtio_mmio_devices[VIRTIO_MMIO_MAX_NUM_DEV];
65
66         /* minimum and maximum physical memory addresses. When we set up the initial
67          * default page tables we use this range. Note that even if the "physical"
68          * memory has holes, we'll create PTEs for it. This seems enough for now but
69          * we shall see. */
70         uintptr_t                   minphys;
71         uintptr_t                   maxphys;
72
73         /* Default root pointer to use if one is not set in a
74          * guest thread. We expect this to be the common case,
75          * where all guests share a page table. It's not required
76          * however. */
77         void                                            *root;
78
79         /* Default value for whether guest threads halt on an exit. */
80         bool                                            halt_exit;
81 };
82
83 char *regname(uint8_t reg);
84 int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
85            uint64_t **regp, int *store, int *size, int *advance);
86 int io(struct guest_thread *vm_thread);
87 void showstatus(FILE *f, struct guest_thread *vm_thread);
88 int gvatogpa(struct guest_thread *vm_thread, uint64_t va, uint64_t *pa);
89 int rippa(struct guest_thread *vm_thread, uint64_t *pa);
90 int msrio(struct guest_thread *vm_thread, struct vmm_gpcore_init *gpci,
91           uint32_t opcode);
92 int do_ioapic(struct guest_thread *vm_thread, uint64_t gpa,
93               int destreg, uint64_t *regp, int store);
94 bool handle_vmexit(struct guest_thread *gth);
95 int __apic_access(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
96                   uint64_t *regp, int store);
97 int vmm_interrupt_guest(struct virtual_machine *vm, unsigned int gpcoreid,
98                         unsigned int vector);
99 uintptr_t load_elf(char *filename, uint64_t offset, uint64_t *highest,
100                    Elf64_Ehdr *ehdr_out);
101 ssize_t setup_initrd(char *filename, void *membase, size_t memsize);
102 /* Lookup helpers */
103
104 static struct virtual_machine *gth_to_vm(struct guest_thread *gth)
105 {
106         return ((struct vmm_thread*)gth)->vm;
107 }
108
109 static struct vm_trapframe *gth_to_vmtf(struct guest_thread *gth)
110 {
111         return &gth->uthread.u_ctx.tf.vm_tf;
112 }
113
114 static struct vmm_gpcore_init *gth_to_gpci(struct guest_thread *gth)
115 {
116         struct virtual_machine *vm = gth_to_vm(gth);
117
118         return &vm->gpcis[gth->gpc_id];
119 }
120
121 static struct virtual_machine *get_my_vm(void)
122 {
123         return ((struct vmm_thread*)current_uthread)->vm;
124 }
125
126 /* memory helpers */
127 void *init_e820map(struct virtual_machine *vm, struct boot_params *bp);
128 void checkmemaligned(uintptr_t memstart, size_t memsize);
129 void mmap_memory(struct virtual_machine *vm, uintptr_t memstart,
130                  size_t memsize);
131 void *setup_paging(struct virtual_machine *vm, bool debug);
132 void *setup_biostables(struct virtual_machine *vm,
133                        void *a, void *smbiostable);