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

📄 excep.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		  if( !nmi )
		  {
		  /*  CAUSE does not make sense for NMI, since the reset code,
		  *  which is excecuted upon an NMI, changes CAUSE.
			  */
			  
			  printf("CAUSE    = 0x%08x          ", (UINT32)context->cp0_cause );
		  }
		  
		  printf("STATUS   = 0x%08x\n", (UINT32)context->cp0_status );
		  
		  printf("EPC      = 0x%08x%08x  ERROREPC = 0x%08x%08x\n",
			  HI32(context->cp0_epc), 
			  LO32(context->cp0_epc),
			  HI32(context->cp0_errorepc), 
			  LO32(context->cp0_errorepc) );
		  
		  printf("BADVADDR = 0x%08x%08x\n",
			  HI32(context->cp0_badvaddr), 
			  LO32(context->cp0_badvaddr) );
		  
		  if( EXCEP_ejtag )
		  {
			  printf("DEBUG    = 0x%08x%08x  DEPC = 0x%08x%08x\n", 
				  HI32(context->cp0_debug), 
				  LO32(context->cp0_debug),
				  HI32(context->cp0_depc), 
				  LO32(context->cp0_depc) );
		  }
	  }
	  else
	  {
		  if( !nmi )
		  {
		  /*  CAUSE does not make sense for NMI, since the reset code,
		  *  which is excecuted upon an NMI, changes CAUSE.
			  */
			  
			  printf("CAUSE    = 0x%08x  ", (UINT32)context->cp0_cause );
		  }
		  
		  printf("STATUS   = 0x%08x\n", (UINT32)context->cp0_status );
		  
		  printf("EPC      = 0x%08x  ERROREPC = 0x%08x\n",
			  (UINT32)context->cp0_epc,
			  (UINT32)context->cp0_errorepc );
		  
		  printf("BADVADDR = 0x%08x\n", (UINT32)context->cp0_badvaddr );
		  
		  if( EXCEP_ejtag )
		  {
			  printf("DEBUG    = 0x%08x  DEPC = 0x%08x\n", 
				  (UINT32)context->cp0_debug,
				  (UINT32)context->cp0_depc );
		  }
	  }
	  
	  printf( "\n" );
	  
	  regs = (UINT64 *)&context->reg0;
	  
	  for(i=0; i<REG_NAMES_COUNT; i++)
	  {
		  if( sys_64bit )
		  {
			  j = ((i & 1) << 4) + (i >> 1);
			  
			  reg64 = regs[j];
			  
			  printf("$%2d(%s):0x%08x%08x%s", j, reg_names[j], 
				  HI32(reg64), LO32(reg64),
				  (i & 1) == 1 ? "\n" : "  ");
		  }
		  else
		  {
			  j = ((i & 3) << 3) + (i >> 2);
			  
			  printf("$%2d(%s):0x%08x%s", j, reg_names[j], (UINT32)regs[j],
				  (i & 3) == 3 ? "\n" : "  ");
		  }		   
	  }
	  
	  if( nmi )
		  while(1);
}


/************************************************************************
*      Implementation : Static functions
************************************************************************/



