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

📄 excep.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	
    if( cpu_int == EXCEP_DEFAULT_HANDLER )
    {
        h = &table.default_int;
    }
    else if( cpu_int >= MAX_INTERRUPTS )
    {
        /* Interrupt specified is unknown */
        rc = ERROR_EXCEP_ILLEGAL_INTERRUPT;
    }
    else
    {
        /* Specific interrupt */
		
        if( handler == NULL )
        {
            rc = ERROR_EXCEP_ILLEGAL_HANDLER;
        }
        else if( table.interrupt[cpu_int].list_size == INT_HANDLERS_PER_LINE )
        {
            /* Too many handlers have been registered */
            rc = ERROR_EXCEP_NO_SPACE;
        }
        else
        {
            /* Find unused entry in array */
            for( i = 0, h = &table.interrupt[cpu_int].int_handler[0];
			(i < INT_HANDLERS_PER_LINE) && (h->handler != NULL);
			i++, h++) 
            {
				;
			}
			
            table.interrupt[cpu_int].list_size++;
			enable = TRUE;
        }
    }
	
    if( rc == OK )
    {
        h->handler = handler;	
		h->data    = data;
		
        if( ref )
            *ref = (t_EXCEP_ref)h;
		
        /* Enable interrupt mask */
		if( enable )
            sys_enable_int_mask( cpu_int );
    }
	
    /* Restore interrupt enable status */
    if(old_ie)
        sys_enable_int();
	
    return rc;
}


/************************************************************************
*
*                          EXCEP_deregister_cpu_isr
*  Description :
*  -------------
*
*  Deregisters interrupt handler. 
*  It is OK to call this function even if we are in interrupt context.
*  
*  Parameters :
*  ------------
*
*  'ref',	 IN,   Handle obtained when calling EXCEP_register_cpu_isr
*
*  Return values :
*  ---------------
*
*  'OK'(=0)
*  'ERROR_EXCEP_ILLEGAL_HANDLER':  ref is unknown
*
************************************************************************/
INT32 
EXCEP_deregister_cpu_isr(
						 t_EXCEP_ref ref )	             /* In : Handle for deregistration */
{
    UINT32		      old_ie;
    t_INT_handler             *h = (t_INT_handler *)ref;
    t_EXCEP_int_handler_list  *list;
    INT32		      rc = ERROR_EXCEP_ILLEGAL_HANDLER;
    UINT32		      i, t;
	
    /* Disable interrupts */
    old_ie = sys_disable_int();
	
    /* Find and deregister handler pointed to by ref (h) */
	
    if( h == &table.default_int )
    {
        h->handler = NULL;
		rc	   = OK;
    }
    else
    {
        for( i=0; (i<MAX_INTERRUPTS) && (rc != OK); i++ )
        {
            list = &table.interrupt[ i ];
			
			for( t=0; (t<INT_HANDLERS_PER_LINE) && (rc != OK); t++ )
			{
				if( &list->int_handler[t] == h )
				{
					(list->list_size)--;
					h->handler = NULL;
					
					if( list->list_size == 0 )
					{
						if( interrupt_context )
						{
						/*  Function called in interrupt context,
						*  so interrupts are unmasked by updating
						*  the context that will be restored when
						*  we return from exception.
							*/
							
							EXCEP_gdb_regs.cp0_status &= 
								~(1 << (i + C0_STATUS_IM_SHF));
						}
						else
						{
							/* Disable interrupt mask */
							sys_disable_int_mask( i );
						}
					}
					
					rc = OK;
				}
			}
        }
    }
	
    /* Restore interrupt enable status */
    if(old_ie)
        sys_enable_int();
	
    return rc;
}


