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

📄 excep.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* '192'      set */ {   2,  { 7,6,0,0,0,0,0,0 } },
/* '193'      set */ {   3,  { 7,6,0,0,0,0,0,0 } },
/* '194'      set */ {   3,  { 7,6,1,0,0,0,0,0 } },
/* '195'      set */ {   4,  { 7,6,1,0,0,0,0,0 } },

/* '196'      set */ {   3,  { 7,6,2,0,0,0,0,0 } },
/* '197'      set */ {   4,  { 7,6,2,0,0,0,0,0 } },
/* '198'      set */ {   4,  { 7,6,2,1,0,0,0,0 } },
/* '199'      set */ {   5,  { 7,6,2,1,0,0,0,0 } },

/* '200'      set */ {   3,  { 7,6,3,0,0,0,0,0 } },
/* '201'      set */ {   4,  { 7,6,3,0,0,0,0,0 } },
/* '202'      set */ {   4,  { 7,6,3,1,0,0,0,0 } },
/* '203'      set */ {   5,  { 7,6,3,1,0,0,0,0 } },

/* '204'      set */ {   4,  { 7,6,3,2,0,0,0,0 } },
/* '205'      set */ {   5,  { 7,6,3,2,0,0,0,0 } },
/* '206'      set */ {   5,  { 7,6,3,2,1,0,0,0 } },
/* '207'      set */ {   6,  { 7,6,3,2,1,0,0,0 } },

/* '208'      set */ {   3,  { 7,6,4,0,0,0,0,0 } },
/* '209'      set */ {   4,  { 7,6,4,0,0,0,0,0 } },
/* '210'      set */ {   4,  { 7,6,4,1,0,0,0,0 } },
/* '211'      set */ {   5,  { 7,6,4,1,0,0,0,0 } },

/* '212'      set */ {   4,  { 7,6,4,2,0,0,0,0 } },
/* '213'      set */ {   5,  { 7,6,4,2,0,0,0,0 } },
/* '214'      set */ {   5,  { 7,6,4,2,1,0,0,0 } },
/* '215'      set */ {   6,  { 7,6,4,2,1,0,0,0 } },

/* '216'      set */ {   4,  { 7,6,4,3,0,0,0,0 } },
/* '217'      set */ {   5,  { 7,6,4,3,0,0,0,0 } },
/* '218'      set */ {   5,  { 7,6,4,3,1,0,0,0 } },
/* '219'      set */ {   6,  { 7,6,4,3,1,0,0,0 } },

/* '220'      set */ {   5,  { 7,6,4,3,2,0,0,0 } },
/* '221'      set */ {   6,  { 7,6,4,3,2,0,0,0 } },
/* '222'      set */ {   6,  { 7,6,4,3,2,1,0,0 } },
/* '223'      set */ {   7,  { 7,6,4,3,2,1,0,0 } },

/* '224'      set */ {   3,  { 7,6,5,0,0,0,0,0 } },
/* '225'      set */ {   4,  { 7,6,5,0,0,0,0,0 } },
/* '226'      set */ {   4,  { 7,6,5,1,0,0,0,0 } },
/* '227'      set */ {   5,  { 7,6,5,1,0,0,0,0 } },

/* '228'      set */ {   4,  { 7,6,5,2,0,0,0,0 } },
/* '229'      set */ {   5,  { 7,6,5,2,0,0,0,0 } },
/* '230'      set */ {   5,  { 7,6,5,2,1,0,0,0 } },
/* '231'      set */ {   6,  { 7,6,5,2,1,0,0,0 } },

/* '232'      set */ {   4,  { 7,6,5,3,0,0,0,0 } },
/* '233'      set */ {   5,  { 7,6,5,3,0,0,0,0 } },
/* '234'      set */ {   5,  { 7,6,5,3,1,0,0,0 } },
/* '235'      set */ {   6,  { 7,6,5,3,1,0,0,0 } },

/* '236'      set */ {   5,  { 7,6,5,3,2,0,0,0 } },
/* '237'      set */ {   6,  { 7,6,5,3,2,0,0,0 } },
/* '238'      set */ {   6,  { 7,6,5,3,2,1,0,0 } },
/* '239'      set */ {   7,  { 7,6,5,3,2,1,0,0 } },

/* '240'      set */ {   4,  { 7,6,5,4,0,0,0,0 } },
/* '241'      set */ {   5,  { 7,6,5,4,0,0,0,0 } },
/* '242'      set */ {   5,  { 7,6,5,4,1,0,0,0 } },
/* '243'      set */ {   6,  { 7,6,5,4,1,0,0,0 } },

/* '244'      set */ {   5,  { 7,6,5,4,2,0,0,0 } },
/* '245'      set */ {   6,  { 7,6,5,4,2,0,0,0 } },
/* '246'      set */ {   6,  { 7,6,5,4,2,1,0,0 } },
/* '247'      set */ {   7,  { 7,6,5,4,2,1,0,0 } },

/* '248'      set */ {   5,  { 7,6,5,4,3,0,0,0 } },
/* '249'      set */ {   6,  { 7,6,5,4,3,0,0,0 } },
/* '250'      set */ {   6,  { 7,6,5,4,3,1,0,0 } },
/* '251'      set */ {   7,  { 7,6,5,4,3,1,0,0 } },

/* '252'      set */ {   6,  { 7,6,5,4,3,2,0,0 } },
/* '253'      set */ {   7,  { 7,6,5,4,3,2,0,0 } },
/* '254'      set */ {   7,  { 7,6,5,4,3,2,1,0 } },
/* '255'      set */ {   8,  { 7,6,5,4,3,2,1,0 } }

};


/* Textual descriptions of cause codes */
static char *(cause_names[]) =
{
	/* C0_CAUSE_CODE_INT    */ "Interrupt",
	/* C0_CAUSE_CODE_MOD    */ "TLB modification",
	/* C0_CAUSE_CODE_TLBL   */ "TLB (load or instruction fetch)",
	/* C0_CAUSE_CODE_TLBS   */ "TLB (store)",
	/* C0_CAUSE_CODE_ADEL   */ "Address error (load or instruction fetch)",
	/* C0_CAUSE_CODE_ADES   */ "Address error (store)",
	/* C0_CAUSE_CODE_IBE    */ "Bus error (instruction fetch)",
	/* C0_CAUSE_CODE_DBE    */ "Bus error (data reference: load or store)",
	/* C0_CAUSE_CODE_SYS    */ "Syscall",
	/* C0_CAUSE_CODE_BP     */ "Breakpoint",
	/* C0_CAUSE_CODE_RI     */ "Reserved instruction",
	/* C0_CAUSE_CODE_CPU    */ "Coprocessor Unusable",
	/* C0_CAUSE_CODE_OV     */ "Arithmetic Overflow",
	/* C0_CAUSE_CODE_TR     */ "Trap",
	/* 14 (reserved)        */ NULL,
	/* C0_CAUSE_CODE_FPE    */ "Floating point",
	/* 16		          */ NULL,
	/* 17		          */ NULL,
	/* 18		          */ NULL,
	/* 19		          */ NULL,
	/* 20		          */ NULL,
	/* 21		          */ NULL,
	/* 22		          */ NULL,
	/* C0_CAUSE_CODE_WATCH  */ "Reference to WatchHi/WatchLo address",
	/* C0_CAUSE_CODE_MCHECK */ "Machine check",
	/* 25		          */ NULL,
	/* 26		          */ NULL,
	/* 27		          */ NULL,
	/* 28		          */ NULL,
	/* 29		          */ NULL,
	/* 30		          */ NULL,
	/* 31		          */ NULL
};


/* CPU register names */
static const char *(reg_names[]) =
{
    "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3",
		"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
		"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
		"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
};

#define REG_NAMES_COUNT		(sizeof(reg_names)/sizeof(char *))


/************************************************************************
*      Static function prototypes
************************************************************************/


static void 
exception_sr( 
			 UINT32 exc_code,
			 bool   ejtag);

static void 
interrupt_sr( void ); 

static void 
controller_sr( 
			  void *data );

static void
default_handler( 
				char *msg );


				/************************************************************************
				*      Implementation : Public functions
************************************************************************/


/************************************************************************
*
*                          EXCEP_init
*  Description :
*  -------------
*
*  Initializes the 'EXCEP' module.
*  
*  Parameters :
*  ------------
*
*  None
*
*  Return values :
*  ---------------
*
*  'OK'(=0)
*
************************************************************************/
INT32 
EXCEP_init( void ) 
{
    UINT32 rcode, i, j;
	
    /* Initialize interrupt controller */
    arch_excep_init_intctrl(&excep_ic_count, &excep_ic_int);
	
    if( excep_ic_count > MAX_IC )	     /* Should not happen	*/
        while(1);
		
		/**** Initialize exception handler structure ****/
		
		/* Initialize specific exception handlers */
		for( i = 0; i < MAX_EXCEPTIONS; i++)
		{
			table.exception[i].handler = NULL;
		}
		
		/* Initialize interrupt handler table */
		for( i = 0; i < MAX_INTERRUPTS; i++)
		{
			for( j = 0; j < INT_HANDLERS_PER_LINE; j++)
			{
				table.interrupt[i].int_handler[j].handler = NULL;
				table.interrupt[i].int_handler[j].data    = NULL;
			}
			table.interrupt[i].list_size = 0;
		}
		
		/* Initialize interrupt controller handler table */
		for( i = 0; i < MAX_IC; i++)
		{
			for( j = 0; j < CTRL_HANDLERS_PER_LINE; j++)
			{
				table.controller[i].ctrl_handler[j].handler = NULL;         
				table.controller[i].ctrl_handler[j].data    = NULL;         
			}
			table.controller[i].list_size = 0;         
		}
		
		/* Initialise remaining entries of the exception handler structure */
		table.ejtag.handler             = NULL;
		table.default_exception.handler = NULL;    
		table.default_int.handler	    = NULL;    
		table.default_ctrl.handler	    = NULL;    
		
		/* Register ESR for interrupt exception */
		EXCEP_register_esr( C0_CAUSE_CODE_INT,
			FALSE,
			interrupt_sr,
			NULL,
			NULL );
		
		/* Register interrupt control handler if controller is available */
		if( excep_ic_count > 0 )
			EXCEP_register_cpu_isr( excep_ic_int, controller_sr, NULL, NULL );
		
		/* register low level exception handler */
		EXCEP_install_exc_in_ram( 0, exception_sr );
		
		/* Enable interrupts */
		sys_enable_int();
}


/************************************************************************
*
*                          EXCEP_register_esr
*  Description :
*  -------------
*
*  Registers an exception handler, also known as an "Exception Service
*  Routine" (ESR) for the specified exception.
*  
*  Two special exception IDs are defined :
*      EXCEP_DEFAULT_HANDLER used for a default handler.
*      EXCEP_EJTAG_HANDLER used for EJTAG exceptions.
*	
*  The default handler is called if no other handler is registered
*  for an exception. If no default handler is registered, a static
*  (i.e. not registered) "super default" function is invoked.
*  This function prints out the registers and halts.
*
*  Deregistration of a handler may be be done by calling this function 
*  with 'handler' set to NULL.
*  Handlers can also be deregistered using EXCEP_deregister_esr.
*
*  A handler may be registered even if a previously registered 
*  handler has not been deregistered. In this case the previously
*  registered handler is lost.
*
*  In case an ESR does not want to handle the exception, it may
*  call the return function passed in the 'retfunc' parameter.
*
*  Case 1 : 'retfunc' called by ESR registered for the INTERRUPT exception.
*
*  We assume an application has registered this ESR and wants
*  YAMON to process the (remaining) interrupts.
*  So, we call the ESR, which is used by YAMON for handling 
*  interrupt exceptions, i.e. interrupt_sr().
*
*  Case 2 :  'retfunc' called by an ESR registered for a specific
*	      exception (not INTERRUPT).
*
*  Default handling will be done.
*
*  Case 3 : 'retfunc' is called by the ESR registered as default handler.
*
*  The exception will be handled as though no ESR is registered 
*  (i.e. the "super default" function is called).
*
*  Parameters :
*  ------------
*
*  'exception', IN,    Exception code (C0_CAUSE_CODE_xxx).
*			or EXCEP_DEFAULT_HANDLER for a default handler
*			or EXCEP_EJTAG_HANDLER for ejtag exceptions.
*  'raw',	 IN     If TRUE, ESR will get called with registers
*			in the state they were when the exception occurred.
*			This includes all CP0 registers and CPU registers
*			$0..$31, except for k0,k1 ($26,$27).
*  'handler',   IN,    Function pointer for ESR.
*  'ref',	 OUT,   Handle used for deregistration of handler.
*  'retfunc',	 OUT,   Pointer to function pointer for the return
*			function described above.
*
*  Return values :
*  ---------------
*
*  'OK'(=0)
*  'ERROR_EXCEP_ILLEGAL_EXCEPTION':  Exception ID is unknown
*
************************************************************************/
INT32 
EXCEP_register_esr(
				   UINT32          exception,	     /* Exception identification	*/
				   bool	    raw,	     /* Pass on unmodified registers	*/
				   t_EXCEP_esr     handler,	     /* ESR to be registered		*/
				   t_EXCEP_ref     *ref,	     /* OUT : Handle for deregistration */
				   t_EXCEP_retfunc *retfunc )       /* OUT : Return function		*/
{
    t_EXCEP_handler *h;
	
    if( exception == EXCEP_DEFAULT_HANDLER )
    {
        h = &table.default_exception;
    }
    else if( exception == EXCEP_EJTAG_HANDLER )
    {
        h = &table.ejtag;
    }
    else if( exception >= MAX_EXCEPTIONS )
    {
        return ERROR_EXCEP_ILLEGAL_EXCEPTION;
    }
    else
    {
        /* Specific exception */
        h = &table.exception[exception];
    }
	
    /* register/deregister exception handler */
    h->handler = handler;
    h->raw     = raw;
	
    if( ref )
        *ref = (t_EXCEP_ref)h;
	
    if( retfunc )
        *retfunc = EXCEP_return;
	
    return OK;
}


