* add p cc
[mascara-docs.git] / amd64 / bareMetalOS-0.5.2 / baremetal0.5.2 / os / init_64.asm
blobd1a379bc786723af952b2edfaa9dc863121b5c15
1 ; =============================================================================
2 ; BareMetal -- a 64-bit OS written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2011 Return Infinity -- see LICENSE.TXT
5 ; INIT_64
6 ; =============================================================================
8 align 16
9 db 'DEBUG: INIT_64 '
10 align 16
13 init_64:
14 ; Make sure that memory range 0x110000 - 0x200000 is cleared
15 mov rdi, os_SystemVariables
16 xor rcx, rcx
17 xor rax, rax
18 clearmem:
19 stosq
20 add rcx, 1
21 cmp rcx, 122880 ; Clear 960 KiB
22 jne clearmem
24 mov ax, 0x000A ; Set the cursor to 0,10 and clear the screen (needs to happen before anything is printed to the screen)
25 call os_move_cursor
27 xor rdi, rdi ; create the 64-bit IDT (at linear address 0x0000000000000000) as defined by Pure64
29 ; Create exception gate stubs (Pure64 has already set the correct gate markers)
30 mov rcx, 32
31 mov rax, exception_gate
32 make_exception_gate_stubs:
33 call create_gate
34 add rdi, 1
35 sub rcx, 1
36 jnz make_exception_gate_stubs
38 ; Create interrupt gate stubs (Pure64 has already set the correct gate markers)
39 mov rcx, 256-32
40 mov rax, interrupt_gate
41 make_interrupt_gate_stubs:
42 call create_gate
43 add rdi, 1
44 sub rcx, 1
45 jnz make_interrupt_gate_stubs
47 ; Set up the exception gates for all of the CPU exceptions
48 mov rcx, 20
49 xor rdi, rdi
50 mov rax, exception_gate_00
51 make_exception_gates:
52 call create_gate
53 add rdi, 1
54 add rax, 16 ; The exception gates are aligned at 16 bytes
55 sub rcx, 1
56 jnz make_exception_gates
58 ; Set up the IRQ handlers
59 mov rdi, 0x21
60 mov rax, keyboard
61 call create_gate
62 mov rdi, 0x22
63 mov rax, cascade
64 call create_gate
65 mov rdi, 0x28
66 mov rax, rtc
67 call create_gate
68 mov rdi, 0x80
69 mov rax, ap_wakeup
70 call create_gate
71 mov rdi, 0x81
72 mov rax, ap_reset
73 call create_gate
75 ; Set up RTC
76 ; Rate defines how often the RTC interrupt is triggered
77 ; Rate is a 4-bit value from 1 to 15. 1 = 32768Hz, 6 = 1024Hz, 15 = 2Hz
78 ; RTC value must stay at 32.768KHz or the computer will not keep the correct time
79 ; http://wiki.osdev.org/RTC
80 mov al, 0x0a
81 out 0x70, al
82 mov al, 00101101b ; RTC@32.768KHz (0010), Rate@8Hz (1101)
83 out 0x71, al
84 mov al, 0x0b
85 out 0x70, al
86 mov al, 01000010b ; Periodic(6), 24H clock(2)
87 out 0x71, al
88 mov al, 0x0C ; Acknowledge the RTC
89 out 0x70, al
90 in al, 0x71
92 mov al, 0x0B ; Set RTC to binary mode
93 out 0x70, al
94 in al, 0x71
95 bts ax, 2
96 mov bl, al
97 mov al, 0x0B
98 out 0x70, al
99 mov al, bl
100 out 0x71, al
102 ; Disable blink
103 mov dx, 0x3DA
104 in al, dx
105 mov dx, 0x3C0
106 mov al, 0x30
107 out dx, al
108 add dx, 1
109 in al, dx
110 and al, 0xF7
111 sub dx, 1
112 out dx, al
114 ; Set color palette
115 xor eax, eax
116 mov dx, 0x03C8 ; DAC Address Write Mode Register
117 out dx, al
118 mov dx, 0x03C9 ; DAC Data Register
119 mov rbx, 16 ; 16 lines
120 nextline:
121 mov rcx, 16 ; 16 colors
122 mov rsi, palette
123 nexttritone:
124 lodsb
125 out dx, al
126 lodsb
127 out dx, al
128 lodsb
129 out dx, al
130 dec rcx
131 cmp rcx, 0
132 jne nexttritone
133 dec rbx
134 cmp rbx, 0
135 jne nextline ; Set the next 16 colors to the same
136 mov eax, 0x14 ; Fix for color 6
137 mov dx, 0x03c8 ; DAC Address Write Mode Register
138 out dx, al
139 mov dx, 0x03c9 ; DAC Data Register
140 mov rsi, palette
141 add rsi, 18
142 lodsb
143 out dx, al
144 lodsb
145 out dx, al
146 lodsb
147 out dx, al
149 ; Grab data from Pure64's infomap
150 mov rsi, 0x5000
151 lodsq
152 mov [os_LocalAPICAddress], rax
153 lodsq
154 mov [os_IOAPICAddress], rax
156 mov rsi, 0x5012
157 lodsw
158 mov [os_NumCores], ax
160 mov rsi, 0x5020
161 lodsw
162 mov [os_MemAmount], ax ; In MiB's
164 ; Build the OS memory table
165 call init_memory_map
167 ; Initialize all AP's to run our reset code. Skip the BSP
168 xor rax, rax
169 xor rcx, rcx
170 mov rsi, 0x0000000000005700 ; Location in memory of the Pure64 CPU data
172 next_ap:
173 cmp rsi, 0x0000000000005800 ; Enable up to 256 CPU Cores
174 je no_more_aps
175 lodsb ; Load the CPU parameters
176 bt rax, 0 ; Check if the CPU is enabled
177 jnc skip_ap
178 bt rax, 1 ; Test to see if this is the BSP (Do not init!)
179 jc skip_ap
180 mov rax, rcx
181 call os_smp_reset ; Reset the CPU
182 skip_ap:
183 add rcx, 1
184 jmp next_ap
186 no_more_aps:
188 ; Enable specific interrupts
189 in al, 0x21
190 mov al, 11111001b ; Enable Cascade, Keyboard
191 out 0x21, al
192 in al, 0xA1
193 mov al, 11111110b ; Enable RTC
194 out 0xA1, al
196 call os_seed_random ; Seed the RNG
198 ; Reset keyboard and empty the buffer
199 mov al, 0x20 ; Command to read byte of keyboard controller RAM
200 out 0x64, al ; Send command
201 in al, 0x60 ; Grab the keyboard controller command byte
202 or al, 00000001b ; Enable interrupts
203 and al, 11101111b ; Enable keyboard
204 push rax
205 mov al, 0x60 ; Command to write byte of keyboard controller RAM
206 out 0x64, al ; Send command
207 pop rax
208 out 0x60, al ; Send new keyboard controller command byte
212 ; create_gate
213 ; rax = address of handler
214 ; rdi = gate # to configure
215 create_gate:
216 push rdi
217 push rax
219 shl rdi, 4 ; quickly multiply rdi by 16
220 stosw ; store the low word (15..0)
221 shr rax, 16
222 add rdi, 4 ; skip the gate marker
223 stosw ; store the high word (31..16)
224 shr rax, 16
225 stosd ; store the high dword (63..32)
227 pop rax
228 pop rdi
232 init_memory_map: ; Build the OS memory table
233 push rax
234 push rcx
235 push rdi
237 ; Build a fresh memory map for the system
238 mov rdi, os_MemoryMap
239 push rdi
240 xor rcx, rcx
241 mov cx, [os_MemAmount]
242 shr cx, 1 ; Divide actual memory by 2
243 mov al, 1
244 rep stosb
245 pop rdi
246 mov al, 2
247 stosb ; Mark the first 2 MiB as in use (by Kernel and system buffers)
248 stosb ; As well as the second 2 MiB (by loaded application)
249 ; The CLI should take care of the Application memory
251 ; Allocate memory for CPU stacks (2 MiB's for each core)
252 xor rcx, rcx
253 mov cx, [os_NumCores] ; Get the amount of cores in the system
254 call os_mem_allocate ; Allocate a page for each core
255 cmp rcx, 0 ; os_mem_allocate returns 0 on failure
256 je system_failure
257 add rax, 2097152
258 mov [os_StackBase], rax ; Store the Stack base address
260 pop rdi
261 pop rcx
262 pop rax
266 system_failure:
267 mov ax, 0x0016
268 call os_move_cursor
269 mov rsi, memory_message
270 mov bl, 0xF0
271 call os_print_string_with_color
272 system_failure_hang:
274 jmp system_failure_hang
277 ; =============================================================================
278 ; EOF