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 so <<
075 { 073 {
076 const char *exname = sos_exception_get_name( 074 const char *exname = sos_exception_get_name(exid);
077 075
078 if (sos_cpu_context_is_in_user_mode(ctxt)) 076 if (sos_cpu_context_is_in_user_mode(ctxt))
079 { 077 {
080 078
081 sos_bochs_printf("Exception %s in User m 079 sos_bochs_printf("Exception %s in User mode at instruction 0x%x (info=%x)!\n",
082 exname, 080 exname,
083 sos_cpu_context_get_PC( 081 sos_cpu_context_get_PC(ctxt),
084 (unsigned)sos_cpu_conte 082 (unsigned)sos_cpu_context_get_EX_info(ctxt));
085 sos_bochs_printf("Terminating User threa 083 sos_bochs_printf("Terminating User thread\n");
086 sos_thread_exit(); 084 sos_thread_exit();
087 } 085 }
088 else 086 else
089 sos_display_fatal_error("Exception %s in K 087 sos_display_fatal_error("Exception %s in Kernel at instruction 0x%x (info=%x)!\n",
090 exname, 088 exname,
091 sos_cpu_context_ge 089 sos_cpu_context_get_PC(ctxt),
092 (unsigned)sos_cpu_ 090 (unsigned)sos_cpu_context_get_EX_info(ctxt));
093 } 091 }
094 092
095 093
096 sos_ret_t sos_exception_subsystem_setup(void) 094 sos_ret_t sos_exception_subsystem_setup(void)
097 { 095 {
098 sos_ret_t retval; 096 sos_ret_t retval;
099 int exid; 097 int exid;
100 098
101 099
102 100
103 for (exid = 0 ; exid < SOS_EXCEPT_NUM ; exid 101 for (exid = 0 ; exid < SOS_EXCEPT_NUM ; exid ++)
104 { 102 {
105 103
106 if (exid == SOS_EXCEPT_DOUBLE_FAULT) 104 if (exid == SOS_EXCEPT_DOUBLE_FAULT)
107 continue; 105 continue;
108 106
109 retval = sos_exception_set_routine(exid, 107 retval = sos_exception_set_routine(exid, sos_generic_ex);
110 if (SOS_OK != retval) 108 if (SOS_OK != retval)
111 return retval; 109 return retval;
112 } 110 }
113 111
114 112
115 113
116 114
117 115
118 116
119 return sos_idt_set_handler(SOS_EXCEPT_BASE + 117 return sos_idt_set_handler(SOS_EXCEPT_BASE + SOS_EXCEPT_DOUBLE_FAULT,
120 (sos_vaddr_t) sos_ 118 (sos_vaddr_t) sos_exception_wrapper_array[SOS_EXCEPT_DOUBLE_FAULT],
121 0 119 0 );
122 } 120 }
123 121
124 122
125 sos_ret_t sos_exception_set_routine(int except 123 sos_ret_t sos_exception_set_routine(int exception_number,
126 sos_except 124 sos_exception_handler_t routine)
127 { 125 {
128 sos_ret_t retval; 126 sos_ret_t retval;
129 sos_ui32_t flags; 127 sos_ui32_t flags;
130 128
131 if ((exception_number < 0) || (exception_num 129 if ((exception_number < 0) || (exception_number >= SOS_EXCEPT_NUM))
132 return -SOS_EINVAL; 130 return -SOS_EINVAL;
133 131
134 132
135 if (exception_number == SOS_EXCEPT_DOUBLE_FA 133 if (exception_number == SOS_EXCEPT_DOUBLE_FAULT)
136 return -SOS_ENOSUP; 134 return -SOS_ENOSUP;
137 135
138 sos_disable_IRQs(flags); 136 sos_disable_IRQs(flags);
139 137
140 retval = SOS_OK; 138 retval = SOS_OK;
141 139
142 140
143 sos_exception_handler_array[exception_number 141 sos_exception_handler_array[exception_number] = routine;
144 142
145 143
146 144
147 if (routine != NULL) 145 if (routine != NULL)
148 retval 146 retval
149 = sos_idt_set_handler(SOS_EXCEPT_BASE + 147 = sos_idt_set_handler(SOS_EXCEPT_BASE + exception_number,
150 (sos_vaddr_t) sos_ 148 (sos_vaddr_t) sos_exception_wrapper_array[exception_number],
151 0 149 0 );
152 else 150 else
153 retval 151 retval
154 = sos_idt_set_handler(SOS_EXCEPT_BASE + 152 = sos_idt_set_handler(SOS_EXCEPT_BASE + exception_number,
155 (sos_vaddr_t)NULL 153 (sos_vaddr_t)NULL ,
156 0 154 0 );
157 155
158 sos_restore_IRQs(flags); 156 sos_restore_IRQs(flags);
159 return retval; 157 return retval;
160 } 158 }
161 159
162 160
163 sos_exception_handler_t sos_exception_get_rout 161 sos_exception_handler_t sos_exception_get_routine(int exception_number)
164 { 162 {
165 if ((exception_number < 0) || (exception_num 163 if ((exception_number < 0) || (exception_number >= SOS_EXCEPT_NUM))
166 return NULL; 164 return NULL;
167 165
168 166
169 if (exception_number == SOS_EXCEPT_DOUBLE_FA 167 if (exception_number == SOS_EXCEPT_DOUBLE_FAULT)
170 return NULL; 168 return NULL;
171 169
172 170
173 return sos_exception_handler_array[exception 171 return sos_exception_handler_array[exception_number];
174 } 172 }
175 173
176 174
177 const char * sos_exception_get_name(int except 175 const char * sos_exception_get_name(int exception_number)
178 { 176 {
179 if ((exception_number < 0) || (exception_num 177 if ((exception_number < 0) || (exception_number >= SOS_EXCEPT_NUM))
180 return NULL; 178 return NULL;
181 179
182 return sos_x86_exnames[exception_number]; 180 return sos_x86_exnames[exception_number];
183 } 181 }