Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:58

0001 /* PowerPC exception handling middleware; consult README for more
0002  * information.
0003  *
0004  * Author: Till Straumann <strauman@slac.stanford.edu>, 2007
0005  *
0006  *  The license and distribution terms for this file may be
0007  *  found in the file LICENSE in this distribution or at
0008  *  http://www.rtems.org/license/LICENSE.
0009  */
0010 
0011 #include <bsp/vectors.h>
0012 
0013 #include <rtems/score/threaddispatch.h>
0014 
0015 /* Provide temp. storage space for a few registers.
0016  * This is used by the assembly code prior to setting up
0017  * the stack.
0018  * One set is needed for each exception type with its
0019  * own SRR0/SRR1 pair since such exceptions may nest.
0020  *
0021  * NOTE: The assembly code needs these variables to
0022  *       be in the .sdata section and accesses them
0023  *       via R13.
0024  */
0025 uint32_t ppc_exc_lock_std  = 0;
0026 uint32_t ppc_exc_lock_crit = 0;
0027 uint32_t ppc_exc_lock_mchk = 0;
0028 
0029 uint32_t ppc_exc_vector_register_std  = 0;
0030 uint32_t ppc_exc_vector_register_crit = 0;
0031 uint32_t ppc_exc_vector_register_mchk = 0;
0032 
0033 #ifndef PPC_EXC_CONFIG_BOOKE_ONLY
0034 
0035 /* MSR bits to enable once critical status info is saved and the stack
0036  * is switched; must be set depending on CPU type
0037  *
0038  * Default is set here for classic PPC CPUs with a MMU
0039  * but is overridden from vectors_init.c
0040  */
0041 uint32_t ppc_exc_msr_bits = MSR_IR | MSR_DR | MSR_RI;
0042 
0043 #endif /* PPC_EXC_CONFIG_BOOKE_ONLY */
0044 
0045 int ppc_exc_handler_default(BSP_Exception_frame *f, unsigned int vector)
0046 {
0047   return -1;
0048 }
0049 
0050 #ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
0051 
0052 exception_handler_t globalExceptHdl = C_exception_handler;
0053 
0054 /* Table of C-handlers */
0055 ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1] = {
0056   [0 ... LAST_VALID_EXC] = ppc_exc_handler_default
0057 };
0058 
0059 #endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
0060 
0061 ppc_exc_handler_t ppc_exc_get_handler(unsigned vector)
0062 {
0063   if (
0064     vector <= LAST_VALID_EXC
0065       && ppc_exc_handler_table [vector] != ppc_exc_handler_default
0066   ) {
0067     return ppc_exc_handler_table [vector];
0068   } else {
0069     return NULL;
0070   }
0071 }
0072 
0073 rtems_status_code ppc_exc_set_handler(unsigned vector, ppc_exc_handler_t handler)
0074 {
0075   if (vector <= LAST_VALID_EXC) {
0076     if (handler == NULL) {
0077       handler = ppc_exc_handler_default;
0078     }
0079 
0080     if (ppc_exc_handler_table [vector] != handler) {
0081 #ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
0082       ppc_exc_handler_table [vector] = handler;
0083 #else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
0084       return RTEMS_RESOURCE_IN_USE;
0085 #endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
0086     }
0087 
0088     return RTEMS_SUCCESSFUL;
0089   } else {
0090     return RTEMS_INVALID_ID;
0091   }
0092 }
0093 
0094 void ppc_exc_wrapup(BSP_Exception_frame *frame)
0095 {
0096   Per_CPU_Control *cpu_self;
0097 
0098   cpu_self = _Per_CPU_Get();
0099 
0100   if (cpu_self->isr_dispatch_disable) {
0101     return;
0102   }
0103 
0104   while (cpu_self->dispatch_necessary) {
0105     rtems_interrupt_level level;
0106 
0107     cpu_self->isr_dispatch_disable = 1;
0108     cpu_self->thread_dispatch_disable_level = 1;
0109     _Thread_Do_dispatch(cpu_self, frame->EXC_SRR1);
0110     rtems_interrupt_local_disable(level);
0111     (void) level;
0112     cpu_self = _Per_CPU_Get();
0113   }
0114 
0115   cpu_self->isr_dispatch_disable = 0;
0116 }