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