sys_rawhide.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/alpha/kernel/sys_rawhide.c
  3.  *
  4.  * Copyright (C) 1995 David A Rusling
  5.  * Copyright (C) 1996 Jay A Estabrook
  6.  * Copyright (C) 1998, 1999 Richard Henderson
  7.  *
  8.  * Code supporting the RAWHIDE.
  9.  */
  10. #include <linux/kernel.h>
  11. #include <linux/types.h>
  12. #include <linux/mm.h>
  13. #include <linux/sched.h>
  14. #include <linux/pci.h>
  15. #include <linux/init.h>
  16. #include <asm/ptrace.h>
  17. #include <asm/system.h>
  18. #include <asm/dma.h>
  19. #include <asm/irq.h>
  20. #include <asm/mmu_context.h>
  21. #include <asm/io.h>
  22. #include <asm/pgtable.h>
  23. #include <asm/core_mcpcia.h>
  24. #include "proto.h"
  25. #include "irq_impl.h"
  26. #include "pci_impl.h"
  27. #include "machvec_impl.h"
  28. /*
  29.  * HACK ALERT! only the boot cpu is used for interrupts.
  30.  */
  31. /* Note mask bit is true for ENABLED irqs.  */
  32. static unsigned int hose_irq_masks[4] = {
  33. 0xff0000, 0xfe0000, 0xff0000, 0xff0000
  34. };
  35. static unsigned int cached_irq_masks[4];
  36. spinlock_t rawhide_irq_lock = SPIN_LOCK_UNLOCKED;
  37. static inline void
  38. rawhide_update_irq_hw(int hose, int mask)
  39. {
  40. *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose)) = mask;
  41. mb();
  42. *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose));
  43. }
  44. static inline void 
  45. rawhide_enable_irq(unsigned int irq)
  46. {
  47. unsigned int mask, hose;
  48. irq -= 16;
  49. hose = irq / 24;
  50. irq -= hose * 24;
  51. mask = 1 << irq;
  52. spin_lock(&rawhide_irq_lock);
  53. mask |= cached_irq_masks[hose];
  54. cached_irq_masks[hose] = mask;
  55. rawhide_update_irq_hw(hose, mask);
  56. spin_unlock(&rawhide_irq_lock);
  57. }
  58. static void 
  59. rawhide_disable_irq(unsigned int irq)
  60. {
  61. unsigned int mask, hose;
  62. irq -= 16;
  63. hose = irq / 24;
  64. irq -= hose * 24;
  65. mask = ~(1 << irq) | hose_irq_masks[hose];
  66. spin_lock(&rawhide_irq_lock);
  67. mask &= cached_irq_masks[hose];
  68. cached_irq_masks[hose] = mask;
  69. rawhide_update_irq_hw(hose, mask);
  70. spin_unlock(&rawhide_irq_lock);
  71. }
  72. static void
  73. rawhide_mask_and_ack_irq(unsigned int irq)
  74. {
  75. unsigned int mask, mask1, hose;
  76. irq -= 16;
  77. hose = irq / 24;
  78. irq -= hose * 24;
  79. mask1 = 1 << irq;
  80. mask = ~mask1 | hose_irq_masks[hose];
  81. spin_lock(&rawhide_irq_lock);
  82. mask &= cached_irq_masks[hose];
  83. cached_irq_masks[hose] = mask;
  84. rawhide_update_irq_hw(hose, mask);
  85. /* Clear the interrupt.  */
  86. *(vuip)MCPCIA_INT_REQ(MCPCIA_HOSE2MID(hose)) = mask1;
  87. spin_unlock(&rawhide_irq_lock);
  88. }
  89. static unsigned int
  90. rawhide_startup_irq(unsigned int irq)
  91. {
  92. rawhide_enable_irq(irq);
  93. return 0;
  94. }
  95. static void
  96. rawhide_end_irq(unsigned int irq)
  97. {
  98. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  99. rawhide_enable_irq(irq);
  100. }
  101. static struct hw_interrupt_type rawhide_irq_type = {
  102. typename: "RAWHIDE",
  103. startup: rawhide_startup_irq,
  104. shutdown: rawhide_disable_irq,
  105. enable: rawhide_enable_irq,
  106. disable: rawhide_disable_irq,
  107. ack: rawhide_mask_and_ack_irq,
  108. end: rawhide_end_irq,
  109. };
  110. static void 
  111. rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
  112. {
  113. int irq;
  114. irq = (vector - 0x800) >> 4;
  115.         /*
  116.          * The RAWHIDE SRM console reports PCI interrupts with a vector
  117.  * 0x80 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
  118.  * shows up as IRQ 24, etc, etc. We adjust it down by 8 to have
  119.  * it line up with the actual bit numbers from the REQ registers,
  120.  * which is how we manage the interrupts/mask. Sigh...
  121.  *
  122.  * Also, PCI #1 interrupts are offset some more... :-(
  123.          */
  124. if (irq == 52) {
  125. /* SCSI on PCI1 is special.  */
  126. irq = 72;
  127. }
  128. /* Adjust by which hose it is from.  */
  129. irq -= ((irq + 16) >> 2) & 0x38;
  130. handle_irq(irq, regs);
  131. }
  132. static void __init
  133. rawhide_init_irq(void)
  134. {
  135. struct pci_controller *hose;
  136. long i;
  137. mcpcia_init_hoses();
  138. for (hose = hose_head; hose; hose = hose->next) {
  139. unsigned int h = hose->index;
  140. unsigned int mask = hose_irq_masks[h];
  141. cached_irq_masks[h] = mask;
  142. *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask;
  143. *(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0;
  144. }
  145. for (i = 16; i < 128; ++i) {
  146. irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
  147. irq_desc[i].handler = &rawhide_irq_type;
  148. }
  149. init_i8259a_irqs();
  150. common_init_isa_dma();
  151. }
  152. /*
  153.  * PCI Fixup configuration.
  154.  *
  155.  * Summary @ MCPCIA_PCI0_INT_REQ:
  156.  * Bit      Meaning
  157.  * 0        Interrupt Line A from slot 2 PCI0
  158.  * 1        Interrupt Line B from slot 2 PCI0
  159.  * 2        Interrupt Line C from slot 2 PCI0
  160.  * 3        Interrupt Line D from slot 2 PCI0
  161.  * 4        Interrupt Line A from slot 3 PCI0
  162.  * 5        Interrupt Line B from slot 3 PCI0
  163.  * 6        Interrupt Line C from slot 3 PCI0
  164.  * 7        Interrupt Line D from slot 3 PCI0
  165.  * 8        Interrupt Line A from slot 4 PCI0
  166.  * 9        Interrupt Line B from slot 4 PCI0
  167.  * 10       Interrupt Line C from slot 4 PCI0
  168.  * 11       Interrupt Line D from slot 4 PCI0
  169.  * 12       Interrupt Line A from slot 5 PCI0
  170.  * 13       Interrupt Line B from slot 5 PCI0
  171.  * 14       Interrupt Line C from slot 5 PCI0
  172.  * 15       Interrupt Line D from slot 5 PCI0
  173.  * 16       EISA interrupt (PCI 0) or SCSI interrupt (PCI 1)
  174.  * 17-23    NA
  175.  *
  176.  * IdSel
  177.  *   1  EISA bridge (PCI bus 0 only)
  178.  *   2   PCI option slot 2
  179.  *   3  PCI option slot 3
  180.  *   4   PCI option slot 4
  181.  *   5   PCI option slot 5
  182.  * 
  183.  */
  184. static int __init
  185. rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  186. {
  187. static char irq_tab[5][5] __initdata = {
  188. /*INT    INTA   INTB   INTC   INTD */
  189. { 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */
  190. { 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
  191. { 16+ 4, 16+ 4, 16+ 5, 16+ 6, 16+ 7}, /* IdSel 3 slot 3 */
  192. { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 4 slot 4 */
  193. { 16+12, 16+12, 16+13, 16+14, 16+15}  /* IdSel 5 slot 5 */
  194. };
  195. const long min_idsel = 1, max_idsel = 5, irqs_per_slot = 5;
  196. struct pci_controller *hose = dev->sysdata;
  197. int irq = COMMON_TABLE_LOOKUP;
  198. if (irq >= 0)
  199. irq += 24 * hose->index;
  200. return irq;
  201. }
  202. /*
  203.  * The System Vector
  204.  */
  205. struct alpha_machine_vector rawhide_mv __initmv = {
  206. vector_name: "Rawhide",
  207. DO_EV5_MMU,
  208. DO_DEFAULT_RTC,
  209. DO_MCPCIA_IO,
  210. DO_MCPCIA_BUS,
  211. machine_check: mcpcia_machine_check,
  212. max_dma_address: ALPHA_MAX_DMA_ADDRESS,
  213. min_io_address: DEFAULT_IO_BASE,
  214. min_mem_address: MCPCIA_DEFAULT_MEM_BASE,
  215. pci_dac_offset: MCPCIA_DAC_OFFSET,
  216. nr_irqs: 128,
  217. device_interrupt: rawhide_srm_device_interrupt,
  218. init_arch: mcpcia_init_arch,
  219. init_irq: rawhide_init_irq,
  220. init_rtc: common_init_rtc,
  221. init_pci: common_init_pci,
  222. kill_arch: NULL,
  223. pci_map_irq: rawhide_map_irq,
  224. pci_swizzle: common_swizzle,
  225. };
  226. ALIAS_MV(rawhide)