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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/alpha/kernel/sys_jensen.c
  3.  *
  4.  * Copyright (C) 1995 Linus Torvalds
  5.  * Copyright (C) 1998, 1999 Richard Henderson
  6.  *
  7.  * Code supporting the Jensen.
  8.  */
  9. #include <linux/kernel.h>
  10. #include <linux/types.h>
  11. #include <linux/mm.h>
  12. #include <linux/sched.h>
  13. #include <linux/pci.h>
  14. #include <linux/init.h>
  15. #include <asm/ptrace.h>
  16. #include <asm/system.h>
  17. #define __EXTERN_INLINE inline
  18. #include <asm/io.h>
  19. #include <asm/jensen.h>
  20. #undef  __EXTERN_INLINE
  21. #include <asm/dma.h>
  22. #include <asm/irq.h>
  23. #include <asm/mmu_context.h>
  24. #include <asm/pgtable.h>
  25. #include "proto.h"
  26. #include "irq_impl.h"
  27. #include "pci_impl.h"
  28. #include "machvec_impl.h"
  29. /*
  30.  * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
  31.  * 0x9X0 for the local motherboard interrupts.
  32.  *
  33.  * Note especially that those local interrupts CANNOT be masked,
  34.  * which causes much of the pain below...
  35.  *
  36.  * 0x660 - NMI
  37.  *
  38.  * 0x800 - IRQ0  interval timer (not used, as we use the RTC timer)
  39.  * 0x810 - IRQ1  line printer (duh..)
  40.  * 0x860 - IRQ6  floppy disk
  41.  *
  42.  * 0x900 - COM1
  43.  * 0x920 - COM2
  44.  * 0x980 - keyboard
  45.  * 0x990 - mouse
  46.  *
  47.  * PCI-based systems are more sane: they don't have the local
  48.  * interrupts at all, and have only normal PCI interrupts from
  49.  * devices.  Happily it's easy enough to do a sane mapping from the
  50.  * Jensen.
  51.  * 
  52.  * Note that this means that we may have to do a hardware
  53.  * "local_op" to a different interrupt than we report to the rest of the
  54.  * world.
  55.  */
  56. static unsigned int
  57. jensen_local_startup(unsigned int irq)
  58. {
  59. /* the parport is really hw IRQ 1, silly Jensen.  */
  60. if (irq == 7)
  61. i8259a_startup_irq(1);
  62. else
  63. /*
  64.  * For all true local interrupts, set the flag that prevents
  65.  * the IPL from being dropped during handler processing.
  66.  */
  67. if (irq_desc[irq].action)
  68. irq_desc[irq].action->flags |= SA_INTERRUPT;
  69. return 0;
  70. }
  71. static void
  72. jensen_local_shutdown(unsigned int irq)
  73. {
  74. /* the parport is really hw IRQ 1, silly Jensen.  */
  75. if (irq == 7)
  76. i8259a_disable_irq(1);
  77. }
  78. static void
  79. jensen_local_enable(unsigned int irq)
  80. {
  81. /* the parport is really hw IRQ 1, silly Jensen.  */
  82. if (irq == 7)
  83. i8259a_enable_irq(1);
  84. }
  85. static void
  86. jensen_local_disable(unsigned int irq)
  87. {
  88. /* the parport is really hw IRQ 1, silly Jensen.  */
  89. if (irq == 7)
  90. i8259a_disable_irq(1);
  91. }
  92. static void
  93. jensen_local_ack(unsigned int irq)
  94. {
  95. /* the parport is really hw IRQ 1, silly Jensen.  */
  96. if (irq == 7)
  97. i8259a_mask_and_ack_irq(1);
  98. }
  99. static void
  100. jensen_local_end(unsigned int irq)
  101. {
  102. /* the parport is really hw IRQ 1, silly Jensen.  */
  103. if (irq == 7)
  104. i8259a_end_irq(1);
  105. }
  106. static struct hw_interrupt_type jensen_local_irq_type = {
  107. typename: "LOCAL",
  108. startup: jensen_local_startup,
  109. shutdown: jensen_local_shutdown,
  110. enable: jensen_local_enable,
  111. disable: jensen_local_disable,
  112. ack: jensen_local_ack,
  113. end: jensen_local_end,
  114. };
  115. static void 
  116. jensen_device_interrupt(unsigned long vector, struct pt_regs * regs)
  117. {
  118. int irq;
  119. switch (vector) {
  120. case 0x660:
  121. printk("Whee.. NMI received. Probable hardware errorn");
  122. printk("61=%02x, 461=%02xn", inb(0x61), inb(0x461));
  123. return;
  124. /* local device interrupts: */
  125. case 0x900: irq = 4; break; /* com1 -> irq 4 */
  126. case 0x920: irq = 3; break; /* com2 -> irq 3 */
  127. case 0x980: irq = 1; break; /* kbd -> irq 1 */
  128. case 0x990: irq = 9; break; /* mouse -> irq 9 */
  129. default:
  130. if (vector > 0x900) {
  131. printk("Unknown local interrupt %lxn", vector);
  132. return;
  133. }
  134. irq = (vector - 0x800) >> 4;
  135. if (irq == 1)
  136. irq = 7;
  137. break;
  138. }
  139. /* If there is no handler yet... */
  140. if (irq_desc[irq].action == NULL) {
  141.     /* If it is a local interrupt that cannot be masked... */
  142.     if (vector >= 0x900)
  143.     {
  144.         /* Clear keyboard/mouse state */
  145.      inb(0x64);
  146. inb(0x60);
  147. /* Reset serial ports */
  148. inb(0x3fa);
  149. inb(0x2fa);
  150. outb(0x0c, 0x3fc);
  151. outb(0x0c, 0x2fc);
  152. /* Clear NMI */
  153. outb(0,0x61);
  154. outb(0,0x461);
  155.     }
  156. }
  157. #if 0
  158.         /* A useful bit of code to find out if an interrupt is going wild.  */
  159.         {
  160.           static unsigned int last_msg = 0, last_cc = 0;
  161.           static int last_irq = -1, count = 0;
  162.           unsigned int cc;
  163.           __asm __volatile("rpcc %0" : "=r"(cc));
  164.           ++count;
  165. #define JENSEN_CYCLES_PER_SEC (150000000)
  166.           if (cc - last_msg > ((JENSEN_CYCLES_PER_SEC) * 3) ||
  167.       irq != last_irq) {
  168.                 printk(KERN_CRIT " irq %d count %d cc %u @ %lxn",
  169.                        irq, count, cc-last_cc, regs->pc);
  170.                 count = 0;
  171.                 last_msg = cc;
  172.                 last_irq = irq;
  173.           }
  174.           last_cc = cc;
  175.         }
  176. #endif
  177. handle_irq(irq, regs);
  178. }
  179. static void __init
  180. jensen_init_irq(void)
  181. {
  182. init_i8259a_irqs();
  183. irq_desc[1].handler = &jensen_local_irq_type;
  184. irq_desc[4].handler = &jensen_local_irq_type;
  185. irq_desc[3].handler = &jensen_local_irq_type;
  186. irq_desc[7].handler = &jensen_local_irq_type;
  187. irq_desc[9].handler = &jensen_local_irq_type;
  188. common_init_isa_dma();
  189. }
  190. static void __init
  191. jensen_init_arch(void)
  192. {
  193. struct pci_controller *hose;
  194. /* Create a hose so that we can report i/o base addresses to
  195.    userland.  */
  196. pci_isa_hose = hose = alloc_pci_controller();
  197. hose->io_space = &ioport_resource;
  198. hose->mem_space = &iomem_resource;
  199. hose->index = 0;
  200. hose->sparse_mem_base = EISA_MEM - IDENT_ADDR;
  201. hose->dense_mem_base = 0;
  202. hose->sparse_io_base = EISA_IO - IDENT_ADDR;
  203. hose->dense_io_base = 0;
  204. hose->sg_isa = hose->sg_pci = NULL;
  205. __direct_map_base = 0;
  206. __direct_map_size = 0xffffffff;
  207. }
  208. static void
  209. jensen_machine_check (u64 vector, u64 la, struct pt_regs *regs)
  210. {
  211. printk(KERN_CRIT "Machine checkn");
  212. }
  213. #define jensen_pci_tbi ((void*)0)
  214. /*
  215.  * The System Vector
  216.  */
  217. struct alpha_machine_vector jensen_mv __initmv = {
  218. vector_name: "Jensen",
  219. DO_EV4_MMU,
  220. IO_LITE(JENSEN,jensen),
  221. BUS(jensen),
  222. machine_check: jensen_machine_check,
  223. max_dma_address: ALPHA_MAX_DMA_ADDRESS,
  224. rtc_port: 0x170,
  225. nr_irqs: 16,
  226. device_interrupt: jensen_device_interrupt,
  227. init_arch: jensen_init_arch,
  228. init_irq: jensen_init_irq,
  229. init_rtc: common_init_rtc,
  230. init_pci: NULL,
  231. kill_arch: NULL,
  232. };
  233. ALIAS_MV(jensen)