Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 #include "idt.h" 018 #include "idt.h"
019 #include "irq.h" 019 #include "irq.h"
020 020
021 #include <sos/assert.h> 021 #include <sos/assert.h>
>> 022 #include <drivers/bochs.h>
>> 023 #include <sos/thread.h>
>> 024
022 #include "exception.h" 025 #include "exception.h"
023 026
024 027
025 extern sos_vaddr_t sos_exception_wrapper_array 028 extern sos_vaddr_t sos_exception_wrapper_array[SOS_EXCEPT_NUM];
026 029
027 030
028 sos_exception_handler_t sos_exception_handler_ 031 sos_exception_handler_t sos_exception_handler_array[SOS_EXCEPT_NUM] =
029 { NULL, }; 032 { NULL, };
030 033
031 034
032 static const char * sos_x86_exnames[] = { 035 static const char * sos_x86_exnames[] = {
033 [SOS_EXCEPT_DIVIDE_ERROR] = " 036 [SOS_EXCEPT_DIVIDE_ERROR] = "Division by zero",
034 [SOS_EXCEPT_DEBUG] = " 037 [SOS_EXCEPT_DEBUG] = "Debug",
035 [SOS_EXCEPT_NMI_INTERRUPT] = " 038 [SOS_EXCEPT_NMI_INTERRUPT] = "Non Maskable Interrupt",
036 [SOS_EXCEPT_BREAKPOINT] = " 039 [SOS_EXCEPT_BREAKPOINT] = "Breakpoint",
037 [SOS_EXCEPT_OVERFLOW] = " 040 [SOS_EXCEPT_OVERFLOW] = "Overflow",
038 [SOS_EXCEPT_BOUND_RANGE_EXCEDEED] = " 041 [SOS_EXCEPT_BOUND_RANGE_EXCEDEED] = "Bound Range Exceeded",
039 [SOS_EXCEPT_INVALID_OPCODE] = " 042 [SOS_EXCEPT_INVALID_OPCODE] = "Invalid Opcode",
040 [SOS_EXCEPT_DEVICE_NOT_AVAILABLE] = " 043 [SOS_EXCEPT_DEVICE_NOT_AVAILABLE] = "Device Unavailable",
041 [SOS_EXCEPT_DOUBLE_FAULT] = " 044 [SOS_EXCEPT_DOUBLE_FAULT] = "Double Fault",
042 [SOS_EXCEPT_COPROCESSOR_SEGMENT_OVERRUN] = " 045 [SOS_EXCEPT_COPROCESSOR_SEGMENT_OVERRUN] = "Coprocessor Segment Overrun",
043 [SOS_EXCEPT_INVALID_TSS] = " 046 [SOS_EXCEPT_INVALID_TSS] = "Invalid TSS",
044 [SOS_EXCEPT_SEGMENT_NOT_PRESENT] = " 047 [SOS_EXCEPT_SEGMENT_NOT_PRESENT] = "Segment Not Present",
045 [SOS_EXCEPT_STACK_SEGMENT_FAULT] = " 048 [SOS_EXCEPT_STACK_SEGMENT_FAULT] = "Stack Segfault",
046 [SOS_EXCEPT_GENERAL_PROTECTION] = " 049 [SOS_EXCEPT_GENERAL_PROTECTION] = "General Protection",
047 [SOS_EXCEPT_PAGE_FAULT] = " 050 [SOS_EXCEPT_PAGE_FAULT] = "Page Fault",
048 [SOS_EXCEPT_INTEL_RESERVED_1] = " 051 [SOS_EXCEPT_INTEL_RESERVED_1] = "INTEL1",
049 [SOS_EXCEPT_FLOATING_POINT_ERROR] = " 052 [SOS_EXCEPT_FLOATING_POINT_ERROR] = "FP Error",
050 [SOS_EXCEPT_ALIGNEMENT_CHECK] = " 053 [SOS_EXCEPT_ALIGNEMENT_CHECK] = "Alignment Check",
051 [SOS_EXCEPT_MACHINE_CHECK] = " 054 [SOS_EXCEPT_MACHINE_CHECK] = "Machine Check",
052 [SOS_EXCEPT_INTEL_RESERVED_2] = " 055 [SOS_EXCEPT_INTEL_RESERVED_2] = "INTEL2",
053 [SOS_EXCEPT_INTEL_RESERVED_3] = " 056 [SOS_EXCEPT_INTEL_RESERVED_3] = "INTEL3",
054 [SOS_EXCEPT_INTEL_RESERVED_4] = " 057 [SOS_EXCEPT_INTEL_RESERVED_4] = "INTEL4",
055 [SOS_EXCEPT_INTEL_RESERVED_5] = " 058 [SOS_EXCEPT_INTEL_RESERVED_5] = "INTEL5",
056 [SOS_EXCEPT_INTEL_RESERVED_6] = " 059 [SOS_EXCEPT_INTEL_RESERVED_6] = "INTEL6",
057 [SOS_EXCEPT_INTEL_RESERVED_7] = " 060 [SOS_EXCEPT_INTEL_RESERVED_7] = "INTEL7",
058 [SOS_EXCEPT_INTEL_RESERVED_8] = " 061 [SOS_EXCEPT_INTEL_RESERVED_8] = "INTEL8",
059 [SOS_EXCEPT_INTEL_RESERVED_9] = " 062 [SOS_EXCEPT_INTEL_RESERVED_9] = "INTEL9",
060 [SOS_EXCEPT_INTEL_RESERVED_10] = " 063 [SOS_EXCEPT_INTEL_RESERVED_10] = "INTEL10",
061 [SOS_EXCEPT_INTEL_RESERVED_11] = " 064 [SOS_EXCEPT_INTEL_RESERVED_11] = "INTEL11",
062 [SOS_EXCEPT_INTEL_RESERVED_12] = " 065 [SOS_EXCEPT_INTEL_RESERVED_12] = "INTEL12",
063 [SOS_EXCEPT_INTEL_RESERVED_13] = " 066 [SOS_EXCEPT_INTEL_RESERVED_13] = "INTEL13",
064 [SOS_EXCEPT_INTEL_RESERVED_14] = " 067 [SOS_EXCEPT_INTEL_RESERVED_14] = "INTEL14"
065 }; 068 };
066 069
067 070
068 071
069 static void sos_generic_ex(int exid, const str !! 072 static void sos_generic_ex(int exid, struct sos_cpu_state *ctxt)
>> 073 __attribute__((noreturn));
>> 074 static void sos_generic_ex(int exid, struct sos_cpu_state *ctxt)
070 { 075 {
071 const char *exname = sos_exception_get_name( 076 const char *exname = sos_exception_get_name(exid);
072 077
073 sos_display_fatal_error("Exception %s in Ker !! 078 if (sos_cpu_context_is_in_user_mode(ctxt))
074 exname, !! 079 {
075 sos_cpu_context_get_ !! 080
076 (unsigned)sos_cpu_co !! 081 sos_bochs_printf("Exception %s in User mode at instruction 0x%x (info=%x)!\n",
>> 082 exname,
>> 083 sos_cpu_context_get_PC(ctxt),
>> 084 (unsigned)sos_cpu_context_get_EX_info(ctxt));
>> 085 sos_bochs_printf("Terminating User thread\n");
>> 086 sos_thread_exit();
>> 087 }
>> 088 else
>> 089 sos_display_fatal_error("Exception %s in Kernel at instruction 0x%x (info=%x)!\n",
>> 090 exname,
>> 091 sos_cpu_context_get_PC(ctxt),
>> 092 (unsigned)sos_cpu_context_get_EX_info(ctxt));
077 } 093 }
078 094
079 095
080 sos_ret_t sos_exception_subsystem_setup(void) 096 sos_ret_t sos_exception_subsystem_setup(void)
081 { 097 {
082 sos_ret_t retval; 098 sos_ret_t retval;
083 int exid; 099 int exid;
084 100
085 101
086 102
087 for (exid = 0 ; exid < SOS_EXCEPT_NUM ; exid 103 for (exid = 0 ; exid < SOS_EXCEPT_NUM ; exid ++)
088 { 104 {
089 105
090 if (exid == SOS_EXCEPT_DOUBLE_FAULT) 106 if (exid == SOS_EXCEPT_DOUBLE_FAULT)
091 continue; 107 continue;
092 108
093 retval = sos_exception_set_routine(exid, 109 retval = sos_exception_set_routine(exid, sos_generic_ex);
094 if (SOS_OK != retval) 110 if (SOS_OK != retval)
095 return retval; 111 return retval;
096 } 112 }
097 113
098 114
099 115
100 116
101 117
102 118
103 return sos_idt_set_handler(SOS_EXCEPT_BASE + 119 return sos_idt_set_handler(SOS_EXCEPT_BASE + SOS_EXCEPT_DOUBLE_FAULT,
104 (sos_vaddr_t) sos_ 120 (sos_vaddr_t) sos_exception_wrapper_array[SOS_EXCEPT_DOUBLE_FAULT],
105 0 121 0 );
106 } 122 }
107 123
108 124
109 sos_ret_t sos_exception_set_routine(int except 125 sos_ret_t sos_exception_set_routine(int exception_number,
110 sos_except 126 sos_exception_handler_t routine)
111 { 127 {
112 sos_ret_t retval; 128 sos_ret_t retval;
113 sos_ui32_t flags; 129 sos_ui32_t flags;
114 130
115 if ((exception_number < 0) || (exception_num 131 if ((exception_number < 0) || (exception_number >= SOS_EXCEPT_NUM))
116 return -SOS_EINVAL; 132 return -SOS_EINVAL;
117 133
118 134
119 if (exception_number == SOS_EXCEPT_DOUBLE_FA 135 if (exception_number == SOS_EXCEPT_DOUBLE_FAULT)
120 return -SOS_ENOSUP; 136 return -SOS_ENOSUP;
121 137
122 sos_disable_IRQs(flags); 138 sos_disable_IRQs(flags);
123 139
124 retval = SOS_OK; 140 retval = SOS_OK;
125 141
126 142
127 sos_exception_handler_array[exception_number 143 sos_exception_handler_array[exception_number] = routine;
128 144
129 145
130 146
131 if (routine != NULL) 147 if (routine != NULL)
132 retval 148 retval
133 = sos_idt_set_handler(SOS_EXCEPT_BASE + 149 = sos_idt_set_handler(SOS_EXCEPT_BASE + exception_number,
134 (sos_vaddr_t) sos_ 150 (sos_vaddr_t) sos_exception_wrapper_array[exception_number],
135 0 151 0 );
136 else 152 else
137 retval 153 retval
138 = sos_idt_set_handler(SOS_EXCEPT_BASE + 154 = sos_idt_set_handler(SOS_EXCEPT_BASE + exception_number,
139 (sos_vaddr_t)NULL 155 (sos_vaddr_t)NULL ,
140 0 156 0 );
141 157
142 sos_restore_IRQs(flags); 158 sos_restore_IRQs(flags);
143 return retval; 159 return retval;
144 } 160 }
145 161
146 162
147 sos_exception_handler_t sos_exception_get_rout 163 sos_exception_handler_t sos_exception_get_routine(int exception_number)
148 { 164 {
149 if ((exception_number < 0) || (exception_num 165 if ((exception_number < 0) || (exception_number >= SOS_EXCEPT_NUM))
150 return NULL; 166 return NULL;
151 167
152 168
153 if (exception_number == SOS_EXCEPT_DOUBLE_FA 169 if (exception_number == SOS_EXCEPT_DOUBLE_FAULT)
154 return NULL; 170 return NULL;
155 171
156 172
157 return sos_exception_handler_array[exception 173 return sos_exception_handler_array[exception_number];
158 } 174 }
159 175
160 176
161 const char * sos_exception_get_name(int except 177 const char * sos_exception_get_name(int exception_number)
162 { 178 {
163 if ((exception_number < 0) || (exception_num 179 if ((exception_number < 0) || (exception_number >= SOS_EXCEPT_NUM))
164 return NULL; 180 return NULL;
165 181
166 return sos_x86_exnames[exception_number]; 182 return sos_x86_exnames[exception_number];
167 } 183 }