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

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