i8259Pic.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:6k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* i8259Pic.c - Intel 8259A PIC (Programmable Interrupt Controller) driver */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01g,17mar97,hdn  added sysIntLock(), sysIntUnlock() for the system mode.
  8. 01f,25jun96,hdn  added sysIntLevel() for windview.
  9. 01e,23may96,wlf  doc: cleanup.
  10. 01d,14jun95,hdn  renamed sysEndOfInt to sysIntEOI.
  11.  moved global function prototypes to sysLib.h.
  12. 01c,08aug94,hdn  stopped toggling IRQ9 in enabling and disabling.
  13. 01b,22apr94,hdn  made IRQ9 off in the initialization.
  14.  moved sysVectorIRQ0 to sysLib.c.
  15. 01a,05sep93,hdn  written.
  16. */
  17. /*
  18. DESCRIPTION
  19. This module implements the Intel 8259A PIC driver.
  20. */
  21. #include "drv/intrCtl/i8259a.h"
  22. /* globals */
  23. IMPORT UINT sysVectorIRQ0; /* vector for IRQ0 */
  24. /* local */
  25. char sysIntMask1; /* interrupt mask for PIC1 */
  26. char sysIntMask2; /* interrupt mask for PIC2 */
  27. /* forward static functions */
  28. LOCAL void sysIntInitPIC (void);
  29. LOCAL void sysIntEOI   (void);
  30. /*******************************************************************************
  31. *
  32. * sysIntInitPIC - initialize the PIC
  33. *
  34. * This routine initializes the PIC.
  35. *
  36. */
  37. LOCAL void sysIntInitPIC (void)
  38.     {
  39.     /* initialize the PIC (Programmable Interrupt Controller) */
  40.     sysOutByte (PIC_port1 (PIC1_BASE_ADR),0x11);        /* ICW1 */
  41.     sysOutByte (PIC_port2 (PIC1_BASE_ADR),sysVectorIRQ0); /* ICW2 */
  42.     sysOutByte (PIC_port2 (PIC1_BASE_ADR),0x04);        /* ICW3 */
  43.     sysOutByte (PIC_port2 (PIC1_BASE_ADR),0x01);        /* ICW4 */
  44.     sysOutByte (PIC_port1 (PIC2_BASE_ADR),0x11);        /* ICW1 */
  45.     sysOutByte (PIC_port2 (PIC2_BASE_ADR),sysVectorIRQ0+8); /* ICW2 */
  46.     sysOutByte (PIC_port2 (PIC2_BASE_ADR),0x02);        /* ICW3 */
  47.     sysOutByte (PIC_port2 (PIC2_BASE_ADR),0x01);        /* ICW4 */
  48.     /* disable interrupts */
  49.     sysOutByte (PIC_IMASK (PIC1_BASE_ADR),0xfb);
  50.     sysOutByte (PIC_IMASK (PIC2_BASE_ADR),0xff);
  51.     }
  52. /*******************************************************************************
  53. *
  54. * sysIntEOI - send EOI(end of interrupt) signal.
  55. *
  56. * This routine is called at the end of the interrupt handler.
  57. *
  58. */
  59. LOCAL void sysIntEOI (void)
  60.     {
  61.     int oldLevel;
  62.     oldLevel = intLock ();
  63.     sysOutByte (PIC_IACK (PIC1_BASE_ADR), 0x20);
  64.     sysOutByte (PIC_IACK (PIC2_BASE_ADR), 0x20);
  65.     intUnlock (oldLevel);
  66.     }
  67. /*******************************************************************************
  68. *
  69. * sysIntDisablePIC - disable a PIC interrupt level
  70. *
  71. * This routine disables a specified PIC interrupt level.
  72. *
  73. * RETURNS: OK, always.
  74. *
  75. * SEE ALSO: sysIntEnablePIC()
  76. *
  77. * ARGSUSED0
  78. */
  79. STATUS sysIntDisablePIC
  80.     (
  81.     int intLevel        /* interrupt level to disable */
  82.     )
  83.     {
  84.     if (intLevel < 8)
  85. {
  86. sysOutByte (PIC_IMASK (PIC1_BASE_ADR),
  87.     sysInByte (PIC_IMASK (PIC1_BASE_ADR)) | (1 << intLevel));
  88. }
  89.     else
  90. {
  91. sysOutByte (PIC_IMASK (PIC2_BASE_ADR),
  92.     sysInByte (PIC_IMASK (PIC2_BASE_ADR)) | (1 << (intLevel - 8)));
  93. }
  94.     return (OK);
  95.     }
  96. /*******************************************************************************
  97. *
  98. * sysIntEnablePIC - enable a PIC interrupt level
  99. *
  100. * This routine enables a specified PIC interrupt level.
  101. *
  102. * RETURNS: OK, always.
  103. *
  104. * SEE ALSO: sysIntDisablePIC()
  105. *
  106. * ARGSUSED0
  107. */
  108. STATUS sysIntEnablePIC
  109.     (
  110.     int intLevel        /* interrupt level to enable */
  111.     )
  112.     {
  113.     if (intLevel < 8)
  114. {
  115. sysOutByte (PIC_IMASK (PIC1_BASE_ADR),
  116.     sysInByte (PIC_IMASK (PIC1_BASE_ADR)) & ~(1 << intLevel));
  117. }
  118.     else
  119. {
  120. sysOutByte (PIC_IMASK (PIC2_BASE_ADR),
  121.     sysInByte (PIC_IMASK (PIC2_BASE_ADR)) & ~(1 << (intLevel - 8)));
  122. }
  123.     return (OK);
  124.     }
  125. /*******************************************************************************
  126. *
  127. * sysIntLevel - Get interrupt level by reading Interrupt Service Register.
  128. *
  129. * This routine is called to get an interrupt level in service.
  130. *
  131. * RETURNS: 0 - 15.
  132. *
  133. * ARGSUSED0
  134. */
  135. int sysIntLevel (void)
  136.     {
  137.     int inserviceReg;
  138.     int level;
  139.     int oldLevel;
  140.     int retry;
  141.     oldLevel = intLock ();
  142.     for (retry=0; retry < 1; retry ++)
  143. {
  144.         sysOutByte (PIC_port1 (PIC1_BASE_ADR), 0x0b);
  145.         inserviceReg = sysInByte (PIC_port1 (PIC1_BASE_ADR));
  146.         for (level=0; level < 8; level++)
  147.     if ((inserviceReg & 1) && (level != 2))
  148.         goto sysIntLevelExit;
  149.     else
  150.         inserviceReg >>= 1;
  151.         sysOutByte (PIC_port1 (PIC2_BASE_ADR), 0x0b);
  152.         inserviceReg = sysInByte (PIC_port1 (PIC2_BASE_ADR));
  153.         for (level=8; level < 16; level++)
  154.     if (inserviceReg & 1)
  155.         goto sysIntLevelExit;
  156.     else
  157.         inserviceReg >>= 1;
  158. }
  159.     sysIntLevelExit:
  160.     intUnlock (oldLevel);
  161.     return (level);
  162.     }
  163. /*******************************************************************************
  164. *
  165. * sysIntLock - lock out all PIC interrupts
  166. *
  167. * This routine saves the mask and locks out all PIC interrupts.
  168. * It should be called in the interrupt disable state(IF bit is 0).
  169. *
  170. * SEE ALSO: sysIntUnlock()
  171. *
  172. * ARGSUSED0
  173. */
  174. VOID sysIntLock (void)
  175.     {
  176.     sysIntMask1 = sysInByte (PIC_IMASK (PIC1_BASE_ADR));
  177.     sysIntMask2 = sysInByte (PIC_IMASK (PIC2_BASE_ADR));
  178.     sysOutByte (PIC_IMASK (PIC1_BASE_ADR), 0xff);
  179.     sysOutByte (PIC_IMASK (PIC2_BASE_ADR), 0xff);
  180.     }
  181. /*******************************************************************************
  182. *
  183. * sysIntUnlock - unlock the PIC interrupts
  184. *
  185. * This routine restores the mask and unlocks the PIC interrupts
  186. * It should be called in the interrupt disable state(IF bit is 0).
  187. *
  188. * SEE ALSO: sysIntLock()
  189. *
  190. * ARGSUSED0
  191. */
  192. VOID sysIntUnlock (void)
  193.     {
  194.     sysOutByte (PIC_IMASK (PIC1_BASE_ADR), sysIntMask1);
  195.     sysOutByte (PIC_IMASK (PIC2_BASE_ADR), sysIntMask2);
  196.     }