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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#include "device/processor.h"
#include "arch/x86_64/tables.h"
#include "include/arch/x86_64/idt.h"
#include "include/arch/x86_64/object.h"
#include "jove.h"
processor_t s_bsp = {
.odir = &_initDirectory
};
struct jove_ObjectDirectory s_processor_dir = {
.entries = {
[0] = {
.type = KO_OBJECT_DIRECTORY,
.data = 2
},
[1] = {
.type = KO_DEV_PROCESSOR,
.data = (uintptr_t)&s_bsp
}
}
};
char s_initial_response_buffer[256] = { 0 };
typedef union msr_efer
{
struct {
uint8_t sce : 1;
uint8_t resv : 7;
uint8_t lme : 1;
uint8_t unk0 : 1;
uint8_t lma : 1;
uint8_t nxe : 1;
uint8_t svme : 1;
uint8_t lmsle : 1;
uint8_t ffxsr : 1;
uint8_t tce : 1;
};
uint32_t v[2];
} msr_efer_t;
typedef union msr_star
{
struct {
uint32_t eip;
uint16_t kcs;
uint16_t ucs;
};
uint32_t v[2];
} msr_star_t;
typedef union msr_lstar
{
uint32_t v[2];
uintptr_t ip;
} msr_lstar_t;
static void
s_enable_sce(void)
{
msr_efer_t feat;
rdmsr(MSR_EFER, &feat.v[0], &feat.v[1]);
feat.sce = 1;
wrmsr(MSR_EFER, feat.v[0], feat.v[1]);
msr_star_t star;
star.kcs = GDT_ENTRY_KERNEL_CODE * sizeof(segment_descriptor_t);
star.ucs = GDT_ENTRY_USER_CODE * sizeof(segment_descriptor_t);
wrmsr(MSR_STAR, star.v[0], star.v[1]);
extern void _syscall_entry(void);
msr_lstar_t lstar;
lstar.ip = (uintptr_t)_syscall_entry;
wrmsr(MSR_LSTAR, lstar.v[0], lstar.v[1]);
}
void
processor_setup(void *_processor)
{
processor_t *processor = (processor_t*)_processor;
gdt_setup(processor);
idt_setup(processor);
wrmsr(MSR_GS_BASE,
(uint32_t)((uintptr_t)_processor & 0xFFFFFFFF),
(uint32_t)((uintptr_t)_processor >> 32));
}
void enable_fpu(void);
void enable_sse(void);
void enable_avx(void);
void
bsp_setup(void)
{
#ifdef ENABLE_SSE
enable_fpu();
enable_sse();
#endif
#ifdef ENABLE_AVX
enable_avx();
#endif
_initDirectory.entries[INIT_OBJECT_PROCESSOR_DIR] = (objdir_entry_t) {
.type = KO_OBJECT_DIRECTORY,
.data = (uintptr_t)(&s_processor_dir)
};
ivt_setup();
s_enable_sce();
processor_setup(&s_bsp);
}
void
rdmsr(uint32_t msr, uint32_t *lo, uint32_t *hi)
{
__asm__ volatile("rdmsr": "=a"(*lo), "=d"(*hi): "c"(msr));
}
void
wrmsr(uint32_t msr, uint32_t lo, uint32_t hi)
{
__asm__ volatile("wrmsr":: "a"(lo), "d"(hi), "c"(msr));
}
void*
processor_current(void)
{
uint64_t r = 0;
rdmsr(MSR_GS_BASE, (uint32_t*)&r, ((uint32_t*)&r) + 1);
return (void*)r;
}
|