Ejemplo n.º 1
0
void _CPU_ISR_install_raw_handler(
  uint32_t    vector,
  proc_ptr    new_handler,
  proc_ptr   *old_handler
)
{
  uint32_t               real_vector;
  CPU_Trap_table_entry  *tbr;
  CPU_Trap_table_entry  *slot;
  uint32_t               u32_tbr;
  uint32_t               u32_handler;

  /*
   *  Get the "real" trap number for this vector ignoring the synchronous
   *  versus asynchronous indicator included with our vector numbers.
   */

  real_vector = SPARC_REAL_TRAP_NUMBER( vector );

  /*
   *  Get the current base address of the trap table and calculate a pointer
   *  to the slot we are interested in.
   */

  sparc_get_tbr( u32_tbr );

  u32_tbr &= 0xfffff000;

  tbr = (CPU_Trap_table_entry *) u32_tbr;

  slot = &tbr[ 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->mov_psr_l0 == _CPU_Trap_slot_template.mov_psr_l0 ) {
    u32_handler =
      (slot->sethi_of_handler_to_l4 << HIGH_BITS_SHIFT) |
      (slot->jmp_to_low_of_handler_plus_l4 & LOW_BITS_MASK);
    *old_handler = (proc_ptr) u32_handler;
  } else
    *old_handler = 0;

  /*
   *  Copy the template to the slot and then fix it.
   */

  *slot = _CPU_Trap_slot_template;

  u32_handler = (uint32_t) new_handler;

  slot->mov_vector_l3 |= vector;
  slot->sethi_of_handler_to_l4 |=
    (u32_handler & HIGH_BITS_MASK) >> HIGH_BITS_SHIFT;
  slot->jmp_to_low_of_handler_plus_l4 |= (u32_handler & LOW_BITS_MASK);

  /*
   * There is no instruction cache snooping, so we need to invalidate
   * the instruction cache to make sure that the processor sees the
   * changes to the trap table. This step is required on both single-
   * and multiprocessor systems.
   *
   * In a SMP configuration a change to the trap table might be
   * missed by other cores. If the system state is up, the other
   * cores can be notified using SMP messages that they need to
   * flush their icache. If the up state has not been reached
   * there is no need to notify other cores. They will do an
   * automatic flush of the icache just after entering the up
   * state, but before enabling interrupts.
   */
  rtems_cache_invalidate_entire_instruction();
}
Ejemplo n.º 2
0
void _CPU_ISR_install_raw_handler(
    uint32_t    vector,
    proc_ptr    new_handler,
    proc_ptr   *old_handler
)
{
    uint32_t               real_vector;
    CPU_Trap_table_entry  *tbr;
    CPU_Trap_table_entry  *slot;
    uint32_t               u32_tbr;
    uint32_t               u32_handler;

    /*
     *  Get the "real" trap number for this vector ignoring the synchronous
     *  versus asynchronous indicator included with our vector numbers.
     */

    real_vector = SPARC_REAL_TRAP_NUMBER( vector );

    /*
     *  Get the current base address of the trap table and calculate a pointer
     *  to the slot we are interested in.
     */

    sparc_get_tbr( u32_tbr );

    u32_tbr &= 0xfffff000;

    tbr = (CPU_Trap_table_entry *) u32_tbr;

    slot = &tbr[ 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->mov_psr_l0 == _CPU_Trap_slot_template.mov_psr_l0 ) {
        u32_handler =
            (slot->sethi_of_handler_to_l4 << HIGH_BITS_SHIFT) |
            (slot->jmp_to_low_of_handler_plus_l4 & LOW_BITS_MASK);
        *old_handler = (proc_ptr) u32_handler;
    } else
        *old_handler = 0;

    /*
     *  Copy the template to the slot and then fix it.
     */

    *slot = _CPU_Trap_slot_template;

    u32_handler = (uint32_t) new_handler;

    slot->mov_vector_l3 |= vector;
    slot->sethi_of_handler_to_l4 |=
        (u32_handler & HIGH_BITS_MASK) >> HIGH_BITS_SHIFT;
    slot->jmp_to_low_of_handler_plus_l4 |= (u32_handler & LOW_BITS_MASK);

    /* need to flush icache after this !!! */

    rtems_cache_invalidate_entire_instruction();

}