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