⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i8259.c

📁 一个简单的操作系统minix的核心代码
💻 C
字号:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				src/kernel/i8259.c	 	 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

07600	/* This file contains routines for initializing the 8259 interrupt controller:
07601	 *      get_irq_handler: address of handler for a given interrupt
07602	 *      put_irq_handler: register an interrupt handler
07603	 *      intr_init:      initialize the interrupt controller(s)
07604	 */
07605	
07606	#include "kernel.h"
07607	
07608	#define ICW1_AT         0x11    /* edge triggered, cascade, need ICW4 */
07609	#define ICW1_PC         0x13    /* edge triggered, no cascade, need ICW4 */
07610	#define ICW1_PS         0x19    /* level triggered, cascade, need ICW4 */
07611	#define ICW4_AT         0x01    /* not SFNM, not buffered, normal EOI, 8086 */
07612	#define ICW4_PC         0x09    /* not SFNM, buffered, normal EOI, 8086 */
07613	
07614	FORWARD _PROTOTYPE( int spurious_irq, (int irq) );
07615	
07616	#define set_vec(nr, addr)       ((void)0) /* kluge for protected mode */
07617	
07618	/*==========================================================================*
07619	 *                              intr_init                                   *
07620	 *==========================================================================*/
07621	PUBLIC void intr_init(mine)
07622	int mine;
07623	{
07624	/* Initialize the 8259s, finishing with all interrupts disabled.  This is
07625	 * only done in protected mode, in real mode we don't touch the 8259s, but
07626	 * use the BIOS locations instead.  The flag "mine" is set if the 8259s are
07627	 * to be programmed for Minix, or to be reset to what the BIOS expects.
07628	 */
07629	
07630	  int i;
07631	
07632	  lock();
07633	  /* The AT and newer PS/2 have two interrupt controllers, one master,
07634	   * one slaved at IRQ 2.  (We don't have to deal with the PC that
07635	   * has just one controller, because it must run in real mode.)
07636	   */
07637	  out_byte(INT_CTL, ps_mca ? ICW1_PS : ICW1_AT);
07638	  out_byte(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
07639	                                                /* ICW2 for master */
07640	  out_byte(INT_CTLMASK, (1 << CASCADE_IRQ));    /* ICW3 tells slaves */
07641	  out_byte(INT_CTLMASK, ICW4_AT);
07642	  out_byte(INT_CTLMASK, ~(1 << CASCADE_IRQ));   /* IRQ 0-7 mask */
07643	  out_byte(INT2_CTL, ps_mca ? ICW1_PS : ICW1_AT);
07644	  out_byte(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
07645	                                                /* ICW2 for slave */
07646	  out_byte(INT2_CTLMASK, CASCADE_IRQ);          /* ICW3 is slave nr */
07647	  out_byte(INT2_CTLMASK, ICW4_AT);
07648	  out_byte(INT2_CTLMASK, ~0);                   /* IRQ 8-15 mask */
07649	
07650	  /* Initialize the table of interrupt handlers. */
07651	  for (i = 0; i < NR_IRQ_VECTORS; i++) irq_table[i] = spurious_irq;
07652	}
	
07654	/*=========================================================================*
07655	 *                              spurious_irq                               *
07656	 *=========================================================================*/
07657	PRIVATE int spurious_irq(irq)
07658	int irq;
07659	{
07660	/* Default interrupt handler.  It complains a lot. */
07661	
07662	  if (irq < 0 || irq >= NR_IRQ_VECTORS)
07663	        panic("invalid call to spurious_irq", irq);
07664	
07665	  printf("spurious irq %d\n", irq);
07666	
07667	  return 1;     /* Reenable interrupt */
07668	}
	
07670	/*=========================================================================*
07671	 *                              put_irq_handler                            *
07672	 *=========================================================================*/
07673	PUBLIC void put_irq_handler(irq, handler)
07674	int irq;
07675	irq_handler_t handler;
07676	{
07677	/* Register an interrupt handler. */
07678	
07679	  if (irq < 0 || irq >= NR_IRQ_VECTORS)
07680	        panic("invalid call to put_irq_handler", irq);
07681	
07682	  if (irq_table[irq] == handler)
07683	        return;         /* extra initialization */
07684	
07685	  if (irq_table[irq] != spurious_irq)
07686	        panic("attempt to register second irq handler for irq", irq);
07687	
07688	  disable_irq(irq);
07689	  if (!protected_mode) set_vec(BIOS_VECTOR(irq), irq_vec[irq]);
07690	  irq_table[irq]= handler;
07691	  irq_use |= 1 << irq;
07692	}
	







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -