Subversion Repositories Kolibri OS

Rev

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

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