Rev 9828 | Rev 9910 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9828 | Rev 9831 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License. ;; |
4 | ;; Distributed under terms of the GNU General Public License. ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | 7 | ||
8 | $Revision: 9828 $ |
8 | $Revision: 9831 $ |
9 | 9 | ||
10 | align 4 ;3A08 |
10 | align 4 ;3A08 |
11 | build_interrupt_table: |
11 | build_interrupt_table: |
12 | mov edi, idts |
12 | mov edi, idts |
13 | mov esi, sys_int |
13 | mov esi, sys_int |
14 | mov ecx, 0x40 |
14 | mov ecx, 0x40 |
15 | mov eax, (10001110b shl 24) + os_code |
15 | mov eax, (10001110b shl 24) + os_code |
16 | @@: |
16 | @@: |
17 | movsw ; low word of code-entry |
17 | movsw ; low word of code-entry |
18 | stosd ; interrupt gate type : os_code selector |
18 | stosd ; interrupt gate type : os_code selector |
19 | movsw ; high word of code-entry |
19 | movsw ; high word of code-entry |
20 | loop @b |
20 | loop @b |
21 | movsd ; copy low dword of trap gate for int 0x40 |
21 | movsd ; copy low dword of trap gate for int 0x40 |
22 | movsd ; copy high dword of trap gate for int 0x40 |
22 | movsd ; copy high dword of trap gate for int 0x40 |
23 | mov ecx, 23 |
23 | mov ecx, 23 |
24 | mov eax, (10001110b shl 24) + os_code |
24 | mov eax, (10001110b shl 24) + os_code |
25 | @@: |
25 | @@: |
26 | movsw ; low word of code-entry |
26 | movsw ; low word of code-entry |
27 | stosd ; interrupt gate type : os_code selector |
27 | stosd ; interrupt gate type : os_code selector |
28 | movsw ; high word of code-entry |
28 | movsw ; high word of code-entry |
29 | loop @b |
29 | loop @b |
30 | lidt [esi] |
30 | lidt [esi] |
31 | ret |
31 | ret |
32 | 32 | ||
33 | iglobal |
33 | iglobal |
34 | align 4 |
34 | align 4 |
35 | sys_int: |
35 | sys_int: |
36 | ; exception handlers addresses (for interrupt gate construction) |
36 | ; exception handlers addresses (for interrupt gate construction) |
37 | dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc |
37 | dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc |
38 | dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 |
38 | dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 |
39 | dd e16, e17,e18, e19 |
39 | dd e16, e17,e18, e19 |
40 | times 12 dd unknown_interrupt ;int_20..int_31 |
40 | times 12 dd unknown_interrupt ;int_20..int_31 |
41 | 41 | ||
42 | ; interrupt handlers addresses (for interrupt gate construction) |
42 | ; interrupt handlers addresses (for interrupt gate construction) |
43 | ; 0x20+ are IRQ handlers |
43 | ; 0x20+ are IRQ handlers |
44 | dd irq0 |
44 | dd irq0 |
45 | rept 12 irqn:1 \{dd irq_serv.irq_\#irqn\} |
45 | rept 12 irqn:1 \{dd irq_serv.irq_\#irqn\} |
46 | dd irqD |
46 | dd irqD |
47 | rept 18 irqn:14 \{dd irq_serv.irq_\#irqn\} |
47 | rept 18 irqn:14 \{dd irq_serv.irq_\#irqn\} |
48 | 48 | ||
49 | ; int_0x40 gate trap (for directly copied) |
49 | ; int_0x40 gate trap (for directly copied) |
50 | dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 |
50 | dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 |
51 | 51 | ||
52 | rept 23 irqn:33 \{dd irq_serv.irq_\#irqn\} |
52 | rept 23 irqn:33 \{dd irq_serv.irq_\#irqn\} |
53 | 53 | ||
54 | idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) |
54 | idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) |
55 | dw 2*($-sys_int-4)-1 |
55 | dw 2*($-sys_int-4)-1 |
56 | dd idts ; 0x8000B100 |
56 | dd idts ; 0x8000B100 |
57 | dw 0 ; alignment |
57 | dw 0 ; alignment |
58 | 58 | ||
59 | msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b |
59 | msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b |
60 | dd msg_exc_c,msg_exc_d,msg_exc_e,msg_exc_u |
60 | dd msg_exc_c,msg_exc_d,msg_exc_e,msg_exc_u |
61 | dd msg_exc_u,msg_exc_11 |
61 | dd msg_exc_u,msg_exc_11 |
62 | 62 | ||
63 | msg_exc_8 db "Double fault", 0 |
63 | msg_exc_8 db "Double fault", 0 |
64 | msg_exc_u db "Undefined Exception", 0 |
64 | msg_exc_u db "Undefined Exception", 0 |
65 | msg_exc_a db "Invalid TSS", 0 |
65 | msg_exc_a db "Invalid TSS", 0 |
66 | msg_exc_b db "Segment not present", 0 |
66 | msg_exc_b db "Segment not present", 0 |
67 | msg_exc_c db "Stack fault", 0 |
67 | msg_exc_c db "Stack fault", 0 |
68 | msg_exc_d db "General protection fault", 0 |
68 | msg_exc_d db "General protection fault", 0 |
69 | msg_exc_e db "Page fault", 0 |
69 | msg_exc_e db "Page fault", 0 |
70 | msg_exc_11 db "Alignment Check", 0 |
70 | msg_exc_11 db "Alignment Check", 0 |
71 | 71 | ||
72 | if lang eq sp |
72 | if lang eq sp |
73 | include 'core/sys32-sp.inc' |
73 | include 'core/sys32-sp.inc' |
74 | else |
74 | else |
75 | msg_sel_ker db "kernel", 0 |
75 | msg_sel_ker db "kernel", 0 |
76 | msg_sel_app db "application", 0 |
76 | msg_sel_app db "application", 0 |
77 | end if |
77 | end if |
78 | 78 | ||
79 | endg |
79 | endg |
80 | 80 | ||
81 | macro save_ring3_context { |
81 | macro save_ring3_context { |
82 | pushad |
82 | pushad |
83 | } |
83 | } |
84 | macro restore_ring3_context { |
84 | macro restore_ring3_context { |
85 | popad |
85 | popad |
86 | } |
86 | } |
87 | macro exc_wo_code [num] { |
87 | macro exc_wo_code [num] { |
88 | e#num : |
88 | e#num : |
89 | save_ring3_context |
89 | save_ring3_context |
90 | mov bl, num |
90 | mov bl, num |
91 | jmp exc_c |
91 | jmp exc_c |
92 | } exc_wo_code 0,1,2,3,4,5,6,15,16,19 |
92 | } exc_wo_code 0,1,2,3,4,5,6,15,16,19 |
93 | 93 | ||
94 | macro exc_w_code [num] { |
94 | macro exc_w_code [num] { |
95 | e#num : |
95 | e#num : |
96 | add esp, 4 |
96 | add esp, 4 |
97 | save_ring3_context |
97 | save_ring3_context |
98 | mov bl, num |
98 | mov bl, num |
99 | jmp exc_c |
99 | jmp exc_c |
100 | } exc_w_code 8,9,10,11,12,13,17,18 |
100 | } exc_w_code 8,9,10,11,12,13,17,18 |
101 | 101 | ||
102 | 102 | ||
103 | uglobal |
103 | uglobal |
104 | pf_err_code dd ? |
104 | pf_err_code dd ? |
105 | endg |
105 | endg |
106 | 106 | ||
107 | page_fault_exc: ; foolproof: selectors are clobbered ... |
107 | page_fault_exc: ; foolproof: selectors are clobbered ... |
108 | pop [ss:pf_err_code] ; actually, until the next #PF |
108 | pop [ss:pf_err_code] ; actually, until the next #PF |
109 | save_ring3_context |
109 | save_ring3_context |
110 | mov bl, 14 |
110 | mov bl, 14 |
111 | 111 | ||
112 | exc_c: ; exceptions (all but 7th - #NM) |
112 | exc_c: ; exceptions (all but 7th - #NM) |
113 | ; stack frame when exception/interrupt from ring3 + pushad (i.e right here) |
113 | ; stack frame when exception/interrupt from ring3 + pushad (i.e right here) |
114 | reg_ss equ esp+0x30 |
114 | reg_ss equ esp+0x30 |
115 | reg_esp3 equ esp+0x2C |
115 | reg_esp3 equ esp+0x2C |
116 | reg_eflags equ esp+0x28 |
116 | reg_eflags equ esp+0x28 |
117 | reg_cs3 equ esp+0x24 |
117 | reg_cs3 equ esp+0x24 |
118 | reg_eip equ esp+0x20 |
118 | reg_eip equ esp+0x20 |
119 | ; this if frame from pushad |
119 | ; this if frame from pushad |
120 | reg_eax equ esp+0x1C |
120 | reg_eax equ esp+0x1C |
121 | reg_ecx equ esp+0x18 |
121 | reg_ecx equ esp+0x18 |
122 | reg_edx equ esp+0x14 |
122 | reg_edx equ esp+0x14 |
123 | reg_ebx equ esp+0x10 |
123 | reg_ebx equ esp+0x10 |
124 | reg_esp0 equ esp+0x0C |
124 | reg_esp0 equ esp+0x0C |
125 | reg_ebp equ esp+0x08 |
125 | reg_ebp equ esp+0x08 |
126 | reg_esi equ esp+0x04 |
126 | reg_esi equ esp+0x04 |
127 | reg_edi equ esp+0x00 |
127 | reg_edi equ esp+0x00 |
128 | 128 | ||
129 | mov ax, app_data ; exception |
129 | mov ax, app_data ; exception |
130 | mov ds, ax ; load proper values |
130 | mov ds, ax ; load proper values |
131 | mov es, ax ; to registers |
131 | mov es, ax ; to registers |
132 | cld ; clear the direction flag |
132 | cld ; clear the direction flag |
133 | movzx ebx, bl |
133 | movzx ebx, bl |
134 | ; redirect to V86 manager? (EFLAGS & 0x20000) != 0? |
134 | ; redirect to V86 manager? (EFLAGS & 0x20000) != 0? |
135 | test byte[reg_eflags+2], 2 |
135 | test byte[reg_eflags+2], 2 |
136 | jnz v86_exc_c |
136 | jnz v86_exc_c |
137 | cmp bl, 14 ; #PF |
137 | cmp bl, 14 ; #PF |
138 | jne @f |
138 | jne @f |
139 | call page_fault_handler ; SEE: core/memory.inc |
139 | call page_fault_handler ; SEE: core/memory.inc |
140 | @@: |
140 | @@: |
141 | mov esi, [current_slot] |
141 | mov esi, [current_slot] |
142 | btr [esi + APPDATA.except_mask], ebx |
142 | btr [esi + APPDATA.except_mask], ebx |
143 | jnc @f |
143 | jnc @f |
144 | mov eax, [esi + APPDATA.exc_handler] |
144 | mov eax, [esi + APPDATA.exc_handler] |
145 | test eax, eax |
145 | test eax, eax |
146 | jnz IRetToUserHook |
146 | jnz IRetToUserHook |
147 | @@: |
147 | @@: |
148 | cli |
148 | cli |
149 | mov eax, [esi + APPDATA.debugger_slot] |
149 | mov eax, [esi + APPDATA.debugger_slot] |
150 | test eax, eax |
150 | test eax, eax |
151 | jnz .debug |
151 | jnz .debug |
152 | ; not debuggee => say error and terminate |
152 | ; not debuggee => say error and terminate |
153 | call show_error_parameters ; this function output in edx = current_slot |
153 | call show_error_parameters ; this function output in edx = current_slot |
154 | sti |
154 | sti |
155 | mov [edx + APPDATA.state], TSTATE_TERMINATING |
155 | mov [edx + APPDATA.state], TSTATE_TERMINATING |
156 | call wakeup_osloop |
156 | call wakeup_osloop |
157 | call change_task |
157 | call change_task |
158 | ; If we're here, then the main OS thread has crashed before initializing IDLE thread. |
158 | ; If we're here, then the main OS thread has crashed before initializing IDLE thread. |
159 | ; Or they both have crashed. Anyway, things are hopelessly broken. |
159 | ; Or they both have crashed. Anyway, things are hopelessly broken. |
160 | hlt |
160 | hlt |
161 | jmp $-1 |
161 | jmp $-1 |
162 | .debug: |
162 | .debug: |
163 | ; we are debugged process, notify debugger and suspend ourself |
163 | ; we are debugged process, notify debugger and suspend ourself |
164 | ; eax=debugger PID |
164 | ; eax=debugger PID |
165 | mov ecx, 1 ; debug_message code=other_exception |
165 | mov ecx, 1 ; debug_message code=other_exception |
166 | cmp bl, 1 ; #DB |
166 | cmp bl, 1 ; #DB |
167 | jne .notify ; notify debugger and suspend ourself |
167 | jne .notify ; notify debugger and suspend ourself |
168 | mov ebx, dr6 ; debug_message data=DR6_image |
168 | mov ebx, dr6 ; debug_message data=DR6_image |
169 | xor edx, edx |
169 | xor edx, edx |
170 | mov dr6, edx |
170 | mov dr6, edx |
171 | mov edx, dr7 |
171 | mov edx, dr7 |
172 | mov cl, not 8 |
172 | mov cl, not 8 |
173 | .l1: |
173 | .l1: |
174 | shl dl, 2 |
174 | shl dl, 2 |
175 | jc @f |
175 | jc @f |
176 | and bl, cl |
176 | and bl, cl |
177 | @@: |
177 | @@: |
178 | sar cl, 1 |
178 | sar cl, 1 |
179 | jc .l1 |
179 | jc .l1 |
180 | mov cl, 3 ; debug_message code=debug_exception |
180 | mov cl, 3 ; debug_message code=debug_exception |
181 | .notify: |
181 | .notify: |
182 | push ebx ; debug_message data |
182 | push ebx ; debug_message data |
183 | mov ebx, [current_slot] |
183 | mov ebx, [current_slot] |
184 | push [ebx + APPDATA.tid] ; PID |
184 | push [ebx + APPDATA.tid] ; PID |
185 | push ecx ; debug_message code ((here: ecx==1/3)) |
185 | push ecx ; debug_message code ((here: ecx==1/3)) |
186 | mov cl, 12 ; debug_message size |
186 | mov cl, 12 ; debug_message size |
187 | call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc |
187 | call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc |
188 | add esp, 12 |
188 | add esp, 12 |
189 | mov edx, [current_slot] |
189 | mov edx, [current_slot] |
190 | mov [edx + APPDATA.state], TSTATE_RUN_SUSPENDED |
190 | mov [edx + APPDATA.state], TSTATE_RUN_SUSPENDED |
191 | call change_task ; SEE: core/shed.inc |
191 | call change_task ; SEE: core/shed.inc |
192 | restore_ring3_context |
192 | restore_ring3_context |
193 | iretd |
193 | iretd |
194 | 194 | ||
195 | IRetToUserHook: |
195 | IRetToUserHook: |
196 | xchg eax, [reg_eip] |
196 | xchg eax, [reg_eip] |
197 | sub dword[reg_esp3], 8 |
197 | sub dword[reg_esp3], 8 |
198 | mov edi, [reg_esp3] |
198 | mov edi, [reg_esp3] |
199 | stosd |
199 | stosd |
200 | mov [edi], ebx |
200 | mov [edi], ebx |
201 | restore_ring3_context |
201 | restore_ring3_context |
202 | ; simply return control to interrupted process |
202 | ; simply return control to interrupted process |
203 | unknown_interrupt: |
203 | unknown_interrupt: |
204 | iretd |
204 | iretd |
205 | 205 | ||
206 | ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
206 | ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
207 | ; bl - error vector |
207 | ; bl - error vector |
208 | show_error_parameters: |
208 | show_error_parameters: |
209 | cmp bl, 0x06 |
209 | cmp bl, 0x06 |
210 | jnz .no_ud |
210 | jnz .no_ud |
211 | push ebx |
211 | push ebx |
212 | mov ebx, ud_user_message |
212 | mov ebx, ud_user_message |
213 | mov ebp, notifyapp |
213 | mov ebp, notifyapp |
214 | call fs_execute_from_sysdir_param |
214 | call fs_execute_from_sysdir_param |
215 | pop ebx |
215 | pop ebx |
216 | .no_ud: |
216 | .no_ud: |
217 | mov edx, [current_slot];not scratched below |
217 | mov edx, [current_slot];not scratched below |
218 | if lang eq sp |
218 | if lang eq sp |
219 | DEBUGF 1, "K : Proceso - terminado forzado PID: %x [%s]\n", [edx + APPDATA.tid], [current_slot] |
219 | DEBUGF 1, "K : Proceso - terminado forzado PID: %x [%s]\n", [edx + APPDATA.tid], [current_slot] |
220 | else |
220 | else |
221 | DEBUGF 1, "K : Process - forced terminate PID: %x [%s]\n", [edx + APPDATA.tid], [current_slot] |
221 | DEBUGF 1, "K : Process - forced terminate PID: %x [%s]\n", [edx + APPDATA.tid], [current_slot] |
222 | end if |
222 | end if |
223 | cmp bl, 0x08 |
223 | cmp bl, 0x08 |
224 | jb .l0 |
224 | jb .l0 |
225 | cmp bl, 0x11 |
225 | cmp bl, 0x11 |
226 | jbe .l1 |
226 | jbe .l1 |
227 | .l0: |
227 | .l0: |
228 | mov bl, 0x09 |
228 | mov bl, 0x09 |
229 | .l1: |
229 | .l1: |
230 | mov eax, [msg_fault_sel+ebx*4 - 0x08*4] |
230 | mov eax, [msg_fault_sel+ebx*4 - 0x08*4] |
231 | DEBUGF 1, "K : %s\n", eax |
231 | DEBUGF 1, "K : %s\n", eax |
232 | mov eax, [reg_cs3+4] |
232 | mov eax, [reg_cs3+4] |
233 | mov edi, msg_sel_app |
233 | mov edi, msg_sel_app |
234 | mov ebx, [reg_esp3+4] |
234 | mov ebx, [reg_esp3+4] |
235 | cmp eax, app_code |
235 | cmp eax, app_code |
236 | je @f |
236 | je @f |
237 | mov edi, msg_sel_ker |
237 | mov edi, msg_sel_ker |
238 | mov ebx, [reg_esp0+4] |
238 | mov ebx, [reg_esp0+4] |
239 | @@: |
239 | @@: |
240 | DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] |
240 | DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] |
241 | DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] |
241 | DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] |
242 | DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx |
242 | DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx |
243 | DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi |
243 | DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi |
244 | 244 | ||
245 | DEBUGF 1, "K : Stack dump:\n" |
245 | DEBUGF 1, "K : Stack dump:\n" |
246 | push eax ebx ecx edx |
246 | push eax ebx ecx edx |
247 | call .check_ESP |
247 | call .check_ESP |
248 | test eax, eax |
248 | test eax, eax |
249 | jnz .error_ESP |
249 | jnz .error_ESP |
250 | DEBUGF 1, "K : [ESP+00]: %x",[ebx] |
250 | DEBUGF 1, "K : [ESP+00]: %x",[ebx] |
251 | add ebx, 4 |
251 | add ebx, 4 |
252 | call .check_ESP |
252 | call .check_ESP |
253 | test eax, eax |
253 | test eax, eax |
254 | jnz .error_ESP |
254 | jnz .error_ESP |
255 | DEBUGF 1, " [ESP+04]: %x",[ebx] |
255 | DEBUGF 1, " [ESP+04]: %x",[ebx] |
256 | add ebx, 4 |
256 | add ebx, 4 |
257 | call .check_ESP |
257 | call .check_ESP |
258 | test eax, eax |
258 | test eax, eax |
259 | jnz .error_ESP |
259 | jnz .error_ESP |
260 | DEBUGF 1, " [ESP+08]: %x\n",[ebx] |
260 | DEBUGF 1, " [ESP+08]: %x\n",[ebx] |
261 | add ebx, 4 |
261 | add ebx, 4 |
262 | call .check_ESP |
262 | call .check_ESP |
263 | test eax, eax |
263 | test eax, eax |
264 | jnz .error_ESP |
264 | jnz .error_ESP |
265 | DEBUGF 1, "K : [ESP+12]: %x",[ebx] |
265 | DEBUGF 1, "K : [ESP+12]: %x",[ebx] |
266 | add ebx, 4 |
266 | add ebx, 4 |
267 | call .check_ESP |
267 | call .check_ESP |
268 | test eax, eax |
268 | test eax, eax |
269 | jnz .error_ESP |
269 | jnz .error_ESP |
270 | DEBUGF 1, " [ESP+16]: %x",[ebx] |
270 | DEBUGF 1, " [ESP+16]: %x",[ebx] |
271 | add ebx, 4 |
271 | add ebx, 4 |
272 | call .check_ESP |
272 | call .check_ESP |
273 | test eax, eax |
273 | test eax, eax |
274 | jnz .error_ESP |
274 | jnz .error_ESP |
275 | DEBUGF 1, " [ESP+20]: %x\n",[ebx] |
275 | DEBUGF 1, " [ESP+20]: %x\n",[ebx] |
276 | add ebx, 4 |
276 | add ebx, 4 |
277 | call .check_ESP |
277 | call .check_ESP |
278 | test eax, eax |
278 | test eax, eax |
279 | jnz .error_ESP |
279 | jnz .error_ESP |
280 | DEBUGF 1, "K : [ESP+24]: %x",[ebx] |
280 | DEBUGF 1, "K : [ESP+24]: %x",[ebx] |
281 | add ebx, 4 |
281 | add ebx, 4 |
282 | call .check_ESP |
282 | call .check_ESP |
283 | test eax, eax |
283 | test eax, eax |
284 | jnz .error_ESP |
284 | jnz .error_ESP |
285 | DEBUGF 1, " [ESP+28]: %x",[ebx] |
285 | DEBUGF 1, " [ESP+28]: %x",[ebx] |
286 | add ebx, 4 |
286 | add ebx, 4 |
287 | call .check_ESP |
287 | call .check_ESP |
288 | test eax, eax |
288 | test eax, eax |
289 | jnz .error_ESP |
289 | jnz .error_ESP |
290 | DEBUGF 1, " [ESP+32]: %x\n",[ebx] |
290 | DEBUGF 1, " [ESP+32]: %x\n",[ebx] |
291 | pop edx ecx ebx eax |
291 | pop edx ecx ebx eax |
292 | ret |
292 | ret |
293 | .error_ESP: |
293 | .error_ESP: |
294 | pop edx ecx ebx eax |
294 | pop edx ecx ebx eax |
295 | DEBUGF 1, "\n" |
295 | DEBUGF 1, "\n" |
296 | DEBUGF 1, "K : Unexpected end of the stack\n" |
296 | DEBUGF 1, "K : Unexpected end of the stack\n" |
297 | ret |
297 | ret |
298 | ;-------------------------------------- |
298 | ;-------------------------------------- |
299 | .check_ESP: |
299 | .check_ESP: |
300 | push ebx |
300 | push ebx |
301 | shr ebx, 12 |
301 | shr ebx, 12 |
302 | mov ecx, ebx |
302 | mov ecx, ebx |
303 | shr ecx, 10 |
303 | shr ecx, 10 |
304 | mov edx, [master_tab + ecx*4] |
304 | mov edx, [master_tab + ecx*4] |
305 | test edx, PG_READ |
305 | test edx, PG_READ |
306 | jz .fail ; page table is not created |
306 | jz .fail ; page table is not created |
307 | ; incorrect address in the program |
307 | ; incorrect address in the program |
308 | 308 | ||
309 | mov eax, [page_tabs + ebx*4] |
309 | mov eax, [page_tabs + ebx*4] |
310 | test eax, 2 |
310 | test eax, 2 |
311 | jz .fail ; address not reserved for use. error |
311 | jz .fail ; address not reserved for use. error |
312 | 312 | ||
313 | pop ebx |
313 | pop ebx |
314 | xor eax, eax |
314 | xor eax, eax |
315 | ret |
315 | ret |
316 | 316 | ||
317 | .fail: |
317 | .fail: |
318 | pop ebx |
318 | pop ebx |
319 | xor eax, eax |
319 | xor eax, eax |
320 | dec eax |
320 | dec eax |
321 | ret |
321 | ret |
322 | ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
322 | ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
323 | 323 | ||
324 | restore reg_ss |
324 | restore reg_ss |
325 | restore reg_esp3 |
325 | restore reg_esp3 |
326 | restore reg_eflags |
326 | restore reg_eflags |
327 | restore reg_cs |
327 | restore reg_cs |
328 | restore reg_eip |
328 | restore reg_eip |
329 | restore reg_eax |
329 | restore reg_eax |
330 | restore reg_ecx |
330 | restore reg_ecx |
331 | restore reg_edx |
331 | restore reg_edx |
332 | restore reg_ebx |
332 | restore reg_ebx |
333 | restore reg_esp0 |
333 | restore reg_esp0 |
334 | restore reg_ebp |
334 | restore reg_ebp |
335 | restore reg_esi |
335 | restore reg_esi |
336 | restore reg_edi |
336 | restore reg_edi |
337 | 337 | ||
338 | 338 | ||
339 | align 4 |
339 | align 4 |
340 | lock_application_table: |
340 | lock_application_table: |
341 | push eax ecx edx |
341 | push eax ecx edx |
342 | mov ecx, application_table_mutex |
342 | mov ecx, application_table_mutex |
343 | call mutex_lock |
343 | call mutex_lock |
344 | 344 | ||
345 | mov eax, [current_slot] |
345 | mov eax, [current_slot] |
346 | mov eax, [eax + APPDATA.tid] |
346 | mov eax, [eax + APPDATA.tid] |
347 | 347 | ||
348 | mov [application_table_owner], eax |
348 | mov [application_table_owner], eax |
349 | 349 | ||
350 | pop edx ecx eax |
350 | pop edx ecx eax |
351 | 351 | ||
352 | ret |
352 | ret |
353 | 353 | ||
354 | align 4 |
354 | align 4 |
355 | unlock_application_table: |
355 | unlock_application_table: |
356 | push eax ecx edx |
356 | push eax ecx edx |
357 | 357 | ||
358 | mov [application_table_owner], 0 |
358 | mov [application_table_owner], 0 |
359 | mov ecx, application_table_mutex |
359 | mov ecx, application_table_mutex |
360 | call mutex_unlock |
360 | call mutex_unlock |
361 | 361 | ||
362 | pop edx ecx eax |
362 | pop edx ecx eax |
363 | 363 | ||
364 | ret |
364 | ret |
365 | 365 | ||
366 | ; sysfn 64 implementation |
366 | ; sysfn 64 implementation |
367 | align 4 |
367 | align 4 |
368 | sys_resize_app_memory: |
368 | sys_resize_app_memory: |
369 | ; in: eax = 64 - function number |
369 | ; in: eax = 64 - function number |
370 | ; ebx = 1 - number of its only subfunction |
370 | ; ebx = 1 - number of its only subfunction |
371 | ; ecx = new amount of memory |
371 | ; ecx = new amount of memory |
372 | ; out: |
372 | ; out: |
373 | ; eax = 0 - success |
373 | ; eax = 0 - success |
374 | ; eax = 1 - out of memory |
374 | ; eax = 1 - out of memory |
375 | 375 | ||
376 | ; cmp eax,1 |
376 | ; cmp eax,1 |
377 | dec ebx |
377 | dec ebx |
378 | jnz .no_application_mem_resize |
378 | jnz .no_application_mem_resize |
379 | 379 | ||
380 | mov eax, [pg_data.pages_free] |
380 | mov eax, [pg_data.pages_free] |
381 | shl eax, 12 |
381 | shl eax, 12 |
382 | cmp eax, ecx |
382 | cmp eax, ecx |
383 | jae @f |
383 | jae @f |
384 | 384 | ||
385 | xor eax, eax |
385 | xor eax, eax |
386 | inc eax |
386 | inc eax |
387 | jmp .store_result |
387 | jmp .store_result |
388 | @@: |
388 | @@: |
389 | stdcall new_mem_resize, ecx |
389 | stdcall new_mem_resize, ecx |
390 | .store_result: |
390 | .store_result: |
391 | mov [esp + SYSCALL_STACK._eax], eax |
391 | mov [esp + SYSCALL_STACK.eax], eax |
392 | .no_application_mem_resize: |
392 | .no_application_mem_resize: |
393 | ret |
393 | ret |
394 | 394 | ||
395 | iglobal |
395 | iglobal |
396 | ; process_terminating db 'K : Process - terminating',13,10,0 |
396 | ; process_terminating db 'K : Process - terminating',13,10,0 |
397 | ; process_terminated db 'K : Process - done',13,10,0 |
397 | ; process_terminated db 'K : Process - done',13,10,0 |
398 | msg_obj_destroy db 'K : destroy app object',13,10,0 |
398 | msg_obj_destroy db 'K : destroy app object',13,10,0 |
399 | endg |
399 | endg |
400 | 400 | ||
401 | ; param |
401 | ; param |
402 | ; esi= slot |
402 | ; esi= slot |
403 | 403 | ||
404 | align 4 |
404 | align 4 |
405 | terminate: ; terminate application |
405 | terminate: ; terminate application |
406 | destroy_thread: |
406 | destroy_thread: |
407 | 407 | ||
408 | .slot equ esp+4 ;locals |
408 | .slot equ esp+4 ;locals |
409 | .process equ esp ;ptr to parent process |
409 | .process equ esp ;ptr to parent process |
410 | 410 | ||
411 | 411 | ||
412 | push esi ;save .slot |
412 | push esi ;save .slot |
413 | 413 | ||
414 | shl esi, BSF sizeof.APPDATA |
414 | shl esi, BSF sizeof.APPDATA |
415 | mov edx, [SLOT_BASE + esi + APPDATA.process] |
415 | mov edx, [SLOT_BASE + esi + APPDATA.process] |
416 | test edx, edx |
416 | test edx, edx |
417 | jnz @F |
417 | jnz @F |
418 | mov [SLOT_BASE + esi + APPDATA.state], TSTATE_FREE |
418 | mov [SLOT_BASE + esi + APPDATA.state], TSTATE_FREE |
419 | pop esi |
419 | pop esi |
420 | ret |
420 | ret |
421 | @@: |
421 | @@: |
422 | push edx ;save .process |
422 | push edx ;save .process |
423 | lea edx, [SLOT_BASE + esi] |
423 | lea edx, [SLOT_BASE + esi] |
424 | call scheduler_remove_thread |
424 | call scheduler_remove_thread |
425 | call lock_application_table |
425 | call lock_application_table |
426 | 426 | ||
427 | ; if the process is in V86 mode... |
427 | ; if the process is in V86 mode... |
428 | mov eax, [.slot] |
428 | mov eax, [.slot] |
429 | shl eax, BSF sizeof.APPDATA |
429 | shl eax, BSF sizeof.APPDATA |
430 | mov esi, [SLOT_BASE + eax + APPDATA.pl0_stack] |
430 | mov esi, [SLOT_BASE + eax + APPDATA.pl0_stack] |
431 | add esi, RING0_STACK_SIZE |
431 | add esi, RING0_STACK_SIZE |
432 | cmp [SLOT_BASE + eax + APPDATA.saved_esp0], esi |
432 | cmp [SLOT_BASE + eax + APPDATA.saved_esp0], esi |
433 | jz .nov86 |
433 | jz .nov86 |
434 | ; ...it has page directory for V86 mode |
434 | ; ...it has page directory for V86 mode |
435 | mov esi, [SLOT_BASE + eax + APPDATA.saved_esp0] |
435 | mov esi, [SLOT_BASE + eax + APPDATA.saved_esp0] |
436 | mov ecx, [esi+4] |
436 | mov ecx, [esi+4] |
437 | mov [SLOT_BASE + eax + APPDATA.process], ecx |
437 | mov [SLOT_BASE + eax + APPDATA.process], ecx |
438 | ; ...and I/O permission map for V86 mode |
438 | ; ...and I/O permission map for V86 mode |
439 | mov ecx, [esi+12] |
439 | mov ecx, [esi+12] |
440 | mov [SLOT_BASE + eax + APPDATA.io_map], ecx |
440 | mov [SLOT_BASE + eax + APPDATA.io_map], ecx |
441 | mov ecx, [esi+8] |
441 | mov ecx, [esi+8] |
442 | mov [SLOT_BASE + eax + APPDATA.io_map+4], ecx |
442 | mov [SLOT_BASE + eax + APPDATA.io_map+4], ecx |
443 | .nov86: |
443 | .nov86: |
444 | ; destroy per-thread kernel objects |
444 | ; destroy per-thread kernel objects |
445 | mov esi, [.slot] |
445 | mov esi, [.slot] |
446 | shl esi, BSF sizeof.APPDATA |
446 | shl esi, BSF sizeof.APPDATA |
447 | add esi, SLOT_BASE + APP_OBJ_OFFSET |
447 | add esi, SLOT_BASE + APP_OBJ_OFFSET |
448 | @@: |
448 | @@: |
449 | mov eax, [esi + APPOBJ.fd] |
449 | mov eax, [esi + APPOBJ.fd] |
450 | test eax, eax |
450 | test eax, eax |
451 | jz @F |
451 | jz @F |
452 | 452 | ||
453 | cmp eax, esi |
453 | cmp eax, esi |
454 | je @F |
454 | je @F |
455 | 455 | ||
456 | push esi |
456 | push esi |
457 | call [eax + APPOBJ.destroy] |
457 | call [eax + APPOBJ.destroy] |
458 | DEBUGF 1,"%s",msg_obj_destroy |
458 | DEBUGF 1,"%s",msg_obj_destroy |
459 | pop esi |
459 | pop esi |
460 | jmp @B |
460 | jmp @B |
461 | @@: |
461 | @@: |
462 | mov esi, [.slot] |
462 | mov esi, [.slot] |
463 | cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2 |
463 | cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2 |
464 | jne @F |
464 | jne @F |
465 | 465 | ||
466 | mov [fpu_owner], 2 |
466 | mov [fpu_owner], 2 |
467 | mov eax, [SLOT_BASE + sizeof.APPDATA*2 + APPDATA.fpu_state] |
467 | mov eax, [SLOT_BASE + sizeof.APPDATA*2 + APPDATA.fpu_state] |
468 | clts |
468 | clts |
469 | bt [cpu_caps], CAPS_SSE |
469 | bt [cpu_caps], CAPS_SSE |
470 | jnc .no_SSE |
470 | jnc .no_SSE |
471 | fxrstor [eax] |
471 | fxrstor [eax] |
472 | jmp @F |
472 | jmp @F |
473 | .no_SSE: |
473 | .no_SSE: |
474 | fnclex |
474 | fnclex |
475 | frstor [eax] |
475 | frstor [eax] |
476 | @@: |
476 | @@: |
477 | 477 | ||
478 | mov [KEY_COUNT], byte 0 ; empty keyboard buffer |
478 | mov [KEY_COUNT], byte 0 ; empty keyboard buffer |
479 | mov [BTN_COUNT], byte 0 ; empty button buffer |
479 | mov [BTN_COUNT], byte 0 ; empty button buffer |
480 | 480 | ||
481 | 481 | ||
482 | ; remove defined hotkeys |
482 | ; remove defined hotkeys |
483 | mov eax, hotkey_list |
483 | mov eax, hotkey_list |
484 | .loop: |
484 | .loop: |
485 | cmp [eax+8], esi |
485 | cmp [eax+8], esi |
486 | jnz .cont |
486 | jnz .cont |
487 | mov ecx, [eax] |
487 | mov ecx, [eax] |
488 | jecxz @f |
488 | jecxz @f |
489 | push dword [eax+12] |
489 | push dword [eax+12] |
490 | pop dword [ecx+12] |
490 | pop dword [ecx+12] |
491 | @@: |
491 | @@: |
492 | mov ecx, [eax+12] |
492 | mov ecx, [eax+12] |
493 | push dword [eax] |
493 | push dword [eax] |
494 | pop dword [ecx] |
494 | pop dword [ecx] |
495 | xor ecx, ecx |
495 | xor ecx, ecx |
496 | mov [eax], ecx |
496 | mov [eax], ecx |
497 | mov [eax+4], ecx |
497 | mov [eax+4], ecx |
498 | mov [eax+8], ecx |
498 | mov [eax+8], ecx |
499 | mov [eax+12], ecx |
499 | mov [eax+12], ecx |
500 | .cont: |
500 | .cont: |
501 | add eax, 16 |
501 | add eax, 16 |
502 | cmp eax, hotkey_list+256*16 |
502 | cmp eax, hotkey_list+256*16 |
503 | jb .loop |
503 | jb .loop |
504 | ; get process PID |
504 | ; get process PID |
505 | mov eax, esi |
505 | mov eax, esi |
506 | shl eax, BSF sizeof.APPDATA |
506 | shl eax, BSF sizeof.APPDATA |
507 | mov eax, [eax + SLOT_BASE + APPDATA.tid] |
507 | mov eax, [eax + SLOT_BASE + APPDATA.tid] |
508 | ; compare current lock input with process PID |
508 | ; compare current lock input with process PID |
509 | cmp eax, [PID_lock_input] |
509 | cmp eax, [PID_lock_input] |
510 | jne @f |
510 | jne @f |
511 | 511 | ||
512 | xor eax, eax |
512 | xor eax, eax |
513 | mov [PID_lock_input], eax |
513 | mov [PID_lock_input], eax |
514 | @@: |
514 | @@: |
515 | ; remove hotkeys in buffer |
515 | ; remove hotkeys in buffer |
516 | mov eax, hotkey_buffer |
516 | mov eax, hotkey_buffer |
517 | .loop2: |
517 | .loop2: |
518 | cmp [eax], esi |
518 | cmp [eax], esi |
519 | jnz .cont2 |
519 | jnz .cont2 |
520 | and dword [eax+4], 0 |
520 | and dword [eax+4], 0 |
521 | and dword [eax], 0 |
521 | and dword [eax], 0 |
522 | .cont2: |
522 | .cont2: |
523 | add eax, 8 |
523 | add eax, 8 |
524 | cmp eax, hotkey_buffer+120*8 |
524 | cmp eax, hotkey_buffer+120*8 |
525 | jb .loop2 |
525 | jb .loop2 |
526 | 526 | ||
527 | mov ecx, esi ; remove buttons |
527 | mov ecx, esi ; remove buttons |
528 | bnewba2: |
528 | bnewba2: |
529 | mov edi, [BTN_ADDR] |
529 | mov edi, [BTN_ADDR] |
530 | mov eax, edi |
530 | mov eax, edi |
531 | cld |
531 | cld |
532 | movzx ebx, word [edi] |
532 | movzx ebx, word [edi] |
533 | inc bx |
533 | inc bx |
534 | bnewba: |
534 | bnewba: |
535 | dec bx |
535 | dec bx |
536 | jz bnmba |
536 | jz bnmba |
537 | add eax, 0x10 |
537 | add eax, 0x10 |
538 | cmp cx, [eax] |
538 | cmp cx, [eax] |
539 | jnz bnewba |
539 | jnz bnewba |
540 | pusha |
540 | pusha |
541 | mov ecx, ebx |
541 | mov ecx, ebx |
542 | inc ecx |
542 | inc ecx |
543 | shl ecx, 4 |
543 | shl ecx, 4 |
544 | mov ebx, eax |
544 | mov ebx, eax |
545 | add eax, 0x10 |
545 | add eax, 0x10 |
546 | call memmove |
546 | call memmove |
547 | dec dword [edi] |
547 | dec dword [edi] |
548 | popa |
548 | popa |
549 | jmp bnewba2 |
549 | jmp bnewba2 |
550 | bnmba: |
550 | bnmba: |
551 | 551 | ||
552 | pusha ; save window coordinates for window restoring |
552 | pusha ; save window coordinates for window restoring |
553 | cld |
553 | cld |
554 | shl esi, BSF sizeof.WDATA |
554 | shl esi, BSF sizeof.WDATA |
555 | add esi, window_data |
555 | add esi, window_data |
556 | mov eax, [esi + WDATA.box.left] |
556 | mov eax, [esi + WDATA.box.left] |
557 | mov [draw_limits.left], eax |
557 | mov [draw_limits.left], eax |
558 | add eax, [esi + WDATA.box.width] |
558 | add eax, [esi + WDATA.box.width] |
559 | mov [draw_limits.right], eax |
559 | mov [draw_limits.right], eax |
560 | mov eax, [esi + WDATA.box.top] |
560 | mov eax, [esi + WDATA.box.top] |
561 | mov [draw_limits.top], eax |
561 | mov [draw_limits.top], eax |
562 | add eax, [esi + WDATA.box.height] |
562 | add eax, [esi + WDATA.box.height] |
563 | mov [draw_limits.bottom], eax |
563 | mov [draw_limits.bottom], eax |
564 | 564 | ||
565 | xor eax, eax |
565 | xor eax, eax |
566 | mov edi, esi |
566 | mov edi, esi |
567 | mov ecx, sizeof.WDATA/4 |
567 | mov ecx, sizeof.WDATA/4 |
568 | rep stosd |
568 | rep stosd |
569 | 569 | ||
570 | lea edi, [esi - window_data + draw_data] |
570 | lea edi, [esi - window_data + draw_data] |
571 | mov ecx, sizeof.WDATA/4 |
571 | mov ecx, sizeof.WDATA/4 |
572 | rep stosd |
572 | rep stosd |
573 | popa |
573 | popa |
574 | 574 | ||
575 | ; debuggee test |
575 | ; debuggee test |
576 | pushad |
576 | pushad |
577 | mov edi, esi |
577 | mov edi, esi |
578 | shl edi, BSF sizeof.APPDATA |
578 | shl edi, BSF sizeof.APPDATA |
579 | mov eax, [SLOT_BASE + edi + APPDATA.debugger_slot] |
579 | mov eax, [SLOT_BASE + edi + APPDATA.debugger_slot] |
580 | test eax, eax |
580 | test eax, eax |
581 | jz .nodebug |
581 | jz .nodebug |
582 | movi ecx, 8 |
582 | movi ecx, 8 |
583 | push dword [SLOT_BASE + edi + APPDATA.tid]; PID |
583 | push dword [SLOT_BASE + edi + APPDATA.tid]; PID |
584 | push 2 |
584 | push 2 |
585 | call debugger_notify |
585 | call debugger_notify |
586 | pop ecx |
586 | pop ecx |
587 | pop ecx |
587 | pop ecx |
588 | .nodebug: |
588 | .nodebug: |
589 | popad |
589 | popad |
590 | 590 | ||
591 | mov ebx, [.slot] |
591 | mov ebx, [.slot] |
592 | shl ebx, BSF sizeof.APPDATA |
592 | shl ebx, BSF sizeof.APPDATA |
593 | push ebx |
593 | push ebx |
594 | mov ebx, [SLOT_BASE + ebx + APPDATA.pl0_stack] |
594 | mov ebx, [SLOT_BASE + ebx + APPDATA.pl0_stack] |
595 | 595 | ||
596 | stdcall kernel_free, ebx |
596 | stdcall kernel_free, ebx |
597 | 597 | ||
598 | pop ebx |
598 | pop ebx |
599 | mov ebx, [SLOT_BASE + ebx + APPDATA.cur_dir] |
599 | mov ebx, [SLOT_BASE + ebx + APPDATA.cur_dir] |
600 | stdcall kernel_free, ebx |
600 | stdcall kernel_free, ebx |
601 | 601 | ||
602 | mov edi, [.slot] |
602 | mov edi, [.slot] |
603 | shl edi, BSF sizeof.APPDATA |
603 | shl edi, BSF sizeof.APPDATA |
604 | add edi, SLOT_BASE |
604 | add edi, SLOT_BASE |
605 | 605 | ||
606 | mov eax, [edi + APPDATA.io_map] |
606 | mov eax, [edi + APPDATA.io_map] |
607 | cmp eax, [SLOT_BASE + sizeof.APPDATA+APPDATA.io_map] |
607 | cmp eax, [SLOT_BASE + sizeof.APPDATA+APPDATA.io_map] |
608 | je @F |
608 | je @F |
609 | call free_page |
609 | call free_page |
610 | @@: |
610 | @@: |
611 | mov eax, [edi+APPDATA.io_map+4] |
611 | mov eax, [edi+APPDATA.io_map+4] |
612 | cmp eax, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4] |
612 | cmp eax, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4] |
613 | je @F |
613 | je @F |
614 | call free_page |
614 | call free_page |
615 | @@: |
615 | @@: |
616 | lea ebx, [edi + APPDATA.list] |
616 | lea ebx, [edi + APPDATA.list] |
617 | list_del ebx ;destroys edx, ecx |
617 | list_del ebx ;destroys edx, ecx |
618 | 618 | ||
619 | ; activate window |
619 | ; activate window |
620 | movzx eax, word [WIN_STACK + esi*2] |
620 | movzx eax, word [WIN_STACK + esi*2] |
621 | cmp eax, [thread_count] |
621 | cmp eax, [thread_count] |
622 | jne .dont_activate |
622 | jne .dont_activate |
623 | pushad |
623 | pushad |
624 | .check_next_window: |
624 | .check_next_window: |
625 | dec eax |
625 | dec eax |
626 | cmp eax, 1 |
626 | cmp eax, 1 |
627 | jbe .nothing_to_activate |
627 | jbe .nothing_to_activate |
628 | lea esi, [WIN_POS + eax*2] |
628 | lea esi, [WIN_POS + eax*2] |
629 | movzx edi, word [esi] ; edi = process |
629 | movzx edi, word [esi] ; edi = process |
630 | shl edi, BSF sizeof.APPDATA |
630 | shl edi, BSF sizeof.APPDATA |
631 | cmp [SLOT_BASE + edi + APPDATA.state], TSTATE_FREE ; skip free slots |
631 | cmp [SLOT_BASE + edi + APPDATA.state], TSTATE_FREE ; skip free slots |
632 | je .check_next_window |
632 | je .check_next_window |
633 | shr edi, 3 |
633 | shr edi, 3 |
634 | add edi, window_data |
634 | add edi, window_data |
635 | ; \begin{diamond}[19.09.2006] |
635 | ; \begin{diamond}[19.09.2006] |
636 | ; skip minimized windows |
636 | ; skip minimized windows |
637 | test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED |
637 | test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED |
638 | jnz .check_next_window |
638 | jnz .check_next_window |
639 | ; \end{diamond} |
639 | ; \end{diamond} |
640 | call waredraw |
640 | call waredraw |
641 | .nothing_to_activate: |
641 | .nothing_to_activate: |
642 | popad |
642 | popad |
643 | .dont_activate: |
643 | .dont_activate: |
644 | 644 | ||
645 | push esi ; remove hd1 & cd & flp reservation |
645 | push esi ; remove hd1 & cd & flp reservation |
646 | shl esi, BSF sizeof.APPDATA |
646 | shl esi, BSF sizeof.APPDATA |
647 | mov esi, [SLOT_BASE + esi + APPDATA.tid] |
647 | mov esi, [SLOT_BASE + esi + APPDATA.tid] |
648 | cmp [cd_status], esi |
648 | cmp [cd_status], esi |
649 | jnz @f |
649 | jnz @f |
650 | call free_cd_channel |
650 | call free_cd_channel |
651 | and [cd_status], 0 |
651 | and [cd_status], 0 |
652 | @@: |
652 | @@: |
653 | pop esi |
653 | pop esi |
654 | cmp [bgrlockpid], esi |
654 | cmp [bgrlockpid], esi |
655 | jnz @f |
655 | jnz @f |
656 | and [bgrlockpid], 0 |
656 | and [bgrlockpid], 0 |
657 | and [bgrlock], 0 |
657 | and [bgrlock], 0 |
658 | @@: |
658 | @@: |
659 | 659 | ||
660 | pusha ; remove all port reservations |
660 | pusha ; remove all port reservations |
661 | mov edx, esi |
661 | mov edx, esi |
662 | shl edx, BSF sizeof.APPDATA |
662 | shl edx, BSF sizeof.APPDATA |
663 | mov edx, [SLOT_BASE + edx + APPDATA.tid] |
663 | mov edx, [SLOT_BASE + edx + APPDATA.tid] |
664 | 664 | ||
665 | rmpr0: |
665 | rmpr0: |
666 | mov esi, [RESERVED_PORTS] |
666 | mov esi, [RESERVED_PORTS] |
667 | 667 | ||
668 | test esi, esi |
668 | test esi, esi |
669 | jz rmpr9 |
669 | jz rmpr9 |
670 | 670 | ||
671 | rmpr3: |
671 | rmpr3: |
672 | 672 | ||
673 | mov edi, esi |
673 | mov edi, esi |
674 | shl edi, 4 |
674 | shl edi, 4 |
675 | add edi, RESERVED_PORTS |
675 | add edi, RESERVED_PORTS |
676 | 676 | ||
677 | cmp edx, [edi] |
677 | cmp edx, [edi] |
678 | je rmpr4 |
678 | je rmpr4 |
679 | 679 | ||
680 | dec esi |
680 | dec esi |
681 | jnz rmpr3 |
681 | jnz rmpr3 |
682 | 682 | ||
683 | jmp rmpr9 |
683 | jmp rmpr9 |
684 | 684 | ||
685 | rmpr4: |
685 | rmpr4: |
686 | 686 | ||
687 | mov ecx, 256 |
687 | mov ecx, 256 |
688 | sub ecx, esi |
688 | sub ecx, esi |
689 | shl ecx, 4 |
689 | shl ecx, 4 |
690 | 690 | ||
691 | mov esi, edi |
691 | mov esi, edi |
692 | add esi, 16 |
692 | add esi, 16 |
693 | cld |
693 | cld |
694 | rep movsb |
694 | rep movsb |
695 | 695 | ||
696 | dec dword [RESERVED_PORTS] |
696 | dec dword [RESERVED_PORTS] |
697 | 697 | ||
698 | jmp rmpr0 |
698 | jmp rmpr0 |
699 | 699 | ||
700 | rmpr9: |
700 | rmpr9: |
701 | popa |
701 | popa |
702 | 702 | ||
703 | ; clearing APPDATA structure this thread |
703 | ; clearing APPDATA structure this thread |
704 | pushad |
704 | pushad |
705 | mov edi, esi |
705 | mov edi, esi |
706 | shl edi, BSF sizeof.APPDATA |
706 | shl edi, BSF sizeof.APPDATA |
707 | add edi, SLOT_BASE |
707 | add edi, SLOT_BASE |
708 | mov eax, 0x20202020 |
708 | mov eax, 0x20202020 |
709 | stosd |
709 | stosd |
710 | stosd |
710 | stosd |
711 | stosd |
711 | stosd |
712 | mov ecx, 244/4 |
712 | mov ecx, 244/4 |
713 | xor eax, eax |
713 | xor eax, eax |
714 | rep stosd |
714 | rep stosd |
715 | popad |
715 | popad |
716 | 716 | ||
717 | mov edi, esi ; do not run this process slot |
717 | mov edi, esi ; do not run this process slot |
718 | shl edi, BSF sizeof.APPDATA |
718 | shl edi, BSF sizeof.APPDATA |
719 | mov [SLOT_BASE + edi + APPDATA.state], TSTATE_FREE |
719 | mov [SLOT_BASE + edi + APPDATA.state], TSTATE_FREE |
720 | ; debugger test - terminate all debuggees |
720 | ; debugger test - terminate all debuggees |
721 | mov eax, 2 |
721 | mov eax, 2 |
722 | mov ecx, SLOT_BASE + 2*sizeof.APPDATA + APPDATA.debugger_slot |
722 | mov ecx, SLOT_BASE + 2*sizeof.APPDATA + APPDATA.debugger_slot |
723 | .xd0: |
723 | .xd0: |
724 | cmp eax, [thread_count] |
724 | cmp eax, [thread_count] |
725 | ja .xd1 |
725 | ja .xd1 |
726 | cmp dword [ecx], esi |
726 | cmp dword [ecx], esi |
727 | jnz @f |
727 | jnz @f |
728 | and dword [ecx], 0 |
728 | and dword [ecx], 0 |
729 | pushad |
729 | pushad |
730 | xchg eax, ecx |
730 | xchg eax, ecx |
731 | mov ebx, 2 |
731 | mov ebx, 2 |
732 | call sys_system |
732 | call sys_system |
733 | popad |
733 | popad |
734 | @@: |
734 | @@: |
735 | inc eax |
735 | inc eax |
736 | add ecx, sizeof.APPDATA |
736 | add ecx, sizeof.APPDATA |
737 | jmp .xd0 |
737 | jmp .xd0 |
738 | .xd1: |
738 | .xd1: |
739 | ;release slot |
739 | ;release slot |
740 | 740 | ||
741 | bts [thr_slot_map], esi |
741 | bts [thr_slot_map], esi |
742 | 742 | ||
743 | mov ecx, [.process] |
743 | mov ecx, [.process] |
744 | lea eax, [ecx + PROC.thr_list] |
744 | lea eax, [ecx + PROC.thr_list] |
745 | cmp eax, [eax + LHEAD.next] |
745 | cmp eax, [eax + LHEAD.next] |
746 | jne @F |
746 | jne @F |
747 | 747 | ||
748 | call destroy_process.internal |
748 | call destroy_process.internal |
749 | @@: |
749 | @@: |
750 | sti ; .. and life goes on |
750 | sti ; .. and life goes on |
751 | 751 | ||
752 | mov eax, [draw_limits.left] |
752 | mov eax, [draw_limits.left] |
753 | mov ebx, [draw_limits.top] |
753 | mov ebx, [draw_limits.top] |
754 | mov ecx, [draw_limits.right] |
754 | mov ecx, [draw_limits.right] |
755 | mov edx, [draw_limits.bottom] |
755 | mov edx, [draw_limits.bottom] |
756 | call calculatescreen |
756 | call calculatescreen |
757 | xor eax, eax |
757 | xor eax, eax |
758 | xor esi, esi |
758 | xor esi, esi |
759 | call redrawscreen |
759 | call redrawscreen |
760 | 760 | ||
761 | call unlock_application_table |
761 | call unlock_application_table |
762 | ;mov esi,process_terminated |
762 | ;mov esi,process_terminated |
763 | ;call sys_msg_board_str |
763 | ;call sys_msg_board_str |
764 | add esp, 8 |
764 | add esp, 8 |
765 | ret |
765 | ret |
766 | restore .slot |
766 | restore .slot |
767 | restore .process |
767 | restore .process |
768 | 768 | ||
769 | ; Three following procedures are used to guarantee that |
769 | ; Three following procedures are used to guarantee that |
770 | ; some part of kernel code will not be terminated from outside |
770 | ; some part of kernel code will not be terminated from outside |
771 | ; while it is running. |
771 | ; while it is running. |
772 | ; Note: they do not protect a thread from terminating due to errors inside |
772 | ; Note: they do not protect a thread from terminating due to errors inside |
773 | ; the thread; accessing a nonexisting memory would still terminate it. |
773 | ; the thread; accessing a nonexisting memory would still terminate it. |
774 | 774 | ||
775 | ; First two procedures must be used in pair by thread-to-be-protected |
775 | ; First two procedures must be used in pair by thread-to-be-protected |
776 | ; to signal the beginning and the end of an important part. |
776 | ; to signal the beginning and the end of an important part. |
777 | ; It is OK to have nested areas. |
777 | ; It is OK to have nested areas. |
778 | 778 | ||
779 | ; The last procedure must be used by outside wanna-be-terminators; |
779 | ; The last procedure must be used by outside wanna-be-terminators; |
780 | ; if it is safe to terminate the given thread immediately, it returns eax=1; |
780 | ; if it is safe to terminate the given thread immediately, it returns eax=1; |
781 | ; otherwise, it returns eax=0 and notifies the target thread that it should |
781 | ; otherwise, it returns eax=0 and notifies the target thread that it should |
782 | ; terminate itself when leaving a critical area (the last critical area if |
782 | ; terminate itself when leaving a critical area (the last critical area if |
783 | ; they are nested). |
783 | ; they are nested). |
784 | 784 | ||
785 | ; Implementation. Those procedures use one dword in APPDATA for the thread, |
785 | ; Implementation. Those procedures use one dword in APPDATA for the thread, |
786 | ; APPDATA.terminate_protection. |
786 | ; APPDATA.terminate_protection. |
787 | ; * The upper bit is 1 during normal operations and 0 when terminate is requested. |
787 | ; * The upper bit is 1 during normal operations and 0 when terminate is requested. |
788 | ; * Other bits form a number = depth of critical regions, |
788 | ; * Other bits form a number = depth of critical regions, |
789 | ; plus 1 if the upper bit is 1. |
789 | ; plus 1 if the upper bit is 1. |
790 | ; * When this dword goes to zero, the thread should be destructed, |
790 | ; * When this dword goes to zero, the thread should be destructed, |
791 | ; and the procedure in which it happened becomes responsible for destruction. |
791 | ; and the procedure in which it happened becomes responsible for destruction. |
792 | 792 | ||
793 | ; Enter critical area. Called by thread which wants to be protected. |
793 | ; Enter critical area. Called by thread which wants to be protected. |
794 | proc protect_from_terminate |
794 | proc protect_from_terminate |
795 | mov edx, [current_slot] |
795 | mov edx, [current_slot] |
796 | ; Atomically increment depth of critical areas and get the old value. |
796 | ; Atomically increment depth of critical areas and get the old value. |
797 | mov eax, 1 |
797 | mov eax, 1 |
798 | lock xadd [edx + APPDATA.terminate_protection], eax |
798 | lock xadd [edx + APPDATA.terminate_protection], eax |
799 | ; If the old value was zero, somebody has started to terminate us, |
799 | ; If the old value was zero, somebody has started to terminate us, |
800 | ; so we are destructing and cannot do anything protected. |
800 | ; so we are destructing and cannot do anything protected. |
801 | ; Otherwise, return to the caller. |
801 | ; Otherwise, return to the caller. |
802 | test eax, eax |
802 | test eax, eax |
803 | jz @f |
803 | jz @f |
804 | ret |
804 | ret |
805 | @@: |
805 | @@: |
806 | ; Wait for somebody to finish us. |
806 | ; Wait for somebody to finish us. |
807 | call change_task |
807 | call change_task |
808 | jmp @b |
808 | jmp @b |
809 | endp |
809 | endp |
810 | 810 | ||
811 | ; Leave critical area. Called by thread which wants to be protected. |
811 | ; Leave critical area. Called by thread which wants to be protected. |
812 | proc unprotect_from_terminate |
812 | proc unprotect_from_terminate |
813 | mov edx, [current_slot] |
813 | mov edx, [current_slot] |
814 | ; Atomically decrement depth of critical areas. |
814 | ; Atomically decrement depth of critical areas. |
815 | lock dec [edx + APPDATA.terminate_protection] |
815 | lock dec [edx + APPDATA.terminate_protection] |
816 | ; If the result of decrement is zero, somebody has requested termination, |
816 | ; If the result of decrement is zero, somebody has requested termination, |
817 | ; but at that moment we were inside a critical area; terminate now. |
817 | ; but at that moment we were inside a critical area; terminate now. |
818 | jz sys_end |
818 | jz sys_end |
819 | ; Otherwise, return to the caller. |
819 | ; Otherwise, return to the caller. |
820 | ret |
820 | ret |
821 | endp |
821 | endp |
822 | 822 | ||
823 | ; Request termination of thread identified by edx = SLOT_BASE + slot*sizeof.APPDATA. |
823 | ; Request termination of thread identified by edx = SLOT_BASE + slot*sizeof.APPDATA. |
824 | ; Called by anyone. |
824 | ; Called by anyone. |
825 | proc request_terminate |
825 | proc request_terminate |
826 | xor eax, eax ; set return value |
826 | xor eax, eax ; set return value |
827 | ; Atomically clear the upper bit. If it was already zero, then |
827 | ; Atomically clear the upper bit. If it was already zero, then |
828 | ; somebody has requested termination before us, so just exit. |
828 | ; somebody has requested termination before us, so just exit. |
829 | lock btr [edx + APPDATA.terminate_protection], 31 |
829 | lock btr [edx + APPDATA.terminate_protection], 31 |
830 | jnc .unsafe |
830 | jnc .unsafe |
831 | ; Atomically decrement depth of critical areas. |
831 | ; Atomically decrement depth of critical areas. |
832 | lock dec [edx + APPDATA.terminate_protection] |
832 | lock dec [edx + APPDATA.terminate_protection] |
833 | ; If the result of decrement is nonzero, the target thread is inside a |
833 | ; If the result of decrement is nonzero, the target thread is inside a |
834 | ; critical area; leave termination to leaving that area. |
834 | ; critical area; leave termination to leaving that area. |
835 | jnz .unsafe |
835 | jnz .unsafe |
836 | ; Otherwise, it is safe to kill the target now and the caller is responsible |
836 | ; Otherwise, it is safe to kill the target now and the caller is responsible |
837 | ; for this. Return eax=1. |
837 | ; for this. Return eax=1. |
838 | inc eax |
838 | inc eax |
839 | .unsafe: |
839 | .unsafe: |
840 | ret |
840 | ret |
841 | endp |
841 | endp |