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

VxWorks

开发平台:

C/C++

  1. /* ipiArchLib.c - I86 Inter Processor Interrupt (IPI) handling facilities */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01d,28feb02,hdn  initialized ipiHandlerTbl[] with NULL
  8.  moved IPI_MAX_XXX macros to ipiI86Lib.h
  9. 01c,27feb02,hdn  moved BSP part of shutdown code to sysShutdownSup()
  10. 01b,26feb02,hdn  replaced loApicIpiIntNumGet() to ipiIntNum
  11. 01a,20feb02,hdn  written
  12. */
  13. /*
  14. This module contains I80X86 architecture dependent portions of the
  15. Inter Processor Interrupt (IPI) handling facilities.  See ipiALib for 
  16. the companion assembly routines.
  17. SEE ALSO: ipiALib
  18. */
  19. #include "vxWorks.h"
  20. #include "esf.h"
  21. #include "iv.h"
  22. #include "sysLib.h"
  23. #include "intLib.h"
  24. #include "taskLib.h"
  25. #include "qLib.h"
  26. #include "errno.h"
  27. #include "string.h"
  28. #include "vxLib.h"
  29. #include "logLib.h"
  30. #include "arch/i86/pentiumLib.h"
  31. #include "arch/i86/ipiI86Lib.h"
  32. #include "drv/intrCtl/loApic.h"
  33. /* defines */
  34. #undef IPI_DBG
  35. #ifdef IPI_DBG
  36. #   define IPI_DBG_MSG(STR,VALUE) printf(STR,VALUE);
  37. #else
  38. #   define IPI_DBG_MSG(STR,VALUE)
  39. #endif /* IPI_DEBUG */
  40. /* externals */
  41. IMPORT int sysCsExc; /* CS for IPI */
  42. IMPORT volatile UINT32 * sysNipi; /* IPI counter */
  43. IMPORT void  sysShutdownSup (); /* BSP shutdown routine */
  44. /* globals */
  45. VOIDFUNCPTR ipiHandlerTbl [IPI_MAX_HANDLERS] = {NULL}; /* IPI handlers */
  46. /* locals */
  47. LOCAL UINT32 ipiIntNum; /* IPI base intNum */
  48. /* forward static functions */
  49. /*******************************************************************************
  50. *
  51. * ipiVecInit - initialize the IPI vectors
  52. *
  53. * This routine sets all IPI vectors in IDT and assigns the default handlers.
  54. * IPI_MAX_HANDLERS vectors are initialized starting from the IPI base vector.
  55. *
  56. * RETURNS: OK (always).
  57. */
  58. void ipiVecInit 
  59.     (
  60.     UINT32 intNum /* IPI base intNum */
  61.     )
  62.     {
  63.     INT32 ix;
  64.     ipiIntNum = intNum; /* remember it */
  65.     /* make all IPI vectors point to generic IPI handler */
  66.     for (ix = 0; ix < IPI_MAX_HANDLERS; ix++, intNum++)
  67. {
  68. intVecSet2 ((FUNCPTR *)INUM_TO_IVEC (intNum),
  69.     (FUNCPTR) &ipiCallTbl[ix << 3],
  70.     IDT_INT_GATE, sysCsExc);
  71. }
  72.     }
  73. /*******************************************************************************
  74. *
  75. * ipiConnect - connect a C routine to the Inter Processor Interrupt
  76. *
  77. * This routine connects a specified C routine to a specified Inter Processor 
  78. * Interrupt vector.  The address of <routine> is stored in ipiHandlerTbl[] 
  79. * that is called by ipiHandler(index) when the IPI occurs.  The connected 
  80. * routine is invoked in supervisor mode in the interrupt level. 
  81. *
  82. * The routine can be any normal C code, except that it must not invoke
  83. * certain operating system functions that may block or perform I/O
  84. * operations.
  85. *
  86. * NOMANUAL
  87. */
  88. STATUS ipiConnect
  89.     (
  90.     UINT32 intNum, /* IPI interrupt number */
  91.     VOIDFUNCPTR routine /* routine to be called */
  92.     )
  93.     {
  94.     /* sanity check */
  95.   
  96.     if ((intNum < ipiIntNum) || 
  97.         (intNum >= (ipiIntNum + IPI_MAX_HANDLERS)))
  98.         {
  99. return (ERROR);
  100. }
  101.     /* register the routine */
  102.     ipiHandlerTbl[intNum - ipiIntNum] = routine;
  103.     return (OK);
  104.     }
  105. /*******************************************************************************
  106. *
  107. * ipiHandler - interrupt level IPI handling routine
  108. *
  109. * This routine handles Inter Processor Interrupt (IPI).  It is never to be 
  110. * called except from the special assembly language interrupt stub routine.
  111. * Since it runs in the interrupt level, the task level work may be deferred 
  112. * by excJobAdd()/logMsg(). 
  113. *
  114. * RETURNS: N/A
  115. *
  116. * NOMANUAL
  117. */
  118. void ipiHandler
  119.     (
  120.     UINT32 index /* index in the ipiHandlerTbl[] */
  121.     )
  122.     {
  123.     /* send EOI */
  124.     *(int *)(loApicBase + LOAPIC_EOI) = 0;
  125.     /* sanity check */
  126.   
  127.     if (index >= IPI_MAX_HANDLERS)
  128. return;
  129.     /* increment the counter */
  130.     sysNipi[index]++;
  131.     /* call the registered IPI handler */
  132.     if (ipiHandlerTbl[index] != NULL)
  133.         (*(ipiHandlerTbl[index])) ();
  134.     }
  135. /*******************************************************************************
  136. *
  137. * ipiHandlerShutdown - interrupt level Shutdown IPI handling routine
  138. *
  139. * This routine handles Shutdown Inter Processor Interrupt (IPI).
  140. *
  141. * Note that this routine runs in the context of the task that got the IPI.
  142. *
  143. * RETURNS: N/A
  144. *
  145. * NOMANUAL
  146. */
  147. void ipiHandlerShutdown (void)
  148.     {
  149.     /* 
  150.      * do it in the interrupt level or task level?
  151.      * doing it in the interrupt level 
  152.      * - is more reliable (works even if the kernel is misbehaving)
  153.      * - doesn't require context switch (to excTask) working
  154.      * - happens immediatly (may be nested interrupt)
  155.      * doing it in the task level 
  156.      * - is more graceful
  157.      * - require context switch (to excTask) working
  158.      * - servicing interrupts will be completed
  159.      * What about having two handlers, one for each?
  160.      */
  161.      
  162.     sysShutdownSup (); /* shutdown the included components */
  163.     loApicEnable (FALSE); /* disable the LOAPIC */
  164.     intLock (); /* LOCK INTERRUPTS */
  165.     ipiShutdownSup (); /* never come back */
  166.     }
  167. /*******************************************************************************
  168. *
  169. * ipiStartup - start up the specified Application Processor (AP)
  170. *
  171. * This routine starts up the specified Application Processor (AP).
  172. *
  173. * RETURNS: N/A
  174. *
  175. * NOMANUAL
  176. */
  177. STATUS ipiStartup
  178.     (
  179.     UINT32 apicId, /* AP's local APIC ID */
  180.     UINT32 vector, /* entry point address */
  181.     UINT32 nTimes /* send SIPI nTimes */
  182.     )
  183.     {
  184.     INT32 ix;
  185.     /* BSP sends AP an INIT IPI */
  186.     if (loApicIpi (apicId, 0, 0, 1, 0, 5, 0) != OK)
  187. {
  188. IPI_DBG_MSG ("failed - 1st INIT %dn",0)
  189. return (ERROR);
  190. }
  191.     if (loApicIpi (apicId, 0, 1, 0, 0, 5, 0) != OK)
  192. {
  193. IPI_DBG_MSG ("failed - 2nd INIT %dn",0)
  194. return (ERROR);
  195. }
  196.     /* BSP delay 10msec */
  197.     for (ix = 0; ix < 15000; ix++) /* 15000*720 ~= 10.8 msec */
  198.          sysDelay (); /* 720ns */
  199.     while (nTimes-- > 0)
  200. {
  201.         /* BSP sends AP a STARTUP IPI again */
  202.         if (loApicIpi (apicId, 0, 0, 1, 0, 6, (vector >> 12)) != OK)
  203.     {
  204.     IPI_DBG_MSG ("failed - SIPI %dn", nTimes)
  205.     return (ERROR);
  206.     }
  207.         /* BSP delays 200usec again */
  208.     
  209.         for (ix = 0; ix < 300; ix++) /* 300*720 ~= 216usec */
  210.              sysDelay (); /* 720ns */
  211. }
  212.     return (OK);
  213.     }
  214. /*******************************************************************************
  215. *
  216. * ipiShutdown - shutdown the specified Application Processor (AP)
  217. *
  218. * This routine shutdowns the specified Application Processor (AP).
  219. *
  220. * NOMANUAL
  221. */
  222. STATUS ipiShutdown
  223.     (
  224.     UINT32 apicId, /* AP's local APIC ID */
  225.     UINT32 intNum /* intNum of IPI_SHUTDOWN */
  226.     )
  227.     {
  228.     STATUS status = OK;
  229.     INT32 retry = 0;
  230.     /* BP sends AP a SHUTDOWN IPI */
  231.     while (loApicIpi (apicId, 0, 0, 1, 0, 0, intNum) != OK)
  232. {
  233.         taskDelay (1);
  234. if (retry++ > IPI_MAX_RETRIES)
  235.     {
  236.             status = ERROR;
  237.     break;
  238.     }
  239. }
  240.     return (status);
  241.     }
  242. #if FALSE /* XXX will be done soon */
  243. /*******************************************************************************
  244. *
  245. * ipiFixedDest - send IPI to the specified Application Processor
  246. *
  247. * This routine sends IPI to the specified Application Processor
  248. *
  249. * NOMANUAL
  250. */
  251. STATUS ipiFixedDest
  252.     (
  253.     UINT32 apicId, /* AP's local APIC ID */
  254.     UINT32 intNum /* intNum to send */
  255.     )
  256.     {
  257.     }
  258. /*******************************************************************************
  259. *
  260. * ipiFixedSelf - send IPI to myself
  261. *
  262. * This routine sends IPI to myself
  263. *
  264. * NOMANUAL
  265. */
  266. STATUS ipiFixedSelf
  267.     (
  268.     UINT32 intNum /* intNum to send */
  269.     )
  270.     {
  271.     }
  272. /*******************************************************************************
  273. *
  274. * ipiFixedAlli - send IPI to all processors including self
  275. *
  276. * This routine sends IPI to all processors including self
  277. *
  278. * NOMANUAL
  279. */
  280. STATUS ipiFixedAlli
  281.     (
  282.     UINT32 intNum /* intNum to send */
  283.     )
  284.     {
  285.     }
  286. /*******************************************************************************
  287. *
  288. * ipiFixedAlle - send IPI to all processors excluding self
  289. *
  290. * This routine sends IPI to all processors excluding self
  291. *
  292. * NOMANUAL
  293. */
  294. STATUS ipiFixedAlle
  295.     (
  296.     UINT32 intNum /* intNum to send */
  297.     )
  298.     {
  299.     }
  300. /*******************************************************************************
  301. *
  302. * ipiNmiDest - send NMI to the specified Application Processor
  303. *
  304. * This routine sends NMI to the specified Application Processor
  305. *
  306. * NOMANUAL
  307. */
  308. STATUS ipiNmiDest
  309.     (
  310.     UINT32 apicId /* AP's local APIC ID */
  311.     )
  312.     {
  313.     }
  314. /*******************************************************************************
  315. *
  316. * ipiNmiSelf - send NMI to myself
  317. *
  318. * This routine sends NMI to myself
  319. *
  320. * NOMANUAL
  321. */
  322. STATUS ipiNmiSelf (void)
  323.     {
  324.     }
  325. /*******************************************************************************
  326. *
  327. * ipiNmiAlli - send NMI to all processors including self
  328. *
  329. * This routine sends NMI to all processors including self
  330. *
  331. * NOMANUAL
  332. */
  333. STATUS ipiNmiAlli (void)
  334.     {
  335.     }
  336. /*******************************************************************************
  337. *
  338. * ipiNmiAlle - send NMI to all processors excluding self
  339. *
  340. * This routine sends NMI to all processors excluding self
  341. *
  342. * NOMANUAL
  343. */
  344. STATUS ipiNmiAlle (void)
  345.     {
  346.     }
  347. /*******************************************************************************
  348. *
  349. * ipiLowestAlli - send IPI to the lowest priority processor including self
  350. *
  351. * This routine sends IPI to the lowest priority processor including self
  352. *
  353. * NOMANUAL
  354. */
  355. STATUS ipiLowestAlli
  356.     (
  357.     UINT32 intNum /* intNum to send */
  358.     )
  359.     {
  360.     }
  361. /*******************************************************************************
  362. *
  363. * ipiLowestAlle - send IPI to the lowest priority processor excluding self
  364. *
  365. * This routine sends IPI to the lowest priority processor excluding self
  366. *
  367. * NOMANUAL
  368. */
  369. STATUS ipiLowestAlle
  370.     (
  371.     UINT32 intNum /* intNum to send */
  372.     )
  373.     {
  374.     }
  375. #endif