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