Subversion Repositories Kolibri OS

Rev

Rev 5201 | Rev 5984 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5565 serge 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;                                                              ;;
7
;;  MenuetOS process management, protected ring3                ;;
8
;;                                                              ;;
9
;;  Distributed under GPL. See file COPYING for details.        ;;
10
;;  Copyright 2003 Ville Turjanmaa                              ;;
11
;;                                                              ;;
12
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 ha 13
 
593 mikedld 14
$Revision: 5565 $
15
 
1056 Galkov 16
align 4 ;3A08
1 ha 17
build_interrupt_table:
1056 Galkov 18
        mov     edi, idts
19
        mov     esi, sys_int
20
        mov     ecx, 0x40
21
        mov     eax, (10001110b shl 24) + os_code
2434 Serge 22
  @@:
23
        movsw   ;low word of code-entry
1056 Galkov 24
        stosd   ;interrupt gate type : os_code selector
25
        movsw   ;high word of code-entry
26
        loop    @b
27
        movsd   ;copy low  dword of trap gate for int 0x40
28
        movsd   ;copy high dword of trap gate for int 0x40
29
        lidt    [esi]
30
        ret
1 ha 31
 
1056 Galkov 32
iglobal
33
  align 4
34
  sys_int:
35
    ;exception handlers addresses (for interrupt gate construction)
1076 Galkov 36
        dd      e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc
1056 Galkov 37
        dd      e8,e9,e10,e11,e12,e13,page_fault_exc,e15
38
        dd      e16, e17,e18, e19
39
        times   12 dd unknown_interrupt ;int_20..int_31
164 serge 40
 
1056 Galkov 41
    ;interrupt handlers addresses (for interrupt gate construction)
2434 Serge 42
        ; 0x20 .. 0x2F - IRQ handlers
1056 Galkov 43
        dd      irq0, irq_serv.irq_1, irq_serv.irq_2
44
        dd      irq_serv.irq_3, irq_serv.irq_4
2010 serge 45
        dd      irq_serv.irq_5,  irq_serv.irq_6,  irq_serv.irq_7
1056 Galkov 46
        dd      irq_serv.irq_8,  irq_serv.irq_9,  irq_serv.irq_10
2010 serge 47
        dd      irq_serv.irq_11, irq_serv.irq_12, irqD, irq_serv.irq_14, irq_serv.irq_15
2434 Serge 48
        dd irq_serv.irq_16
49
        dd irq_serv.irq_17
50
        dd irq_serv.irq_18
51
        dd irq_serv.irq_19
52
        dd irq_serv.irq_20
53
        dd irq_serv.irq_21
54
        dd irq_serv.irq_22
55
        dd irq_serv.irq_23
1 ha 56
 
2130 serge 57
    times 32 - IRQ_RESERVED dd unknown_interrupt
1056 Galkov 58
    ;int_0x40 gate trap (for directly copied)
59
        dw      i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
656 mikedld 60
 
1076 Galkov 61
  idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data)
1056 Galkov 62
        dw      2*($-sys_int-4)-1
63
        dd      idts ;0x8000B100
3555 Serge 64
        dw      0    ;просто выравнивание
656 mikedld 65
 
1056 Galkov 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
164 serge 68
 
1056 Galkov 69
  msg_exc_8     db "Double fault", 0
70
  msg_exc_u     db "Undefined Exception", 0
71
  msg_exc_a     db "Invalid TSS", 0
72
  msg_exc_b     db "Segment not present", 0
73
  msg_exc_c     db "Stack fault", 0
74
  msg_exc_d     db "General protection fault", 0
75
  msg_exc_e     db "Page fault", 0
1 ha 76
 
3500 Serge 77
  if lang eq sp
78
    include 'core/sys32-sp.inc'
79
  else
3908 Serge 80
    msg_sel_ker   db "kernel", 0
81
    msg_sel_app   db "application", 0
3500 Serge 82
  end if
1 ha 83
 
84
endg
85
 
1056 Galkov 86
macro save_ring3_context {
87
        pushad
40 halyavin 88
}
1056 Galkov 89
macro restore_ring3_context {
90
        popad
40 halyavin 91
}
1056 Galkov 92
macro exc_wo_code [num] {
8 poddubny 93
  e#num :
1056 Galkov 94
        save_ring3_context
95
        mov     bl, num
96
        jmp     exc_c
97
} exc_wo_code   0,1,2,3,4,5,6,15,16,19
1 ha 98
 
