excArchLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* excArchLib.c - i80X86 exception handling facilities */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01j,20nov01,hdn  doc clean up for 5.5
  8. 01i,28aug01,hdn  added Pentium4/SSE/SSE2/MCE support
  9.  added esp, ss, esp0, cr[23], esp0[07] to EXC_INFO.
  10.  added "error" parameter to exc{Exc,Int}Handle.
  11. 01h,29jul96,sbs  Made windview conditionally compile.
  12. 01g,15nov94,hdn  WindView instrumetation.
  13. 01f,01nov94,hdn  added X86CPU_PENTIUM of sysProcessor.
  14. 01e,29may94,hdn  changed I80486 to sysProcessor.
  15. 01d,14nov93,hdn  deleted excExcepHook.
  16. 01c,03jun93,hdn  updated to 5.1
  17.                   -changed functions to ansi style
  18.   -changed includes to have absolute path from h/
  19.   -fixed #else and #endif
  20.   -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY O_RDWR
  21.   -changed VOID to void
  22.   -changed copyright notice
  23. 01b,26mar93,hdn  supported 486's exception, alignment check.
  24. 01a,28feb92,hdn  written based on TRON, 68k version.
  25. */
  26. /*
  27. This module contains I80X86 architecture dependent portions of the
  28. exception handling facilities.  See excLib for the portions that are
  29. architecture independent.
  30. SEE ALSO: dbgLib, sigLib, intLib, "Debugging"
  31. */
  32. #include "vxWorks.h"
  33. #include "esf.h"
  34. #include "iv.h"
  35. #include "sysLib.h"
  36. #include "intLib.h"
  37. #include "taskLib.h"
  38. #include "qLib.h"
  39. #include "errno.h"
  40. #include "string.h"
  41. #include "vxLib.h"
  42. #include "logLib.h"
  43. #include "rebootLib.h"
  44. #include "private/funcBindP.h"
  45. #include "private/kernelLibP.h"
  46. #include "private/taskLibP.h"
  47. #include "private/sigLibP.h"
  48. /* externals */
  49. IMPORT UINT sysProcessor;           /* 0=386, 1=486, 2=P5, 4=P6, 5=P7 */
  50. IMPORT char excCallTbl []; /* table of Calls in excALib.s */
  51. IMPORT UINT sysIntIdtType; /* interrupt or trap gate */
  52. IMPORT CPUID sysCpuId; /* CPUID features */
  53. IMPORT int sysCsInt; /* CS for interrupt */
  54. IMPORT int sysCsExc; /* CS for exception */
  55. /* globals */
  56. /* locals */
  57. /* forward declarations */
  58. LOCAL void excGetInfoFromESF (int vecNum, ESF0 * pEsf, REG_SET * pRegs,
  59.           EXC_INFO * pExcInfo, BOOL error);
  60. LOCAL BOOL programError (int vecNum);
  61. /*******************************************************************************
  62. *
  63. * excVecInit - initialize the exception/interrupt vectors
  64. *
  65. * This routine sets all exception vectors to point to the appropriate
  66. * default exception handlers.  These handlers will safely trap and report
  67. * exceptions caused by program errors or unexpected hardware interrupts.
  68. * All vectors from vector 0 (address 0x0000) to 255 (address 0x07f8) are
  69. * initialized.
  70. *
  71. * WHEN TO CALL
  72. * This routine is usually called from the system start-up routine
  73. * usrInit() in usrConfig, before interrupts are enabled.
  74. *
  75. * RETURNS: OK (always).
  76. */
  77. STATUS excVecInit (void)
  78.     {
  79.     FAST int vecNum;
  80.     /* 
  81.      * make all exception vectors point to either generic exception or
  82.      * interrupt trap handler
  83.      */
  84.     for (vecNum = LOW_VEC; vecNum <= HIGH_VEC; ++vecNum)
  85. {
  86. intVecSet2 ((FUNCPTR *)INUM_TO_IVEC (vecNum),
  87.     (FUNCPTR) &excCallTbl[vecNum * 5],
  88.     programError (vecNum) ? IDT_TRAP_GATE : sysIntIdtType,
  89.     programError (vecNum) ? sysCsExc : sysCsInt);
  90. }
  91.     /* enable the Machine Check exception if it is supported */
  92.     if (sysCpuId.featuresEdx & CPUID_MCE)
  93. vxCr4Set (vxCr4Get () | CR4_MCE);
  94.     /* enable the SSE or SSE+SSE2 if it is supported */
  95.     if ((sysCpuId.featuresEdx & CPUID_SSE) ||
  96.         (sysCpuId.featuresEdx & CPUID_SSE2))
  97. vxCr4Set (vxCr4Get () | CR4_OSXMMEXCEPT);
  98.     return (OK);
  99.     }
  100. /*******************************************************************************
  101. *
  102. * excExcHandle - interrupt level handling of exceptions
  103. *
  104. * This routine handles exception traps.  It is never to be called except
  105. * from the special assembly language interrupt stub routine.
  106. *
  107. * It prints out a bunch of pertinent information about the trap that
  108. * occurred via excTask.
  109. *
  110. * Note that this routine runs in the context of the task that got the exception.
  111. *
  112. * NOMANUAL
  113. */
  114. void excExcHandle
  115.     (
  116.     int vecNum, /* exception vector number */
  117.     ESF0 * pEsf, /* pointer to exception stack frame */
  118.     REG_SET * pRegs, /* pointer to register info on stack */
  119.     BOOL error /* TRUE if ESF has error-code */
  120.     )
  121.     {
  122.     EXC_INFO excInfo;
  123.     /* fill excInfo/pRegs */
  124.     excGetInfoFromESF (vecNum, pEsf, pRegs, &excInfo, error);
  125.     if ((_func_excBaseHook != NULL) &&  /* user hook around? */
  126. ((* _func_excBaseHook) (vecNum, pEsf, pRegs, &excInfo)))
  127. return; /* user hook fixed it */
  128. #ifdef WV_INSTRUMENTATION
  129.     /* windview - level 3 event logging */
  130.     EVT_CTX_1(EVENT_EXCEPTION, vecNum);
  131. #endif  /* WV_INSTRUMENTATION */
  132.     /* if exception occured in an isr or before multi tasking then reboot */
  133.     if ((INT_CONTEXT ()) || (Q_FIRST (&activeQHead) == NULL))
  134. {
  135. if (_func_excPanicHook != NULL) /* panic hook? */
  136.     (*_func_excPanicHook) (vecNum, pEsf, pRegs, &excInfo);
  137. reboot (BOOT_WARM_AUTOBOOT);
  138. return; /* reboot returns?! */
  139. }
  140.     /* task caused exception */
  141.     taskIdCurrent->pExcRegSet = pRegs; /* for taskRegs[GS]et */
  142.     taskIdDefault ((int)taskIdCurrent); /* update default tid */
  143.     bcopy ((char *) &excInfo, (char *) &(taskIdCurrent->excInfo),
  144.    sizeof (EXC_INFO)); /* copy in exc info */
  145.     if (_func_sigExcKill != NULL) /* signals installed? */
  146. (*_func_sigExcKill) (vecNum, INUM_TO_IVEC(vecNum), pRegs);
  147.     if (_func_excInfoShow != NULL) /* default show rtn? */
  148. (*_func_excInfoShow) (&excInfo, TRUE);
  149.     if (excExcepHook != NULL) /* 5.0.2 hook? */
  150.         (* excExcepHook) (taskIdCurrent, vecNum, pEsf);
  151.     taskSuspend (0); /* whoa partner... */
  152.     taskIdCurrent->pExcRegSet = (REG_SET *) NULL; /* invalid after rts */
  153.     }
  154. /*******************************************************************************
  155. *
  156. * excIntHandle - interrupt level handling of interrupts
  157. *
  158. * This routine handles interrupts.  It is never to be called except
  159. * from the special assembly language interrupt stub routine.
  160. *
  161. * It prints out a bunch of pertinent information about the trap that
  162. * occurred via excTask().
  163. *
  164. * NOMANUAL
  165. */
  166. void excIntHandle
  167.     (
  168.     int vecNum, /* exception vector number */
  169.     ESF0 * pEsf, /* pointer to exception stack frame */
  170.     REG_SET * pRegs, /* pointer to register info on stack */
  171.     BOOL error /* TRUE if ESF has error-code */
  172.     )
  173.     {
  174.     EXC_INFO excInfo;
  175.     /* fill excInfo/pRegs */
  176.     excGetInfoFromESF (vecNum, pEsf, pRegs, &excInfo, error);
  177. #ifdef WV_INSTRUMENTATION
  178.     /* windview - level 3 event logging */
  179.     EVT_CTX_1(EVENT_EXCEPTION, vecNum);
  180. #endif  /* WV_INSTRUMENTATION */
  181.     if (_func_excIntHook != NULL)
  182. (*_func_excIntHook) (vecNum, pEsf, pRegs, &excInfo);
  183.     if (Q_FIRST (&activeQHead) == NULL) /* pre kernel */
  184. reboot (BOOT_WARM_AUTOBOOT); /* better reboot */
  185.     }
  186. /*****************************************************************************
  187. *
  188. * excGetInfoFromESF - get relevent info from exception stack frame
  189. *
  190. */
  191. LOCAL void excGetInfoFromESF
  192.     (
  193.     int  vecNum, /* vector number */
  194.     ESF0 * pEsf, /* pointer to exception stack frame */
  195.     REG_SET * pRegs, /* pointer to register info on stack */
  196.     EXC_INFO * pExcInfo, /* where to fill in exception info */
  197.     BOOL errorCode /* TRUE if ESF has errorCode */
  198.     )
  199.     {
  200.     int size;
  201.     pExcInfo->valid  = EXC_VEC_NUM; /* vecNum is valid */
  202.     pExcInfo->vecNum = vecNum; /* set vecNum */
  203.     /* find out a type of ESF with errorCode and CS in ESF */
  204.     if (errorCode)
  205. {
  206. /* it happened in supervisor mode, type is ESF1, PL not changed */
  207. pExcInfo->valid  |= EXC_ERROR_CODE;
  208. pExcInfo->errCode = ((ESF1 *)pEsf)->errCode;
  209. pExcInfo->pc   = ((ESF1 *)pEsf)->pc;
  210. pExcInfo->cs   = ((ESF1 *)pEsf)->cs;
  211. pExcInfo->eflags  = ((ESF1 *)pEsf)->eflags;
  212. size              = ESF1_NBYTES;
  213. }
  214.     else
  215. {
  216. /* it happened in supervisor mode, type is ESF0, PL not changed */
  217. pExcInfo->pc   = ((ESF0 *)pEsf)->pc;
  218. pExcInfo->cs   = ((ESF0 *)pEsf)->cs;
  219. pExcInfo->eflags  = ((ESF0 *)pEsf)->eflags;
  220. size              = ESF0_NBYTES;
  221. }
  222.     if (vecNum == IN_PAGE_FAULT)
  223. {
  224. pExcInfo->valid |= EXC_CR2;
  225. pExcInfo->cr2 = vxCr2Get (); /* get CR2 that is PF addr */
  226. }
  227.     pExcInfo->cr3 = vxCr3Get (); /* get CR3 */
  228.     pExcInfo->esp0 = (UINT32)pEsf + size; /* get ESP before exception */
  229.     /* adjust the stack pointer ESP in REG_SET */
  230.     pRegs->spReg = (ULONG)((char *) pEsf + size);
  231.     /* get content of the supervisor stack: 8 long words */
  232.     pExcInfo->esp00 = *(UINT32 *)pExcInfo->esp0;
  233.     pExcInfo->esp01 = *((UINT32 *)pExcInfo->esp0 + 1);
  234.     pExcInfo->esp02 = *((UINT32 *)pExcInfo->esp0 + 2);
  235.     pExcInfo->esp03 = *((UINT32 *)pExcInfo->esp0 + 3);
  236.     pExcInfo->esp04 = *((UINT32 *)pExcInfo->esp0 + 4);
  237.     pExcInfo->esp05 = *((UINT32 *)pExcInfo->esp0 + 5);
  238.     pExcInfo->esp06 = *((UINT32 *)pExcInfo->esp0 + 6);
  239.     pExcInfo->esp07 = *((UINT32 *)pExcInfo->esp0 + 7);
  240.     }
  241. /*******************************************************************************
  242. *
  243. * programError - determine if exception is program error
  244. *
  245. * RETURNS:
  246. *   TRUE if exception indicates program error,
  247. *   FALSE if hardware interrupt or failure.
  248. */
  249. LOCAL BOOL programError
  250.     (
  251.     int vecNum /* exception vector number */
  252.     )
  253.     {
  254.     if (sysProcessor != X86CPU_386) /* is the CPU 486 or Upper ? */
  255.         {
  256. if ((sysCpuId.featuresEdx & CPUID_SSE) ||
  257.     (sysCpuId.featuresEdx & CPUID_SSE2))
  258.             return (vecNum <= IN_SIMD);
  259. else
  260.             return (vecNum <= IN_MACHINE_CHECK);
  261.         }
  262.     else
  263.         return (vecNum <= IN_CP_ERROR);
  264.     }