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

📄 i8259intr.c

📁 VxWorks实时系统中的中断控制器驱动程序源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
	}    }/********************************************************************************* i8259IntEoiSmm - disable Special Mask Mode with EOI signal to the master PIC** This routine is called at the end of the IRQ0 interrupt handler that is * PIT(8253) channel 0 system clock interrupt handler in the Special Mask Mode.**/VOID i8259IntEoiSmm     (    int irqNo		/* IRQ number to send EOI */    )    {    INT32 oldLevel = intLock ();			/* LOCK INTERRUPT */    sysOutByte (PIC_IMASK (PIC1_BASE_ADR), i8259Mask);	/* restore old mask */    sysOutByte (PIC_port1 (PIC1_BASE_ADR), 0x08);	/* disable SMM PIC1 */    sysOutByte (PIC_IACK (PIC1_BASE_ADR), 0x20);	/* NS EOI to PIC1 */    intUnlock (oldLevel);				/* UNLOCK INTERRUPT */    }/********************************************************************************* i8259IntEoiMaster - send EOI(end of interrupt) signal to the master PIC.** This routine is called at the end of the interrupt handler.**/VOID i8259IntEoiMaster     (    INT32 irqNo		/* IRQ number to send EOI */    )    {#ifdef	I8259_EOI_OPTIMIZED	/* optimized version */    WRS_ASM ("			\	pushfl;			\	cli;			\	movl	$0x20, %edx;	\	movl	$0x20, %eax;	\	outb	%al, %dx;	\	popfl;			\	");#else				/* portable version */    INT32 oldLevel = intLock ();	/* LOCK INTERRUPTS */    sysOutByte (PIC_IACK (PIC1_BASE_ADR), I8259_EOI); /* non-specific EOI */    intUnlock (oldLevel);		/* UNLOCK INTERRUPTS */#endif	/* I8259_EOI_OPTIMIZED */    }/********************************************************************************* i8259IntEoiSlave - send EOI(end of interrupt) signal to the slave PIC.** This routine is called at the end of the interrupt handler in the Normal * Fully Nested Mode.  This is kept for the backward compatibility.**/VOID i8259IntEoiSlave    (    INT32 irqNo		/* IRQ number to send EOI */    )    {#ifdef	I8259_EOI_OPTIMIZED	/* optimized version */    WRS_ASM ("			\	pushfl;			\	cli;			\	movl	$0xa0, %edx;	\	movl	$0x20, %eax;	\	outb	%al, %dx;	\	movl	$0x20, %edx;	\	outb	%al, %dx;	\	popfl;			\	");#else				/* portable version */    INT32 oldLevel = intLock ();		/* LOCK INTERRUPTS */    sysOutByte (PIC_IACK (PIC2_BASE_ADR), I8259_EOI); /* non-specific EOI */    sysOutByte (PIC_IACK (PIC1_BASE_ADR), I8259_EOI); /* non-specific EOI */    intUnlock (oldLevel);			/* UNLOCK INTERRUPTS */#endif	/* I8259_EOI_OPTIMIZED */    }/********************************************************************************* i8259IntEoiSlaveNfnm - send EOI(end of interrupt) signal to the slave PIC.** This routine is called at the end of the interrupt handler in the Normal * Fully Nested Mode.**/VOID i8259IntEoiSlaveNfnm    (    INT32 irqNo		/* IRQ number to send EOI */    )    {#ifdef	I8259_EOI_OPTIMIZED	/* optimized version */    WRS_ASM ("			\	pushfl;			\	cli;			\	movl	$0xa0, %edx;	\	movl	$0x20, %eax;	\	outb	%al, %dx;	\	movl	$0x20, %edx;	\	outb	%al, %dx;	\	popfl;			\	");#else				/* portable version */    INT32 oldLevel = intLock ();		/* LOCK INTERRUPTS */    sysOutByte (PIC_IACK (PIC2_BASE_ADR), I8259_EOI); /* non-specific EOI */    sysOutByte (PIC_IACK (PIC1_BASE_ADR), I8259_EOI); /* non-specific EOI */    intUnlock (oldLevel);			/* UNLOCK INTERRUPTS */#endif	/* I8259_EOI_OPTIMIZED */    }/********************************************************************************* i8259IntEoiSlaveSfnm - send EOI(end of interrupt) signal to the slave PIC.** This routine is called at the end of the interrupt handler in the Special * Fully Nested Mode.**/VOID i8259IntEoiSlaveSfnm    (    int irqNo		/* IRQ number to send EOI */    )    {    INT8  inserviceReg;    INT32 oldLevel = intLock ();			/* LOCK INTERRUPT */    sysOutByte (PIC_IACK (PIC2_BASE_ADR), 0x20);	/* NS EOI to PIC2 */    sysOutByte (PIC_port1 (PIC2_BASE_ADR), 0x0b);	/* issue OCW3 */    inserviceReg = sysInByte (PIC_port1 (PIC2_BASE_ADR)); /* read ISR */    if (inserviceReg == 0)         sysOutByte (PIC_IACK (PIC1_BASE_ADR), 0x20);	/* NS EOI to PIC1 */    intUnlock (oldLevel);				/* UNLOCK INTERRUPT */    }/********************************************************************************* i8259IntDisable - disable a specified PIC interrupt input line** This routine disables a specified PIC interrupt input line.** RETURNS: OK, always.** SEE ALSO: i8259IntEnable()** ARGSUSED0*/LOCAL STATUS i8259IntDisable    (    INT32 irqNo        /* IRQ number to disable */    )    {    if (irqNo < 8)	{	sysOutByte (PIC_IMASK (PIC1_BASE_ADR),	    sysInByte (PIC_IMASK (PIC1_BASE_ADR)) | (1 << irqNo));	}    else	{	sysOutByte (PIC_IMASK (PIC2_BASE_ADR),	    sysInByte (PIC_IMASK (PIC2_BASE_ADR)) | (1 << (irqNo - 8)));	}    return (OK);    }/********************************************************************************* i8259IntEnable - enable a specified PIC interrupt input line** This routine enables a specified PIC interrupt input line.** RETURNS: OK, always.** SEE ALSO: i8259IntDisable()** ARGSUSED0*/LOCAL STATUS i8259IntEnable    (    INT32 irqNo        /* IRQ number to enable */    )    {    if (irqNo < 8)	{	sysOutByte (PIC_IMASK (PIC1_BASE_ADR),	    sysInByte (PIC_IMASK (PIC1_BASE_ADR)) & ~(1 << irqNo));	}    else	{	sysOutByte (PIC_IMASK (PIC2_BASE_ADR),	    sysInByte (PIC_IMASK (PIC2_BASE_ADR)) & ~(1 << (irqNo - 8)));	}    return (OK);    }/********************************************************************************* i8259IntLock - lock out all PIC interrupts** This routine saves the mask and locks out all PIC interrupts.* It should be called in the interrupt disable state(IF bit is 0).** SEE ALSO: i8259IntUnlock()** ARGSUSED0*/LOCAL VOID i8259IntLock (void)    {    i8259IntMask1 = sysInByte (PIC_IMASK (PIC1_BASE_ADR));    i8259IntMask2 = sysInByte (PIC_IMASK (PIC2_BASE_ADR));    sysOutByte (PIC_IMASK (PIC1_BASE_ADR), 0xff);    sysOutByte (PIC_IMASK (PIC2_BASE_ADR), 0xff);    }/********************************************************************************* i8259IntUnlock - unlock the PIC interrupts** This routine restores the mask and unlocks the PIC interrupts* It should be called in the interrupt disable state(IF bit is 0).** SEE ALSO: i8259IntLock()** ARGSUSED0*/LOCAL VOID i8259IntUnlock (void)    {    sysOutByte (PIC_IMASK (PIC1_BASE_ADR), i8259IntMask1);    sysOutByte (PIC_IMASK (PIC2_BASE_ADR), i8259IntMask2);    }#if	FALSE/* * There is a function sysIntLevel() which get the interrupt level from the  * interrupt stub, so we don't need it anymore. *//********************************************************************************* i8259IntLevel - Get IRQ number by reading Interrupt Service Register.** This routine is called to get an IRQ number in service.** RETURNS: 0 - 15.** ARGSUSED0*/LOCAL INT32 i8259IntLevel (void)    {    INT32 inserviceReg;    INT32 irq;    INT32 oldLevel;    INT32 retry;    oldLevel = intLock ();    for (retry=0; retry < 1; retry ++)	{        sysOutByte (PIC_port1 (PIC1_BASE_ADR), 0x0b);        inserviceReg = sysInByte (PIC_port1 (PIC1_BASE_ADR));        for (irq=0; irq < 8; irq++)	    if ((inserviceReg & 1) && (irq != 2))	        goto i8259IntLevelExit;	    else	        inserviceReg >>= 1;        sysOutByte (PIC_port1 (PIC2_BASE_ADR), 0x0b);        inserviceReg = sysInByte (PIC_port1 (PIC2_BASE_ADR));        for (irq=8; irq < 16; irq++)	    if (inserviceReg & 1)	        goto i8259IntLevelExit;	    else	        inserviceReg >>= 1;	}    i8259IntLevelExit:    intUnlock (oldLevel);    return (irq);    }#endif	/* FALSE */#endif	/* SYMMETRIC_IO_MODE */

⌨️ 快捷键说明

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