/************************************************************************
*
*                          exception_sr
*  Description :
*  -------------
*
*  This function implements the exception handler, which gets called
*  by the first-level exception handler. According to the parameter
*  'exc_code', any user registered exception handler for the asserted
*  exception, will be called from this function. 
*  
*  Parameters :
*  ------------
*
*  exc_code         the exception code from the 5-bit ExcCode-field in
*                   the CP0-status register.
* 
*  Return values :
*  ---------------
*
*  None
*
************************************************************************/
static void 
exception_sr( 
			 UINT32 exc_code,
			 bool   ejtag )
{
    t_EXCEP_handler *reg_esr;
    bool	    default_handling;
    t_EXCEP_handler int_esr;
    bool	    nmi;
	
    EXCEP_ejtag = ejtag;
	
    /* First check for NMI */
    if( SYSCON_read( SYSCON_BOARD_NMI_STATUS_ID, 
		(void *)&nmi,
		sizeof(bool) ) == OK )
    {
        if( nmi )
		{
			default_handler( NULL );
		}
    }
	
    if( ejtag )
    {
        reg_esr = &table.ejtag;
    }
    else if( exc_code < MAX_EXCEPTIONS )
    {
		reg_esr = &table.exception[exc_code];
    }
    else
        reg_esr = NULL;
	
    default_handling = 
        ( (reg_esr == NULL) || (reg_esr->handler == NULL) ) ?
TRUE : FALSE;
	
    if( EXCEP_return_flag )
    {
	/*  A registered exception handler was invoked for this
	*  exception, but it called EXCEP_return().
	*  This means that it does not want to handle the exception,
	*  so we must handle it.
	*
	*  Case 1 : If the exception handler was the ESR registered
	*	     for interrupts, we assume an application has
	*	     registered an ESR for the interrupt exception.
	*	     So, we call the ESR, which is used by YAMON
	*	     for handling interrupt exceptions, i.e.
	*	     interrupt_sr().
	*
	*  Case 2 : If the exception handler was a specific one,
	*	     other than interrupt, we try default handling.
	*
	*  Case 3 : If the exception handler was the default ESR, 
	*           we must call default_handler().
		*/
		
		if( exc_code == C0_CAUSE_CODE_INT )
		{
			/* Case 1 */
			int_esr.handler = interrupt_sr;
			int_esr.raw     = FALSE;
			reg_esr	     = &int_esr;
		}
		else if( !default_handling )
		{
			/* Case 2 */
			default_handling = TRUE;
		}
		else
		{
			/* Case 3 */
			default_handler( NULL );
		}
    }	     
	
    if( default_handling )
    {
	/*  Either EXCEP_return() was called (se above), or
	*  there is no registered ESR for the specific exception. 
	*  Check if there is a registered default ESR.
		*/
		
		reg_esr = &table.default_exception;
		
        if( reg_esr->handler == NULL )
        {
		/*  No default ESR has been registered, so call our own
		*  (never returns).
			*/
			default_handler( NULL );
        }
    }
	
    if( reg_esr->raw )
        EXCEP_exc_handler_jump( reg_esr->handler );
    else
        reg_esr->handler();
}

			 
/************************************************************************
*
*                          interrupt_sr
*  Description :
*  -------------
*
*  This function implements the CPU interrupt handler, which is
*  registered for the interrupt exception.
*
*  Return values :
*  ---------------
*
*  None
*
************************************************************************/
static void 
interrupt_sr( void )
{
    UINT32                   h, i, count, index;
    bool		     old_EXCEP_ejtag;
    UINT32		     int_pending;
    t_EXCEP_int_handler_list *table_interrupt;
    t_INT_handler	     *int_handler;
	
    interrupt_context = TRUE;
	
    /*  Determine the pending interrupts based on CAUSE register IP field
	*  masked with STATUS register IM (Interrupt mask) field.
	*/
    int_pending = REGFIELD( EXCEP_gdb_regs.cp0_cause,  C0_CAUSE_IP ) &
		REGFIELD( EXCEP_gdb_regs.cp0_status, C0_STATUS_IM );
	
	
		/*  Save old setting of EXCEP_ejtag and set EXCEP_ejtag to FALSE.
		*  This way, if EXCEP_print_context is called due to this
		*  interrupt, it will be know that we are not handling an
		*  ejtag exception.
		*  Before this function returns, EXCEP_ejtag value is restored
		*  since EXCEP_ejtag must indicate whether the last "non-interrupt"
		*  exception was an EJTAG exception.
	*/
    old_EXCEP_ejtag = EXCEP_ejtag;
    EXCEP_ejtag	    = FALSE;    
	
    /* validate 'int_pending' */
    if(int_pending <= (C0_CAUSE_IP_MSK >> C0_CAUSE_IP_SHF) )
    {
        /* Handle the 8 possible interrupts: 0..7 */
		
        /* Calculate how many interrupts are pending */
        count = EXCEP_set_to_list[int_pending].list_size;
		
        /* do call handlers for all pending interrupts ('count') */
        for( i = 0; i < count; i++)
        {
		/*  Handle the interrupts in a sequence, controlled
		*  by the EXCEP_set_to_list-table.
			*/
			
            index = EXCEP_set_to_list[int_pending].index[i];
			
            /*  Now, use the derived index to call into the
			*  handler table (index = interrupt line).
			*/
			
			table_interrupt = &table.interrupt[index];
			
			if( table_interrupt->list_size == 0 )
			{
				/* No registered handler, so use default */
				
                if( table.default_int.handler )
				{
					/* A default handler has been registered, so call it */
                    table.default_int.handler(table.default_int.data);
				}
                else
                {
					/* No default handler has been registered, so call our own */
					default_handler( "Unregistered CPU interrupt occurred" );
                }
			}
			else
			{
                /* For one int. line, more handlers may be registered */
                for( h=0; h < INT_HANDLERS_PER_LINE; h++)
                {
					int_handler = &table_interrupt->int_handler[h];
					
                    if( int_handler->handler != NULL)
                        (*int_handler->handler)(int_handler->data);
                }
            }
        }
    }
    else
    {
        /* Should not happen */
		while(1);
    }
	
    /* Restore setting of EXCEP_ejtag (see comment above) */
    EXCEP_ejtag = old_EXCEP_ejtag;
	
    interrupt_context = FALSE;
}


