Subversion Repositories Kolibri OS

Rev

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

Rev 7733 Rev 8050
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2020. 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: 7733 $
8
$Revision: 8050 $
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:                 ; дуракоусточивость: селекторы испорчены...
107
page_fault_exc:                   ; foolproof: selectors are clobbered ...
108
        pop     [ss:pf_err_code]; действительно до следующего #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:                          ; исключения (все, кроме 7-го - #NM)
112
exc_c:                            ; exceptions (all but 7th - #NM)
113
; Фрэйм стека при исключении/прерывании из 3-го кольца + pushad (т.е., именно здесь)
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
 ; это фрэйм от 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        ;исключение
129
        mov     ax, app_data       ; exception
130
        mov     ds, ax                  ;загрузим правильные значения
130
        mov     ds, ax             ; load proper values
131
        mov     es, ax                  ;в регистры
131
        mov     es, ax             ; to registers
132
        cld                     ; и приводим DF к стандарту
132
        cld                        ; clear the destination 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], byte 4 ; terminate
155
        mov     [edx + TASKDATA.state], byte 4 ; terminate
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     byte [edx+TASKDATA.state], 1 ; suspended
190
        mov     byte [edx+TASKDATA.state], 1 ; 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_TASK]
345
        mov     eax, [CURRENT_TASK]
346
        shl     eax, 5
346
        shl     eax, 5
347
        add     eax, CURRENT_TASK+TASKDATA.pid
347
        add     eax, CURRENT_TASK+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
 
-
 
368
;  * eax = 64 - номер функции
-
 
369
;  * ebx = 1 - единственная подфункция
-
 
370
;  * ecx = новый размер памяти
-
 
371
;Возвращаемое значение:
367
 
372
;  * eax = 0 - успешно
-
 
373
;  * eax = 1 - недостаточно памяти
-
 
374
 
368
; sysfn 64 implementation
375
align 4
369
align 4
376
sys_resize_app_memory:
370
sys_resize_app_memory:
-
 
371
; in:   eax = 64 - function number
377
        ; ebx = 1 - resize
372
;       ebx = 1 - number of its only subfunction
-
 
373
;       ecx = new amount of memory
-
 
374
; out:
-
 
375
;       eax = 0 - success
378
        ; ecx = new amount of memory
376
;       eax = 1 - out of memory
379
 
377
 
380
;        cmp    eax,1
378
;        cmp    eax,1
381
        dec     ebx
379
        dec     ebx
382
        jnz     .no_application_mem_resize
380
        jnz     .no_application_mem_resize
383
 
381
 
384
        mov     eax, [pg_data.pages_free]
382
        mov     eax, [pg_data.pages_free]
385
        shl     eax, 12
383
        shl     eax, 12
386
        cmp     eax, ecx
384
        cmp     eax, ecx
387
        jae     @f
385
        jae     @f
388
 
386
 
389
        xor     eax, eax
387
        xor     eax, eax
390
        inc     eax
388
        inc     eax
391
        jmp     .store_result
389
        jmp     .store_result
392
@@:
390
@@:
393
        stdcall new_mem_resize, ecx
391
        stdcall new_mem_resize, ecx
394
.store_result:
392
.store_result:
395
        mov     [esp+32], eax
393
        mov     [esp+32], eax
396
.no_application_mem_resize:
394
.no_application_mem_resize:
397
        ret
395
        ret
398
 
396
 
399
iglobal
397
iglobal
400
;  process_terminating  db 'K : Process - terminating',13,10,0
398
;  process_terminating  db 'K : Process - terminating',13,10,0
401
;  process_terminated   db 'K : Process - done',13,10,0
399
;  process_terminated   db 'K : Process - done',13,10,0
402
  msg_obj_destroy       db 'K : destroy app object',13,10,0
400
  msg_obj_destroy       db 'K : destroy app object',13,10,0
403
endg
401
endg
404
 
402
 
405
; param
403
; param
406
;  esi= slot
404
;  esi= slot
407
 
405
 
408
align 4
406
align 4
409
terminate: ; terminate application
407
terminate: ; terminate application
410
destroy_thread:
408
destroy_thread:
411
 
409
 
412
        .slot     equ esp+4             ;locals
410
        .slot     equ esp+4             ;locals
