18b9f5f82271dd20d921f59b96854578d6f277ab
[tpg/acess2.git] / start.asm
1 ; AcessOS Microkernel Version
2 ; Start.asm
3
4 [bits 32]
5
6 KERNEL_BASE     equ 0xC0000000
7 %define MAX_CPUS        16
8
9 [extern __load_addr]
10 [extern __bss_start]
11 [extern gKernelEnd]
12 [section .multiboot]
13 mboot:
14         ; Multiboot macros to make a few lines later more readable
15         MULTIBOOT_PAGE_ALIGN    equ 1<<0
16         MULTIBOOT_MEMORY_INFO   equ 1<<1
17         MULTIBOOT_REQVIDMODE    equ 1<<2
18         MULTIBOOT_HEADER_MAGIC  equ 0x1BADB002
19         MULTIBOOT_HEADER_FLAGS  equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_REQVIDMODE
20         MULTIBOOT_CHECKSUM      equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
21         
22         ; This is the GRUB Multiboot header. A boot signature
23         dd MULTIBOOT_HEADER_MAGIC
24         dd MULTIBOOT_HEADER_FLAGS
25         dd MULTIBOOT_CHECKSUM
26         
27         dd mboot; - KERNEL_BASE ;Location of Multiboot Header
28         dd 0    ; load_addr
29         dd 0    ; load_end_addr
30         dd 0    ; bss_end_addr
31         dd 0    ; entry_addr
32         
33         dd 0    ; Mode type (0: LFB)
34         dd 0    ; Width (no preference)
35         dd 0    ; Height (no preference)
36         dd 32   ; Depth (32-bit preferred)
37         
38 ; Multiboot 2 Header
39 ;mboot2:
40 ;       MULTIBOOT2_HEADER_MAGIC equ 0xE85250D6
41 ;       MULTIBOOT2_HEADER_ARCH  equ 0
42 ;       MULTIBOOT2_HEADER_LENGTH        equ (mboot2_end-mboot2)
43 ;       MULTIBOOT2_CHECKSUM     equ -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH + MULTIBOOT2_HEADER_LENGTH)
44 ;       
45 ;       dd MULTIBOOT2_HEADER_MAGIC
46 ;       dd MULTIBOOT2_HEADER_ARCH
47 ;       dd MULTIBOOT2_HEADER_LENGTH
48 ;       dd MULTIBOOT2_CHECKSUM
49 ;       ; MBoot2 Address Header
50 ;       dw      2, 0
51 ;       dd      8 + 16
52 ;       dd      mboot2  ; Location of Multiboot Header
53 ;       dd      __load_addr - KERNEL_BASE       ; Kernel Load base
54 ;       dd      __bss_start - KERNEL_BASE       ; Kernel Data End
55 ;       dd      gKernelEnd - KERNEL_BASE        ; Kernel BSS End
56 ;       ; MBoot2 Entry Point Tag
57 ;       dw      3, 0
58 ;       dd      8 + 4
59 ;       dd      start - KERNEL_BASE
60 ;       ; MBoot2 Module Alignment Tag
61 ;       dw      6, 0
62 ;       dd      12      ; ???
63 ;       dd      0       ; Search me, seems it wants padding
64 ;       ; Terminator
65 ;       dw      0, 0
66 ;       dd      8
67 ;mboot2_end:
68         
69 [section .inittext]
70 [extern kmain]
71 [extern Desctab_Install]
72 [global start]
73 start:
74         ; Just show we're here
75         mov WORD [0xB8000], 0x0741      ; 'A'
76         
77         ; Set up stack
78         mov esp, Kernel_Stack_Top
79         
80         ; Start Paging
81         mov ecx, gaInitPageDir - KERNEL_BASE
82         mov cr3, ecx
83         mov ecx, cr0
84         or ecx, 0x80010000      ; PG and WP
85         mov cr0, ecx
86         
87         mov WORD [0xB8002], 0x0763      ; 'c'
88         
89         ; Set GDT
90         lgdt [gGDTPtr]
91         mov cx, 0x10    ; PL0 Data
92         mov ss, cx
93         mov ds, cx
94         mov es, cx
95         mov gs, cx
96         mov fs, cx
97         mov WORD [0xB8004], 0x0765      ; 'e'
98         jmp 0x08:.higher_half
99 .higher_half:
100         
101         mov WORD [0xB8006], 0x0773      ; 's'
102         
103         push ebx        ; Multiboot Info
104         push eax        ; Multiboot Magic Value
105         ; NOTE: These are actually for kmain
106         
107         call Desctab_Install
108         mov WORD [0xB8008], 0x0773      ; 's'
109
110         ; Call the kernel
111         mov WORD [0xB800A], 0x0732      ; '2'
112         call kmain
113
114         ; Halt the Machine
115         cli
116 .hlt:
117         hlt
118         jmp .hlt
119
120
121 ; Multiprocessing AP Startup Code (Must be within 0 - 0x10FFF0)
122 ;
123 %if USE_MP
124 [extern gIDTPtr]
125 [extern gpMP_LocalAPIC]
126 [extern giMP_TimerCount]
127 [extern gaAPIC_to_CPU]
128 [extern gaCPUs]
129 [extern giNumInitingCPUs]
130 [extern MM_NewKStack]
131 [extern Proc_InitialiseSSE]
132
133 lGDTPtr:        ; Local GDT Pointer
134         dw      3*8-1
135         dd      gGDT-KERNEL_BASE
136
137 [bits 16]
138 [global APWait]
139 APWait:
140         ;xchg bx, bx
141 .hlt:
142         ;hlt
143         jmp .hlt
144 [extern Proc_Reschedule]
145 [global APStartup]
146 APStartup:
147         ;xchg bx, bx    ; MAGIC BREAK!
148         ; Load initial GDT
149         mov ax, 0xFFFF
150         mov ds, ax
151         lgdt [DWORD ds:lGDTPtr-0xFFFF0]
152         ; Enable PMode in CR0
153         mov eax, cr0
154         or al, 1
155         mov cr0, eax
156         ; Jump into PMode
157         jmp 08h:DWORD .ProtectedMode
158 [bits 32]
159 .ProtectedMode:
160         ; Load segment registers
161         mov ax, 0x10
162         mov ss, ax
163         mov ds, ax
164         mov es, ax
165         mov fs, ax
166         mov gs, ax
167         ; Start Paging
168         mov eax, gaInitPageDir - KERNEL_BASE
169         mov cr3, eax
170         mov eax, cr0
171         or eax, 0x80010000      ; PG and WP
172         mov cr0, eax
173         ; Jump to higher half
174         lea eax, [.higherHalf]
175         jmp eax
176 .higherHalf:
177         ; Load True GDT & IDT
178         lgdt [gGDTPtr]
179         lidt [gIDTPtr]
180
181         mov ebp, [gpMP_LocalAPIC]
182         mov ebx, [ebp+0x20]     ; Read ID
183         shr ebx, 24
184         ;xchg bx, bx    ; MAGIC BREAK
185         ; BL is now local APIC ID
186         mov cl, BYTE [gaAPIC_to_CPU+ebx]
187         xor ebx, ebx
188         mov bl, cl
189         ; BL is now the CPU ID
190         mov dr1, ebx    ; Save the CPU number to a debug register
191         ; Mark the CPU as up
192         mov BYTE [gaCPUs+ebx*8+1], 1
193         ; Decrement the remaining CPU count
194         dec DWORD [giNumInitingCPUs]
195         
196         ; Create a stack
197         lea edx, [ebx+1]
198         shl edx, 5+2    ; *32 *4
199         lea esp, [gInitAPStacks+edx]
200         call MM_NewKStack
201         mov esp, eax
202         
203         ; Set TSS
204         lea ecx, [ebx*8+0x30]
205         ltr cx
206         
207         ;xchg bx, bx    ; MAGIC_BREAK
208         ; Enable Local APIC
209         mov DWORD [ebp+0x0F0], 0x000001EF       ; Spurious Interrupt Vector (0xEF)
210         mov ecx, DWORD [giMP_TimerCount]
211         mov DWORD [ebp+0x380], ecx      ; Set Initial Count
212         mov DWORD [ebp+0x320], 0x000200EE       ; Enable timer on IVT#0xEE
213         mov DWORD [ebp+0x330], 0x000100E0       ; ##Enable thermal sensor on IVT#0xE0
214         mov DWORD [ebp+0x340], 0x000100D0       ; ##Enable performance counters on IVT#0xD0
215         mov DWORD [ebp+0x350], 0x000100D1       ; ##Enable LINT0 on IVT#0xD1
216         mov DWORD [ebp+0x360], 0x000100D2       ; ##Enable LINT1 on IVT#0xD2
217         mov DWORD [ebp+0x370], 0x000100E1       ; ##Enable Error on IVT#0xE1
218         mov DWORD [ebp+0x0B0], 0        ; Send an EOI (just in case)
219
220         ; Initialise SSE support
221         call Proc_InitialiseSSE
222         
223         ; CPU is now marked as initialised
224
225 .hlt:
226         sti
227         call Proc_Reschedule    
228         hlt
229         jmp .hlt
230 %endif
231
232 ;
233 ;
234 ;
235 [section .text]
236 [global GetEIP]
237 GetEIP:
238         mov eax, [esp]
239         ret
240
241 ; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args)
242 ; Call a function passing the array as arguments
243 [global CallWithArgArray]
244 CallWithArgArray:
245         push ebp
246         mov ebp, esp
247         mov ecx, [ebp+12]       ; Get NArgs
248         mov edx, [ebp+16]
249
250 .top:
251         mov eax, [edx+ecx*4-4]
252         push eax
253         loop .top
254         
255         mov eax, [ebp+8]
256         call eax
257         lea esp, [ebp]
258         pop ebp
259         ret
260
261 [section .data]
262 ; GDT
263 GDT_SIZE        equ     (1+2*2+1+MAX_CPUS)*8
264 [global gGDT]
265 gGDT:
266         ; PL0 - Kernel
267         ; PL3 - User
268         dd 0x00000000, 0x00000000       ; 00 NULL Entry
269         dd 0x0000FFFF, 0x00CF9A00       ; 08 PL0 Code
270         dd 0x0000FFFF, 0x00CF9200       ; 10 PL0 Data
271         dd 0x0000FFFF, 0x00CFFA00       ; 18 PL3 Code
272         dd 0x0000FFFF, 0x00CFF200       ; 20 PL3 Data
273         dd 26*4-1, 0x00408900   ; 28 Double Fault TSS
274         times MAX_CPUS  dd 26*4-1, 0x00408900   ; 30+ TSSes
275 [global gGDTPtr]
276 gGDTPtr:
277         dw      GDT_SIZE-1
278         dd      gGDT
279
280 [section .initpd]
281 [global gaInitPageDir]
282 [global gaInitPageTable]
283 align 4096
284 gaInitPageDir:
285         dd      gaInitPageTable-KERNEL_BASE+3   ; 0x000 - Low kernel
286         times 0x300-0x000-1     dd      0
287         dd      gaInitPageTable-KERNEL_BASE+3   ; 0xC00 - High kernel
288         times 0x3F0-0x300-1     dd      0
289         dd      gaInitPageDir-KERNEL_BASE+3     ; 0xFC0 - Fractal
290         times 0x400-0x3F0-1     dd      0
291 align 4096
292 gaInitPageTable:
293         %assign i 0
294         %rep 1024
295         dd      i*0x1000+3
296         %assign i i+1
297         %endrep
298 [global Kernel_Stack_Top]
299 ALIGN 4096
300         times 1024      dd      0
301 Kernel_Stack_Top:
302 gInitAPStacks:
303         times 32*MAX_CPUS       dd      0
304
305 ; vim: ft=nasm ts=8     

UCC git Repository :: git.ucc.asn.au