bcb0f586fefe241eb643482ff7bf124c60acb84d
[tpg/acess2.git] / Kernel / arch / x86 / proc.asm
1 ; AcessOS Microkernel Version
2 ; Start.asm
3
4 [bits 32]
5
6 KERNEL_BASE     equ 0xC0000000
7
8 KSTACK_USERSTATE_SIZE   equ     (4+8+1+5)*4     ; SRegs, GPRegs, CPU, IRET
9
10 [section .text]
11 [extern giMP_TimerCount]
12 [extern gpMP_LocalAPIC]
13 [extern Isr240]
14 [global SetAPICTimerCount]
15 SetAPICTimerCount:
16         pusha
17         push ds
18         push es
19         push fs
20         push gs
21         
22         mov ax, 0x10
23         mov ds, ax
24         mov es, ax
25         mov fs, ax
26         mov gs, ax
27         
28         mov eax, [gpMP_LocalAPIC]
29         mov ecx, [eax+0x320]
30         test ecx, 0x0001000
31         jz .setTime
32         mov DWORD [eax+0x380], 0xFFFFFFFF       ; Set Initial Count
33         mov DWORD [eax+0x320], 0x000000F0       ; Enable the timer on IVT#0xEF (One Shot)
34         jmp .ret
35
36 .setTime:       
37         ; Get Timer Count
38         mov ecx, 0xFFFFFFFF
39         sub ecx, [eax+0x390]
40         mov DWORD [giMP_TimerCount], ecx
41         ; Disable APIC Timer
42         mov DWORD [eax+0x320], 0x00010000
43
44         ; Update Timer IRQ to the IRQ code
45         mov eax, SchedulerBase
46         sub eax, Isr240+5+5+1
47         mov DWORD [Isr240+5+5+1], eax
48
49 .ret:
50         mov dx, 0x20
51         mov al, 0x20
52         out dx, al              ; ACK IRQ
53         popa
54         add esp, 4      ; CPU ID
55         ; No Error code / int num
56         iret
57
58 ; --------------
59 ; Task Scheduler
60 ; --------------
61 [extern Proc_Scheduler]
62 [global SchedulerBase]
63 SchedulerBase:
64         pusha
65         push ds
66         push es
67         push fs
68         push gs
69         
70         mov ax, 0x10
71         mov ds, ax
72         mov es, ax
73         mov fs, ax
74         mov gs, ax
75         
76         call GetCPUNum
77         push eax        ; Push as argument
78         
79         call Proc_Scheduler
80         
81         add esp, 4      ; Remove Argument
82         
83         pop gs
84         pop fs
85         pop es
86         pop ds
87
88         mov dx, 0x20
89         mov al, 0x20
90         out dx, al              ; ACK IRQ
91         popa
92         add esp, 4      ; CPU ID
93         ; No Error code / int num
94         iret
95
96 [extern Proc_Clone]
97 [extern Threads_Exit]
98 [global SpawnTask]
99 SpawnTask:
100         ; Call Proc_Clone with Flags=0
101         xor eax, eax
102         push eax
103         push eax
104         call Proc_Clone
105         add esp, 8      ; Remove arguments from stack
106         
107         test eax, eax
108         jnz .parent
109         
110         ; In child, so now set up stack frame
111         mov ebx, [esp+4]        ; Child Function
112         mov edx, [esp+8]        ; Argument
113         ; Child
114         push edx        ; Argument
115         call ebx        ; Function
116         push eax        ; Exit Code
117         push   0        ; Kill this thread
118         call Threads_Exit       ; Kill Thread
119         
120 .parent:
121         ret
122
123 ;
124 ; Calls a user fault handler
125 ;
126 [global Proc_ReturnToUser]
127 [extern Proc_GetCurThread]
128 Proc_ReturnToUser:
129         ; EBP is the handler to use
130         
131         call Proc_GetCurThread
132         
133         ; EAX is the current thread
134         mov ebx, eax
135         mov eax, [ebx+40]       ; Get Kernel Stack
136         sub eax, KSTACK_USERSTATE_SIZE
137         
138         ;
139         ; NOTE: This can cause corruption if the signal happens while the user
140         ;       has called a kernel operation.
141         ; Good thing this can only be called on a user fault.
142         ;
143         
144         ; Validate user ESP
145         ; - Page Table
146         mov edx, [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
147         %if USE_PAE
148         %error PAE Support
149         %else
150         mov ecx, edx
151         shr ecx, 22
152         test BYTE [0xFC3F0000+ecx*4], 1
153         jnz .justKillIt
154         %endif
155         ; - Page
156         mov ecx, edx
157         shr ecx, 12
158         test BYTE [0xFC000000+ecx*4], 1
159         jnz .justKillIt
160         ; Adjust
161         sub edx, 8
162         ; - Page Table
163         %if USE_PAE
164         %else
165         mov ecx, edx
166         shr ecx, 22
167         test BYTE [0xFC3F0000+ecx*4], 1
168         jnz .justKillIt
169         %endif
170         ; - Page
171         mov ecx, edx
172         shr ecx, 12
173         test BYTE [0xFC000000+ecx*4], 1
174         jnz .justKillIt
175         
176         ; Get and alter User SP
177         mov ecx, edx
178         mov edx, [ebx+60]       ; Get Signal Number from TCB
179         mov [ecx+4], edx        ; Parameter (Signal/Error Number)
180         mov [ecx], DWORD User_Syscall_RetAndExit        ; Return Address
181         
182         ; Restore Segment Registers
183         mov ax, 0x23
184         mov ds, ax
185         mov es, ax
186         mov fs, ax
187         mov gs, ax
188         
189         push 0x23       ; SS
190         push ecx        ; ESP
191         push 0x202      ; EFLAGS (IP and Rsvd)
192         push 0x1B       ; CS
193         push ebp        ; EIP
194         
195         iret
196         
197         ; Just kill the bleeding thing
198         ; (I know it calls int 0xAC in kernel mode, but meh)
199 .justKillIt:
200         xor eax, eax
201         xor ebx, ebx
202         dec ebx
203         int 0xAC
204
205 [global GetCPUNum]
206 GetCPUNum:
207         xor eax, eax
208         str ax
209         sub ax, 0x30
210         shr ax, 3       ; ax /= 8
211         ret
212
213 ; Usermode code exported by the kernel
214 [section .usertext]
215 User_Syscall_RetAndExit:
216         push eax
217         call User_Syscall_Exit
218 User_Syscall_Exit:
219         xor eax, eax
220         mov ebx, [esp+4]
221         int 0xAC

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