Subversion Repositories Kolibri OS

Rev

Rev 9976 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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