413
        .process  equ esp               ;ptr to parent process
411
        .process  equ esp               ;ptr to parent process
414
 
412
 
415
 
413
 
416
        push    esi        ;save .slot
414
        push    esi        ;save .slot
417
 
415
 
418
        shl     esi, 8
416
        shl     esi, 8
419
        mov     edx, [SLOT_BASE+esi+APPDATA.process]
417
        mov     edx, [SLOT_BASE+esi+APPDATA.process]
420
        test    edx, edx
418
        test    edx, edx
421
        jnz     @F
419
        jnz     @F
422
        pop     esi
420
        pop     esi
423
        shl     esi, 5
421
        shl     esi, 5
424
        mov     [CURRENT_TASK+esi+TASKDATA.state], 9
422
        mov     [CURRENT_TASK+esi+TASKDATA.state], 9
425
        ret
423
        ret
426
@@:
424
@@:
427
        push    edx                     ;save .process
425
        push    edx                     ;save .process
428
        lea     edx, [SLOT_BASE+esi]
426
        lea     edx, [SLOT_BASE+esi]
429
        call    scheduler_remove_thread
427
        call    scheduler_remove_thread
430
        call    lock_application_table
428
        call    lock_application_table
431
 
429
 
432
; if the process is in V86 mode...
430
; if the process is in V86 mode...
433
        mov     eax, [.slot]
431
        mov     eax, [.slot]
434
        shl     eax, 8
432
        shl     eax, 8
435
        mov     esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
433
        mov     esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
436
        add     esi, RING0_STACK_SIZE
434
        add     esi, RING0_STACK_SIZE
437
        cmp     [eax+SLOT_BASE+APPDATA.saved_esp0], esi
435
        cmp     [eax+SLOT_BASE+APPDATA.saved_esp0], esi
438
        jz      .nov86
436
        jz      .nov86
439
; ...it has page directory for V86 mode
437
; ...it has page directory for V86 mode
440
        mov     esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
438
        mov     esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
441
        mov     ecx, [esi+4]
439
        mov     ecx, [esi+4]
442
        mov     [eax+SLOT_BASE+APPDATA.process], ecx
440
        mov     [eax+SLOT_BASE+APPDATA.process], ecx
443
; ...and I/O permission map for V86 mode
441
; ...and I/O permission map for V86 mode
444
        mov     ecx, [esi+12]
442
        mov     ecx, [esi+12]
445
        mov     [eax+SLOT_BASE+APPDATA.io_map], ecx
443
        mov     [eax+SLOT_BASE+APPDATA.io_map], ecx
446
        mov     ecx, [esi+8]
444
        mov     ecx, [esi+8]
447
        mov     [eax+SLOT_BASE+APPDATA.io_map+4], ecx
445
        mov     [eax+SLOT_BASE+APPDATA.io_map+4], ecx
448
.nov86:
446
.nov86:
449
;destroy per-thread kernel objects
447
; destroy per-thread kernel objects
450
        mov     esi, [.slot]
448
        mov     esi, [.slot]
451
        shl     esi, 8
449
        shl     esi, 8
452
        add     esi, SLOT_BASE+APP_OBJ_OFFSET
450
        add     esi, SLOT_BASE+APP_OBJ_OFFSET
453
@@:
451
@@:
454
        mov     eax, [esi+APPOBJ.fd]
452
        mov     eax, [esi+APPOBJ.fd]
455
        test    eax, eax
453
        test    eax, eax
456
        jz      @F
454
        jz      @F
457
 
455
 
458
        cmp     eax, esi
456
        cmp     eax, esi
459
        je      @F
457
        je      @F
460
 
458
 
461
        push    esi
459
        push    esi
462
        call    [eax+APPOBJ.destroy]
460
        call    [eax+APPOBJ.destroy]
463
           DEBUGF 1,"%s",msg_obj_destroy
461
           DEBUGF 1,"%s",msg_obj_destroy
464
        pop     esi
462
        pop     esi
465
        jmp     @B
463
        jmp     @B
466
@@:
464
@@:
467
        mov     esi, [.slot]
465
        mov     esi, [.slot]
468
        cmp     [fpu_owner], esi ; if user fpu last -> fpu user = 2
466
        cmp     [fpu_owner], esi ; if user fpu last -> fpu user = 2