/************************************************************************
*
*                          EXCEP_register_ic_isr
*  Description :
*  -------------
*
*  Registers an interrupt handler for the specified source in the
*  interrupt controller. 
*
*  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 an 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 interrupts must be deregistered using 
*  EXCEP_deregister_ic_isr.

  *  Parameters :
  *  ------------
  *
  *  'ic_int_line', IN,    Interrupt source line in Int. Controller
  *			  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': Int. source line is unknown
  *  'ERROR_EXCEP_ILLEGAL_HANDLER':   Handler reference is NULL
  *  'ERROR_EXCEP_NO_SPACE':          Too many handlers have been registered
  *
  ************************************************************************/
  INT32 
	  EXCEP_register_ic_isr(
	  UINT32      ic_int_line,	    /* Exception identification		*/
	  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;
	  bool	  enable = FALSE;
	  UINT32        rc     = OK;
	  int		  i;
	  
	  /* Disable interrupts */
	  old_ie = sys_disable_int();
	  
	  if( ic_int_line == EXCEP_DEFAULT_HANDLER )
	  {
		  h = &table.default_ctrl;
	  }
	  else if( ic_int_line >= excep_ic_count )
	  {
		  /* Interrupt specified is unknown */
		  rc = ERROR_EXCEP_ILLEGAL_INTERRUPT;
	  }
	  else
	  {
		  /* Specific interrupt */
		  
		  if( handler == NULL )
		  {
			  rc = ERROR_EXCEP_ILLEGAL_HANDLER;
		  }
		  else if( table.controller[ic_int_line].list_size == CTRL_HANDLERS_PER_LINE )
		  {
			  /* Too many handlers have been registered */
			  rc = ERROR_EXCEP_NO_SPACE;
		  }
		  else
		  {
			  /* Find unused entry in array */
			  for( i = 0, h = &table.controller[ic_int_line].ctrl_handler[0];
			  (i < CTRL_HANDLERS_PER_LINE) && (h->handler != NULL);
			  i++, h++) 
			  {
				  ;
			  }
			  
			  table.controller[ic_int_line].list_size++;
			  enable = TRUE;
		  }
	  }
	  
	  if( rc == OK )
	  {
		  h->handler = handler;
		  h->data    = data;
		  
		  if( ref )
			  *ref = (t_EXCEP_ref)h;
		  
		  /* add this source to enable mask of interrupt controller */
		  if( enable )
			  arch_excep_enable_int(ic_int_line);
	  }
	  
	  /* Restore interrupt enable status */
	  if(old_ie)
		  sys_enable_int();
	  
	  return rc;
  }
  
  
  /************************************************************************
  *
  *                          EXCEP_deregister_ic_isr
  *  Description :
  *  -------------
  *
  *  Deregisters interrupt handler for source in interrupt controller
  *  It is OK to call this function even if we are in interrupt context.
  *
  *  Parameters :
  *  ------------
  *
  *  'ref',	 IN,   Handle obtained when calling EXCEP_register_ic_isr
  *
  *  Return values :
  *  ---------------
  *
  *  'OK'(=0)
  *  'ERROR_EXCEP_ILLEGAL_HANDLER':  ref is unknown
  *
  ************************************************************************/
  INT32 
	  EXCEP_deregister_ic_isr(
	  t_EXCEP_ref ref )	             /* In : Handle for deregistration */
  {
	  UINT32		      old_ie;
	  t_INT_handler             *h = (t_INT_handler *)ref;
	  t_EXCEP_ctrl_handler_list *list;
	  INT32		      rc = ERROR_EXCEP_ILLEGAL_HANDLER;
	  UINT32		      i, t;
	  
	  /* Disable interrupts */
	  old_ie = sys_disable_int();
	  
	  /* Find and deregister handler pointed to by ref (h) */
	  
	  if( h == &table.default_ctrl )
	  {
		  h->handler = NULL;
		  rc	   = OK;
	  }
	  else
	  {
		  for( i=0; (i<MAX_IC) && (rc != OK); i++ )
		  {
			  list = &table.controller[ i ];
			  
			  for( t=0; (t<CTRL_HANDLERS_PER_LINE) && (rc != OK); t++ )
			  {
				  if( &list->ctrl_handler[t] == h )
				  {
					  (list->list_size)--;
					  h->handler = NULL;
					  
					  if( list->list_size == 0 )
					  {
						  /* Disable interrupt mask */
						  arch_excep_disable_int( i );
					  }
					  
					  rc = OK;
				  }
			  }
		  }
	  }
	  
	  /* Restore interrupt enable status */
	  if(old_ie)
		  sys_enable_int();
	  
	  return rc;
  }
  
  
  /************************************************************************
  *
  *                          EXCEP_toggle_handlers
  *  Description :
  *  -------------
  *
  *  Based on 'store' parameter, the current setup of registered
  *  exception handlers is stored or restored.
  *
  ************************************************************************/
  void 
	  EXCEP_toggle_handlers(
	  bool store )    /* TRUE -> Store current setup, FALSE -> Restore setup */
  {
	  UINT32        old_ie;
	  /* Disable interrupts */
	  old_ie = sys_disable_int();
	  
	  if( store )
		  memcpy( &table_copy, &table, sizeof(t_table) );
	  else
		  memcpy( &table, &table_copy, sizeof(t_table) );
	  
	  /* Restore interrupt enable status */
	  if(old_ie)
		  sys_enable_int();
  }
  
  
  /************************************************************************
  *
  *                          EXCEP_print_context
  *  Description :
  *  -------------
  *
  *  Print context
  *
  *  Note : The EXCEP module in installed before the serial drivers
  *  (see initmodules.h), so if an exception occurs before the serial
  *  drivers are installed, printf, which is used in this function, will
  *  not work. printf ultimately causes IO module to be called, and since
  *  the IO module initialises write function pointers to dummy functions,
  *  everything is OK.
  *
  *  Return values :
  *  ---------------
  *
  *  None
  *
  ************************************************************************/
  void
	  EXCEP_print_context( 
	  t_gdb_regs *context,	/* Context to print			*/
	  char       *msg,		/* Special msg to be printed (or NULL)	*/
	  bool       user,		/* In user context			*/
	  bool       display )	/* TRUE -> Print EPC in ASCII display	*/
  {
	  char   *s;
	  UINT64 *regs;
	  UINT64 reg64;
	  UINT32 i,j;
	  bool   nmi;
	  UINT32 werr;
	  
	  if( msg )
		  printf( "\n* %s *\n\n", msg );
	  else	
	  {
		  printf( "\n* Exception " );
		  printf( user ? "(user) : " : ": " );
	  }
	  
	  if( SYSCON_read( SYSCON_BOARD_NMI_STATUS_ID, 
		  (void *)&nmi,
		  sizeof(bool) ) != OK )
	  {
		  nmi = FALSE;
	  }	
	  
	  if( SYSCON_read( SYSCON_BOARD_NMI_WERR_ID, 
		  (void *)&werr,
		  sizeof(UINT32) ) != OK )
	  {
		  werr = 0;
	  }	
	  
	  if( nmi )
	  {
		  s = werr ? "NMI - write access error" :
	  "NMI";
	  }
	  else
	  {
		  if( display )
			  DISP( (UINT32)context->cp0_epc );
		  s = cause_names[ REGFIELD((UINT32)context->cp0_cause, C0_CAUSE_CODE) ];
	  }
	  
	  if( msg == NULL )
	  {
		  if( !EXCEP_ejtag )
		  {
			  if( s )
				  printf("%s", s); 
			  else
				  printf("Unknown exception code : 0x%02x",
				  REGFIELD((UINT32)context->cp0_cause, C0_CAUSE_CODE) );
		  }
		  else
			  printf( "EJTAG" );
		  
		  printf( " *\n\n" );
	  }
	  
	  if( sys_64bit )
	  {

⌨️ 快捷键说明

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