- ; Halt the Machine\r
- cli\r
-.hlt:\r
- hlt\r
- jmp .hlt\r
-\r
-; \r
-; Multiprocessing AP Startup Code (Must be within 0x10FFF0)\r
-;\r
-%if USE_MP\r
-[extern gGDT]\r
-[extern gGDTPtr]\r
-[extern gIDTPtr]\r
-[extern gpMP_LocalAPIC]\r
-[extern gaAPIC_to_CPU]\r
-[extern gaCPUs]\r
-[extern giNumInitingCPUs]\r
-lGDTPtr: ; Local GDT Pointer\r
- dw 2*8-1\r
- dd gGDT-KERNEL_BASE\r
-\r
-[bits 16]\r
-[global APStartup]\r
-APStartup:\r
- xchg bx, bx ; MAGIC BREAK!\r
- mov ax, 0xFFFF\r
- mov ds, ax\r
- lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]\r
- mov eax, cr0\r
- or al, 1\r
- mov cr0, eax\r
- jmp 08h:DWORD .ProtectedMode-KERNEL_BASE\r
-[bits 32]\r
-.ProtectedMode:\r
- ; Start Paging\r
- mov eax, gaInitPageDir - KERNEL_BASE\r
- mov cr3, eax\r
- mov eax, cr0\r
- or eax, 0x80010000 ; PG and WP\r
- mov cr0, eax\r
- ; Jump to higher half\r
- lea eax, [.higherHalf]\r
- jmp eax\r
-.higherHalf:\r
- ; Load True GDT & IDT\r
- lgdt [gGDTPtr]\r
- lidt [gIDTPtr]\r
-\r
- mov eax, [gpMP_LocalAPIC]\r
- mov DWORD [eax], 0\r
- xor ecx, ecx\r
- mov cl, BYTE [eax+0x10]\r
- ; CL is now local APIC ID\r
- mov cl, BYTE [gaAPIC_to_CPU+ecx]\r
- ; CL is now the CPU ID\r
- mov BYTE [gaCPUs+ecx*8+1], 1\r
- ; Decrement the remaining CPU count\r
- dec DWORD [giNumInitingCPUs]\r
- ; CPU is now marked as initialised\r
- sti\r
-.hlt:\r
- hlt\r
- jmp .hlt\r
-%endif\r
-\r
-[global GetEIP]\r
-GetEIP:\r
- mov eax, [esp]\r
- ret\r
-\r
-[extern Proc_Clone]\r
-[extern Threads_Exit]\r
-[global SpawnTask]\r
-SpawnTask:\r
- ; Call Proc_Clone with Flags=0\r
- xor eax, eax\r
+ ; Halt the Machine
+ cli
+.hlt:
+ hlt
+ jmp .hlt
+
+;
+; Multiprocessing AP Startup Code (Must be within 0 - 0x10FFF0)
+;
+%if USE_MP
+[extern gGDT]
+[extern gGDTPtr]
+[extern gIDTPtr]
+[extern gpMP_LocalAPIC]
+[extern giMP_TimerCount]
+[extern gaAPIC_to_CPU]
+[extern gaCPUs]
+[extern giNumInitingCPUs]
+[extern MM_NewKStack]
+
+lGDTPtr: ; Local GDT Pointer
+ dw 3*8-1
+ dd gGDT-KERNEL_BASE
+
+[bits 16]
+[global APWait]
+APWait:
+ ;xchg bx, bx
+.hlt:
+ ;hlt
+ jmp .hlt
+[global APStartup]
+APStartup:
+ ;xchg bx, bx ; MAGIC BREAK!
+ ; Load initial GDT
+ mov ax, 0xFFFF
+ mov ds, ax
+ lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
+ ; Enable PMode in CR0
+ mov eax, cr0
+ or al, 1
+ mov cr0, eax
+ ; Jump into PMode
+ jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
+[bits 32]
+.ProtectedMode:
+ ; Load segment registers
+ mov ax, 0x10
+ mov ss, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ ; Start Paging
+ mov eax, gaInitPageDir - KERNEL_BASE
+ mov cr3, eax
+ mov eax, cr0
+ or eax, 0x80010000 ; PG and WP
+ mov cr0, eax
+ ; Jump to higher half
+ lea eax, [.higherHalf]
+ jmp eax
+.higherHalf:
+ ; Load True GDT & IDT
+ lgdt [gGDTPtr]
+ lidt [gIDTPtr]
+
+ mov ebp, [gpMP_LocalAPIC]
+ mov ebx, [ebp+0x20] ; Read ID
+ shr ebx, 24
+ ;xchg bx, bx ; MAGIC BREAK
+ ; CL is now local APIC ID
+ mov cl, BYTE [gaAPIC_to_CPU+ebx]
+ xor ebx, ebx
+ mov bl, cl
+ ; BL is now the CPU ID
+ mov BYTE [gaCPUs+ebx*8+1], 1
+ ; Decrement the remaining CPU count
+ dec DWORD [giNumInitingCPUs]
+
+ ; Create a stack
+ lea edx, [ebx+1]
+ shl edx, 5+2 ; *32 *4
+ lea esp, [gInitAPStacks+edx]
+ call MM_NewKStack
+ mov esp, eax
+
+ ; Set TSS
+ lea ecx, [ebx*8+0x30]
+ ltr cx
+ ; Save the CPU number to a debug register
+ mov dr1, ebx
+
+ ;xchg bx, bx ; MAGIC_BREAK
+ ; Enable Local APIC
+ mov DWORD [ebp+0x0F0], 0x000001EF ; Spurious Interrupt Vector (0xEF)
+ mov ecx, DWORD [giMP_TimerCount]
+ mov DWORD [ebp+0x380], ecx ; Set Initial Count
+ mov DWORD [ebp+0x320], 0x000200EE ; Enable timer on IVT#0xEE
+ mov DWORD [ebp+0x330], 0x000100E0 ; ##Enable thermal sensor on IVT#0xE0
+ mov DWORD [ebp+0x340], 0x000100D0 ; ##Enable performance counters on IVT#0xD0
+ mov DWORD [ebp+0x350], 0x000100D1 ; ##Enable LINT0 on IVT#0xD1
+ mov DWORD [ebp+0x360], 0x000100D2 ; ##Enable LINT1 on IVT#0xD2
+ mov DWORD [ebp+0x370], 0x000100E1 ; ##Enable Error on IVT#0xE1
+ mov DWORD [ebp+0x0B0], 0 ; Send an EOI (just in case)
+
+ ; CPU is now marked as initialised
+ sti
+ ;xchg bx, bx ; MAGIC BREAK
+.hlt:
+ hlt
+ jmp .hlt
+%endif
+
+[global GetEIP]
+GetEIP:
+ mov eax, [esp]
+ ret
+
+; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args)
+; Call a function passing the array as arguments
+[global CallWithArgArray]
+CallWithArgArray:
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+12] ; Get NArgs
+ mov edx, [ebp+16]
+
+.top:
+ mov eax, [edx+ecx*4-4]