* remove "\r" nonsense
[mascara-docs.git] / amd64 / bareMetalOS-0.5.3 / os / init_64.asm
blob9b44948de78bbf95e9029a93d96220a344bc43a8
1 ; =============================================================================
2 ; BareMetal -- a 64-bit OS written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2012 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 (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 (Network IRQ handler is configured in init_net)
59 mov rdi, 0x21
60 mov rax, keyboard
61 call create_gate
62 mov rdi, 0x28
63 mov rax, rtc
64 call create_gate
65 mov rdi, 0x80
66 mov rax, ap_wakeup
67 call create_gate
68 mov rdi, 0x81
69 mov rax, ap_reset
70 call create_gate
72 ; Set up RTC
73 ; Rate defines how often the RTC interrupt is triggered
74 ; Rate is a 4-bit value from 1 to 15. 1 = 32768Hz, 6 = 1024Hz, 15 = 2Hz
75 ; RTC value must stay at 32.768KHz or the computer will not keep the correct time
76 ; http://wiki.osdev.org/RTC
77 rtc_poll:
78 mov al, 0x0A ; Status Register A
79 out 0x70, al
80 in al, 0x71
81 test al, 0x80 ; Is there an update in process?
82 jne rtc_poll ; If so then keep polling
83 mov al, 0x0A ; Status Register A
84 out 0x70, al
85 mov al, 00101101b ; RTC@32.768KHz (0010), Rate@8Hz (1101)
86 out 0x71, al
87 mov al, 0x0C ; Acknowledge the RTC
88 out 0x70, al
89 in al, 0x71
91 ; Disable blink
92 mov dx, 0x3DA
93 in al, dx
94 mov dx, 0x3C0
95 mov al, 0x30
96 out dx, al
97 add dx, 1
98 in al, dx
99 and al, 0xF7
100 sub dx, 1
101 out dx, al
103 ; Set color palette
104 xor eax, eax
105 mov dx, 0x03C8 ; DAC Address Write Mode Register
106 out dx, al
107 mov dx, 0x03C9 ; DAC Data Register
108 mov rbx, 16 ; 16 lines
109 nextline:
110 mov rcx, 16 ; 16 colors
111 mov rsi, palette
112 nexttritone:
113 lodsb
114 out dx, al
115 lodsb
116 out dx, al
117 lodsb
118 out dx, al
119 dec rcx
120 cmp rcx, 0
121 jne nexttritone
122 dec rbx
123 cmp rbx, 0
124 jne nextline ; Set the next 16 colors to the same
125 mov eax, 0x14 ; Fix for color 6
126 mov dx, 0x03c8 ; DAC Address Write Mode Register
127 out dx, al
128 mov dx, 0x03c9 ; DAC Data Register
129 mov rsi, palette
130 add rsi, 18
131 lodsb
132 out dx, al
133 lodsb
134 out dx, al
135 lodsb
136 out dx, al
138 xor eax, eax
139 xor ebx, ebx
140 xor ecx, ecx
141 ; Grab data from Pure64's infomap
142 mov rsi, 0x5008
143 lodsd ; Load the BSP ID
144 mov ebx, eax ; Save it to EBX
145 mov rsi, 0x5012
146 lodsw ; Load the number of activated cores
147 mov cx, ax ; Save it to CX
148 mov rsi, 0x5060
149 lodsq
150 mov [os_LocalAPICAddress], rax
151 lodsq
152 mov [os_IOAPICAddress], rax
154 mov rsi, 0x5012
155 lodsw
156 mov [os_NumCores], ax
158 mov rsi, 0x5020
159 lodsw
160 mov [os_MemAmount], ax ; In MiB's
162 ; Build the OS memory table
163 call init_memory_map
165 ; Initialize all AP's to run our reset code. Skip the BSP
166 xor rax, rax
167 mov rsi, 0x0000000000005100 ; Location in memory of the Pure64 CPU data
168 next_ap:
169 cmp cx, 0
170 je no_more_aps
171 lodsb ; Load the CPU APIC ID
172 cmp al, bl
173 je skip_ap
174 call os_smp_reset ; Reset the CPU
175 skip_ap:
176 sub cx, 1
177 jmp next_ap
179 no_more_aps:
181 ; Enable specific interrupts
182 mov rcx, 1 ; Enable Keyboard
183 mov rax, 0x21
184 call ioapic_entry_write
185 mov rcx, 8 ; Enable RTC
186 mov rax, 0x0100000000000928 ; Lowest priority
187 ; mov rax, 0x28 ; Handled by APIC ID 0 (BSP)
188 call ioapic_entry_write
190 call os_seed_random ; Seed the RNG
194 ; create_gate
195 ; rax = address of handler
196 ; rdi = gate # to configure
197 create_gate:
198 push rdi
199 push rax
201 shl rdi, 4 ; quickly multiply rdi by 16
202 stosw ; store the low word (15..0)
203 shr rax, 16
204 add rdi, 4 ; skip the gate marker
205 stosw ; store the high word (31..16)
206 shr rax, 16
207 stosd ; store the high dword (63..32)
209 pop rax
210 pop rdi
214 init_memory_map: ; Build the OS memory table
215 push rax
216 push rcx
217 push rdi
219 ; Build a fresh memory map for the system
220 mov rdi, os_MemoryMap
221 push rdi
222 xor rcx, rcx
223 mov cx, [os_MemAmount]
224 shr cx, 1 ; Divide actual memory by 2
225 mov al, 1
226 rep stosb
227 pop rdi
228 mov al, 2
229 stosb ; Mark the first 2 MiB as in use (by Kernel and system buffers)
230 stosb ; As well as the second 2 MiB (by loaded application)
231 ; The CLI should take care of the Application memory
233 ; Allocate memory for CPU stacks (2 MiB's for each core)
234 xor rcx, rcx
235 mov cx, [os_NumCores] ; Get the amount of cores in the system
236 call os_mem_allocate ; Allocate a page for each core
237 cmp rcx, 0 ; os_mem_allocate returns 0 on failure
238 je system_failure
239 add rax, 2097152
240 mov [os_StackBase], rax ; Store the Stack base address
242 pop rdi
243 pop rcx
244 pop rax
248 system_failure:
249 mov ax, 0x0016
250 call os_move_cursor
251 mov rsi, memory_message
252 mov bl, 0xF0
253 call os_print_string_with_color
254 system_failure_hang:
256 jmp system_failure_hang
259 ; -----------------------------------------------------------------------------
260 ; ioapic_reg_write -- Write to an I/O APIC register
261 ; IN: EAX = Value to write
262 ; ECX = Index of register
263 ; OUT: Nothing. All registers preserved
264 ioapic_reg_write:
265 push rsi
266 mov rsi, [os_IOAPICAddress]
267 mov dword [rsi], ecx ; Write index to register selector
268 mov dword [rsi + 0x10], eax ; Write data to window register
269 pop rsi
271 ; -----------------------------------------------------------------------------
274 ; -----------------------------------------------------------------------------
275 ; ioapic_entry_write -- Write to an I/O APIC entry in the redirection table
276 ; IN: RAX = Data to write to entry
277 ; ECX = Index of the entry
278 ; OUT: Nothing. All registers preserved
279 ioapic_entry_write:
280 push rax
281 push rcx
283 ; Calculate index for lower DWORD
284 shl rcx, 1 ; Quick multiply by 2
285 add rcx, 0x10 ; IO Redirection tables start at 0x10
287 ; Write lower DWORD
288 call ioapic_reg_write
290 ; Write higher DWORD
291 shr rax, 32
292 add rcx, 1
293 call ioapic_reg_write
295 pop rcx
296 pop rax
298 ; -----------------------------------------------------------------------------
301 ; =============================================================================
302 ; EOF