|
6 | 6 |
|
7 | 7 | namespace protocol = windower::protocol; |
8 | 8 |
|
| 9 | +#include "../../../include/crescent/evm.h" |
9 | 10 | #include "vga.hpp" |
10 | 11 | #include "vm.hpp" |
11 | 12 |
|
| 13 | +asm(R"( |
| 14 | +.globl some_code |
| 15 | +.globl some_code_end |
| 16 | +some_code: |
| 17 | + hlt |
| 18 | +some_code_end: |
| 19 | +)"); |
| 20 | + |
| 21 | +extern char some_code[]; |
| 22 | +extern char some_code_end[]; |
| 23 | + |
| 24 | +#include <cassert> |
| 25 | +#include <cstdio> |
| 26 | + |
| 27 | +#define CR0_PE 1u |
| 28 | +#define CR0_MP (1U << 1) |
| 29 | +#define CR0_EM (1U << 2) |
| 30 | +#define CR0_TS (1U << 3) |
| 31 | +#define CR0_ET (1U << 4) |
| 32 | +#define CR0_NE (1U << 5) |
| 33 | +#define CR0_WP (1U << 16) |
| 34 | +#define CR0_AM (1U << 18) |
| 35 | +#define CR0_NW (1U << 29) |
| 36 | +#define CR0_CD (1U << 30) |
| 37 | +#define CR0_PG (1U << 31) |
| 38 | + |
| 39 | +/* CR4 bits */ |
| 40 | +#define CR4_VME 1 |
| 41 | +#define CR4_PVI (1U << 1) |
| 42 | +#define CR4_TSD (1U << 2) |
| 43 | +#define CR4_DE (1U << 3) |
| 44 | +#define CR4_PSE (1U << 4) |
| 45 | +#define CR4_PAE (1U << 5) |
| 46 | +#define CR4_MCE (1U << 6) |
| 47 | +#define CR4_PGE (1U << 7) |
| 48 | +#define CR4_PCE (1U << 8) |
| 49 | +#define CR4_OSFXSR (1U << 8) |
| 50 | +#define CR4_OSXMMEXCPT (1U << 10) |
| 51 | +#define CR4_UMIP (1U << 11) |
| 52 | +#define CR4_VMXE (1U << 13) |
| 53 | +#define CR4_SMXE (1U << 14) |
| 54 | +#define CR4_FSGSBASE (1U << 16) |
| 55 | +#define CR4_PCIDE (1U << 17) |
| 56 | +#define CR4_OSXSAVE (1U << 18) |
| 57 | +#define CR4_SMEP (1U << 20) |
| 58 | +#define CR4_SMAP (1U << 21) |
| 59 | + |
| 60 | +#define EFER_SCE 1 |
| 61 | +#define EFER_LME (1U << 8) |
| 62 | +#define EFER_LMA (1U << 10) |
| 63 | +#define EFER_NXE (1U << 11) |
| 64 | + |
| 65 | +/* 32-bit page directory entry bits */ |
| 66 | +#define PDE32_PRESENT 1 |
| 67 | +#define PDE32_RW (1U << 1) |
| 68 | +#define PDE32_USER (1U << 2) |
| 69 | +#define PDE32_PS (1U << 7) |
| 70 | + |
| 71 | +/* 64-bit page * entry bits */ |
| 72 | +#define PDE64_PRESENT 1 |
| 73 | +#define PDE64_RW (1U << 1) |
| 74 | +#define PDE64_USER (1U << 2) |
| 75 | +#define PDE64_ACCESSED (1U << 5) |
| 76 | +#define PDE64_DIRTY (1U << 6) |
| 77 | +#define PDE64_PS (1U << 7) |
| 78 | +#define PDE64_G (1U << 8) |
| 79 | + |
12 | 80 | int main() { |
13 | | - windower::Windower windower; |
| 81 | + CrescentHandle evm; |
| 82 | + assert(sys_evm_create(evm) == 0); |
| 83 | + CrescentHandle vcpu; |
| 84 | + EvmGuestState* regs; |
| 85 | + assert(sys_evm_create_vcpu(evm, vcpu, ®s) == 0); |
| 86 | + |
| 87 | + void* mem = nullptr; |
| 88 | + assert(sys_map(&mem, 0x200000, CRESCENT_PROT_READ | CRESCENT_PROT_WRITE) == 0); |
| 89 | + assert(sys_evm_map(evm, 0, mem, 0x200000) == 0); |
| 90 | + |
| 91 | + memcpy(mem, some_code, some_code_end - some_code); |
| 92 | + |
| 93 | + uint64_t pml4_addr = 0x2000; |
| 94 | + uint64_t *pml4 = (uint64_t *)((uintptr_t)mem + pml4_addr); |
| 95 | + |
| 96 | + uint64_t pdpt_addr = 0x3000; |
| 97 | + uint64_t *pdpt = (uint64_t *)((uintptr_t)mem + pdpt_addr); |
| 98 | + |
| 99 | + uint64_t pd_addr = 0x4000; |
| 100 | + uint64_t *pd = (uint64_t *)((uintptr_t)mem + pd_addr); |
| 101 | + |
| 102 | + pml4[0] = PDE64_PRESENT | PDE64_RW | PDE64_USER | pdpt_addr; |
| 103 | + pdpt[0] = PDE64_PRESENT | PDE64_RW | PDE64_USER | pd_addr; |
| 104 | + pd[0] = PDE64_PRESENT | PDE64_RW | PDE64_USER | PDE64_PS; |
| 105 | + |
| 106 | + regs->cr3 = pml4_addr; |
| 107 | + regs->cr4 = CR4_PAE; |
| 108 | + regs->cr0 |
| 109 | + = CR0_PE | CR0_MP | CR0_ET | CR0_NE | CR0_WP | CR0_AM | CR0_PG; |
| 110 | + regs->efer = EFER_LME | EFER_LMA; |
| 111 | + |
| 112 | + regs->cs.base = 0; |
| 113 | + regs->cs.selector = 1 << 3; |
| 114 | + regs->cs.limit = 0xffffffff; |
| 115 | + |
| 116 | + regs->ds.base = 0; |
| 117 | + regs->ds.selector = 2 << 3; |
| 118 | + regs->es = regs->ds; |
| 119 | + regs->ss = regs->ds; |
| 120 | + regs->fs = regs->ds; |
| 121 | + regs->gs = regs->ds; |
| 122 | + regs->rflags = 2; |
| 123 | + regs->rip = 0; |
| 124 | + regs->rsp = 2 << 20; |
| 125 | + |
| 126 | + assert(sys_evm_vcpu_write_state(vcpu, EVM_STATE_BITS_SEG_REGS | EVM_STATE_BITS_CONTROL_REGS | EVM_STATE_BITS_EFER) == 0); |
| 127 | + int res = sys_evm_vcpu_run(vcpu); |
| 128 | + printf("res: %d\n", res); |
| 129 | + |
| 130 | + /*windower::Windower windower; |
14 | 131 | if (auto status = windower::Windower::connect(windower); status != 0) { |
15 | 132 | puts("[console]: failed to connect to window manager"); |
16 | 133 | return 1; |
@@ -50,5 +167,5 @@ int main() { |
50 | 167 |
|
51 | 168 | window.redraw(); |
52 | 169 | } |
53 | | - } |
| 170 | + }*/ |
54 | 171 | } |
0 commit comments