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

📄 genpvec.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* *  COPYRIGHT (c) 1998 by Radstone Technology * * * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU. * * You are hereby granted permission to use, copy, modify, and distribute * this file, provided that this notice, plus the above copyright notice * and disclaimer, appears in all copies. Radstone Technology will provide * no support for this code. * *//*  genpvec.c * *  These routines handle the external exception.  Multiple ISRs occur off *  of this one interrupt. * *  COPYRIGHT (c) 1989-1997. *  On-Line Applications Research Corporation (OAR). * *  The license and distribution terms for this file may in *  the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: genpvec.c,v 1.3.4.1 2003/09/04 18:45:11 joel Exp $ */#include <bsp.h>#include <chain.h>#include <assert.h>/*  * Proto types for this file                                           */rtems_isr external_exception_ISR (  rtems_vector_number   vector                                  /* IN  */);#define   NUM_LIRQ_HANDLERS   20#define   NUM_LIRQ            ( MAX_BOARD_IRQS - PPC_IRQ_LAST )/* * Current 8259 masks */unsigned8	ucMaster8259Mask;unsigned8	ucSlave8259Mask;/*  * Structure to for one of possible multiple interrupt handlers for  * a given interrupt. */typedef struct{  Chain_Node          Node;  rtems_isr_entry     handler;                  /* isr routine        */  rtems_vector_number vector;                   /* vector number      */} EE_ISR_Type;/* Note:  The following will not work if we add a method to remove *        handlers at a later time. */  EE_ISR_Type       ISR_Nodes [NUM_LIRQ_HANDLERS];  rtems_unsigned16  Nodes_Used;   Chain_Control     ISR_Array  [NUM_LIRQ];void initialize_external_exception_vector(){	rtems_isr_entry previous_isr;	rtems_status_code status;	int i;	Nodes_Used = 0;	for (i=0; i <NUM_LIRQ; i++)	{		Chain_Initialize_empty( &ISR_Array[i] );	}	/*	 * Initialise the 8259s	 */	outport_byte(ISA8259_M_CTRL, 0x11); /* ICW1 */	outport_byte(ISA8259_S_CTRL, 0x11); /* ICW1 */	outport_byte(ISA8259_M_MASK, 0x00); /* ICW2 vectors 0-7 */	outport_byte(ISA8259_S_MASK, 0x08); /* ICW2 vectors 8-15 */	outport_byte(ISA8259_M_MASK, 0x04); /* ICW3 cascade on IRQ2 */	outport_byte(ISA8259_S_MASK, 0x02); /* ICW3 cascade on IRQ2 */	outport_byte(ISA8259_M_MASK, 0x01); /* ICW4 x86 normal EOI */	outport_byte(ISA8259_S_MASK, 0x01); /* ICW4 x86 normal EOI */	/*	 * Enable IRQ2 cascade and disable all other interrupts	 */	ucMaster8259Mask=0xfb;	ucSlave8259Mask=0xff;	outport_byte(ISA8259_M_MASK, ucMaster8259Mask);	outport_byte(ISA8259_S_MASK, ucSlave8259Mask);	/*	 * Set up edge/level	 */	switch(ucSystemType)	{		case SYS_TYPE_PPC1:		{			if(ucBoardRevMaj<5)			{				outport_byte(ISA8259_S_ELCR,					     ELCRS_INT15_LVL);			}			else			{				outport_byte(ISA8259_S_ELCR,					     ELCRS_INT9_LVL |					     ELCRS_INT11_LVL |					     ELCRS_INT14_LVL |					     ELCRS_INT15_LVL);			}			outport_byte(ISA8259_M_ELCR,				     ELCRM_INT5_LVL |				     ELCRM_INT7_LVL);			break;		}		case SYS_TYPE_PPC1a:		{			outport_byte(ISA8259_S_ELCR,				     ELCRS_INT9_LVL |				     ELCRS_INT11_LVL |				     ELCRS_INT14_LVL |				     ELCRS_INT15_LVL);			outport_byte(ISA8259_M_ELCR,				     ELCRM_INT5_LVL);			break;		}				case SYS_TYPE_PPC2:		case SYS_TYPE_PPC2a:		case SYS_TYPE_PPC4:		default:		{			outport_byte(ISA8259_S_ELCR,				     ELCRS_INT9_LVL |				     ELCRS_INT10_LVL |				     ELCRS_INT11_LVL |				     ELCRS_INT14_LVL |				     ELCRS_INT15_LVL);			outport_byte(ISA8259_M_ELCR,				     ELCRM_INT5_LVL |				     ELCRM_INT7_LVL);			break;		}	}	/*  	 * Install external_exception_ISR () as the handler for 	 *  the General Purpose Interrupt.	 */	status = rtems_interrupt_catch( external_exception_ISR, 					PPC_IRQ_EXTERNAL,					(rtems_isr_entry *) &previous_isr );}/* *  This routine installs one of multiple ISRs for the general purpose  *  inerrupt. */void set_EE_vector(  rtems_isr_entry     handler,      /* isr routine        */  rtems_vector_number vector        /* vector number      */){	rtems_unsigned16 vec_idx  = vector - PPCN_60X_8259_IRQ_BASE;	rtems_unsigned32 index;	assert  (Nodes_Used < NUM_LIRQ_HANDLERS);	/*	 *  If we have already installed this handler for this vector, then	 *  just reset it.	 */	for ( index=0 ; index < Nodes_Used ; index++ )	{		if(ISR_Nodes[index].vector == vector &&		   ISR_Nodes[index].handler == handler)		{			return;		}	}	/*	 *  Doing things in this order makes them more atomic	 */	Nodes_Used++; 	index = Nodes_Used - 1;	ISR_Nodes[index].handler = handler;	ISR_Nodes[index].vector  = vector;	Chain_Append( &ISR_Array[vec_idx], &ISR_Nodes[index].Node );	/*	 * Enable the interrupt	 */	En_Ext_Interrupt(vector);}/*  * This interrupt service routine is called for an External Exception. */rtems_isr external_exception_ISR (  rtems_vector_number   vector             /* IN  */){ 	unsigned16	index;	unsigned8	ucISr;	EE_ISR_Type	*node;	index = *((volatile unsigned8 *)IRQ_VECTOR_BASE);	/*	 * check for spurious interrupt	 */	if(index==7)	{		/*		 * OCW3 select IS register		 */		outport_byte(ISA8259_M_CTRL, 0x0b);		/*		 * Read IS register		 */		inport_byte(ISA8259_M_CTRL, ucISr);		if(!(ucISr & 0x80))		{			/*			 * Spurious interrupt			 */			return;		}	}	node=(EE_ISR_Type *)ISR_Array[index].first;	while(!_Chain_Is_tail(&ISR_Array[index], (Chain_Node *)node))	{		(*node->handler)( node->vector );		node = (EE_ISR_Type *)node->Node.next;	}	/*	 * Dismiss the interrupt	 */	if(index&8)	{		/*		 * Dismiss the interrupt in Slave first as it		 * is cascaded		 */		outport_byte(ISA8259_S_CTRL, NONSPECIFIC_EOI);	}	/*	 * Dismiss the interrupt in Master	 */	outport_byte(ISA8259_M_CTRL, NONSPECIFIC_EOI);}void Dis_Ext_Interrupt(int level){	ISR_Level Irql;	level-=PPCN_60X_8259_IRQ_BASE;	if(level==2)	{		/*		 * Level 2 is for cascade and must not be fiddled with		 */		return;	}	/*	 * Ensure that accesses to the mask are indivisible	 */	_ISR_Disable(Irql);	if(level<8)	{		/*		 * Interrupt is handled by Master		 */		ucMaster8259Mask|=1<<level;		outport_byte(ISA8259_M_MASK, ucMaster8259Mask);	}	else	{		/*		 * Interrupt is handled by Slave		 */		ucSlave8259Mask|=1<<(level-8);		outport_byte(ISA8259_S_MASK, ucSlave8259Mask);	}	_ISR_Enable(Irql);}void En_Ext_Interrupt(int level){	ISR_Level Irql;	level-=PPCN_60X_8259_IRQ_BASE;	if(level==2)	{		/*		 * Level 2 is for cascade and must not be fiddled with		 */		return;	}	/*	 * Ensure that accesses to the mask are indivisible	 */	_ISR_Disable(Irql);	if(level<8)	{		/*		 * Interrupt is handled by Master		 */		ucMaster8259Mask&=~(1<<level);		outport_byte(ISA8259_M_MASK, ucMaster8259Mask);	}	else	{		/*		 * Interrupt is handled by Slave		 */		ucSlave8259Mask&=~(1<<(level-8));		outport_byte(ISA8259_S_MASK, ucSlave8259Mask);	}	_ISR_Enable(Irql);}

⌨️ 快捷键说明

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