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

📄 cpu.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
 * *  _CPU_ISR_install_raw_handler * *  This routine installs the specified handler as a "raw" non-executive *  supported trap handler (a.k.a. interrupt service routine). * *  Input Parameters: *    vector      - trap table entry number plus synchronous  *                    vs. asynchronous information *    new_handler - address of the handler to be installed *    old_handler - pointer to an address of the handler previously installed * *  Output Parameters: NONE *    *new_handler - address of the handler previously installed *  *  NOTE:  * *  This routine is based on the SPARC routine _CPU_ISR_install_raw_handler. *  Install a software trap handler as an executive interrupt handler  *  (which is desirable since RTEMS takes care of window and register issues), *  then the executive needs to know that the return address is to the trap  *  rather than the instruction following the trap. * */ void _CPU_ISR_install_raw_handler(  unsigned32  vector,  proc_ptr    new_handler,  proc_ptr   *old_handler){  unsigned32             real_vector;  CPU_Trap_table_entry  *slot;  unsigned32             u32_handler=0;  /*   *  Get the "real" trap number for this vector ignoring the synchronous   *  versus asynchronous indicator included with our vector numbers.   */  real_vector = vector;  /*   *  Get the current base address of the trap table and calculate a pointer   *  to the slot we are interested in.   */  slot = (CPU_Trap_table_entry  *)ppc_exception_vector_addr( real_vector );  /*   *  Get the address of the old_handler from the trap table.   *   *  NOTE: The old_handler returned will be bogus if it does not follow   *        the RTEMS model.   */#define HIGH_BITS_MASK   0xFFFFFC00#define HIGH_BITS_SHIFT  10#define LOW_BITS_MASK    0x000003FF  if (slot->stwu_r1 == _CPU_Trap_slot_template.stwu_r1) {    /*      * Set u32_handler = to target address       */    u32_handler = slot->b_Handler & 0x03fffffc;    /* IMD FIX: sign extend address fragment... */    if (u32_handler & 0x02000000) {      u32_handler  |= 0xfc000000;    }    *old_handler =  (proc_ptr) u32_handler;  } else/* There are two kinds of handlers for the MPC860. One is the 'standard'  *  one like above. The other is for the cascaded interrupts from the SIU *  and CPM. Therefore we must check for the alternate one if the standard *  one is not present */#if defined(mpc860) || defined(mpc821)  if (slot->stwu_r1 == _CPU_Trap_slot_template_m860.stwu_r1) {    /*      * Set u32_handler = to target address       */    u32_handler = slot->b_Handler & 0x03fffffc;    *old_handler =  (proc_ptr) u32_handler;  } else#endif /* mpc860 */    *old_handler = 0;  /*   *  Copy the template to the slot and then fix it.   */#if defined(mpc860) || defined(mpc821)  if (vector >= PPC_IRQ_IRQ0)    *slot = _CPU_Trap_slot_template_m860;  else#endif /* mpc860 */  *slot = _CPU_Trap_slot_template;  u32_handler = (unsigned32) new_handler;  /*    * IMD FIX: insert address fragment only (bits 6..29)    *          therefore check for proper address range    *          and remove unwanted bits   */  if ((u32_handler & 0xfc000000) == 0xfc000000) {    u32_handler  &= ~0xfc000000;  }  else if ((u32_handler & 0xfc000000) != 0x00000000) {    _Internal_error_Occurred(INTERNAL_ERROR_CORE,			     TRUE,			     u32_handler);  }  slot->b_Handler |= u32_handler;  slot->li_r0_IRQ  |= vector;  _CPU_Data_Cache_Block_Flush( slot );}unsigned32  ppc_exception_vector_addr(   unsigned32 vector){#if (!PPC_HAS_EVPR)  unsigned32 Msr;#endif  unsigned32 Top = 0;  unsigned32 Offset = 0x000;#if (PPC_HAS_EXCEPTION_PREFIX)  _CPU_MSR_Value ( Msr );  if ( ( Msr & PPC_MSR_EP) != 0 ) /* Vectors at FFFx_xxxx */    Top = 0xfff00000;#elif (PPC_HAS_EVPR)  asm volatile( "mfspr %0,0x3d6" : "=r" (Top)); /* EVPR */  Top = Top & 0xffff0000;#endif  switch ( vector ) {    case PPC_IRQ_SYSTEM_RESET:   /* on 40x aka PPC_IRQ_CRIT */      Offset = 0x00100;      break;    case PPC_IRQ_MCHECK:      Offset = 0x00200;      break;    case PPC_IRQ_PROTECT:      Offset = 0x00300;      break;    case PPC_IRQ_ISI:      Offset = 0x00400;      break;    case PPC_IRQ_EXTERNAL:      Offset = 0x00500;      break;    case PPC_IRQ_ALIGNMENT:      Offset = 0x00600;      break;    case PPC_IRQ_PROGRAM:      Offset = 0x00700;      break;    case PPC_IRQ_NOFP:      Offset = 0x00800;      break;    case PPC_IRQ_DECREMENTER:      Offset = 0x00900;      break;    case PPC_IRQ_RESERVED_A:      Offset = 0x00a00;      break;    case PPC_IRQ_RESERVED_B:      Offset = 0x00b00;      break;    case PPC_IRQ_SCALL:      Offset = 0x00c00;      break;    case PPC_IRQ_TRACE:      Offset = 0x00d00;      break;    case PPC_IRQ_FP_ASST:      Offset = 0x00e00;      break;#if defined(ppc403) || defined(ppc405)                                  /*  PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET    case PPC_IRQ_CRIT:      Offset = 0x00100;      break;*/    case PPC_IRQ_PIT:      Offset = 0x01000;      break;    case PPC_IRQ_FIT:      Offset = 0x01010;      break;    case PPC_IRQ_WATCHDOG:      Offset = 0x01020;      break;    case PPC_IRQ_DEBUG:      Offset = 0x02000;      break;#elif defined(ppc601)    case PPC_IRQ_TRACE:      Offset = 0x02000;      break;#elif defined(ppc603)    case PPC_IRQ_TRANS_MISS:      Offset = 0x1000;      break;    case PPC_IRQ_DATA_LOAD:      Offset = 0x1100;      break;    case PPC_IRQ_DATA_STORE:      Offset = 0x1200;      break;    case PPC_IRQ_ADDR_BRK:      Offset = 0x1300;      break;    case PPC_IRQ_SYS_MGT:      Offset = 0x1400;      break;#elif defined(ppc603e)    case PPC_TLB_INST_MISS:      Offset = 0x1000;      break;    case PPC_TLB_LOAD_MISS:      Offset = 0x1100;      break;    case PPC_TLB_STORE_MISS:      Offset = 0x1200;      break;    case PPC_IRQ_ADDRBRK:      Offset = 0x1300;      break;    case PPC_IRQ_SYS_MGT:      Offset = 0x1400;      break;#elif defined(mpc604)    case PPC_IRQ_ADDR_BRK:      Offset = 0x1300;      break;    case PPC_IRQ_SYS_MGT:      Offset = 0x1400;      break;#elif defined(mpc860) || defined(mpc821)    case PPC_IRQ_EMULATE:      Offset = 0x1000;      break;    case PPC_IRQ_INST_MISS:      Offset = 0x1100;      break;    case PPC_IRQ_DATA_MISS:      Offset = 0x1200;      break;    case PPC_IRQ_INST_ERR:      Offset = 0x1300;      break;    case PPC_IRQ_DATA_ERR:      Offset = 0x1400;      break;    case PPC_IRQ_DATA_BPNT:      Offset = 0x1c00;      break;    case PPC_IRQ_INST_BPNT:      Offset = 0x1d00;      break;    case PPC_IRQ_IO_BPNT:      Offset = 0x1e00;      break;    case PPC_IRQ_DEV_PORT:      Offset = 0x1f00;      break;    case PPC_IRQ_IRQ0:      Offset = 0x2000;      break;    case PPC_IRQ_LVL0:      Offset = 0x2040;      break;    case PPC_IRQ_IRQ1:      Offset = 0x2080;      break;    case PPC_IRQ_LVL1:      Offset = 0x20c0;      break;    case PPC_IRQ_IRQ2:      Offset = 0x2100;      break;    case PPC_IRQ_LVL2:      Offset = 0x2140;      break;    case PPC_IRQ_IRQ3:      Offset = 0x2180;      break;    case PPC_IRQ_LVL3:      Offset = 0x21c0;      break;    case PPC_IRQ_IRQ4:      Offset = 0x2200;      break;    case PPC_IRQ_LVL4:      Offset = 0x2240;      break;    case PPC_IRQ_IRQ5:      Offset = 0x2280;      break;    case PPC_IRQ_LVL5:      Offset = 0x22c0;      break;    case PPC_IRQ_IRQ6:      Offset = 0x2300;      break;    case PPC_IRQ_LVL6:      Offset = 0x2340;      break;    case PPC_IRQ_IRQ7:      Offset = 0x2380;      break;    case PPC_IRQ_LVL7:      Offset = 0x23c0;      break;    case PPC_IRQ_CPM_ERROR:      Offset = 0x2400;      break;    case PPC_IRQ_CPM_PC4:      Offset = 0x2410;      break;    case PPC_IRQ_CPM_PC5:      Offset = 0x2420;      break;    case PPC_IRQ_CPM_SMC2:      Offset = 0x2430;      break;    case PPC_IRQ_CPM_SMC1:      Offset = 0x2440;      break;    case PPC_IRQ_CPM_SPI:      Offset = 0x2450;      break;    case PPC_IRQ_CPM_PC6:      Offset = 0x2460;      break;    case PPC_IRQ_CPM_TIMER4:      Offset = 0x2470;      break;    case PPC_IRQ_CPM_RESERVED_8:      Offset = 0x2480;      break;    case PPC_IRQ_CPM_PC7:      Offset = 0x2490;      break;    case PPC_IRQ_CPM_PC8:      Offset = 0x24a0;      break;    case PPC_IRQ_CPM_PC9:      Offset = 0x24b0;      break;    case PPC_IRQ_CPM_TIMER3:      Offset = 0x24c0;      break;    case PPC_IRQ_CPM_RESERVED_D:      Offset = 0x24d0;      break;    case PPC_IRQ_CPM_PC10:      Offset = 0x24e0;      break;    case PPC_IRQ_CPM_PC11:      Offset = 0x24f0;      break;    case PPC_IRQ_CPM_I2C:      Offset = 0x2500;      break;    case PPC_IRQ_CPM_RISC_TIMER:      Offset = 0x2510;      break;    case PPC_IRQ_CPM_TIMER2:      Offset = 0x2520;      break;    case PPC_IRQ_CPM_RESERVED_13:      Offset = 0x2530;      break;    case PPC_IRQ_CPM_IDMA2:      Offset = 0x2540;      break;    case PPC_IRQ_CPM_IDMA1:      Offset = 0x2550;      break;    case PPC_IRQ_CPM_SDMA_ERROR:      Offset = 0x2560;      break;    case PPC_IRQ_CPM_PC12:      Offset = 0x2570;      break;    case PPC_IRQ_CPM_PC13:      Offset = 0x2580;      break;    case PPC_IRQ_CPM_TIMER1:      Offset = 0x2590;      break;    case PPC_IRQ_CPM_PC14:      Offset = 0x25a0;      break;    case PPC_IRQ_CPM_SCC4:      Offset = 0x25b0;      break;    case PPC_IRQ_CPM_SCC3:      Offset = 0x25c0;      break;    case PPC_IRQ_CPM_SCC2:      Offset = 0x25d0;      break;    case PPC_IRQ_CPM_SCC1:      Offset = 0x25e0;      break;    case PPC_IRQ_CPM_PC15:      Offset = 0x25f0;      break;#endif  }  Top += Offset;  return Top;}/*PAGE * *  This is the PowerPC specific implementation of the routine which *  returns TRUE if an interrupt is in progress. * *  NOTE: This is the same as the generic version. But since the *        PowerPC is still supporting old and new exception processing *        models and the new exception processing model has a hardware *        way of doing this, we have to provide this capability here *        for symmetry. */boolean _ISR_Is_in_progress( void ){  return (_ISR_Nest_level != 0);}

⌨️ 快捷键说明

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