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

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