Subversion Repositories Kolibri OS

Rev

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

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