Пример #1
0
void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
{
  uint32_t msr_value;
  /*
   * get current MSR value
   */
  _CPU_MSR_GET(msr_value);

  msr_value &= ~PPC_MSR_EE;
  _CPU_MSR_SET(msr_value);
}
Пример #2
0
/***********************************************************
 * functions to enable/disable/query external/critical interrupts
 */
void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data)
{
  uint32_t msr_value;
  /*
   * get current MSR value
   */
  _CPU_MSR_GET(msr_value);

  msr_value |= PPC_MSR_EE;
  _CPU_MSR_SET(msr_value);
}
Пример #3
0
/*
 * High level IRQ handler called from shared_raw_irq_code_entry
 */
int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
{
  register unsigned int irq;
  register unsigned msr;
  register unsigned new_msr;

  if (excNum == ASM_DEC_VECTOR) {
    _CPU_MSR_GET(msr);
    new_msr = msr | MSR_EE;
    _CPU_MSR_SET(new_msr);

    rtems_hdl_tbl[BSP_DECREMENTER].hdl(rtems_hdl_tbl[BSP_DECREMENTER].handle);

    _CPU_MSR_SET(msr);
    return 0;

  }

  irq = read_and_clear_irq();
  _CPU_MSR_GET(msr);
  new_msr = msr | MSR_EE;
  _CPU_MSR_SET(new_msr);

  /* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */
  {
     rtems_irq_connect_data* vchain;
     for( vchain = &rtems_hdl_tbl[irq];
          ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
          vchain = (rtems_irq_connect_data*)vchain->next_handler )
     {
        vchain->hdl(vchain->handle);
     }
  }

  _CPU_MSR_SET(msr);

  return 0;
}
Пример #4
0
Файл: cpu.c Проект: rtemss/rtems
void _CPU_Context_Initialize(
  Context_Control  *the_context,
  uint32_t         *stack_base,
  uint32_t          size,
  uint32_t          new_level,
  void             *entry_point,
  bool              is_fp
)
{
  uint32_t   msr_value;
  uint32_t   sp;

  sp = (uint32_t)stack_base + size - PPC_MINIMUM_STACK_FRAME_SIZE;

  sp &= ~(CPU_STACK_ALIGNMENT-1);

  *((uint32_t*)sp) = 0;

  _CPU_MSR_GET( msr_value );

  /*
   * Setting the interrupt mask here is not strictly necessary
   * since the IRQ level will be established from _Thread_Handler()
   * again, as soon as the task starts execution.
   * Because we have to establish a defined state anyways we
   * can as well leave this code here.
   * I.e., simply (and unconditionally) saying
   *
   *   msr_value &= ~ppc_interrupt_get_disable_mask();
   *
   * would be an alternative.
   */

  if (!(new_level & CPU_MODES_INTERRUPT_MASK)) {
    msr_value |= ppc_interrupt_get_disable_mask();
  }
  else {
    msr_value &= ~ppc_interrupt_get_disable_mask();
  }

  /*
   *  The FP bit of the MSR should only be enabled if this is a floating
   *  point task.  Unfortunately, the vfprintf_r routine in newlib
   *  ends up pushing a floating point register regardless of whether or
   *  not a floating point number is being printed.  Serious restructuring
   *  of vfprintf.c will be required to avoid this behavior.  At this
   *  time (7 July 1997), this restructuring is not being done.
   */

  /* Make sure integer tasks have no FPU access in order to
   * catch violations. Gcc may implicitely use the FPU and
   * data corruption may happen.
   * Since we set the_contex->msr using our current MSR,
   * we must make sure MSR_FP is off if (!is_fp)...
   * Unfortunately, this means that users of vfprintf_r have to use FP
   * tasks or fix vfprintf. Furthermore, users of int-only tasks
   * must prevent gcc from using the FPU (currently -msoft-float is the
   * only way...)
   */
  if ( is_fp )
    msr_value |= PPC_MSR_FP;
  else
    msr_value &= ~PPC_MSR_FP;

  memset( the_context, 0, sizeof( *the_context ) );

  PPC_CONTEXT_SET_SP( the_context, sp );
  PPC_CONTEXT_SET_PC( the_context, (uint32_t) entry_point );
  PPC_CONTEXT_SET_MSR( the_context, msr_value );

#ifndef __SPE__
#if (PPC_ABI == PPC_ABI_SVR4)
  /*
   * SVR4 says R2 is for 'system-reserved' use; it cannot hurt to
   * propagate R2 to all task contexts.
   */
  { uint32_t    r2 = 0;
    unsigned    r13 = 0;
    __asm__ volatile ("mr %0,2; mr %1,13" : "=r" ((r2)), "=r" ((r13)));

    the_context->gpr2 = r2;
    the_context->gpr13 = r13;
  }
#elif (PPC_ABI == PPC_ABI_EABI)
  { uint32_t    r2 = 0;
    unsigned    r13 = 0;
    __asm__ volatile ("mr %0,2; mr %1,13" : "=r" ((r2)), "=r" ((r13)));

    the_context->gpr2 = r2;
    the_context->gpr13 = r13;
  }
#else
#error unsupported PPC_ABI
#endif
#endif /* __SPE__ */

#ifdef __ALTIVEC__
  _CPU_Context_initialize_altivec(the_context);
#endif
}
Пример #5
0
/*
 *  Initialize SS555
 */
void _InitSS555 (void)
{
  register uint32_t plprcr, msr;

  /*
   * Initialize the System Protection Control Register (SYPCR).
   * The SYPCR can only be written once after Reset.
   */
  usiu.sypcr =
      USIU_SYPCR_SWTC(WATCHDOG_TIMEOUT)	/* set watchdog timeout */
    | USIU_SYPCR_BMT(0xFF) 		/* set bus monitor timeout */
    | USIU_SYPCR_BME 			/* enable bus monitor */
    | USIU_SYPCR_SWF			/* watchdog halted in freeze */
#if WATCHDOG_TIMEOUT != 0xFFFF
    | USIU_SYPCR_SWE			/* enable watchdog */
#endif
    | USIU_SYPCR_SWRI			/* watchdog forces reset */
    | USIU_SYPCR_SWP;			/* prescale watchdog by 2048 */

  TICKLE_WATCHDOG();			/* restart watchdog timer */

  /*
   * Re-tune the PLL to the desired system clock frequency.
   */
  usiu.plprck = USIU_UNLOCK_KEY;	/* unlock PLPRCR */
  usiu.plprcr =
      USIU_PLPRCR_TEXPS			/* assert TEXP always */
    | USIU_PLPRCR_MF(BSP_CLOCK_HZ / BSP_CRYSTAL_HZ);
  					/* PLL multiplication factor */
  usiu.plprck = 0;			/* lock PLPRCR */

  while (((plprcr = usiu.plprcr) & USIU_PLPRCR_SPLS) == 0)
    ;					/* wait for PLL to re-lock */

  /*
   * Enable the timebase and decrementer, then initialize decrementer
   * register to a large value to guarantee that a decrementer interrupt
   * will not be generated before the kernel is fully initialized.
   * Initialize the timebase register to zero.
   */
  usiu.tbscrk = USIU_UNLOCK_KEY;
  usiu.tbscr |= USIU_TBSCR_TBE;		/* enable time base and decrementer */
  usiu.tbscrk = 0;

  usiu.tbk = USIU_UNLOCK_KEY;
  _write_PPC_DEC(0x7FFFFFFF);
  _write_TBWU(0x00000000 );
  _write_TBWL(0x00000000 );
  usiu.tbk = 0;

  /*
   * Run the Inter-Module Bus at full speed.
   */
  imb.uimb.umcr &= ~UIMB_UMCR_HSPEED;

  /*
   * Initialize Memory Controller for External RAM
   *
   * Initialize the Base and Option Registers (BR0-BR7 and OR0-OR7).  Note
   * that for all chip selects, ORx should be programmed before BRx.
   *
   * If booting from internal flash ROM, configure the external RAM to
   * extend the internal RAM.  If booting from external RAM, leave it at
   * zero but set it up appropriately.
   */
  usiu.memc[0]._or =
      USIU_MEMC_OR_512K			/* bank size */
    | USIU_MEMC_OR_SCY(0)		/* wait states in first beat of burst */
    | USIU_MEMC_OR_BSCY(0);		/* wait states in subsequent beats */

  usiu.memc[0]._br =
      USIU_MEMC_BR_BA(_read_IMMR() & IMMR_FLEN
        ? (uint32_t)int_ram_top : 0)	/* base address */
    | USIU_MEMC_BR_PS32			/* 32-bit data bus */
    | USIU_MEMC_BR_TBDIP		/* toggle bdip */
    | USIU_MEMC_BR_V;			/* base register valid */

  /*
   * Initialize Memory Controller for External CPLD
   *
   * The SS555 board includes a CPLD to control on-board features and
   * off-board devices.  (Configuration taken from Intec's hwhook.c)
   */
  usiu.memc[3]._or =
      USIU_MEMC_OR_16M			/* bank size */
    | USIU_MEMC_OR_CSNT			/* negate CS/WE early */
    | USIU_MEMC_OR_ACS_HALF		/* assert CS half cycle after address */
    | USIU_MEMC_OR_SCY(15)		/* wait states in first beat of burst */
    | USIU_MEMC_OR_TRLX;		/* relaxed timing */

  usiu.memc[3]._br =
      USIU_MEMC_BR_BA(&cpld)		/* base address */
    | USIU_MEMC_BR_PS16			/* 16-bit data bus */
    | USIU_MEMC_BR_BI			/* inhibit bursting */
    | USIU_MEMC_BR_V;			/* base register valid */

  /*
   * Disable show cycles and serialization so that burst accesses will work
   * properly.  A different value, such as 0x0, may be more appropriate for
   * debugging, but can be set with the debugger, if needed.
   */
  _write_ICTRL(0x00000007);

  /*
   * Set up Burst Buffer Controller (BBC)
   */
  _write_BBCMCR(
      BBCMCR_ETRE			/* enable exception relocation */
    | BBCMCR_BE);			/* enable burst accesses */
  _isync;

  _CPU_MSR_GET(msr);
  msr |= MSR_IP;		/* set prefix for exception relocation */
  _CPU_MSR_SET(msr);
}
Пример #6
0
/*
 * mmu_init
 *
 * This routine sets up the virtual memory maps on an MPC8xx.
 * The MPC8xx does not support block address translation (BATs)
 * and does not have segment registers. Thus, we must set up page
 * translation. However, its MMU supports variable size pages
 * (1-, 4-, 16-, 512-Kbyte or 8-Mbyte), which simplifies the task.
 *
 * The MPC8xx has separate data and instruction 32-entry translation
 * lookaside buffers (TLB). By mapping all of DRAM as one huge page,
 * we can preload the TLBs and not have to be concerned with taking
 * TLB miss exceptions.
 *
 * We set up the virtual memory map so that virtual address of a
 * location is equal to its real address.
 */