/************************************************************************
*
*                          controller_sr
*  Description :
*  -------------
*
*  This function implements the generic interrupt handler for the 
*  interrupt controller. It gets called by the second-level 
*  interrupt handler (interrupt_sr), when the HW-INT-line of 
*  the interrupt controller is asserted.
*
*  Return values :
*  ---------------
*
*  None
*
************************************************************************/
static void 
controller_sr( 
			  void *data )     /* Data pointer set during registration (NULL)	*/
{
    UINT32 pending, mask, int_set;
    UINT32 h, i, j, count, index;
    char   msg[80];
	
    /* get the pending controller interrupts */
	
    while( (pending = arch_excep_pending()) != 0)
    {
        mask = pending;
		
        /* handle the max. int. sources in rounds of 8 */
        j = 0;
		
        while( j<MAX_IC )
        {
            /* select this round's max. 8 int. sources */
            int_set = (pending & 0x000000ff);
			
            /* check for any set */
            if(int_set)
            {
                /* calculate how many interrupts are pending */
                count =  EXCEP_set_to_list[int_set].list_size;
				
                /* do call handlers for all pending interrupts ('count') */
                for( i = 0; i < count; i++)
                {
				/*  Handle the interrupts in a sequence, controlled
				*  by the EXCEP_set_to_list-table.
					*/
					
                    index = EXCEP_set_to_list[int_set].index[i];
					
					/* index + j == interrupt line */
					
                    /*  Now, use the derived index to call into the
					*  handler table.
					*/
					if( table.controller[index+j].list_size == 0 )
					{
						/* No registered handler, so use default */
						
						if( table.default_ctrl.handler )
						{
							/* A default handler has been registered, so call it */
							table.default_ctrl.handler(table.default_int.data);
						}			
						else
						{
							/* No default handler has been registered, so call our own */
							sprintf( msg, "Unregistered interrupt controller event occurred,"
								" mask = 0x%08x", mask );
							default_handler( msg );
						}
					}
					else
					{
                        for( h=0; h < CTRL_HANDLERS_PER_LINE; h++)
						{
                            /* For one int. line, more handlers may be registered */
							if(table.controller[index+j].ctrl_handler[h].handler != NULL)
							{
                                /* call the handlers in sequence */
								(*table.controller[index+j].ctrl_handler[h].handler)
                                    (table.controller[index+j].ctrl_handler[h].data);
                            }
                        }
					}
					
					/* Issue End Of Interrupt (EOI) */
					arch_excep_eoi(index+j);
                }
            }
			
            pending /= 256;
            j       += 8;
        }
    }
}


/************************************************************************
*
*                          default_handler
*  Description :
*  -------------
*
*  Default exception handler
*
************************************************************************/
static void
default_handler(
				char *msg )
{
    /* Print context */
    EXCEP_print_context( &EXCEP_gdb_regs, msg, FALSE, TRUE );
	
    /* loop forever */
    while(1);
}


⌨️ 快捷键说明

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