summaryrefslogtreecommitdiff
path: root/src/kernel/smp_trampoline.asm
blob: f723aa67f88e946586c783fa2634fa78f712bf38 (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
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
136
137
138
139
140
global smp_bootstrap_corecount;

[bits 16]
smp_trampoline:
cli
hlt
hlt

xor ax, ax
mov ds, ax
lgdt [.gdt_descriptor_p]
mov eax, cr0
or eax, 0x1
mov cr0, eax ; now in long mode

jmp 0x8:.smp_protected


;________________________________________________________________________________________

;TODO find how to use old gdt
.gdt_start_p: ; we need to start with a null gdt
dd 0
dd 0

.gdt_code_p:
dw 0xffff
dw 0x0000
db 0x00
db 10011010b 
db 11001111b
db 0x0000

.gdt_data_p:
dw 0xffff
dw 0x0000
db 0x00
db 10010010b 
db 11001111b
db 0x0000

.gdt_end_p:

.gdt_descriptor_p: 
  dw .gdt_end_p - .gdt_start_p - 1 
dq .gdt_start_p

SMP_PROTECTED_CODE_SEGMENT equ .gdt_code_p - .gdt_start_p
SMP_PROTECTED_DATA_SEGMENT equ .gdt_data_p - .gdt_start_p

;________________________________________________________________________________________

.smp_protected

[bits 32]
mov ax, SMP_PROTECTED_DATA_SEGMENT
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax

mov eax, 0x10000 ;TODO clarify _why_ this is a thing
mov cr3, eax

;setting up misc features
mov eax, cr4         
; PAE, OSFXSR, OSXMMEXCPT
or eax, 1 << 5 | 1 << 9 | 1 << 10
mov cr4, eax         


;set NX and LME
mov eax, 0x80000001
cpuid
and edx, 1 << 20
shr edx, 9
  
mov ecx, 0xc0000080
rdmsr
or eax, 1 << 8 | 1 << 11
or eax, edx
wrmsr

;enable paging 
mov eax, cr0
or eax, 1 << 31 | 1 << 0; 
and ax, ~(1 << 2)
mov cr0, eax

jmp SMP_LONG_CODE_SEGMENT:.counter

;________________________________________________________________________________________

[bits 64]
;TODO do we really need all this?
.gdt_start_l:
;and now we set up a temporary GDT creating a 1:1 mapping
dw 0xffff
dw 0
db 0 ;this is the invalid GDT
db 0
db 1
db 0

;now for the code GDT:
.gdt_code_l:
dw 0 ; segment limit 15:00 (I don't think this matters in 64 bit mode!)
dw 0 ; base address 15:00
db 0 ; base address 23:16
db 10011010b  
db 00100000b 
db 0

.gdt_data_l:
dw 0 
dw 0 
db 0 
db 10010010b  
db 00100000b  
db 0

.gdt_end_l: ; later calculates offset in defs below


.descriptor_l: 
  dw .gdt_end_l - .gdt_start_l - 1 
dq .gdt_start_l

SMP_LONG_CODE_SEGMENT equ .gdt_code_l - .gdt_start_l
SMP_LONG_DATA_SEGMENT equ .gdt_data_l - .gdt_start_l

.counter:
mov rax, [smp_bootstrap_corecount]
inc QWORD [rax]
cli
hlt
;TODO set up stack; enter kernel

smp_bootstrap_corecount: db 0