void mmu_init( void )
{
  register uint32_t   reg1, i;

  /*
   * Initialize the TLBs
   *
   * Instruction address translation and data address translation
   * must be disabled during initialization (IR=0, DR=0 in MSR).
   * We can assume the MSR has already been set this way.
   */

  /*
   * Initialize IMMU & DMMU Control Registers (MI_CTR & MD_CTR)
   * 	GPM [0]			0b0 = PowerPC mode
   *	PPM [1]			0b0 = Page resolution of protection
   *	CIDEF [2]		0b0/0b0 = Default cache-inhibit attribute =
   *							NO for IMMU, NO for DMMU
   *                            NOTE: it is vital that data caching is ON, when
   *                            DMMU is off, otherwise valid/dirty values in
   *                            cache would be ignored during exception entry
   *	reserved/WTDEF [3]	0b0 = Default write-through attribute = not
   *	RSV4x [4]		0b0 = 4 entries not reserved
   *	reserved/TWAM [5]	0b0/0b1 = 4-Kbyte page hardware assist
   *	PPCS [6]		0b0 = Ignore user/supervisor state
   *	reserved [7-18]		0x00
   *	xTLB_INDX [19-23]	31 = 0x1F
   *	reserved [24-31]	0x00
   *
   * Note: It is important that cache-inhibit be set as the default for the
   * data cache when the DMMU is disabled in order to prevent internal memory
   * mapped registers from being cached accidentally when address translation
   * is turned off at the start of exception processing.
   */
  reg1 = M8xx_MI_CTR_ITLB_INDX(31);
  _mtspr( M8xx_MI_CTR, reg1 );
  reg1 = M8xx_MD_CTR_TWAM | M8xx_MD_CTR_DTLB_INDX(31);
  _mtspr( M8xx_MD_CTR, reg1 );
  _isync;

  /*
   * Invalidate all TLB entries in both TLBs.
   * Note: We rely on the RSV4 bit in MI_CTR and MD_CTR being 0b0, so
   *       all 32 entries are invalidated.
   */
  __asm__ volatile ("tlbia\n"::);
  _isync;

  /*
   * Set Current Address Space ID Register (M_CASID).
   * Supervisor: CASID = 0
   */
  reg1 = 0;
  _mtspr( M8xx_M_CASID, reg1 );

  /*
   * Initialize the MMU Access Protection Registers (MI_AP, MD_AP)
   * We ignore the Access Protection Group (APG) mechanism globally
   * by setting all of the Mx_AP fields to 0b01 : client access
   * permission is defined by page protection bits.
   */
  reg1 = 0x55555555;
  _mtspr( M8xx_MI_AP, reg1 );
  _mtspr( M8xx_MD_AP, reg1 );

  /*
   * Load both 32-entry TLBs with values from the MMU_TLB_table
   * which is defined in the BSP.
   * Note the _TLB_Table must have at most 32 entries. This code
   * makes no effort to enforce this restriction.
   */
  for( i = 0; i < MMU_N_TLB_Table_Entries; ++i ) {
    reg1 = MMU_TLB_table[i].mmu_epn;
    _mtspr( M8xx_MI_EPN, reg1 );
    _mtspr( M8xx_MD_EPN, reg1 );
    reg1 = MMU_TLB_table[i].mmu_twc;
    _mtspr( M8xx_MI_TWC, reg1 );
    _mtspr( M8xx_MD_TWC, reg1 );
    reg1 = MMU_TLB_table[i].mmu_rpn;	/* RPN must be written last! */
    _mtspr( M8xx_MI_RPN, reg1 );
    _mtspr( M8xx_MD_RPN, reg1 );
  }

  /*
   * Turn on address translation by setting MSR[IR] and MSR[DR].
   */
  _CPU_MSR_GET( reg1 );
  reg1 |= PPC_MSR_IR | PPC_MSR_DR;
  _CPU_MSR_SET( reg1 );
}