469
        jne     @F
467
        jne     @F
470
 
468
 
471
        mov     [fpu_owner], 2
469
        mov     [fpu_owner], 2
472
        mov     eax, [256*2+SLOT_BASE+APPDATA.fpu_state]
470
        mov     eax, [256*2+SLOT_BASE+APPDATA.fpu_state]
473
        clts
471
        clts
474
        bt      [cpu_caps], CAPS_SSE
472
        bt      [cpu_caps], CAPS_SSE
475
        jnc     .no_SSE
473
        jnc     .no_SSE
476
        fxrstor [eax]
474
        fxrstor [eax]
477
        jmp     @F
475
        jmp     @F
478
.no_SSE:
476
.no_SSE:
479
        fnclex
477
        fnclex
480
        frstor  [eax]
478
        frstor  [eax]
481
@@:
479
@@:
482
 
480
 
483
        mov     [KEY_COUNT], byte 0    ; empty keyboard buffer
481
        mov     [KEY_COUNT], byte 0    ; empty keyboard buffer
484
        mov     [BTN_COUNT], byte 0    ; empty button buffer
482
        mov     [BTN_COUNT], byte 0    ; empty button buffer
485
 
483
 
486
 
484
 
487
; remove defined hotkeys
485
; remove defined hotkeys
488
        mov     eax, hotkey_list
486
        mov     eax, hotkey_list
489
.loop:
487
.loop:
490
        cmp     [eax+8], esi
488
        cmp     [eax+8], esi
491
        jnz     .cont
489
        jnz     .cont
492
        mov     ecx, [eax]
490
        mov     ecx, [eax]
493
        jecxz   @f
491
        jecxz   @f
494
        push    dword [eax+12]
492
        push    dword [eax+12]
495
        pop     dword [ecx+12]
493
        pop     dword [ecx+12]
496
@@:
494
@@:
497
        mov     ecx, [eax+12]
495
        mov     ecx, [eax+12]
498
        push    dword [eax]
496
        push    dword [eax]
499
        pop     dword [ecx]
497
        pop     dword [ecx]
500
        xor     ecx, ecx
498
        xor     ecx, ecx
501
        mov     [eax], ecx
499
        mov     [eax], ecx
502
        mov     [eax+4], ecx
500
        mov     [eax+4], ecx
503
        mov     [eax+8], ecx
501
        mov     [eax+8], ecx
504
        mov     [eax+12], ecx
502
        mov     [eax+12], ecx
505
.cont:
503
.cont:
506
        add     eax, 16
504
        add     eax, 16
507
        cmp     eax, hotkey_list+256*16
505
        cmp     eax, hotkey_list+256*16
508
        jb      .loop
506
        jb      .loop
509
; get process PID
507
; get process PID
510
        mov     eax, esi
508
        mov     eax, esi
511
        shl     eax, 5
509
        shl     eax, 5
512
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
510
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
513
; compare current lock input with process PID
511
; compare current lock input with process PID
514
        cmp     eax, [PID_lock_input]
512
        cmp     eax, [PID_lock_input]
515
        jne     @f
513
        jne     @f
516
 
514
 
517
        xor     eax, eax
515
        xor     eax, eax
518
        mov     [PID_lock_input], eax
516
        mov     [PID_lock_input], eax
519
@@:
517
@@:
520
; remove hotkeys in buffer
518
; remove hotkeys in buffer
521
        mov     eax, hotkey_buffer
519
        mov     eax, hotkey_buffer
522
.loop2:
520
.loop2:
523
        cmp     [eax], esi
521
        cmp     [eax], esi
524
        jnz     .cont2
522
        jnz     .cont2
525
        and     dword [eax+4], 0
523
        and     dword [eax+4], 0
526
        and     dword [eax], 0
524
        and     dword [eax], 0
527
.cont2:
525
.cont2:
528
        add     eax, 8
526
        add     eax, 8
529
        cmp     eax, hotkey_buffer+120*8
527
        cmp     eax, hotkey_buffer+120*8
530
        jb      .loop2
528
        jb      .loop2
531
 
529
 
532
        mov     ecx, esi          ; remove buttons
530
        mov     ecx, esi          ; remove buttons
533
  bnewba2:
531
  bnewba2:
534
        mov     edi, [BTN_ADDR]
532
        mov     edi, [BTN_ADDR]
535
        mov     eax, edi
533
        mov     eax, edi
536
        cld
534
        cld
537
        movzx   ebx, word [edi]
535
        movzx   ebx, word [edi]
538
        inc     bx
536
        inc     bx
539
  bnewba:
537
  bnewba:
540
        dec     bx
538
        dec     bx
541
        jz      bnmba
539
        jz      bnmba
542
        add     eax, 0x10
540
        add     eax, 0x10
543
        cmp     cx, [eax]
541
        cmp     cx, [eax]
544
        jnz     bnewba
542
        jnz     bnewba
545
        pusha
543
        pusha
546
        mov     ecx, ebx
544
        mov     ecx, ebx
547
        inc     ecx
545
        inc     ecx
548
        shl     ecx, 4
546
        shl     ecx, 4
549
        mov     ebx, eax
547
        mov     ebx, eax
550
        add     eax, 0x10
548
        add     eax, 0x10
551
        call    memmove
549
        call    memmove
552
        dec     dword [edi]
550
        dec     dword [edi]
553
        popa
551
        popa
554
        jmp     bnewba2
552
        jmp     bnewba2
555
  bnmba:
553
  bnmba:
556
 
554
 
557
        pusha   ; save window coordinates for window restoring
555
        pusha   ; save window coordinates for window restoring
558
        cld
556
        cld
559
        shl     esi, 5
557
        shl     esi, 5
560
        add     esi, window_data
558
        add     esi, window_data
561
        mov     eax, [esi+WDATA.box.left]
559
        mov     eax, [esi+WDATA.box.left]
562
        mov     [draw_limits.left], eax
560
        mov     [draw_limits.left], eax
563
        add     eax, [esi+WDATA.box.width]
561
        add     eax, [esi+WDATA.box.width]
564
        mov     [draw_limits.right], eax
562
        mov     [draw_limits.right], eax
565
        mov     eax, [esi+WDATA.box.top]
563
        mov     eax, [esi+WDATA.box.top]
566
        mov     [draw_limits.top], eax
564
        mov     [draw_limits.top], eax
567
        add     eax, [esi+WDATA.box.height]
565
        add     eax, [esi+WDATA.box.height]
568
        mov     [draw_limits.bottom], eax
566
        mov     [draw_limits.bottom], eax
569
 
567
 
570
        xor     eax, eax
568
        xor     eax, eax
571
        mov     [esi+WDATA.box.left], eax
569
        mov     [esi+WDATA.box.left], eax
572
        mov     [esi+WDATA.box.width], eax
570
        mov     [esi+WDATA.box.width], eax
573
        mov     [esi+WDATA.box.top], eax
571
        mov     [esi+WDATA.box.top], eax
574
        mov     [esi+WDATA.box.height], eax
572
        mov     [esi+WDATA.box.height], eax
575
        mov     [esi+WDATA.cl_workarea], eax
573
        mov     [esi+WDATA.cl_workarea], eax
576
        mov     [esi+WDATA.cl_titlebar], eax
574
        mov     [esi+WDATA.cl_titlebar], eax
577
        mov     [esi+WDATA.cl_frames], eax
575
        mov     [esi+WDATA.cl_frames], eax
578
        mov     dword [esi+WDATA.z_modif], eax; clear all flags: z_modif, wstate, redraw, wdrawn
576
        mov     dword [esi+WDATA.z_modif], eax; clear all flags: z_modif, wstate, redraw, wdrawn
579
        lea     edi, [esi-window_data+draw_data]
577
        lea     edi, [esi-window_data+draw_data]
580
        mov     ecx, 32/4
578
        mov     ecx, 32/4
581
        rep stosd
579
        rep stosd
582
        popa
580
        popa
583
 
581
 
584
; debuggee test
582
; debuggee test
585
        pushad
583
        pushad
586
        mov     edi, esi
584
        mov     edi, esi
587
        shl     edi, 5
585
        shl     edi, 5
588
        mov     eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
586
        mov     eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
589
        test    eax, eax
587
        test    eax, eax
590
        jz      .nodebug
588
        jz      .nodebug
591
        movi    ecx, 8
589
        movi    ecx, 8
592
        push    dword [CURRENT_TASK+edi+TASKDATA.pid]; PID
