POK(kernelpart)
/home/jaouen/pok_official/pok/trunk/kernel/arch/x86/exceptions.c
Go to the documentation of this file.
00001 /*
00002  *                               POK header
00003  * 
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team 
00013  *
00014  * Created by julien on Thu Jan 15 23:34:13 2009 
00015  */
00016 
00022 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_ERROR_HANDLING)
00023 
00024 #include <errno.h>
00025 #include <arch.h>
00026 #include <core/debug.h>
00027 #include <core/error.h>
00028 #include <core/partition.h>
00029 #include <libc.h>
00030 #include "event.h"
00031 
00032 void            exception_divide_error();
00033 void            exception_debug();
00034 void            exception_nmi();
00035 void            exception_breakpoint();
00036 void            exception_overflow();
00037 void            exception_boundrange();
00038 void            exception_invalidopcode();
00039 void            exception_nomath_coproc();
00040 void            exception_doublefault();
00041 void            exception_copseg_overrun();
00042 void            exception_invalid_tss();
00043 void            exception_segment_not_present();
00044 void            exception_stackseg_fault();
00045 void            exception_general_protection();
00046 void            exception_pagefault();
00047 void            exception_fpu_fault();
00048 void            exception_alignement_check();
00049 void            exception_machine_check();
00050 void            exception_simd_fault();
00051 
00052 static const struct
00053 {
00054   uint16_t      vector;
00055   void          (*handler)(void);
00056 }
00057 exception_list[] =
00058 {
00059   { EXCEPTION_DIVIDE_ERROR, exception_divide_error},
00060   { EXCEPTION_DEBUG, exception_debug},
00061   { EXCEPTION_NMI, exception_nmi},
00062   { EXCEPTION_BREAKPOINT, exception_breakpoint},
00063   { EXCEPTION_OVERFLOW, exception_overflow},
00064   { EXCEPTION_BOUNDRANGE, exception_boundrange},
00065   { EXCEPTION_INVALIDOPCODE, exception_invalidopcode},
00066   { EXCEPTION_NOMATH_COPROC, exception_nomath_coproc},
00067   { EXCEPTION_DOUBLEFAULT, exception_doublefault},
00068   { EXCEPTION_COPSEG_OVERRUN, exception_copseg_overrun},
00069   { EXCEPTION_INVALID_TSS, exception_invalid_tss},
00070   { EXCEPTION_SEGMENT_NOT_PRESENT, exception_segment_not_present},
00071   { EXCEPTION_STACKSEG_FAULT, exception_stackseg_fault},
00072   { EXCEPTION_GENERAL_PROTECTION, exception_general_protection},
00073   { EXCEPTION_PAGEFAULT, exception_pagefault},
00074   { EXCEPTION_FPU_FAULT, exception_fpu_fault},
00075   { EXCEPTION_ALIGNEMENT_CHECK, exception_alignement_check},
00076   { EXCEPTION_MACHINE_CHECK, exception_machine_check},
00077   { EXCEPTION_SIMD_FAULT, exception_simd_fault},
00078   { 0, NULL}
00079 };
00080 
00081 pok_ret_t pok_exception_init()
00082 {
00083   int i;
00084 
00085   for (i = 0; exception_list[i].handler != NULL; ++i)
00086   {
00087     pok_idt_set_gate (exception_list[i].vector,
00088                                 GDT_CORE_CODE_SEGMENT << 3,
00089                       (uint32_t) exception_list[i].handler,
00090                       IDTE_INTERRUPT,
00091                       3);
00092   }
00093 
00094   return (POK_ERRNO_OK);
00095 }
00096 
00097 #if defined (POK_NEEDS_DEBUG) && ! defined (POK_NEEDS_ERROR_HANDLING)
00098 static void dump_registers (interrupt_frame *frame)
00099 {
00100   printf ("ES: %x, DS: %x\n", frame->es, frame->ds);
00101   printf ("CS: %x, SS: %x\n", frame->cs, frame->ss);
00102   printf ("EDI: %x, ESI: %x\n", frame->edi, frame->esi);
00103   printf ("EBP: %x, ESP: %x\n", frame->ebp, frame->esp);
00104   printf ("EAX: %x, ECX: %x\n", frame->eax, frame->ecx);
00105   printf ("EDX: %x, EBX: %x\n", frame->edx, frame->ebx);
00106   printf ("EIP: %x, ErrorCode: %x\n", frame->eip, frame->error);
00107   printf ("EFLAGS: %x\n\n", frame->eflags);
00108 }
00109 #endif
00110 
00111 INTERRUPT_HANDLER (exception_divide_error)
00112 {
00113   (void) frame;
00114 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00115 
00116 #ifdef POK_NEEDS_DEBUG
00117   printf ("[KERNEL] Raise divide by zero error, current thread=%d\n", POK_SCHED_CURRENT_THREAD);
00118 #endif
00119 
00120   pok_error_declare (POK_ERROR_KIND_NUMERIC_ERROR);
00121   pok_sched_activate_error_thread ();
00122 #else
00123   pok_fatal ("Divide error");
00124 #endif
00125 }
00126 
00127 INTERRUPT_HANDLER (exception_debug)
00128 {
00129   (void)frame;
00130 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00131 
00132    #ifdef POK_NEEDS_DEBUG
00133   printf ("[KERNEL] Raise debug fault\n");
00134    #endif
00135 
00136   pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
00137   pok_sched_activate_error_thread ();
00138 #else
00139 
00140    #ifdef POK_NEEDS_DEBUG
00141   dump_registers(frame);
00142   pok_fatal ("Debug fault");
00143    #endif
00144 #endif
00145 }
00146 
00147 INTERRUPT_HANDLER (exception_nmi)
00148 {
00149   (void)frame;
00150 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00151 
00152    #ifdef POK_NEEDS_DEBUG
00153    printf ("[KERNEL] Raise exception NMI fault\n");
00154    #endif
00155 
00156    pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
00157    pok_sched_activate_error_thread ();
00158 #else
00159 
00160    #ifdef POK_NEEDS_DEBUG
00161    dump_registers(frame);
00162    pok_fatal ("NMI Interrupt");
00163    #endif
00164 #endif
00165 }
00166 
00167 INTERRUPT_HANDLER (exception_breakpoint)
00168 {
00169   (void)frame;
00170 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00171 
00172    #ifdef POK_NEEDS_DEBUG
00173    printf ("[KERNEL] Raise exception breakpoint fault\n");
00174    #endif
00175 
00176   pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
00177   pok_sched_activate_error_thread ();
00178 #else
00179    #ifdef POK_NEEDS_DEBUG
00180    dump_registers(frame);
00181    pok_fatal ("Breakpoint");
00182    #endif
00183 #endif
00184 }
00185 
00186 INTERRUPT_HANDLER (exception_overflow)
00187 {
00188   (void)frame;
00189 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00190 
00191    #ifdef POK_NEEDS_DEBUG
00192    printf ("[KERNEL] Raise exception overflow fault\n");
00193    #endif
00194 
00195   pok_error_declare (POK_ERROR_KIND_STACK_OVERFLOW);
00196   pok_sched_activate_error_thread ();
00197 #else
00198    #ifdef POK_NEEDS_DEBUG
00199    dump_registers(frame);
00200    pok_fatal ("Overflow");
00201    #endif
00202 #endif
00203 }
00204 
00205 INTERRUPT_HANDLER (exception_boundrange)
00206 {
00207   (void)frame;
00208 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00209 
00210    #ifdef POK_NEEDS_DEBUG
00211    printf ("[KERNEL] Raise exception bound range fault\n");
00212    #endif
00213 
00214   pok_error_declare (POK_ERROR_KIND_STACK_OVERFLOW);
00215   pok_sched_activate_error_thread ();
00216 #else
00217    #ifdef POK_NEEDS_DEBUG
00218       dump_registers(frame);
00219       pok_fatal ("Bound range exceded");
00220    #endif
00221 #endif
00222 }
00223 
00224 INTERRUPT_HANDLER (exception_invalidopcode)
00225 {
00226   (void)frame;
00227 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00228 
00229    #ifdef POK_NEEDS_DEBUG
00230    printf ("[KERNEL] Raise exception invalid opcode fault, current thread: %d\n", POK_SCHED_CURRENT_THREAD);
00231    #endif
00232 
00233   pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
00234   pok_sched_activate_error_thread ();
00235 #else
00236    #ifdef POK_NEEDS_DEBUG
00237       dump_registers(frame);
00238       pok_fatal ("Invalid Opcode");
00239    #endif
00240 #endif
00241 }
00242 
00243 INTERRUPT_HANDLER (exception_nomath_coproc)
00244 {
00245   (void)frame;
00246 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00247 
00248    #ifdef POK_NEEDS_DEBUG
00249    printf ("[KERNEL] Raise exception no math coprocessor fault\n");
00250    #endif
00251 
00252   pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
00253   pok_sched_activate_error_thread ();
00254 #else
00255 
00256    #ifdef POK_NEEDS_DEBUG
00257       dump_registers(frame);
00258       pok_fatal ("Invalid No Math Coprocessor");
00259    #endif
00260 
00261 #endif
00262 }
00263 
00264 INTERRUPT_HANDLER_errorcode (exception_doublefault)
00265 {
00266   (void)frame;
00267 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00268 
00269    #ifdef POK_NEEDS_DEBUG
00270    printf ("[KERNEL] Raise exception double fault\n");
00271    #endif
00272 
00273   pok_partition_error (POK_SCHED_CURRENT_PARTITION, POK_ERROR_KIND_PARTITION_HANDLER);
00274 #else
00275    #ifdef POK_NEEDS_DEBUG
00276       dump_registers(frame);
00277       pok_fatal ("Double Fault");
00278    #endif
00279 #endif
00280 }
00281 
00282 INTERRUPT_HANDLER (exception_copseg_overrun)
00283 {
00284   (void)frame;
00285 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00286 
00287    #ifdef POK_NEEDS_DEBUG
00288    printf ("[KERNEL] Raise exception copseg overrun fault\n");
00289    #endif
00290 
00291   pok_error_declare (POK_ERROR_KIND_MEMORY_VIOLATION);
00292   pok_sched_activate_error_thread ();
00293 #else
00294    #ifdef POK_NEEDS_DEBUG
00295       dump_registers(frame);
00296       pok_fatal ("Coprocessur Segment Overrun");
00297    #endif
00298 #endif
00299 }
00300 
00301 INTERRUPT_HANDLER_errorcode (exception_invalid_tss)
00302 {
00303   (void)frame;
00304 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00305 
00306    #ifdef POK_NEEDS_DEBUG
00307    printf ("[KERNEL] Raise exception invalid tss fault\n");
00308    #endif
00309 
00310   pok_error_declare (POK_ERROR_KIND_MEMORY_VIOLATION);
00311   pok_sched_activate_error_thread ();
00312 #else
00313    #ifdef POK_NEEDS_DEBUG
00314       dump_registers(frame);
00315       pok_fatal ("Invalid TSS");
00316    #endif
00317 #endif
00318 }
00319 
00320 INTERRUPT_HANDLER_errorcode (exception_segment_not_present)
00321 {
00322   (void)frame;
00323 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00324 
00325    #ifdef POK_NEEDS_DEBUG
00326    printf ("[KERNEL] Raise exception segment not present fault %d\n", POK_SCHED_CURRENT_THREAD);
00327    #endif
00328 
00329   pok_error_declare (POK_ERROR_KIND_MEMORY_VIOLATION);
00330   pok_sched_activate_error_thread ();
00331 #else
00332    #ifdef POK_NEEDS_DEBUG
00333       dump_registers(frame);
00334       pok_fatal ("Segment Not Present");
00335    #endif
00336 #endif
00337 }
00338 
00339 INTERRUPT_HANDLER_errorcode (exception_stackseg_fault)
00340 {
00341   (void)frame;
00342 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00343 
00344    #ifdef POK_NEEDS_DEBUG
00345    printf ("[KERNEL] Raise exception stack segment fault\n");
00346    #endif
00347 
00348    pok_error_declare (POK_ERROR_KIND_MEMORY_VIOLATION);
00349    pok_sched_activate_error_thread ();
00350 #else
00351    #ifdef POK_NEEDS_DEBUG
00352       dump_registers(frame);
00353       pok_fatal ("Stack-Segment Fault");
00354    #endif
00355 #endif
00356 }
00357 
00358 INTERRUPT_HANDLER_errorcode (exception_general_protection)
00359 {
00360   (void)frame;
00361 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00362 
00363    #ifdef POK_NEEDS_DEBUG
00364    printf ("[KERNEL] Raise exception general protection fault current thread=%d\n", POK_SCHED_CURRENT_THREAD);
00365    #endif
00366 
00367   pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
00368   pok_sched_activate_error_thread ();
00369 #else
00370    #ifdef POK_NEEDS_DEBUG
00371    dump_registers(frame);
00372    pok_fatal ("General Protection Fault");
00373    #endif
00374 #endif
00375 }
00376 
00377 INTERRUPT_HANDLER_errorcode (exception_pagefault)
00378 {
00379   (void)frame;
00380 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00381    #ifdef POK_NEEDS_DEBUG
00382    printf ("[KERNEL] Raise exception pagefault fault\n");
00383    #endif
00384 
00385    pok_error_declare (POK_ERROR_KIND_MEMORY_VIOLATION);
00386    pok_sched_activate_error_thread ();
00387 #else
00388    #ifdef POK_NEEDS_DEBUG
00389       dump_registers(frame);
00390       pok_fatal ("Page Fault");
00391    #endif
00392 #endif
00393 }
00394 
00395 INTERRUPT_HANDLER (exception_fpu_fault)
00396 {
00397   (void)frame;
00398 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00399 
00400    #ifdef POK_NEEDS_DEBUG
00401    printf ("[KERNEL] Raise exception FPU fault\n");
00402    #endif
00403 
00404    pok_error_declare (POK_ERROR_KIND_HARDWARE_FAULT);
00405    pok_sched_activate_error_thread ();
00406 #else
00407    #ifdef POK_NEEDS_DEBUG
00408       dump_registers(frame);
00409       pok_fatal ("Floating Point Exception");
00410    #endif
00411 #endif
00412 }
00413 
00414 INTERRUPT_HANDLER_errorcode (exception_alignement_check)
00415 {
00416   (void)frame;
00417 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00418 
00419    #ifdef POK_NEEDS_DEBUG
00420    printf ("[KERNEL] Raise exception alignment fault\n");
00421    #endif
00422 
00423   pok_error_declare (POK_ERROR_KIND_HARDWARE_FAULT);
00424   pok_sched_activate_error_thread ();
00425 #else
00426    #ifdef POK_NEEDS_DEBUG
00427       dump_registers(frame);
00428       pok_fatal ("Bad alignement");
00429    #endif
00430 #endif
00431 }
00432 
00433 INTERRUPT_HANDLER (exception_machine_check)
00434 {
00435   (void)frame;
00436 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00437 
00438    #ifdef POK_NEEDS_DEBUG
00439    printf ("[KERNEL] Raise exception machine check fault\n");
00440    #endif
00441 
00442   pok_error_declare (POK_ERROR_KIND_HARDWARE_FAULT);
00443   pok_sched_activate_error_thread ();
00444 #else
00445    #ifdef POK_NEEDS_DEBUG
00446       pok_fatal ("Machine check error");
00447       dump_registers(frame);
00448    #endif
00449 #endif
00450 }
00451 
00452 INTERRUPT_HANDLER (exception_simd_fault)
00453 {
00454   (void)frame;
00455 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
00456 
00457    #ifdef POK_NEEDS_DEBUG
00458    printf ("[KERNEL] Raise exception SIMD fault\n");
00459    #endif
00460 
00461   pok_error_declare (POK_ERROR_KIND_HARDWARE_FAULT);
00462   pok_sched_activate_error_thread ();
00463 #else
00464 
00465    #ifdef POK_NEEDS_DEBUG
00466       dump_registers(frame);
00467       pok_fatal ("SIMD Fault");
00468    #endif
00469 
00470 #endif
00471 }
00472 
00473 #endif
00474