SayoriOS 0.3.3

mtrr.c
1 #include "common.h"
2 #include "sys/cpuid.h"
3 #include "io/ports.h"
4 #include "sys/msr.h"
5 #include "sys/mtrr.h"
6 #include "io/tty.h"
7
8 #define UNCACHED 0
9 #define WRITECOMBINING 1
10 #define WRITETHROUGH 4
11 #define WRITEPROTECT 5
12 #define WRITEBACK 6
13
14 bool mtrr_is_supported = false;
15 bool mtrr_wc_available = false;
16 bool mtrr_fixed_size_available = false;
17 size_t variable_size_mtrrs = 0;
18
19 #define CALC_MASK(size) (~(size - 1) & 0xffffffff)
20
21 void mtrr_init() {
22 uint32_t unused, eax, edx;
23
24 cpuid(1, unused, unused, unused, edx);
25
26 qemu_log("%x", edx & (1 << 12));
27
28 if(edx & (1 << 12)) {
29 mtrr_is_supported = true;
30 } else {
31 return;
32 }
33
34 rdmsr(0xFE, eax, unused);
35
36 variable_size_mtrrs = eax & 0xff;
37 mtrr_fixed_size_available = eax & (1 << 8) ? true : false;
38 mtrr_wc_available = eax & (1 << 10) ? true : false;
39
40 qemu_log("Variable size MTRRs count: %d", variable_size_mtrrs);
41 qemu_log("Fixed size available: %d", mtrr_fixed_size_available);
42 qemu_log("Writecombining available: %d", mtrr_wc_available);
43
44 for(size_t i = 0; i < variable_size_mtrrs; i++) {
45 uint32_t base, mask;
46
47 read_mtrr(i, &base, &mask);
48
49 qemu_log("[%d] MTRR: base: %x; mask: %x", i, base, mask);
50 }
51 }
52
53 void list_mtrrs() {
54 tty_printf("Physical FB is: %x", getDisplayAddr());
55
56 for(size_t i = 0; i < variable_size_mtrrs; i++) {
57 uint32_t base, mask;
58
59 read_mtrr(i, &base, &mask);
60
61 qemu_log("[%d] MTRR: base: %x; mask: %x", i, base, mask);
62 tty_printf("[%d] MTRR: base: %x; mask: %x\n", i, base, mask);
63 }
64 }
65
66 uint32_t get_mtrr_index(uint32_t address) {
67 for(size_t i = 0; i < variable_size_mtrrs; i++) {
68 uint32_t base, mask;
69
70 read_mtrr(i, &base, &mask);
71
72 if((mask & (1 << 11)) && (base & ~0xfff) == ALIGN(address, 4096)) {
73 return i;
74 }
75 }
76
77 return 0xffffffff;
78 }
79
80
81 void read_mtrr(size_t index, uint32_t* base, uint32_t* mask) {
82 uint32_t unused;
83
84 if(index >= variable_size_mtrrs)
85 return;
86
87 rdmsr(0x200 + (index * 2), *base, unused);
88 rdmsr(0x201 + (index * 2), *mask, unused);
89 }
90
91 void write_mtrr(size_t index, uint32_t base, uint32_t mask) {
92 uint32_t unused = 0;
93
94 if(index >= variable_size_mtrrs)
95 return;
96
97 wrmsr(0x200 + (index * 2), base, unused);
98 wrmsr(0x201 + (index * 2), mask, unused);
99 }
100
101 void write_mtrr_size(size_t index, uint32_t base, uint32_t size, size_t type) {
102 uint32_t unused = 0;
103
104 if(index >= variable_size_mtrrs)
105 return;
106
107 wrmsr(0x200 + (index * 2), ALIGN(base, 4096) | type, unused);
108 wrmsr(0x201 + (index * 2), CALC_MASK(ALIGN(size, 4096)) | (1 << 11), unused);
109 }
110
111 size_t find_free_mtrr() {
112 for(size_t i = 0; i < variable_size_mtrrs; i++) {
113 uint32_t base, mask;
114
115 read_mtrr(i, &base, &mask);
116
117 if((mask & (1 << 11)) == 0) {
118 return i;
119 }
120 }
121
122 return 0xffffffff; // Not found
123 }
common.h
Основные определения ядра