Adding support for the Local APIC Timer (requires some hacks)
[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
8 [extern __load_addr]
9 [extern __bss_start]
10 [extern gKernelEnd]
11 [section .multiboot]
12 mboot:
13         ; Multiboot macros to make a few lines later more readable
14         MULTIBOOT_PAGE_ALIGN    equ 1<<0
15         MULTIBOOT_MEMORY_INFO   equ 1<<1
16         MULTIBOOT_HEADER_MAGIC  equ 0x1BADB002
17         MULTIBOOT_HEADER_FLAGS  equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
18         MULTIBOOT_CHECKSUM      equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
19         
20         ; This is the GRUB Multiboot header. A boot signature
21         dd MULTIBOOT_HEADER_MAGIC
22         dd MULTIBOOT_HEADER_FLAGS
23         dd MULTIBOOT_CHECKSUM
24         dd mboot - KERNEL_BASE  ;Location of Multiboot Header
25         
26 ; Multiboot 2 Header
27 ;mboot2:
28 ;       MULTIBOOT2_HEADER_MAGIC equ 0xE85250D6
29 ;       MULTIBOOT2_HEADER_ARCH  equ 0
30 ;       MULTIBOOT2_HEADER_LENGTH        equ (mboot2_end-mboot2)
31 ;       MULTIBOOT2_CHECKSUM     equ -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH + MULTIBOOT2_HEADER_LENGTH)
32 ;       
33 ;       dd MULTIBOOT2_HEADER_MAGIC
34 ;       dd MULTIBOOT2_HEADER_ARCH
35 ;       dd MULTIBOOT2_HEADER_LENGTH
36 ;       dd MULTIBOOT2_CHECKSUM
37 ;       ; MBoot2 Address Header
38 ;       dw      2, 0
39 ;       dd      8 + 16
40 ;       dd      mboot2  ; Location of Multiboot Header
41 ;       dd      __load_addr - KERNEL_BASE       ; Kernel Load base
42 ;       dd      __bss_start - KERNEL_BASE       ; Kernel Data End
43 ;       dd      gKernelEnd - KERNEL_BASE        ; Kernel BSS End
44 ;       ; MBoot2 Entry Point Tag
45 ;       dw      3, 0
46 ;       dd      8 + 4
47 ;       dd      start - KERNEL_BASE
48 ;       ; MBoot2 Module Alignment Tag
49 ;       dw      6, 0
50 ;       dd      12      ; ???
51 ;       dd      0       ; Search me, seems it wants padding
52 ;       ; Terminator
53 ;       dw      0, 0
54 ;       dd      8
55 ;mboot2_end:
56         
57 [section .text]
58 [extern kmain]
59 [global start]
60 start:
61         
62         ; Set up stack
63         mov esp, Kernel_Stack_Top
64         
65         ; Start Paging
66         mov ecx, gaInitPageDir - KERNEL_BASE
67         mov cr3, ecx
68         
69         mov ecx, cr0
70         or      ecx, 0x80010000 ; PG and WP
71         mov cr0, ecx
72         
73         lea ecx, [.higherHalf]
74         jmp ecx
75 .higherHalf:
76
77         ; Call the kernel
78         push ebx        ; Multiboot Info
79         push eax        ; Multiboot Magic Value
80         call kmain
81
82         ; Halt the Machine
83         cli
84 .hlt:
85         hlt
86         jmp .hlt
87
88
89 ; Multiprocessing AP Startup Code (Must be within 0x10FFF0)
90 ;
91 %if USE_MP
92 [extern gGDT]
93 [extern gGDTPtr]
94 [extern gIDTPtr]
95 [extern gpMP_LocalAPIC]
96 [extern giMP_TimerCount]
97 [extern gaAPIC_to_CPU]
98 [extern gaCPUs]
99 [extern giNumInitingCPUs]
100 lGDTPtr:        ; Local GDT Pointer
101         dw      3*8-1
102         dd      gGDT-KERNEL_BASE
103
104 [bits 16]
105 [global APWait]
106 APWait:
107         ;xchg bx, bx
108 .hlt:
109         ;hlt
110         jmp .hlt
111 [global APStartup]
112 APStartup:
113         ;xchg bx, bx    ; MAGIC BREAK!
114         mov ax, 0xFFFF
115         mov ds, ax
116         lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
117         mov eax, cr0
118         or      al, 1
119         mov     cr0, eax
120         jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
121 [bits 32]
122 .ProtectedMode:
123         ; Load segment registers
124         mov ax, 0x10
125         mov ss, ax
126         mov ds, ax
127         mov es, ax
128         mov fs, ax
129         mov gs, ax
130         ; Start Paging
131         mov eax, gaInitPageDir - KERNEL_BASE
132         mov cr3, eax
133         mov eax, cr0
134         or      eax, 0x80010000 ; PG and WP
135         mov cr0, eax
136         ; Jump to higher half
137         lea eax, [.higherHalf]
138         jmp eax
139 .higherHalf:
140         ; Load True GDT & IDT
141         lgdt [gGDTPtr]
142         lidt [gIDTPtr]
143
144         mov eax, [gpMP_LocalAPIC]
145         mov ecx, [eax+0x20]     ; Read ID
146         shr ecx, 24
147         ;xchg bx, bx    ; MAGIC BREAK
148         ; CL is now local APIC ID
149         mov cl, BYTE [gaAPIC_to_CPU+ecx]
150         ; CL is now the CPU ID
151         mov BYTE [gaCPUs+ecx*8+1], 1
152         ; Decrement the remaining CPU count
153         dec DWORD [giNumInitingCPUs]
154         ; Set TSS
155         shl cx, 3
156         add cx, 0x30
157         ltr cx
158         ; Enable Local APIC Timer
159         mov ecx, [giMP_TimerCount]
160         mov [eax+0x380], ecx    ; Set Initial Count
161         mov DWORD [eax+0x320], 0x000200EF       ; Enable the timer on IVT#0xEF
162         
163         ; CPU is now marked as initialised
164         sti
165         ;xchg bx, bx    ; MAGIC BREAK
166 .hlt:
167         hlt
168         jmp .hlt
169 %endif
170
171 [global GetEIP]
172 GetEIP:
173         mov eax, [esp]
174         ret
175
176 ; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args)
177 ; Call a function passing the array as arguments
178 [global CallWithArgArray]
179 CallWithArgArray:
180         push ebp
181         mov ebp, esp
182         mov ecx, [ebp+12]       ; Get NArgs
183         mov edx, [ebp+16]
184
185 .top:
186         mov eax, [edx+ecx*4-4]
187         push eax
188         loop .top
189         
190         mov eax, [ebp+8]
191         call eax
192         lea esp, [ebp]
193         pop ebp
194         ret
195
196 [section .initpd]
197 [global gaInitPageDir]
198 [global gaInitPageTable]
199 align 0x1000
200 gaInitPageDir:
201         dd      gaInitPageTable-KERNEL_BASE+3   ; 0x00
202         times 1024-256-1        dd      0
203         dd      gaInitPageTable-KERNEL_BASE+3   ; 0xC0
204         times 256-1     dd      0
205 align 0x1000
206 gaInitPageTable:
207         %assign i 0
208         %rep 1024
209         dd      i*0x1000+3
210         %assign i i+1
211         %endrep
212 [global Kernel_Stack_Top]
213 ALIGN 0x1000
214         times 1024      dd      0
215 Kernel_Stack_Top:
216         

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