68bdc55d74979fbb3e445452cd82efc50ea1c7b3
[tpg/acess2.git] / 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 [global start]
61 start:
62         ; Just show we're here
63         mov WORD [0xB8000], 0x0741      ; 'A'
64         
65         ; Set up stack
66         mov esp, Kernel_Stack_Top
67         
68         ; Start Paging
69         mov ecx, gaInitPageDir - KERNEL_BASE
70         mov cr3, ecx
71         
72         mov ecx, cr0
73         or ecx, 0x80010000      ; PG and WP
74         mov cr0, ecx
75         
76         mov WORD [0xB8002], 0x0763      ; 'c'
77         mov WORD [0xB8004], 0x0765      ; 'e'
78         
79         lea ecx, [.higherHalf]
80         jmp ecx
81 .higherHalf:
82         
83         mov WORD [0xB8006], 0x0773      ; 's'
84         mov WORD [0xB8008], 0x0773      ; 's'
85
86         ; Call the kernel
87         push ebx        ; Multiboot Info
88         push eax        ; Multiboot Magic Value
89         mov WORD [0xB800A], 0x0732      ; '2'
90         call kmain
91
92         ; Halt the Machine
93         cli
94 .hlt:
95         hlt
96         jmp .hlt
97
98
99 ; Multiprocessing AP Startup Code (Must be within 0 - 0x10FFF0)
100 ;
101 %if USE_MP
102 [extern gGDT]
103 [extern gGDTPtr]
104 [extern gIDTPtr]
105 [extern gpMP_LocalAPIC]
106 [extern giMP_TimerCount]
107 [extern gaAPIC_to_CPU]
108 [extern gaCPUs]
109 [extern giNumInitingCPUs]
110 [extern MM_NewKStack]
111
112 lGDTPtr:        ; Local GDT Pointer
113         dw      3*8-1
114         dd      gGDT-KERNEL_BASE
115
116 [bits 16]
117 [global APWait]
118 APWait:
119         ;xchg bx, bx
120 .hlt:
121         ;hlt
122         jmp .hlt
123 [extern Proc_Reschedule]
124 [global APStartup]
125 APStartup:
126         ;xchg bx, bx    ; MAGIC BREAK!
127         ; Load initial GDT
128         mov ax, 0xFFFF
129         mov ds, ax
130         lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
131         ; Enable PMode in CR0
132         mov eax, cr0
133         or al, 1
134         mov cr0, eax
135         ; Jump into PMode
136         jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
137 [bits 32]
138 .ProtectedMode:
139         ; Load segment registers
140         mov ax, 0x10
141         mov ss, ax
142         mov ds, ax
143         mov es, ax
144         mov fs, ax
145         mov gs, ax
146         ; Start Paging
147         mov eax, gaInitPageDir - KERNEL_BASE
148         mov cr3, eax
149         mov eax, cr0
150         or eax, 0x80010000      ; PG and WP
151         mov cr0, eax
152         ; Jump to higher half
153         lea eax, [.higherHalf]
154         jmp eax
155 .higherHalf:
156         ; Load True GDT & IDT
157         lgdt [gGDTPtr]
158         lidt [gIDTPtr]
159
160         mov ebp, [gpMP_LocalAPIC]
161         mov ebx, [ebp+0x20]     ; Read ID
162         shr ebx, 24
163         ;xchg bx, bx    ; MAGIC BREAK
164         ; BL is now local APIC ID
165         mov cl, BYTE [gaAPIC_to_CPU+ebx]
166         xor ebx, ebx
167         mov bl, cl
168         ; BL is now the CPU ID
169         mov dr1, ebx    ; Save the CPU number to a debug register
170         ; Mark the CPU as up
171         mov BYTE [gaCPUs+ebx*8+1], 1
172         ; Decrement the remaining CPU count
173         dec DWORD [giNumInitingCPUs]
174         
175         ; Create a stack
176         lea edx, [ebx+1]
177         shl edx, 5+2    ; *32 *4
178         lea esp, [gInitAPStacks+edx]
179         call MM_NewKStack
180         mov esp, eax
181         
182         ; Set TSS
183         lea ecx, [ebx*8+0x30]
184         ltr cx
185         
186         ;xchg bx, bx    ; MAGIC_BREAK
187         ; Enable Local APIC
188         mov DWORD [ebp+0x0F0], 0x000001EF       ; Spurious Interrupt Vector (0xEF)
189         mov ecx, DWORD [giMP_TimerCount]
190         mov DWORD [ebp+0x380], ecx      ; Set Initial Count
191         mov DWORD [ebp+0x320], 0x000200EE       ; Enable timer on IVT#0xEE
192         mov DWORD [ebp+0x330], 0x000100E0       ; ##Enable thermal sensor on IVT#0xE0
193         mov DWORD [ebp+0x340], 0x000100D0       ; ##Enable performance counters on IVT#0xD0
194         mov DWORD [ebp+0x350], 0x000100D1       ; ##Enable LINT0 on IVT#0xD1
195         mov DWORD [ebp+0x360], 0x000100D2       ; ##Enable LINT1 on IVT#0xD2
196         mov DWORD [ebp+0x370], 0x000100E1       ; ##Enable Error on IVT#0xE1
197         mov DWORD [ebp+0x0B0], 0        ; Send an EOI (just in case)
198         
199         ; CPU is now marked as initialised
200
201 .hlt:
202         sti
203         call Proc_Reschedule    
204         hlt
205         jmp .hlt
206 %endif
207
208 [global GetEIP]
209 GetEIP:
210         mov eax, [esp]
211         ret
212
213 ; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args)
214 ; Call a function passing the array as arguments
215 [global CallWithArgArray]
216 CallWithArgArray:
217         push ebp
218         mov ebp, esp
219         mov ecx, [ebp+12]       ; Get NArgs
220         mov edx, [ebp+16]
221
222 .top:
223         mov eax, [edx+ecx*4-4]
224         push eax
225         loop .top
226         
227         mov eax, [ebp+8]
228         call eax
229         lea esp, [ebp]
230         pop ebp
231         ret
232
233 [section .initpd]
234 [global gaInitPageDir]
235 [global gaInitPageTable]
236 align 4096
237 gaInitPageDir:
238         dd      gaInitPageTable-KERNEL_BASE+3   ; 0x000 - Low kernel
239         times 0x300-0x000-1     dd      0
240         dd      gaInitPageTable-KERNEL_BASE+3   ; 0xC00 - High kernel
241         times 0x3F0-0x300-1     dd      0
242         dd      gaInitPageDir-KERNEL_BASE+3     ; 0xFC0 - Fractal
243         times 0x400-0x3F0-1     dd      0
244 align 4096
245 gaInitPageTable:
246         %assign i 0
247         %rep 1024
248         dd      i*0x1000+3
249         %assign i i+1
250         %endrep
251 [global Kernel_Stack_Top]
252 ALIGN 4096
253         times 1024      dd      0
254 Kernel_Stack_Top:
255 gInitAPStacks:
256         times 32*MAX_CPUS       dd      0
257
258 ; vim: ft=nasm ts=8     

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