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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/alpha/kernel/sys_sable.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 Sable and Sable-Gamma systems.
  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/mmu_context.h>
  22. #include <asm/io.h>
  23. #include <asm/pgtable.h>
  24. #include <asm/core_t2.h>
  25. #include "proto.h"
  26. #include "irq_impl.h"
  27. #include "pci_impl.h"
  28. #include "machvec_impl.h"
  29. spinlock_t sable_irq_lock = SPIN_LOCK_UNLOCKED;
  30. /*
  31.  *   For SABLE, which is really baroque, we manage 40 IRQ's, but the
  32.  *   hardware really only supports 24, not via normal ISA PIC,
  33.  *   but cascaded custom 8259's, etc.
  34.  *  0-7  (char at 536)
  35.  *  8-15 (char at 53a)
  36.  * 16-23 (char at 53c)
  37.  *
  38.  * Summary Registers (536/53a/53c):
  39.  *
  40.  * Bit      Meaning               Kernel IRQ
  41.  *------------------------------------------
  42.  * 0        PCI slot 0 34
  43.  * 1        NCR810 (builtin) 33
  44.  * 2        TULIP (builtin) 32
  45.  * 3        mouse 12
  46.  * 4        PCI slot 1 35
  47.  * 5        PCI slot 2 36
  48.  * 6        keyboard 1
  49.  * 7        floppy 6
  50.  * 8        COM2 3
  51.  * 9        parallel port 7
  52.  *10        EISA irq 3 -
  53.  *11        EISA irq 4 -
  54.  *12        EISA irq 5 5
  55.  *13        EISA irq 6 -
  56.  *14        EISA irq 7 -
  57.  *15        COM1 4
  58.  *16        EISA irq 9 9
  59.  *17        EISA irq 10 10
  60.  *18        EISA irq 11 11
  61.  *19        EISA irq 12 -
  62.  *20        EISA irq 13 -
  63.  *21        EISA irq 14 14
  64.  *22        NC 15
  65.  *23        IIC -
  66.  */
  67. static struct 
  68. {
  69. char irq_to_mask[40];
  70. char mask_to_irq[40];
  71. /* Note mask bit is true for DISABLED irqs.  */
  72. unsigned long shadow_mask;
  73. } sable_irq_swizzle = {
  74. {
  75. -1,  6, -1,  8, 15, 12,  7,  9, /* pseudo PIC  0-7  */
  76. -1, 16, 17, 18,  3, -1, 21, 22, /* pseudo PIC  8-15 */
  77. -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7  */
  78. -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */
  79.  2,  1,  0,  4,  5, -1, -1, -1, /* pseudo PCI */
  80. },
  81. {
  82. 34, 33, 32, 12, 35, 36,  1,  6, /* mask 0-7  */
  83.  3,  7, -1, -1,  5, -1, -1,  4, /* mask 8-15  */
  84.  9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23  */
  85. },
  86. -1
  87. };
  88. static inline void
  89. sable_update_irq_hw(unsigned long bit, unsigned long mask)
  90. {
  91. int port = 0x537;
  92. if (bit >= 16) {
  93. port = 0x53d;
  94. mask >>= 16;
  95. } else if (bit >= 8) {
  96. port = 0x53b;
  97. mask >>= 8;
  98. }
  99. outb(mask, port);
  100. }
  101. static inline void
  102. sable_ack_irq_hw(unsigned long bit)
  103. {
  104. int port, val1, val2;
  105. if (bit >= 16) {
  106. port = 0x53c;
  107. val1 = 0xE0 | (bit - 16);
  108. val2 = 0xE0 | 4;
  109. } else if (bit >= 8) {
  110. port = 0x53a;
  111. val1 = 0xE0 | (bit - 8);
  112. val2 = 0xE0 | 3;
  113. } else {
  114. port = 0x536;
  115. val1 = 0xE0 | (bit - 0);
  116. val2 = 0xE0 | 1;
  117. }
  118. outb(val1, port); /* ack the slave */
  119. outb(val2, 0x534); /* ack the master */
  120. }
  121. static inline void
  122. sable_enable_irq(unsigned int irq)
  123. {
  124. unsigned long bit, mask;
  125. bit = sable_irq_swizzle.irq_to_mask[irq];
  126. spin_lock(&sable_irq_lock);
  127. mask = sable_irq_swizzle.shadow_mask &= ~(1UL << bit);
  128. sable_update_irq_hw(bit, mask);
  129. spin_unlock(&sable_irq_lock);
  130. }
  131. static void
  132. sable_disable_irq(unsigned int irq)
  133. {
  134. unsigned long bit, mask;
  135. bit = sable_irq_swizzle.irq_to_mask[irq];
  136. spin_lock(&sable_irq_lock);
  137. mask = sable_irq_swizzle.shadow_mask |= 1UL << bit;
  138. sable_update_irq_hw(bit, mask);
  139. spin_unlock(&sable_irq_lock);
  140. }
  141. static unsigned int
  142. sable_startup_irq(unsigned int irq)
  143. {
  144. sable_enable_irq(irq);
  145. return 0;
  146. }
  147. static void
  148. sable_end_irq(unsigned int irq)
  149. {
  150. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  151. sable_enable_irq(irq);
  152. }
  153. static void
  154. sable_mask_and_ack_irq(unsigned int irq)
  155. {
  156. unsigned long bit, mask;
  157. bit = sable_irq_swizzle.irq_to_mask[irq];
  158. spin_lock(&sable_irq_lock);
  159. mask = sable_irq_swizzle.shadow_mask |= 1UL << bit;
  160. sable_update_irq_hw(bit, mask);
  161. sable_ack_irq_hw(bit);
  162. spin_unlock(&sable_irq_lock);
  163. }
  164. static struct hw_interrupt_type sable_irq_type = {
  165. typename: "SABLE",
  166. startup: sable_startup_irq,
  167. shutdown: sable_disable_irq,
  168. enable: sable_enable_irq,
  169. disable: sable_disable_irq,
  170. ack: sable_mask_and_ack_irq,
  171. end: sable_end_irq,
  172. };
  173. static void 
  174. sable_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
  175. {
  176. /* Note that the vector reported by the SRM PALcode corresponds
  177.    to the interrupt mask bits, but we have to manage via more
  178.    normal IRQs.  */
  179. int bit, irq;
  180. bit = (vector - 0x800) >> 4;
  181. irq = sable_irq_swizzle.mask_to_irq[bit];
  182. handle_irq(irq, regs);
  183. }
  184. static void __init
  185. sable_init_irq(void)
  186. {
  187. long i;
  188. outb(-1, 0x537); /* slave 0 */
  189. outb(-1, 0x53b); /* slave 1 */
  190. outb(-1, 0x53d); /* slave 2 */
  191. outb(0x44, 0x535); /* enable cascades in master */
  192. for (i = 0; i < 40; ++i) {
  193. irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
  194. irq_desc[i].handler = &sable_irq_type;
  195. }
  196. common_init_isa_dma();
  197. }
  198. /*
  199.  * PCI Fixup configuration for ALPHA SABLE (2100) - 2100A is different ??
  200.  *
  201.  * The device to slot mapping looks like:
  202.  *
  203.  * Slot     Device
  204.  *  0       TULIP
  205.  *  1       SCSI
  206.  *  2       PCI-EISA bridge
  207.  *  3       none
  208.  *  4       none
  209.  *  5       none
  210.  *  6       PCI on board slot 0
  211.  *  7       PCI on board slot 1
  212.  *  8       PCI on board slot 2
  213.  *   
  214.  *
  215.  * This two layered interrupt approach means that we allocate IRQ 16 and 
  216.  * above for PCI interrupts.  The IRQ relates to which bit the interrupt
  217.  * comes in on.  This makes interrupt processing much easier.
  218.  */
  219. /*
  220.  * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
  221.  * with the values in the irq swizzling tables above.
  222.  */
  223. static int __init
  224. sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  225. {
  226.         static char irq_tab[9][5] __initdata = {
  227. /*INT    INTA   INTB   INTC   INTD */
  228. { 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
  229. { 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
  230. {   -1,    -1,    -1,    -1,    -1},  /* IdSel 2,  SIO   */
  231. {   -1,    -1,    -1,    -1,    -1},  /* IdSel 3,  none   */
  232. {   -1,    -1,    -1,    -1,    -1},  /* IdSel 4,  none   */
  233. {   -1,    -1,    -1,    -1,    -1},  /* IdSel 5,  none   */
  234. { 32+2,  32+2,  32+2,  32+2,  32+2},  /* IdSel 6,  slot 0 */
  235. { 32+3,  32+3,  32+3,  32+3,  32+3},  /* IdSel 7,  slot 1 */
  236. { 32+4,  32+4,  32+4,  32+4,  32+4},  /* IdSel 8,  slot 2 */
  237.         };
  238. const long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5;
  239. return COMMON_TABLE_LOOKUP;
  240. }
  241. /*
  242.  * The System Vectors
  243.  *
  244.  * In order that T2_HAE_ADDRESS should be a constant, we play
  245.  * these games with GAMMA_BIAS.
  246.  */
  247. #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_GAMMA)
  248. #undef GAMMA_BIAS
  249. #define GAMMA_BIAS 0
  250. struct alpha_machine_vector sable_mv __initmv = {
  251. vector_name: "Sable",
  252. DO_EV4_MMU,
  253. DO_DEFAULT_RTC,
  254. DO_T2_IO,
  255. DO_T2_BUS,
  256. machine_check: t2_machine_check,
  257. max_dma_address: ALPHA_MAX_DMA_ADDRESS,
  258. min_io_address: EISA_DEFAULT_IO_BASE,
  259. min_mem_address: DEFAULT_MEM_BASE,
  260. nr_irqs: 40,
  261. device_interrupt: sable_srm_device_interrupt,
  262. init_arch: t2_init_arch,
  263. init_irq: sable_init_irq,
  264. init_rtc: common_init_rtc,
  265. init_pci: common_init_pci,
  266. kill_arch: NULL,
  267. pci_map_irq: sable_map_irq,
  268. pci_swizzle: common_swizzle,
  269. sys: { t2: {
  270.     gamma_bias: 0
  271. } }
  272. };
  273. ALIAS_MV(sable)
  274. #endif
  275. #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_GAMMA)
  276. #undef GAMMA_BIAS
  277. #define GAMMA_BIAS _GAMMA_BIAS
  278. struct alpha_machine_vector sable_gamma_mv __initmv = {
  279. vector_name: "Sable-Gamma",
  280. DO_EV5_MMU,
  281. DO_DEFAULT_RTC,
  282. DO_T2_IO,
  283. DO_T2_BUS,
  284. machine_check: t2_machine_check,
  285. max_dma_address: ALPHA_MAX_DMA_ADDRESS,
  286. min_io_address: EISA_DEFAULT_IO_BASE,
  287. min_mem_address: DEFAULT_MEM_BASE,
  288. nr_irqs: 40,
  289. device_interrupt: sable_srm_device_interrupt,
  290. init_arch: t2_init_arch,
  291. init_irq: sable_init_irq,
  292. init_rtc: common_init_rtc,
  293. init_pci: common_init_pci,
  294. pci_map_irq: sable_map_irq,
  295. pci_swizzle: common_swizzle,
  296. sys: { t2: {
  297.     gamma_bias: _GAMMA_BIAS
  298. } }
  299. };
  300. ALIAS_MV(sable_gamma)
  301. #endif