1056 Galkov 99
macro exc_w_code [num] {
22 poddubny 100
  e#num :
1056 Galkov 101
        add     esp, 4
102
        save_ring3_context
103
        mov     bl, num
104
        jmp     exc_c
105
} exc_w_code    8,9,10,11,12,13,17,18
22 poddubny 106
 
107
 
1056 Galkov 108
uglobal
109
  pf_err_code   dd ?
110
endg
1 ha 111
 
3555 Serge 112
page_fault_exc:                 ; дуракоусточивость: селекторы испорчены...
113
        pop     [ss:pf_err_code]; действительно до следующего #PF
1056 Galkov 114
        save_ring3_context
2434 Serge 115
        mov     bl, 14
1086 Galkov 116
 
3555 Serge 117
exc_c:                          ; исключения (все, кроме 7-го - #NM)
118
; Фрэйм стека при исключении/прерывании из 3-го кольца + pushad (т.е., именно здесь)
1056 Galkov 119
  reg_ss        equ esp+0x30
120
  reg_esp3      equ esp+0x2C
121
  reg_eflags    equ esp+0x28
122
  reg_cs3       equ esp+0x24
123
  reg_eip       equ esp+0x20
3555 Serge 124
 ; это фрэйм от pushad
1056 Galkov 125
  reg_eax       equ esp+0x1C
126
  reg_ecx       equ esp+0x18
127
  reg_edx       equ esp+0x14
128
  reg_ebx       equ esp+0x10
129
  reg_esp0      equ esp+0x0C
130
  reg_ebp       equ esp+0x08
131
  reg_esi       equ esp+0x04
132
  reg_edi       equ esp+0x00
133
 
3555 Serge 134
        mov     ax, app_data        ;исключение
135
        mov     ds, ax                  ;загрузим правильные значения
136
        mov     es, ax                  ;в регистры
137
        cld                     ; и приводим DF к стандарту
2434 Serge 138
        movzx   ebx, bl
709 diamond 139
; redirect to V86 manager? (EFLAGS & 0x20000) != 0?
2434 Serge 140
        test    byte[reg_eflags+2], 2
1056 Galkov 141
        jnz     v86_exc_c
2434 Serge 142
        cmp     bl, 14          ; #PF
1074 Galkov 143
        jne     @f
1076 Galkov 144
        call    page_fault_handler ; SEE: core/memory.inc
2434 Serge 145
  @@:
146
        mov     esi, [current_slot]
1074 Galkov 147
        btr     [esi+APPDATA.except_mask], ebx
148
        jnc     @f
2434 Serge 149
        mov     eax, [esi+APPDATA.exc_handler]
1074 Galkov 150
        test    eax, eax
1056 Galkov 151
        jnz     IRetToUserHook
2434 Serge 152
  @@:
153
        cli
1056 Galkov 154
        mov     eax, [esi+APPDATA.debugger_slot]
155
        test    eax, eax
156
        jnz     .debug
157
        sti
40 halyavin 158
; not debuggee => say error and terminate
1056 Galkov 159
        call    show_error_parameters ;; only ONE using, inline ???
160
       ;mov     edx, [TASK_BASE]
161
        mov     [edx + TASKDATA.state], byte 4 ; terminate
3555 Serge 162
        call    wakeup_osloop
3626 Serge 163
        call    change_task
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.
166
        hlt
167
        jmp     $-1
40 halyavin 168
.debug:
169
; we are debugged process, notify debugger and suspend ourself
170
; eax=debugger PID
2434 Serge 171
        mov     ecx, 1          ; debug_message code=other_exception
172
        cmp     bl, 1           ; #DB
1076 Galkov 173
        jne     .notify         ; notify debugger and suspend ourself
174
        mov     ebx, dr6        ; debug_message data=DR6_image
175
        xor     edx, edx
176
        mov     dr6, edx
177
        mov     edx, dr7
178
        mov     cl, not 8
2434 Serge 179
  .l1:
180
        shl     dl, 2
1076 Galkov 181
        jc      @f
182
        and     bl, cl
2434 Serge 183
  @@:
184
        sar     cl, 1
1076 Galkov 185
        jc      .l1
186
        mov     cl, 3           ; debug_message code=debug_exception
187
.notify:
188
        push    ebx             ; debug_message data