Merge branch 'vendor/LIBEDIT'
[dragonfly.git] / test / vmm / vmm_test.c
1 #include <sys/param.h>
2 #include <sys/sysctl.h>
3 #include <sys/vmm_guest_ctl.h>
4 #include <sys/types.h>
5 #include <sys/mman.h>
6 #include <sys/vkernel.h>
7
8 #include <cpu/cpufunc.h>
9 #include <cpu/specialreg.h>
10
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <errno.h>
14 #include <err.h>
15 #include <unistd.h>
16 #include <strings.h>
17 #include <fcntl.h>
18 #include <stdarg.h>
19 #define vmm_printf(val, err, exp) \
20         printf("vmm_guest(%d): return %d, expected %d\n", val, err, exp);
21
22 #define STACK_SIZE (512 * PAGE_SIZE)
23
24 int
25 vmm_boostrap(void)
26 {
27         struct vmm_guest_options options;
28         uint64_t *ptr;
29         uint64_t stack_source;
30         uint64_t stack_size;
31         uint64_t stack_dest;
32         int pml4_stack_index;
33         int pdp_stack_index;
34         int pd_stack_index;
35         char tst[1024];
36         void *stack;
37         uint64_t i,j;
38         int regs[4];
39         int amd_feature;
40
41         stack = mmap(NULL, STACK_SIZE,
42             PROT_READ|PROT_WRITE|PROT_EXEC,
43             MAP_ANON, -1, 0);
44
45         if (stack == MAP_FAILED) {
46                 printf("Error on allocating stack\n");
47                 return -1;
48         }
49
50         posix_memalign((void **) &ptr, PAGE_SIZE, (512 + 4) * PAGE_SIZE);
51         bzero(ptr, (512 + 4) * PAGE_SIZE);
52
53         uint64_t *pml4 = ptr;
54         uint64_t *pdp = (uint64_t *)((uint64_t)ptr + PAGE_SIZE);
55         uint64_t *pdp_stack = (uint64_t *)((uint64_t)ptr + 2 * PAGE_SIZE);
56         uint64_t *pd_stack = (uint64_t *)((uint64_t)ptr + 3 * PAGE_SIZE);
57         uint64_t *pd_vec = (uint64_t *)((uint64_t)ptr + 4 * PAGE_SIZE);
58
59         pml4[0] = (uint64_t) pdp | VPTE_V | VPTE_RW| VPTE_U;
60
61         do_cpuid(0x80000001, regs);
62         amd_feature = regs[3];
63
64         if (amd_feature & AMDID_PAGE1GB) {
65                 for (i = 0; i < VPTE_PAGE_ENTRIES; i++) {
66                         pdp[i] = i << 30;
67                         pdp[i] |=  VPTE_V | VPTE_RW | VPTE_U;
68                 }
69         } else {
70                 for (i = 0; i < VPTE_PAGE_ENTRIES; i++) {
71                         uint64_t *pd = &pd_vec[i * VPTE_PAGE_ENTRIES];
72                         pdp[i] = (uint64_t) pd;
73                         pdp[i] |=  VPTE_V | VPTE_RW | VPTE_U;
74                         for (j = 0; j < VPTE_PAGE_ENTRIES; j++) {
75                                 pd[j] = (i << 30) | (j << 21);
76                                 pd[j] |=  VPTE_V | VPTE_RW | VPTE_U | VPTE_PS;
77                         }
78                 }
79         }
80
81         void *stack_addr = NULL;
82
83         pml4_stack_index = (uint64_t)&stack_addr >> PML4SHIFT;
84         pml4[pml4_stack_index] = (uint64_t) pdp_stack;
85         pml4[pml4_stack_index] |= VPTE_V | VPTE_RW| VPTE_U;
86
87         pdp_stack_index = ((uint64_t)&stack_addr & PML4MASK) >> PDPSHIFT;
88         pdp_stack[pdp_stack_index] = (uint64_t) pd_stack;
89         pdp_stack[pdp_stack_index] |= VPTE_V | VPTE_RW| VPTE_U;
90
91         pd_stack_index = ((uint64_t)&stack_addr & PDPMASK) >> PDRSHIFT;
92         pd_stack[pd_stack_index] = (uint64_t) stack;
93         pd_stack[pd_stack_index] |= VPTE_V | VPTE_RW| VPTE_U | VPTE_PS;
94
95         options.new_stack = (uint64_t)stack + STACK_SIZE;
96         options.guest_cr3 = (register_t) pml4;
97         options.master = 1;
98         if(vmm_guest_ctl(VMM_GUEST_RUN, &options)) {
99                 printf("Error: VMM enter failed\n");
100         }
101         printf("vmm_bootstrap: VMM bootstrap success\n");
102
103         return 0;
104 }
105 int
106 main(void)
107 {
108         vmm_boostrap();
109         printf("vmm_test: VMM bootstrap success\n");
110         return 0;
111 }