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