/************************************************************************
*
*                          EXCEP_deregister_esr
*  Description :
*  -------------
*
*  Deregisters exception handler
*  
*  Parameters :
*  ------------
*
*  'ref',	 IN,   Handle obtained when calling EXCEP_register_esr
*
*  Return values :
*  ---------------
*
*  'OK'(=0)
*  'ERROR_EXCEP_ILLEGAL_HANDLER':  ref is unknown
*
************************************************************************/
INT32 
EXCEP_deregister_esr(
					 t_EXCEP_ref ref )	             /* In : Handle for deregistration */
{
    t_EXCEP_handler *h = (t_EXCEP_handler *)ref;
	
    if( h )
    {
        h->handler = NULL;
        return OK;
    }
    else
        return ERROR_EXCEP_ILLEGAL_HANDLER;
}


/************************************************************************
*
*                          EXCEP_register_cpu_isr
*  Description :
*  -------------
*
*  Registers an interrupt handler for the specified CPU interrupt.
*  The highest service priority is attached to HW-INT5, which is
*  connected to the CPU-built-in CP0-timer. SW_INT0 gets the lowest
*  service priority. During registration, the interrupt mask field
*  in the CPU CP0-status register is updated to enable interrupts
*  from the specified interrupt source.
*
*  A special ID is defined :
*      EXCEP_DEFAULT_HANDLER used for a default handler.
*	
*  The default handler is called if no other handler is registered
*  for a CPU interrupt.
*
*  Deregistration of the default handler may be done by calling
*  this function with 'handler' set to NULL.
*  Also, a new default handler may be registered even if a 
*  previously registered handler has not been deregistered.
*  Handlers for specific CPU interrupts must be deregistered using 
*  EXCEP_deregister_cpu_isr.
*
*  Parameters :
*  ------------
*
*  'cpu_int',      IN,    CPU interrupt (C0_STATUS_IM_HW[0..5] |
*					  C0_STATUS_IM_SW[0..1])
*			   or EXCEP_DEFAULT_HANDLER for a default handler.
*  'handler',      IN,    Function pointer for user defined handler
*  'data',         IN,    Data pointer, may be NULL
*  'ref',	    OUT,   Handle used for deregistration of handler.
*
*  Return values :
*  ---------------
*
*  'OK'(=0)
*  'ERROR_EXCEP_ILLEGAL_INTERRUPT': CPU interrupt source is unknown
*  'ERROR_EXCEP_ILLEGAL_HANDLER':   Handler reference is NULL
*  'ERROR_EXCEP_NO_SPACE':          Too many handlers have been registered
*
************************************************************************/
INT32 
EXCEP_register_cpu_isr(
					   UINT32      cpu_int,	     /* CPU interrupt, 0..7		*/
					   t_EXCEP_isr handler,	     /* ISR to be registered		*/
					   void        *data,   	     /* Data reference to be registered */
					   t_EXCEP_ref *ref )	             /* OUT : Handle for deregistration */
{
    UINT32        old_ie;
    t_INT_handler *h;
    UINT32        rc = OK;
    UINT32        i;
    bool	  enable = FALSE;
	
    /* Disable interrupts */
    old_ie = sys_disable_int();

⌨️ 快捷键说明

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