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