summaryrefslogtreecommitdiff
path: root/src/kernel/arch/amd64/paging.h
blob: 70752b0f4fb9c229cbced9e953b6f1ff46cddf1a (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
#pragma once
#include <camellia/types.h>

/* <heat> nitpick: I highly recommend you dont use bitfields for paging
 *        structures
 * <heat> you can't change them atomically and the way they're layed out
 *        in memory is implementation defined iirc
 */
typedef union pe_generic_t {
	struct {
		uint64_t present   : 1;
		uint64_t writeable : 1;
		uint64_t user      : 1;
		uint64_t writethru : 1;

		uint64_t uncached  : 1;
		uint64_t accessed  : 1;
		uint64_t dirty     : 1;
		uint64_t large     : 1; // also, PAT

		uint64_t global    : 1; // CR4.PGE is disabled anyways
		uint64_t _unused2  : 2;
		uint64_t _unused3  : 1; // HLAT

		uint64_t address   : 40;

		uint64_t _unused4  : 7;
		uint64_t pke       : 4;
		uint64_t noexec    : 1;
	} __attribute__((packed));
	void *as_ptr;
} pe_generic_t; // pageentry_generic

struct Pagedir { /* on amd64 actually points to pml4 */
	pe_generic_t e[512];
} __attribute__((packed));


union virt_addr {
	void __user *full;
	struct {
		uint64_t off_4k : 12; //   4Kb // offset in page
		uint64_t pt     :  9; //   2Mb // page table index
		uint64_t pd     :  9; //   1Gb // page directory index
		uint64_t pdpt   :  9; // 512Gb // page directory pointer table index
		uint64_t pml4   :  9; // 256Tb // page map level 4 index
		uint64_t sign   : 16;
	} __attribute__((packed));
};


/* amd64/32/paging.c */
extern pe_generic_t pml4_identity[512];
void pml4_identity_init(void); // called from amd64/32/boot.s