Subversion Repositories Kolibri OS

Rev

Rev 9976 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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