summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/m68k/genmcf548x/startup/bspstart.c
blob: 32c5f534396acd1009d9d878dcba8409da68e6f1 (plain) (tree)


































































































































































































































































































































                                                                                                                          
/*===============================================================*\
| Project: RTEMS generic mcf548x BSP                              |
+-----------------------------------------------------------------+
| File: bspstart.c                                                |
+-----------------------------------------------------------------+
| The file contains the startup code of generic MCF548x BSP       |
+-----------------------------------------------------------------+
|                    Copyright (c) 2007                           |
|                    Embedded Brains GmbH                         |
|                    Obere Lagerstr. 30                           |
|                    D-82178 Puchheim                             |
|                    Germany                                      |
|                    rtems@embedded-brains.de                     |
+-----------------------------------------------------------------+
|                                                                 |
| Parts of the code has been derived from the "dBUG source code"  |
| package Freescale is providing for M548X EVBs. The usage of     |
| the modified or unmodified code and it's integration into the   |
| generic mcf548x BSP has been done according to the Freescale    |
| license terms.                                                  |
|                                                                 |
| The Freescale license terms can be reviewed in the file         |
|                                                                 |
|    Freescale_license.txt                                        |
|                                                                 |
+-----------------------------------------------------------------+
|                                                                 |
| The generic mcf548x BSP has been developed on the basic         |
| structures and modules of the av5282 BSP.                       |
|                                                                 |
+-----------------------------------------------------------------+
|                                                                 |
| The license and distribution terms for this file may be         |
| found in the file LICENSE in this distribution or at            |
|                                                                 |
| http://www.rtems.com/license/LICENSE.                           |
|                                                                 |
+-----------------------------------------------------------------+
|                                                                 |
|   date                      history                        ID   |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 12.11.07                    1.0                            ras  |
|                                                                 |
\*===============================================================*/

#include <bsp.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <string.h>

char *HeapStart, *HeapEnd;
unsigned long _HeapSize;

extern uint32_t _CPU_cacr_shadow;

extern char _SdramBase[];
extern char _BootFlashBase[];
extern char _CodeFlashBase[];
extern char _SdramSize[];
extern char _BootFlashSize[];
extern char _CodeFlashSize[];

/*
 * CPU-space access
 */
#define m68k_set_cacr(_cacr) asm volatile ("movec %0,%%cacr\n\tnop" : : "d" (_cacr))
#define m68k_set_acr0(_acr0) asm volatile ("movec %0,#0x0004" : : "d" (_acr0))
#define m68k_set_acr1(_acr1) asm volatile ("movec %0,#0x0005" : : "d" (_acr1))
#define m68k_set_acr2(_acr2) asm volatile ("movec %0,#0x0005" : : "d" (_acr2))
#define m68k_set_acr3(_acr3) asm volatile ("movec %0,#0x0007" : : "d" (_acr3))

/*
 * Set initial cacr mode, mainly enables branch/intruction/data cache and switch off FPU.
 */
static uint32_t cacr_mode = (0                                          |
                             MCF548X_CACR_DEC                           | /* enable data cache */
                             MCF548X_CACR_BEC                           | /* enable branch cache */
                             MCF548X_CACR_IEC                           | /* enable instruction cache */
                             MCF548X_CACR_DDCM(DCACHE_ON_WRIGHTTHROUGH) | /* set data cache mode to write-through */
                             MCF548X_CACR_DESB                          | /* enable data store buffer */
                             MCF548X_CACR_DDSP                          | /* data access only in supv. mode */
                             MCF548X_CACR_IDSP                          | /* instr. access only in supv. mode */
                             MCF548X_CACR_DF);                            /* disable FPU */


/*
 * Coldfire cacr maintenance functions
 */
void _CPU_cacr_set_mode(uint32_t new_cacr_mode)
{
rtems_interrupt_level level;

rtems_interrupt_disable(level);
cacr_mode = new_cacr_mode;
m68k_set_cacr(new_cacr_mode);
rtems_interrupt_enable(level);
}

/*
 * There is no complete cache lock (only 2 ways of 4 can be locked)
 */
void _CPU_cache_freeze_data(void)
{
}

void _CPU_cache_unfreeze_data(void)
{
}

void _CPU_cache_freeze_instruction(void)
{
}

void _CPU_cache_unfreeze_instruction(void)
{
}

void _CPU_cache_enable_instruction(void)
{
    cacr_mode &= ~(MCF548X_CACR_IDCM);
    _CPU_cacr_set_mode(cacr_mode);
}

void _CPU_cache_disable_instruction(void)
{
    cacr_mode |= MCF548X_CACR_IDCM;
    _CPU_cacr_set_mode(cacr_mode);
}

void _CPU_cache_invalidate_entire_instruction(void)
{
	cacr_mode |= MCF548X_CACR_ICINVA;
    _CPU_cacr_set_mode(cacr_mode);
}

void _CPU_cache_invalidate_1_instruction_line(const void *addr)
{

    asm volatile ("cpushl %%ic,(%0)" :: "a" (addr));
}

void _CPU_cache_enable_data(void)
{
    cacr_mode &= ~MCF548X_CACR_DDCM(DCACHE_OFF_IMPRECISE);
    _CPU_cacr_set_mode(cacr_mode);
}

void _CPU_cache_disable_data(void)
{
    cacr_mode |= MCF548X_CACR_DDCM(DCACHE_OFF_IMPRECISE);
    _CPU_cacr_set_mode(cacr_mode);
}

