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