Subversion Repositories Kolibri OS

Rev

Rev 8874 | Rev 9692 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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