void _CPU_cache_invalidate_entire_data(void)
{
    cacr_mode |= MCF548X_CACR_DCINVA;
    _CPU_cacr_set_mode(cacr_mode);
}

void _CPU_cache_invalidate_1_data_line(const void *addr)
{

   asm volatile ("cpushl %%dc,(%0)" :: "a" (addr));
}

void _CPU_cache_flush_1_data_line(const void *addr)
{
   asm volatile ("cpushl %%dc,(%0)" :: "a" (addr));
}

void _CPU_cache_flush_entire_data(void)
{
register uint32_t way_cnt, set_cnt, addr;

asm volatile("nop");

for(way_cnt=0; way_cnt<4; way_cnt++)
  {
  for(addr=0,set_cnt=0; set_cnt<512; set_cnt++,addr+=0x10)
    {
    asm volatile ("cpushl %%dc,(%0)" :: "a" (addr));
    }
  addr=way_cnt;
  }
}

/*
 *  Use the shared implementations of the following routines
 */

void bsp_predriver_hook()
{
	/* Do nothing */
}

void bsp_postdriver_hook(void);
void bsp_libc_init( void *, uint32_t, int );
void bsp_pretasking_hook(void);		/* m68k version */

void bsp_calc_mem_layout()
{
  /*
   * these labels (!) are defined in the linker command file
   * or when the linker is invoked
   * NOTE: the information(size) is the address of the object,
   * not the object otself
   */
  extern char _TopRamReserved [];
  extern char _WorkspaceBase [];

  /*
   * compute the memory layout:
   * - first unused address is Workspace start
   * - Heap starts at end of workspace
   * - Heap ends at end of memory - reserved memory area
   */
  Configuration.work_space_start = _WorkspaceBase;

  HeapStart = ((char *)Configuration.work_space_start +
                    Configuration.work_space_size);

  HeapEnd = (void *)(RAM_END - (uint32_t)_TopRamReserved);

  _HeapSize = HeapEnd - HeapStart;
}


/*
 * Coldfire acr and mmu settings
 */
 void acr_mmu_mapping(void)
   {

  /*
   * Cache disabled for internal register area (256 kB).
   * Choose the smallest maskable size of 1MB.
   */
  m68k_set_acr0(MCF548X_ACR_BA((uint32_t)(__MBAR))                           |
                MCF548X_ACR_ADMSK_AMM((uint32_t)(0xFFFFF))                   |
                MCF548X_ACR_E                                                |
                MCF548X_ACR_SP               /* supervisor protection */     |
                MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ |
                MCF548X_ACR_CM(CM_OFF_PRECISE));

#ifdef M5484FIREENGINE


  /*
   * Cache enabled for entire SDRAM (64 MB)
   */
  m68k_set_acr1(MCF548X_ACR_BA((uint32_t)(_SdramBase))                       |
                MCF548X_ACR_ADMSK_AMM((uint32_t)(_SdramSize - 1))            |
                MCF548X_ACR_E                                                |
                MCF548X_ACR_SP               /* supervisor protection */     |
                MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ |
                MCF548X_ACR_CM(CM_ON_WRIGHTTHROUGH));

  /*
   * Cache enabled for entire boot flash (2 MB)
   */
  m68k_set_acr2(MCF548X_ACR_BA((uint32_t)(_BootFlashBase))                   |
                MCF548X_ACR_ADMSK_AMM((uint32_t)(_BootFlashSize - 1))        |
                MCF548X_ACR_E                                                |
                MCF548X_ACR_SP               /* supervisor protection */     |
                MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ |
                MCF548X_ACR_CM(CM_ON_COPYBACK));

  /*
   * Cache enabled for entire code flash (16 MB)
   */
  m68k_set_acr3(MCF548X_ACR_BA((uint32_t)(_CodeFlashBase))                   |
                MCF548X_ACR_ADMSK_AMM((uint32_t)(_CodeFlashSize - 1))        |
                MCF548X_ACR_E                                                |
                MCF548X_ACR_SP               /* supervisor protection */     |
                MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ |
                MCF548X_ACR_CM(CM_ON_COPYBACK));
#endif

   }

/*
 *  bsp_start
 *
 *  This routine does the bulk of the system initialisation.
 */
void bsp_start( void )
{
  extern char _RamSize[];
  extern unsigned long  _M68k_Ramsize;

  _M68k_Ramsize = (unsigned long)_RamSize;		/* RAM size set in linker script */

  /*
   *  Allocate the memory for the RTEMS Work Space and Heap.  This can come from
   *  a variety of places: hard coded address, malloc'ed from outside
   *  RTEMS world (e.g. simulator or primitive memory manager), or (as
   *  typically done by stock BSPs) by subtracting the required amount
   *  of work space from the last physical address on the CPU board.
   */
  bsp_calc_mem_layout();

  /*
   * do mapping of acr's and/or mmu
   */
  acr_mmu_mapping();

  /*
   * Load the shadow variable of cacr with initial mode and write it to the cacr.
   * Interrupts are still disabled, so there is no need for surrounding rtems_interrupt_enable()/rtems_interrupt_disable()
   */
  _CPU_cacr_shadow = cacr_mode;
  m68k_set_cacr(_CPU_cacr_shadow);

}


/*
 * Get the XLB clock speed
 */
uint32_t get_CPU_clock_speed(void)
{
    return (uint32_t)BSP_CPU_CLOCK_SPEED;
}