590
        push    dword [CURRENT_TASK+edi+TASKDATA.pid]; PID
593
        push    2
591
        push    2
594
        call    debugger_notify
592
        call    debugger_notify
595
        pop     ecx
593
        pop     ecx
596
        pop     ecx
594
        pop     ecx
597
.nodebug:
595
.nodebug:
598
        popad
596
        popad
599
 
597
 
600
        mov     ebx, [.slot]
598
        mov     ebx, [.slot]
601
        shl     ebx, 8
599
        shl     ebx, 8
602
        push    ebx
600
        push    ebx
603
        mov     ebx, [SLOT_BASE+ebx+APPDATA.pl0_stack]
601
        mov     ebx, [SLOT_BASE+ebx+APPDATA.pl0_stack]
604
 
602
 
605
        stdcall kernel_free, ebx
603
        stdcall kernel_free, ebx
606
 
604
 
607
        pop     ebx
605
        pop     ebx
608
        mov     ebx, [SLOT_BASE+ebx+APPDATA.cur_dir]
606
        mov     ebx, [SLOT_BASE+ebx+APPDATA.cur_dir]
609
        stdcall kernel_free, ebx
607
        stdcall kernel_free, ebx
610
 
608
 
611
        mov     edi, [.slot]
609
        mov     edi, [.slot]
612
        shl     edi, 8
610
        shl     edi, 8
613
        add     edi, SLOT_BASE
611
        add     edi, SLOT_BASE
614
 
612
 
615
        mov     eax, [edi+APPDATA.io_map]
613
        mov     eax, [edi+APPDATA.io_map]
616
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map]
614
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map]
617
        je      @F
615
        je      @F
618
        call    free_page
616
        call    free_page
619
@@:
617
@@:
620
        mov     eax, [edi+APPDATA.io_map+4]
618
        mov     eax, [edi+APPDATA.io_map+4]
621
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map+4]
619
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map+4]
622
        je      @F
620
        je      @F
623
        call    free_page
621
        call    free_page
624
@@:
622
@@:
625
        lea     ebx, [edi+APPDATA.list]
623
        lea     ebx, [edi+APPDATA.list]
626
        list_del ebx                    ;destroys edx, ecx
624
        list_del ebx                    ;destroys edx, ecx
627
 
625
 
628
        mov     eax, 0x20202020
626
        mov     eax, 0x20202020
629
        stosd
627
        stosd
630
        stosd
628
        stosd
631
        stosd
629
        stosd
632
        mov     ecx, 244/4
630
        mov     ecx, 244/4
633
        xor     eax, eax
631
        xor     eax, eax
634
        rep stosd
632
        rep stosd
635
 
633
 
636
  ; activate window
634
  ; activate window
637
        movzx   eax, word [WIN_STACK + esi*2]
635
        movzx   eax, word [WIN_STACK + esi*2]
638
        cmp     eax, [TASK_COUNT]
636
        cmp     eax, [TASK_COUNT]
639
        jne     .dont_activate
637
        jne     .dont_activate
640
        pushad
638
        pushad
641
 .check_next_window:
639
 .check_next_window:
642
        dec     eax
640
        dec     eax
643
        cmp     eax, 1
641
        cmp     eax, 1
644
        jbe     .nothing_to_activate
642
        jbe     .nothing_to_activate
645
        lea     esi, [WIN_POS+eax*2]
643
        lea     esi, [WIN_POS+eax*2]
646
        movzx   edi, word [esi]              ; edi = process
644
        movzx   edi, word [esi]              ; edi = process
647
        shl     edi, 5
645
        shl     edi, 5
648
        cmp     [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
646
        cmp     [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
649
        je      .check_next_window
647
        je      .check_next_window
650
        add     edi, window_data
648
        add     edi, window_data
651
; \begin{diamond}[19.09.2006]
649
; \begin{diamond}[19.09.2006]
652
; skip minimized windows
650
; skip minimized windows
653
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
651
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
654
        jnz     .check_next_window
652
        jnz     .check_next_window
655
; \end{diamond}
653
; \end{diamond}
656
        call    waredraw
654
        call    waredraw
657
 .nothing_to_activate:
655
 .nothing_to_activate:
658
        popad
656
        popad
659
 .dont_activate:
657
 .dont_activate:
660
 
658
 
661
        push    esi     ; remove hd1 & cd & flp reservation
659
        push    esi     ; remove hd1 & cd & flp reservation
662
        shl     esi, 5
660
        shl     esi, 5
663
        mov     esi, [esi+CURRENT_TASK+TASKDATA.pid]
661
        mov     esi, [esi+CURRENT_TASK+TASKDATA.pid]
664
        cmp     [cd_status], esi
662
        cmp     [cd_status], esi
665
        jnz     @f
663
        jnz     @f
666
        call    free_cd_channel
664
        call    free_cd_channel
667
        and     [cd_status], 0
665
        and     [cd_status], 0
668
@@:
666
@@:
669
        pop     esi
667
        pop     esi
670
        cmp     [bgrlockpid], esi
668
        cmp     [bgrlockpid], esi
671
        jnz     @f
669
        jnz     @f
672
        and     [bgrlockpid], 0
670
        and     [bgrlockpid], 0
673
        and     [bgrlock], 0
671
        and     [bgrlock], 0
674
@@:
672
@@:
675
 
673
 
676
        pusha                 ; remove all port reservations
674
        pusha                 ; remove all port reservations
677
        mov     edx, esi
675
        mov     edx, esi
678
        shl     edx, 5
676
        shl     edx, 5
679
        add     edx, CURRENT_TASK
677
        add     edx, CURRENT_TASK
680
        mov     edx, [edx+TASKDATA.pid]
678
        mov     edx, [edx+TASKDATA.pid]
681
 
679
 
682
  rmpr0:
680
  rmpr0:
683
 
681
 
684
        mov     esi, [RESERVED_PORTS]
682
        mov     esi, [RESERVED_PORTS]
685
 
683
 
686
        test    esi, esi
684
        test    esi, esi
687
        jz      rmpr9
685
        jz      rmpr9
688
 
686
 
689
  rmpr3:
687
  rmpr3:
690
 
688
 
691
        mov     edi, esi
689
        mov     edi, esi
692
        shl     edi, 4
690
        shl     edi, 4
693
        add     edi, RESERVED_PORTS
691
        add     edi, RESERVED_PORTS
694
 
692
 
695
        cmp     edx, [edi]
693
        cmp     edx, [edi]
696
        je      rmpr4
694
        je      rmpr4
697
 
695
 
698
        dec     esi
696
        dec     esi
699
        jnz     rmpr3
697
        jnz     rmpr3
700
 
698
 
701
        jmp     rmpr9
699
        jmp     rmpr9
702
 
700
 
703
  rmpr4:
701
  rmpr4:
704
 
702
 
705
        mov     ecx, 256
703
        mov     ecx, 256
706
        sub     ecx, esi
704
        sub     ecx, esi
707
        shl     ecx, 4
705
        shl     ecx, 4
708
 
706
 
709
        mov     esi, edi
707
        mov     esi, edi
710
        add     esi, 16
708
        add     esi, 16
711
        cld
709
        cld
712
        rep movsb
710
        rep movsb
713
 
711
 
714
        dec     dword [RESERVED_PORTS]
712
        dec     dword [RESERVED_PORTS]
715
 
713
 
716
        jmp     rmpr0
714
        jmp     rmpr0
717
 
715
 
718
  rmpr9:
716
  rmpr9:
719
 
717
 
720
        popa
718
        popa
721
        mov     edi, esi ; do not run this process slot
719
        mov     edi, esi ; do not run this process slot
722
        shl     edi, 5
720
        shl     edi, 5
723
        mov     [edi+CURRENT_TASK + TASKDATA.state], byte 9
721
        mov     [edi+CURRENT_TASK + TASKDATA.state], byte 9
724
; debugger test - terminate all debuggees
722
; debugger test - terminate all debuggees
725
        mov     eax, 2
723
        mov     eax, 2
726
        mov     ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
724
        mov     ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
727
.xd0:
725
.xd0:
728
        cmp     eax, [TASK_COUNT]
726
        cmp     eax, [TASK_COUNT]
729
        ja      .xd1
727
        ja      .xd1
730
        cmp     dword [ecx], esi
728
        cmp     dword [ecx], esi
731
        jnz     @f
729
        jnz     @f
732
        and     dword [ecx], 0
730
        and     dword [ecx], 0
733
        pushad
731
        pushad
734
        xchg    eax, ecx
732
        xchg    eax, ecx
735
        mov     ebx, 2
733
        mov     ebx, 2
736
        call    sys_system
734
        call    sys_system
737
        popad
735
        popad
738
@@:
736
@@:
739
        inc     eax
737
        inc     eax
740
        add     ecx, 0x100
738
        add     ecx, 0x100
741
        jmp     .xd0
739
        jmp     .xd0
742
.xd1:
740
.xd1:
743
;release slot
741
;release slot
744
 
742
 
745
        bts     [thr_slot_map], esi
743
        bts     [thr_slot_map], esi
746
 
744
 
747
        mov     ecx, [.process]
745
        mov     ecx, [.process]
748
        lea     eax, [ecx+PROC.thr_list]
746
        lea     eax, [ecx+PROC.thr_list]
749
        cmp     eax, [eax+LHEAD.next]
747
        cmp     eax, [eax+LHEAD.next]
750
        jne     @F
748
        jne     @F
751
 
749
 
752
        call    destroy_process.internal
750
        call    destroy_process.internal
753
@@:
751
@@:
754
        sti     ; .. and life goes on
752
        sti     ; .. and life goes on
755
 
753
 
756
        mov     eax, [draw_limits.left]
754
        mov     eax, [draw_limits.left]
757
        mov     ebx, [draw_limits.top]
755
        mov     ebx, [draw_limits.top]
758
        mov     ecx, [draw_limits.right]
756
        mov     ecx, [draw_limits.right]
759
        mov     edx, [draw_limits.bottom]
757
        mov     edx, [draw_limits.bottom]
760
        call    calculatescreen
758
        call    calculatescreen
761
        xor     eax, eax
759
        xor     eax, eax
762
        xor     esi, esi
760
        xor     esi, esi
763
        call    redrawscreen
761
        call    redrawscreen
764
 
762
 
765
        call    unlock_application_table
763
        call    unlock_application_table
766
    ;mov   esi,process_terminated
764
    ;mov   esi,process_terminated
767
    ;call  sys_msg_board_str
765
    ;call  sys_msg_board_str
768
        add     esp, 8
766
        add     esp, 8
769
        ret
767
        ret
770
restore .slot
768
restore .slot
771
restore .process
769
restore .process
772
 
770
 
773
; Three following procedures are used to guarantee that
771
; Three following procedures are used to guarantee that
774
; some part of kernel code will not be terminated from outside
772
; some part of kernel code will not be terminated from outside
775
; while it is running.
773
; while it is running.
776
; Note: they do not protect a thread from terminating due to errors inside
774
; Note: they do not protect a thread from terminating due to errors inside
777
; the thread; accessing a nonexisting memory would still terminate it.
775
; the thread; accessing a nonexisting memory would still terminate it.
778
 
776
 
779
; First two procedures must be used in pair by thread-to-be-protected
777
; First two procedures must be used in pair by thread-to-be-protected
780
; to signal the beginning and the end of an important part.
778
; to signal the beginning and the end of an important part.
781
; It is OK to have nested areas.
779
; It is OK to have nested areas.
782
 
780
 
783
; The last procedure must be used by outside wanna-be-terminators;
781
; The last procedure must be used by outside wanna-be-terminators;
784
; if it is safe to terminate the given thread immediately, it returns eax=1;
782
; if it is safe to terminate the given thread immediately, it returns eax=1;
785
; otherwise, it returns eax=0 and notifies the target thread that it should
783
; otherwise, it returns eax=0 and notifies the target thread that it should
786
; terminate itself when leaving a critical area (the last critical area if
784
; terminate itself when leaving a critical area (the last critical area if
787
; they are nested).
785
; they are nested).
788
 
786
 
789
; Implementation. Those procedures use one dword in APPDATA for the thread,
787
; Implementation. Those procedures use one dword in APPDATA for the thread,
790
; APPDATA.terminate_protection.
788
; APPDATA.terminate_protection.
791
; * The upper bit is 1 during normal operations and 0 when terminate is requested.
789
; * The upper bit is 1 during normal operations and 0 when terminate is requested.
792
; * Other bits form a number = depth of critical regions,
790
; * Other bits form a number = depth of critical regions,
793
;   plus 1 if the upper bit is 1.
791
;   plus 1 if the upper bit is 1.
794
; * When this dword goes to zero, the thread should be destructed,
792
; * When this dword goes to zero, the thread should be destructed,
795
;   and the procedure in which it happened becomes responsible for destruction.
793
;   and the procedure in which it happened becomes responsible for destruction.
796
 
794
 
797
; Enter critical area. Called by thread which wants to be protected.
795
; Enter critical area. Called by thread which wants to be protected.
798
proc protect_from_terminate
796
proc protect_from_terminate
799
        mov     edx, [current_slot]
797
        mov     edx, [current_slot]
800
; Atomically increment depth of critical areas and get the old value.
798
; Atomically increment depth of critical areas and get the old value.
801
        mov     eax, 1
799
        mov     eax, 1
802
        lock xadd [edx+APPDATA.terminate_protection], eax
800
        lock xadd [edx+APPDATA.terminate_protection], eax
803
; If the old value was zero, somebody has started to terminate us,
801
; If the old value was zero, somebody has started to terminate us,
804
; so we are destructing and cannot do anything protected.
802
; so we are destructing and cannot do anything protected.
805
; Otherwise, return to the caller.
803
; Otherwise, return to the caller.
806
        test    eax, eax
804
        test    eax, eax
807
        jz      @f
805
        jz      @f
808
        ret
806
        ret
809
@@:
807
@@:
810
; Wait for somebody to finish us.
808
; Wait for somebody to finish us.
811
        call    change_task
809
        call    change_task
812
        jmp     @b
810
        jmp     @b
813
endp
811
endp
814
 
812
 
815
; Leave critical area. Called by thread which wants to be protected.
813
; Leave critical area. Called by thread which wants to be protected.
816
proc unprotect_from_terminate
814
proc unprotect_from_terminate
817
        mov     edx, [current_slot]
815
        mov     edx, [current_slot]
818
; Atomically decrement depth of critical areas.
816
; Atomically decrement depth of critical areas.
819
        lock dec [edx+APPDATA.terminate_protection]
817
        lock dec [edx+APPDATA.terminate_protection]
820
; If the result of decrement is zero, somebody has requested termination,
818
; If the result of decrement is zero, somebody has requested termination,
821
; but at that moment we were inside a critical area; terminate now.
819
; but at that moment we were inside a critical area; terminate now.
822
        jz      sys_end
820
        jz      sys_end
823
; Otherwise, return to the caller.
821
; Otherwise, return to the caller.
824
        ret
822
        ret
825
endp
823
endp
826
 
824
 
827
; Request termination of thread identified by edx = SLOT_BASE + slot*256.
825
; Request termination of thread identified by edx = SLOT_BASE + slot*256.
828
; Called by anyone.
826
; Called by anyone.
829
proc request_terminate
827
proc request_terminate
830
        xor     eax, eax        ; set return value
828
        xor     eax, eax        ; set return value
831
; Atomically clear the upper bit. If it was already zero, then
829
; Atomically clear the upper bit. If it was already zero, then
832
; somebody has requested termination before us, so just exit.
830
; somebody has requested termination before us, so just exit.
833
        lock btr [edx+APPDATA.terminate_protection], 31
831
        lock btr [edx+APPDATA.terminate_protection], 31
834
        jnc     .unsafe
832
        jnc     .unsafe
835
; Atomically decrement depth of critical areas.
833
; Atomically decrement depth of critical areas.
836
        lock dec [edx+APPDATA.terminate_protection]
834
        lock dec [edx+APPDATA.terminate_protection]
837
; If the result of decrement is nonzero, the target thread is inside a
835
; If the result of decrement is nonzero, the target thread is inside a
838
; critical area; leave termination to leaving that area.
836
; critical area; leave termination to leaving that area.
839
        jnz     .unsafe
837
        jnz     .unsafe
840
; Otherwise, it is safe to kill the target now and the caller is responsible
838
; Otherwise, it is safe to kill the target now and the caller is responsible
841
; for this. Return eax=1.
839
; for this. Return eax=1.
842
        inc     eax
840
        inc     eax
843
.unsafe:
841
.unsafe:
844
        ret
842
        ret
845
endp
843
endp