sys_mikasa.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/alpha/kernel/sys_mikasa.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 MIKASA (AlphaServer 1000).
  9.  */
  10. #include <linux/config.h>
  11. #include <linux/kernel.h>
  12. #include <linux/types.h>
  13. #include <linux/mm.h>
  14. #include <linux/sched.h>
  15. #include <linux/pci.h>
  16. #include <linux/init.h>
  17. #include <asm/ptrace.h>
  18. #include <asm/system.h>
  19. #include <asm/dma.h>
  20. #include <asm/irq.h>
  21. #include <asm/bitops.h>
  22. #include <asm/mmu_context.h>
  23. #include <asm/io.h>
  24. #include <asm/pgtable.h>
  25. #include <asm/core_apecs.h>
  26. #include <asm/core_cia.h>
  27. #include "proto.h"
  28. #include "irq_impl.h"
  29. #include "pci_impl.h"
  30. #include "machvec_impl.h"
  31. /* Note mask bit is true for ENABLED irqs.  */
  32. static int cached_irq_mask;
  33. static inline void
  34. mikasa_update_irq_hw(int mask)
  35. {
  36. outw(mask, 0x536);
  37. }
  38. static inline void
  39. mikasa_enable_irq(unsigned int irq)
  40. {
  41. mikasa_update_irq_hw(cached_irq_mask |= 1 << (irq - 16));
  42. }
  43. static void
  44. mikasa_disable_irq(unsigned int irq)
  45. {
  46. mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (irq - 16)));
  47. }
  48. static unsigned int
  49. mikasa_startup_irq(unsigned int irq)
  50. {
  51. mikasa_enable_irq(irq);
  52. return 0;
  53. }
  54. static void
  55. mikasa_end_irq(unsigned int irq)
  56. {
  57. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  58. mikasa_enable_irq(irq);
  59. }
  60. static struct hw_interrupt_type mikasa_irq_type = {
  61. typename: "MIKASA",
  62. startup: mikasa_startup_irq,
  63. shutdown: mikasa_disable_irq,
  64. enable: mikasa_enable_irq,
  65. disable: mikasa_disable_irq,
  66. ack: mikasa_disable_irq,
  67. end: mikasa_end_irq,
  68. };
  69. static void 
  70. mikasa_device_interrupt(unsigned long vector, struct pt_regs *regs)
  71. {
  72. unsigned long pld;
  73. unsigned int i;
  74. /* Read the interrupt summary registers */
  75. pld = (((~inw(0x534) & 0x0000ffffUL) << 16)
  76.        | (((unsigned long) inb(0xa0)) << 8)
  77.        | inb(0x20));
  78. /*
  79.  * Now for every possible bit set, work through them and call
  80.  * the appropriate interrupt handler.
  81.  */
  82. while (pld) {
  83. i = ffz(~pld);
  84. pld &= pld - 1; /* clear least bit set */
  85. if (i < 16) {
  86. isa_device_interrupt(vector, regs);
  87. } else {
  88. handle_irq(i, regs);
  89. }
  90. }
  91. }
  92. static void __init
  93. mikasa_init_irq(void)
  94. {
  95. long i;
  96. if (alpha_using_srm)
  97. alpha_mv.device_interrupt = srm_device_interrupt;
  98. mikasa_update_irq_hw(0);
  99. for (i = 16; i < 32; ++i) {
  100. irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
  101. irq_desc[i].handler = &mikasa_irq_type;
  102. }
  103. init_i8259a_irqs();
  104. common_init_isa_dma();
  105. }
  106. /*
  107.  * PCI Fixup configuration.
  108.  *
  109.  * Summary @ 0x536:
  110.  * Bit      Meaning
  111.  * 0        Interrupt Line A from slot 0
  112.  * 1        Interrupt Line B from slot 0
  113.  * 2        Interrupt Line C from slot 0
  114.  * 3        Interrupt Line D from slot 0
  115.  * 4        Interrupt Line A from slot 1
  116.  * 5        Interrupt line B from slot 1
  117.  * 6        Interrupt Line C from slot 1
  118.  * 7        Interrupt Line D from slot 1
  119.  * 8        Interrupt Line A from slot 2
  120.  * 9        Interrupt Line B from slot 2
  121.  *10        Interrupt Line C from slot 2
  122.  *11        Interrupt Line D from slot 2
  123.  *12        NCR 810 SCSI
  124.  *13        Power Supply Fail
  125.  *14        Temperature Warn
  126.  *15        Reserved
  127.  *
  128.  * The device to slot mapping looks like:
  129.  *
  130.  * Slot     Device
  131.  *  6       NCR SCSI controller
  132.  *  7       Intel PCI-EISA bridge chip
  133.  * 11       PCI on board slot 0
  134.  * 12       PCI on board slot 1
  135.  * 13       PCI on board slot 2
  136.  *   
  137.  *
  138.  * This two layered interrupt approach means that we allocate IRQ 16 and 
  139.  * above for PCI interrupts.  The IRQ relates to which bit the interrupt
  140.  * comes in on.  This makes interrupt processing much easier.
  141.  */
  142. static int __init
  143. mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  144. {
  145. static char irq_tab[8][5] __initdata = {
  146. /*INT    INTA   INTB   INTC   INTD */
  147. {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17,  SCSI */
  148. {   -1,    -1,    -1,    -1,    -1}, /* IdSel 18,  PCEB */
  149. {   -1,    -1,    -1,    -1,    -1}, /* IdSel 19,  ???? */
  150. {   -1,    -1,    -1,    -1,    -1}, /* IdSel 20,  ???? */
  151. {   -1,    -1,    -1,    -1,    -1}, /* IdSel 21,  ???? */
  152. { 16+0,  16+0,  16+1,  16+2,  16+3}, /* IdSel 22,  slot 0 */
  153. { 16+4,  16+4,  16+5,  16+6,  16+7}, /* IdSel 23,  slot 1 */
  154. { 16+8,  16+8,  16+9, 16+10, 16+11}, /* IdSel 24,  slot 2 */
  155. };
  156. const long min_idsel = 6, max_idsel = 13, irqs_per_slot = 5;
  157. return COMMON_TABLE_LOOKUP;
  158. }
  159. #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
  160. static void
  161. mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
  162.            struct pt_regs * regs)
  163. {
  164. #define MCHK_NO_DEVSEL 0x205U
  165. #define MCHK_NO_TABT 0x204U
  166. struct el_common *mchk_header;
  167. unsigned int code;
  168. mchk_header = (struct el_common *)la_ptr;
  169. /* Clear the error before any reporting.  */
  170. mb();
  171. mb(); /* magic */
  172. draina();
  173. apecs_pci_clr_err();
  174. wrmces(0x7);
  175. mb();
  176. code = mchk_header->code;
  177. process_mcheck_info(vector, la_ptr, regs, "MIKASA APECS",
  178.     (mcheck_expected(0)
  179.      && (code == MCHK_NO_DEVSEL
  180.          || code == MCHK_NO_TABT)));
  181. }
  182. #endif
  183. /*
  184.  * The System Vector
  185.  */
  186. #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
  187. struct alpha_machine_vector mikasa_mv __initmv = {
  188. vector_name: "Mikasa",
  189. DO_EV4_MMU,
  190. DO_DEFAULT_RTC,
  191. DO_APECS_IO,
  192. DO_APECS_BUS,
  193. machine_check: mikasa_apecs_machine_check,
  194. max_dma_address: ALPHA_MAX_DMA_ADDRESS,
  195. min_io_address: DEFAULT_IO_BASE,
  196. min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
  197. nr_irqs: 32,
  198. device_interrupt: mikasa_device_interrupt,
  199. init_arch: apecs_init_arch,
  200. init_irq: mikasa_init_irq,
  201. init_rtc: common_init_rtc,
  202. init_pci: common_init_pci,
  203. kill_arch: NULL,
  204. pci_map_irq: mikasa_map_irq,
  205. pci_swizzle: common_swizzle,
  206. };
  207. ALIAS_MV(mikasa)
  208. #endif
  209. #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
  210. struct alpha_machine_vector mikasa_primo_mv __initmv = {
  211. vector_name: "Mikasa-Primo",
  212. DO_EV5_MMU,
  213. DO_DEFAULT_RTC,
  214. DO_CIA_IO,
  215. DO_CIA_BUS,
  216. machine_check: cia_machine_check,
  217. max_dma_address: ALPHA_MAX_DMA_ADDRESS,
  218. min_io_address: DEFAULT_IO_BASE,
  219. min_mem_address: CIA_DEFAULT_MEM_BASE,
  220. nr_irqs: 32,
  221. device_interrupt: mikasa_device_interrupt,
  222. init_arch: cia_init_arch,
  223. init_irq: mikasa_init_irq,
  224. init_rtc: common_init_rtc,
  225. init_pci: cia_init_pci,
  226. pci_map_irq: mikasa_map_irq,
  227. pci_swizzle: common_swizzle,
  228. };
  229. ALIAS_MV(mikasa_primo)
  230. #endif