📄 excep.c
字号:
/************************************************************************ * * excep.c * * The 'EXCEP' module implements a first level exception and * interrupt handling and an API to register user defined * exception and interrupt service routines (ESR & ISR). * * Interrupt Service Routine registration is possible at * * a) The MIPS CPU SW/HW interrupt level (CPU-ISR) : 0..7 * b) The Interrupt controller level (IC-ISR) : (platform specific) * * Registration of ISR's imply enabling of the corresponding * interrupt MASK bit in the CPU or the interrupt controller. * * Interrupt Service Routine handling is executed in a prioritized * scheme. First, registered handlers at CPU interrupt level are * called, second, registered handlers at interrupt controller * level are called. * * Public API offers: * * 1) EXCEP_init() * 2) EXCEP_register_esr() * 3) EXCEP_deregister_esr() * 4) EXCEP_register_cpu_isr() * 5) EXCEP_deregister_cpu_isr() * 6) EXCEP_register_ic_isr() * 7) EXCEP_deregister_ic_isr() * 8) EXCEP_print_context() * * ###################################################################### * * mips_start_of_legal_notice * * Copyright (c) 2004 MIPS Technologies, Inc. All rights reserved. * * * Unpublished rights (if any) reserved under the copyright laws of the * United States of America and other countries. * * This code is proprietary to MIPS Technologies, Inc. ("MIPS * Technologies"). Any copying, reproducing, modifying or use of this code * (in whole or in part) that is not expressly permitted in writing by MIPS * Technologies or an authorized third party is strictly prohibited. At a * minimum, this code is protected under unfair competition and copyright * laws. Violations thereof may result in criminal penalties and fines. * * MIPS Technologies reserves the right to change this code to improve * function, design or otherwise. MIPS Technologies does not assume any * liability arising out of the application or use of this code, or of any * error or omission in such code. Any warranties, whether express, * statutory, implied or otherwise, including but not limited to the implied * warranties of merchantability or fitness for a particular purpose, are * excluded. Except as expressly provided in any written license agreement * from MIPS Technologies or an authorized third party, the furnishing of * this code does not give recipient any license to any intellectual * property rights, including any patent rights, that cover this code. * * This code shall not be exported, reexported, transferred, or released, * directly or indirectly, in violation of the law of any country or * international law, regulation, treaty, Executive Order, statute, * amendments or supplements thereto. Should a conflict arise regarding the * export, reexport, transfer, or release of this code, the laws of the * United States of America shall be the governing law. * * This code constitutes one or more of the following: commercial computer * software, commercial computer software documentation or other commercial * items. If the user of this code, or any related documentation of any * kind, including related technical data or manuals, is an agency, * department, or other entity of the United States government * ("Government"), the use, duplication, reproduction, release, * modification, disclosure, or transfer of this code, or any related * documentation of any kind, is restricted in accordance with Federal * Acquisition Regulation 12.212 for civilian agencies and Defense Federal * Acquisition Regulation Supplement 227.7202 for military agencies. The use * of this code by the Government is further restricted in accordance with * the terms of the license agreement(s) and/or applicable contract terms * and conditions covering this code from MIPS Technologies or an authorized * third party. * * * * * mips_end_of_legal_notice * * ************************************************************************//************************************************************************ * Include files ************************************************************************/#include <sysdefs.h>#include <sys_api.h>#include <mips.h>#include <excep_api.h>#include <excep.h>#include <syscon_api.h>#include <shell_api.h>#include <stdio.h>#include <string.h>/************************************************************************ * Definitions ************************************************************************//* max. number of interrupt sources from the CPU */#define MAX_INTERRUPTS (C0_STATUS_IM_MAX + 1)/* max. number of exception codes from the CPU */#define MAX_EXCEPTIONS (EX_MCHECK + 1)/* max. number of interrupt sources from interrupt controller */#define MAX_IC 32/* Basic definition for registered interrupt handler */typedef struct int_handler{ t_EXCEP_isr handler; void *data;} t_INT_handler;/* Basic definition for registered exception handler */typedef struct excep_handler{ t_EXCEP_esr handler; bool raw;} t_EXCEP_handler;/* Element struct to be used for 8-bit-set of int. * pending to int. handler index list. */typedef struct excep_set_to_list{ UINT8 list_size; UINT8 index[8];} t_EXCEP_set_to_list;/* max. number of interrupt handlers per line */#define INT_HANDLERS_PER_LINE 4/* Element struct to be used for keeping a configurable * number of int. handlers per line. */typedef struct excep_int_handler_list{ UINT8 list_size; t_INT_handler int_handler[INT_HANDLERS_PER_LINE];} t_EXCEP_int_handler_list;/* max. number of interrupt control handlers per line */#define CTRL_HANDLERS_PER_LINE 4/* Element struct to be used for keeping a configurable * number of int. controller handlers per line. */typedef struct excep_ctrl_handler_list{ UINT8 list_size; t_INT_handler ctrl_handler[CTRL_HANDLERS_PER_LINE];} t_EXCEP_ctrl_handler_list;/* Struct for holding exception handlers */typedef struct{ /* Exception handler table. */ t_EXCEP_handler exception[MAX_EXCEPTIONS]; /* EJTAG exception handler */ t_EXCEP_handler ejtag; /* CPU Interrupt handler table. */ t_EXCEP_int_handler_list interrupt[MAX_INTERRUPTS]; /* Int. controller handler table. */ t_EXCEP_ctrl_handler_list controller[MAX_IC]; /* Default handlers */ t_EXCEP_handler default_exception; t_INT_handler default_int; t_INT_handler default_ctrl;}t_table;/************************************************************************ * Public variables ************************************************************************/bool EXCEP_nmi = FALSE;UINT32 EXCEP_C0_Config_cacheerr;extern t_gdb_regs ejtag_context;/************************************************************************ * Static variables ************************************************************************/static bool EXCEP_cacheerr = FALSE;/* Number of interrupts handled by interrupt controller */static UINT32 excep_ic_count;/* HW interrupt used by interrupt controller */static UINT32 excep_ic_int;/*********************************************************************** * * Handler function tables * ************************************************************************/static t_table table;static t_table table_shell, table_gdb;/*********************************************************************** * * Private lookup tables * ************************************************************************//* * An 8-bit set is converted to a list of indices * by sequentially using and clearing the most significant bit number. */static const UINT8 byte2msbit[256] ={ 0, 0, 1,1, 2,2,2,2, 3,3,3,3, 3,3,3,3, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7};/* Textual descriptions of cause codes */static char *(cause_names[]) ={ /* EX_INT */ "Interrupt", /* EX_MOD */ "TLB modification", /* EX_TLBL */ "TLB (load or instruction fetch)", /* EX_TLBS */ "TLB (store)", /* EX_ADEL */ "Address error (load or instruction fetch)", /* EX_ADES */ "Address error (store)", /* EX_IBE */ "Bus error (instruction fetch)", /* EX_DBE */ "Bus error (data reference: load or store)", /* EX_SYS */ "Syscall", /* EX_BP */ "Breakpoint", /* EX_RI */ "Reserved instruction", /* EX_CPU */ "Coprocessor Unusable", /* EX_OV */ "Arithmetic Overflow", /* EV_TR */ "Trap", /* 14 (reserved) */ NULL, /* EX_FPE */ "Floating point", /* 16 */ NULL, /* 17 */ NULL, /* 18 */ NULL, /* 19 */ NULL, /* 20 */ NULL, /* 21 */ NULL, /* 22 */ NULL, /* EX_WATCH */ "Reference to WatchHi/WatchLo address", /* EX_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 interrupt_sr( void ); static void controller_sr( void *data );static voiddefault_handler( char *msg, t_gdb_regs *p_context );static voidcacheerr_handler( t_gdb_regs *p_context );/************************************************************************ * Implementation : Public functions ************************************************************************//************************************************************************ * * EXCEP_init * Description : * ------------- * * Initializes the 'EXCEP' module. * * Parameters : * ------------ * * None * * Return values : * --------------- * * 'OK'(=0) * ************************************************************************/INT32 EXCEP_init( void ) { /* 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 ****/ memset((void*)&table, 0, sizeof(table)); /* Register ESR for interrupt exception */ EXCEP_register_esr( EX_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 ); /* Determine what CP0/CP1 registers exist and must be context shifted */ EXCEP_init_reg_mask(); /* set up ram vectors and clear cp0 status BEV */ EXCEP_install_exc_in_ram(); return OK;}/************************************************************************ * * 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -