summaryrefslogtreecommitdiff
path: root/src/arch/amd64/shim.c
blob: 1e735252a1e8ebd19a91c8bc0fd3f36ffefb85fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdint.h>
#include <cpuid.h>

#define F_PRESENT      0x001
#define F_WRITEABLE    0x002
#define F_UNPRIVILEGED 0x004
#define F_WRITETHROUGH 0x008
#define F_CACHEDISABLE 0x010 
#define F_ACCESSED     0x020
#define F_DIRTY        0x040
#define F_MEGABYTE     0x080
#define F_GLOBAL       0x100

// PAGE MAP LEVEL 4 ENTRY
struct pml4e {
	uint64_t flags              : 6;
	uint64_t                    : 6;
	uint64_t address            : 40;
	uint64_t                    : 11;
	uint64_t execute_disable    : 1;
};

// PAGE DIRECTORY POINTER TABLE ENTRY 
struct pdpte {
	uint64_t flags              : 6;
	uint64_t                    : 1;
	uint64_t page_size          : 1;
	uint64_t                    : 4;
	uint64_t address            : 40;
	uint64_t                    : 11;
	uint64_t execute_disable    : 1;
};

// PAGE DIRECTORY ENTRY
struct pde {
	uint64_t flags              : 6;
	uint64_t                    : 1;
	uint64_t page_size          : 1;
	uint64_t                    : 4;
	uint64_t address            : 40;
	uint64_t                    : 11;
	uint64_t execute_disable    : 1;
};

// PAGE TABLE ENTRY
struct pte {
	uint64_t flags              : 9;
	uint64_t                    : 3;
	uint64_t address            : 40;
	uint64_t                    : 7;
	uint64_t protection_key     : 4;
	uint64_t execute_disable    : 1;
};

static int get_maxphysaddr() {
	uint32_t eax, ebx, ecx, edx;
	__cpuid(0x80000008, eax, ebx, ecx, edx);
	return eax & 0xFF;
}

// entry point for amd64
void* amd64_shim(void *boot_info) {
	struct pml4e *pml4 = (struct pml4e *)0x1000;
	struct pdpte *pdpt = (struct pdpte *)0x2000;
	struct pde   *pd   = (struct pd    *)0x3000;
	struct pte   *pt   = (struct pt    *)0x4000;
	pd[1].flags = F_PRESENT | F_WRITEABLE;
	pd[1].address = ((uint64_t)pt) >> 12;
	__asm("invlpg 0x200000");
}