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

Linux/Unix编程

开发平台:

Unix_Linux

  1. #include <linux/config.h>
  2. #include <linux/ptrace.h>
  3. #include <linux/errno.h>
  4. #include <linux/signal.h>
  5. #include <linux/sched.h>
  6. #include <linux/ioport.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/timex.h>
  9. #include <linux/slab.h>
  10. #include <linux/random.h>
  11. #include <linux/smp_lock.h>
  12. #include <linux/init.h>
  13. #include <linux/kernel_stat.h>
  14. #include <asm/atomic.h>
  15. #include <asm/system.h>
  16. #include <asm/io.h>
  17. #include <asm/irq.h>
  18. #include <asm/bitops.h>
  19. #include <asm/pgtable.h>
  20. #include <asm/delay.h>
  21. #include <asm/desc.h>
  22. #include <asm/apic.h>
  23. #include <linux/irq.h>
  24. /*
  25.  * Common place to define all x86 IRQ vectors
  26.  *
  27.  * This builds up the IRQ handler stubs using some ugly macros in irq.h
  28.  *
  29.  * These macros create the low-level assembly IRQ routines that save
  30.  * register context and call do_IRQ(). do_IRQ() then does all the
  31.  * operations that are needed to keep the AT (or SMP IOAPIC)
  32.  * interrupt-controller happy.
  33.  */
  34. BUILD_COMMON_IRQ()
  35. #define BI(x,y) 
  36. BUILD_IRQ(x##y)
  37. #define BUILD_16_IRQS(x) 
  38. BI(x,0) BI(x,1) BI(x,2) BI(x,3) 
  39. BI(x,4) BI(x,5) BI(x,6) BI(x,7) 
  40. BI(x,8) BI(x,9) BI(x,a) BI(x,b) 
  41. BI(x,c) BI(x,d) BI(x,e) BI(x,f)
  42. /*
  43.  * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
  44.  * (these are usually mapped to vectors 0x20-0x2f)
  45.  */
  46. BUILD_16_IRQS(0x0)
  47. #ifdef CONFIG_X86_IO_APIC
  48. /*
  49.  * The IO-APIC gives us many more interrupt sources. Most of these 
  50.  * are unused but an SMP system is supposed to have enough memory ...
  51.  * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
  52.  * across the spectrum, so we really want to be prepared to get all
  53.  * of these. Plus, more powerful systems might have more than 64
  54.  * IO-APIC registers.
  55.  *
  56.  * (these are usually mapped into the 0x30-0xff vector range)
  57.  */
  58.    BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
  59. BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
  60. BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
  61. BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
  62. #endif
  63. #undef BUILD_16_IRQS
  64. #undef BI
  65. /*
  66.  * The following vectors are part of the Linux architecture, there
  67.  * is no hardware IRQ pin equivalent for them, they are triggered
  68.  * through the ICC by us (IPIs)
  69.  */
  70. #ifdef CONFIG_SMP
  71. BUILD_SMP_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
  72. BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
  73. BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
  74. #endif
  75. /*
  76.  * every pentium local APIC has two 'local interrupts', with a
  77.  * soft-definable vector attached to both interrupts, one of
  78.  * which is a timer interrupt, the other one is error counter
  79.  * overflow. Linux uses the local APIC timer interrupt to get
  80.  * a much simpler SMP time architecture:
  81.  */
  82. #ifdef CONFIG_X86_LOCAL_APIC
  83. BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
  84. BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
  85. BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
  86. #endif
  87. #define IRQ(x,y) 
  88. IRQ##x##y##_interrupt
  89. #define IRQLIST_16(x) 
  90. IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), 
  91. IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), 
  92. IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), 
  93. IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
  94. void (*interrupt[NR_IRQS])(void) = {
  95. IRQLIST_16(0x0),
  96. #ifdef CONFIG_X86_IO_APIC
  97.  IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
  98. IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
  99. IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
  100. IRQLIST_16(0xc), IRQLIST_16(0xd)
  101. #endif
  102. };
  103. #undef IRQ
  104. #undef IRQLIST_16
  105. /*
  106.  * This is the 'legacy' 8259A Programmable Interrupt Controller,
  107.  * present in the majority of PC/AT boxes.
  108.  * plus some generic x86 specific things if generic specifics makes
  109.  * any sense at all.
  110.  * this file should become arch/i386/kernel/irq.c when the old irq.c
  111.  * moves to arch independent land
  112.  */
  113. spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
  114. static void end_8259A_irq (unsigned int irq)
  115. {
  116. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  117. enable_8259A_irq(irq);
  118. }
  119. #define shutdown_8259A_irq disable_8259A_irq
  120. void mask_and_ack_8259A(unsigned int);
  121. static unsigned int startup_8259A_irq(unsigned int irq)
  122. enable_8259A_irq(irq);
  123. return 0; /* never anything pending */
  124. }
  125. static struct hw_interrupt_type i8259A_irq_type = {
  126. "XT-PIC",
  127. startup_8259A_irq,
  128. shutdown_8259A_irq,
  129. enable_8259A_irq,
  130. disable_8259A_irq,
  131. mask_and_ack_8259A,
  132. end_8259A_irq,
  133. NULL
  134. };
  135. /*
  136.  * 8259A PIC functions to handle ISA devices:
  137.  */
  138. /*
  139.  * This contains the irq mask for both 8259A irq controllers,
  140.  */
  141. static unsigned int cached_irq_mask = 0xffff;
  142. #define __byte(x,y)  (((unsigned char *)&(y))[x])
  143. #define cached_21 (__byte(0,cached_irq_mask))
  144. #define cached_A1 (__byte(1,cached_irq_mask))
  145. /*
  146.  * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
  147.  * boards the timer interrupt is not really connected to any IO-APIC pin,
  148.  * it's fed to the master 8259A's IR0 line only.
  149.  *
  150.  * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
  151.  * this 'mixed mode' IRQ handling costs nothing because it's only used
  152.  * at IRQ setup time.
  153.  */
  154. unsigned long io_apic_irqs;
  155. void disable_8259A_irq(unsigned int irq)
  156. {
  157. unsigned int mask = 1 << irq;
  158. unsigned long flags;
  159. spin_lock_irqsave(&i8259A_lock, flags);
  160. cached_irq_mask |= mask;
  161. if (irq & 8)
  162. outb(cached_A1,0xA1);
  163. else
  164. outb(cached_21,0x21);
  165. spin_unlock_irqrestore(&i8259A_lock, flags);
  166. }
  167. void enable_8259A_irq(unsigned int irq)
  168. {
  169. unsigned int mask = ~(1 << irq);
  170. unsigned long flags;
  171. spin_lock_irqsave(&i8259A_lock, flags);
  172. cached_irq_mask &= mask;
  173. if (irq & 8)
  174. outb(cached_A1,0xA1);
  175. else
  176. outb(cached_21,0x21);
  177. spin_unlock_irqrestore(&i8259A_lock, flags);
  178. }
  179. int i8259A_irq_pending(unsigned int irq)
  180. {
  181. unsigned int mask = 1<<irq;
  182. unsigned long flags;
  183. int ret;
  184. spin_lock_irqsave(&i8259A_lock, flags);
  185. if (irq < 8)
  186. ret = inb(0x20) & mask;
  187. else
  188. ret = inb(0xA0) & (mask >> 8);
  189. spin_unlock_irqrestore(&i8259A_lock, flags);
  190. return ret;
  191. }
  192. void make_8259A_irq(unsigned int irq)
  193. {
  194. disable_irq_nosync(irq);
  195. io_apic_irqs &= ~(1<<irq);
  196. irq_desc[irq].handler = &i8259A_irq_type;
  197. enable_irq(irq);
  198. }
  199. /*
  200.  * This function assumes to be called rarely. Switching between
  201.  * 8259A registers is slow.
  202.  * This has to be protected by the irq controller spinlock
  203.  * before being called.
  204.  */
  205. static inline int i8259A_irq_real(unsigned int irq)
  206. {
  207. int value;
  208. int irqmask = 1<<irq;
  209. if (irq < 8) {
  210. outb(0x0B,0x20); /* ISR register */
  211. value = inb(0x20) & irqmask;
  212. outb(0x0A,0x20); /* back to the IRR register */
  213. return value;
  214. }
  215. outb(0x0B,0xA0); /* ISR register */
  216. value = inb(0xA0) & (irqmask >> 8);
  217. outb(0x0A,0xA0); /* back to the IRR register */
  218. return value;
  219. }
  220. /*
  221.  * Careful! The 8259A is a fragile beast, it pretty
  222.  * much _has_ to be done exactly like this (mask it
  223.  * first, _then_ send the EOI, and the order of EOI
  224.  * to the two 8259s is important!
  225.  */
  226. void mask_and_ack_8259A(unsigned int irq)
  227. {
  228. unsigned int irqmask = 1 << irq;
  229. unsigned long flags;
  230. spin_lock_irqsave(&i8259A_lock, flags);
  231. /*
  232.  * Lightweight spurious IRQ detection. We do not want
  233.  * to overdo spurious IRQ handling - it's usually a sign
  234.  * of hardware problems, so we only do the checks we can
  235.  * do without slowing down good hardware unnecesserily.
  236.  *
  237.  * Note that IRQ7 and IRQ15 (the two spurious IRQs
  238.  * usually resulting from the 8259A-1|2 PICs) occur
  239.  * even if the IRQ is masked in the 8259A. Thus we
  240.  * can check spurious 8259A IRQs without doing the
  241.  * quite slow i8259A_irq_real() call for every IRQ.
  242.  * This does not cover 100% of spurious interrupts,
  243.  * but should be enough to warn the user that there
  244.  * is something bad going on ...
  245.  */
  246. if (cached_irq_mask & irqmask)
  247. goto spurious_8259A_irq;
  248. cached_irq_mask |= irqmask;
  249. handle_real_irq:
  250. if (irq & 8) {
  251. inb(0xA1); /* DUMMY - (do we need this?) */
  252. outb(cached_A1,0xA1);
  253. outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */
  254. outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */
  255. } else {
  256. inb(0x21); /* DUMMY - (do we need this?) */
  257. outb(cached_21,0x21);
  258. outb(0x60+irq,0x20); /* 'Specific EOI' to master */
  259. }
  260. spin_unlock_irqrestore(&i8259A_lock, flags);
  261. return;
  262. spurious_8259A_irq:
  263. /*
  264.  * this is the slow path - should happen rarely.
  265.  */
  266. if (i8259A_irq_real(irq))
  267. /*
  268.  * oops, the IRQ _is_ in service according to the
  269.  * 8259A - not spurious, go handle it.
  270.  */
  271. goto handle_real_irq;
  272. {
  273. static int spurious_irq_mask;
  274. /*
  275.  * At this point we can be sure the IRQ is spurious,
  276.  * lets ACK and report it. [once per IRQ]
  277.  */
  278. if (!(spurious_irq_mask & irqmask)) {
  279. printk("spurious 8259A interrupt: IRQ%d.n", irq);
  280. spurious_irq_mask |= irqmask;
  281. }
  282. atomic_inc(&irq_err_count);
  283. /*
  284.  * Theoretically we do not have to handle this IRQ,
  285.  * but in Linux this does not cause problems and is
  286.  * simpler for us.
  287.  */
  288. goto handle_real_irq;
  289. }
  290. }
  291. void __init init_8259A(int auto_eoi)
  292. {
  293. unsigned long flags;
  294. spin_lock_irqsave(&i8259A_lock, flags);
  295. outb(0xff, 0x21); /* mask all of 8259A-1 */
  296. outb(0xff, 0xA1); /* mask all of 8259A-2 */
  297. /*
  298.  * outb_p - this has to work on a wide range of PC hardware.
  299.  */
  300. outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
  301. outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
  302. outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */
  303. if (auto_eoi)
  304. outb_p(0x03, 0x21); /* master does Auto EOI */
  305. else
  306. outb_p(0x01, 0x21); /* master expects normal EOI */
  307. outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */
  308. outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
  309. outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */
  310. outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode
  311.     is to be investigated) */
  312. if (auto_eoi)
  313. /*
  314.  * in AEOI mode we just have to mask the interrupt
  315.  * when acking.
  316.  */
  317. i8259A_irq_type.ack = disable_8259A_irq;
  318. else
  319. i8259A_irq_type.ack = mask_and_ack_8259A;
  320. udelay(100); /* wait for 8259A to initialize */
  321. outb(cached_21, 0x21); /* restore master IRQ mask */
  322. outb(cached_A1, 0xA1); /* restore slave IRQ mask */
  323. spin_unlock_irqrestore(&i8259A_lock, flags);
  324. }
  325. /*
  326.  * Note that on a 486, we don't want to do a SIGFPE on an irq13
  327.  * as the irq is unreliable, and exception 16 works correctly
  328.  * (ie as explained in the intel literature). On a 386, you
  329.  * can't use exception 16 due to bad IBM design, so we have to
  330.  * rely on the less exact irq13.
  331.  *
  332.  * Careful.. Not only is IRQ13 unreliable, but it is also
  333.  * leads to races. IBM designers who came up with it should
  334.  * be shot.
  335.  */
  336.  
  337. static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
  338. {
  339. extern void math_error(void *);
  340. outb(0,0xF0);
  341. if (ignore_irq13 || !boot_cpu_data.hard_math)
  342. return;
  343. math_error((void *)regs->eip);
  344. }
  345. /*
  346.  * New motherboards sometimes make IRQ 13 be a PCI interrupt,
  347.  * so allow interrupt sharing.
  348.  */
  349. static struct irqaction irq13 = { math_error_irq, 0, 0, "fpu", NULL, NULL };
  350. /*
  351.  * IRQ2 is cascade interrupt to second interrupt controller
  352.  */
  353. #ifndef CONFIG_VISWS
  354. static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
  355. #endif
  356. void __init init_ISA_irqs (void)
  357. {
  358. int i;
  359. #ifdef CONFIG_X86_LOCAL_APIC
  360. init_bsp_APIC();
  361. #endif
  362. init_8259A(0);
  363. for (i = 0; i < NR_IRQS; i++) {
  364. irq_desc[i].status = IRQ_DISABLED;
  365. irq_desc[i].action = 0;
  366. irq_desc[i].depth = 1;
  367. if (i < 16) {
  368. /*
  369.  * 16 old-style INTA-cycle interrupts:
  370.  */
  371. irq_desc[i].handler = &i8259A_irq_type;
  372. } else {
  373. /*
  374.  * 'high' PCI IRQs filled in on demand
  375.  */
  376. irq_desc[i].handler = &no_irq_type;
  377. }
  378. }
  379. }
  380. void __init init_IRQ(void)
  381. {
  382. int i;
  383. #ifndef CONFIG_X86_VISWS_APIC
  384. init_ISA_irqs();
  385. #else
  386. init_VISWS_APIC_irqs();
  387. #endif
  388. /*
  389.  * Cover the whole vector space, no vector can escape
  390.  * us. (some of these will be overridden and become
  391.  * 'special' SMP interrupts)
  392.  */
  393. for (i = 0; i < NR_IRQS; i++) {
  394. int vector = FIRST_EXTERNAL_VECTOR + i;
  395. if (vector != SYSCALL_VECTOR) 
  396. set_intr_gate(vector, interrupt[i]);
  397. }
  398. #ifdef CONFIG_SMP
  399. /*
  400.  * IRQ0 must be given a fixed assignment and initialized,
  401.  * because it's used before the IO-APIC is set up.
  402.  */
  403. set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
  404. /*
  405.  * The reschedule interrupt is a CPU-to-CPU reschedule-helper
  406.  * IPI, driven by wakeup.
  407.  */
  408. set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
  409. /* IPI for invalidation */
  410. set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
  411. /* IPI for generic function call */
  412. set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
  413. #endif
  414. #ifdef CONFIG_X86_LOCAL_APIC
  415. /* self generated IPI for local APIC timer */
  416. set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
  417. /* IPI vectors for APIC spurious and error interrupts */
  418. set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
  419. set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
  420. #endif
  421. /*
  422.  * Set the clock to HZ Hz, we already have a valid
  423.  * vector now:
  424.  */
  425. outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
  426. outb_p(LATCH & 0xff , 0x40); /* LSB */
  427. outb(LATCH >> 8 , 0x40); /* MSB */
  428. #ifndef CONFIG_VISWS
  429. setup_irq(2, &irq2);
  430. #endif
  431. /*
  432.  * External FPU? Set up irq13 if so, for
  433.  * original braindamaged IBM FERR coupling.
  434.  */
  435. if (boot_cpu_data.hard_math && !cpu_has_fpu)
  436. setup_irq(13, &irq13);
  437. }