summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c')
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c263
1 files changed, 263 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c
new file mode 100644
index 0000000000..45d7fd9617
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/bspstart.c
@@ -0,0 +1,263 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief BSP startup code.
+ */
+
+/*
+ * Copyright (c) 2008
+ * Embedded Brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * rtems@embedded-brains.de
+ *
+ * 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.
+ */
+
+#include <mpc55xx/mpc55xx.h>
+#include <mpc55xx/regs.h>
+#include <mpc55xx/edma.h>
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/libcsupport.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/ppc_exc_bspsupp.h>
+
+#define RTEMS_STATUS_CHECKS_USE_PRINTK
+
+#include <rtems/status-checks.h>
+
+#define DEBUG_DONE() DEBUG_PRINT( "Done\n")
+
+#define MPC55XX_INTERRUPT_STACK_SIZE 0x1000
+
+/* Symbols defined in linker command file */
+LINKER_SYMBOL( bsp_ram_start);
+LINKER_SYMBOL( bsp_ram_end);
+LINKER_SYMBOL( bsp_external_ram_start);
+LINKER_SYMBOL( bsp_external_ram_size);
+LINKER_SYMBOL( bsp_section_bss_end);
+
+unsigned int bsp_clock_speed = 0;
+
+uint32_t bsp_clicks_per_usec = 0;
+
+void BSP_panic( char *s)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable( level);
+
+ printk( "%s PANIC %s\n", _RTEMS_version, s);
+
+ while (1) {
+ /* Do nothing */
+ }
+}
+
+void _BSP_Fatal_error( unsigned n)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable( level);
+
+ printk( "%s PANIC ERROR %u\n", _RTEMS_version, n);
+
+ while (1) {
+ /* Do nothing */
+ }
+}
+
+void bsp_pretasking_hook()
+{
+ uint32_t heap_start = bsp_external_ram_start;
+ uint32_t heap_size = bsp_external_ram_size;
+
+ bsp_libc_init( heap_start, heap_size, 0);
+
+#ifdef STACK_CHECKER_ON
+ Stack_check_Initialize();
+#endif
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+void bsp_predriver_hook()
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ DEBUG_PRINT( "Initialize eDMA ...\n");
+ sc = mpc55xx_edma_init();
+ if (sc != RTEMS_SUCCESSFUL) {
+ BSP_panic( "Cannot initialize eDMA");
+ } else {
+ DEBUG_DONE();
+ }
+}
+
+static void mpc55xx_ebi_init()
+{
+ struct EBI_CS_tag cs = { BR : MPC55XX_ZERO_FLAGS, OR : MPC55XX_ZERO_FLAGS };
+ union SIU_PCR_tag pcr = MPC55XX_ZERO_FLAGS;
+ int i = 0;
+
+ /* External SRAM (0 wait states, 512kB, 4 word burst) */
+ cs.BR.B.BA = 0;
+ cs.BR.B.PS = 1;
+ cs.BR.B.BL = 1;
+ cs.BR.B.WEBS = 0;
+ cs.BR.B.TBDIP = 0;
+ cs.BR.B.BI = 1; /* TODO: Enable burst */
+ cs.BR.B.V = 1;
+
+ cs.OR.B.AM = 0x1fff0;
+ cs.OR.B.SCY = 0;
+ cs.OR.B.BSCY = 0;
+
+ EBI.CS [0] = cs;
+
+ /* !CS [0] */
+ SIU.PCR [0].R = 0x443;
+
+ /* ADDR [8 : 31] */
+ for (i = 4; i < 4 + 24; ++i) {
+ SIU.PCR [i].R = 0x440;
+ }
+
+ /* DATA [0 : 15] */
+ for (i = 28; i < 28 + 16; ++i) {
+ SIU.PCR [i].R = 0x440;
+ }
+
+ /* RD_!WR */
+ SIU.PCR [62].R = 0x443;
+
+ /* !BDIP */
+ SIU.PCR [63].R = 0x443;
+
+ /* !WE [0 : 3] */
+ for (i = 64; i < 64 + 4; ++i) {
+ SIU.PCR [i].R = 0x443;
+ }
+
+ /* !OE */
+ SIU.PCR [68].R = 0x443;
+
+ /* !TS */
+ SIU.PCR [69].R = 0x443;
+}
+
+/**
+ * @brief Start BSP.
+ */
+void bsp_start(void)
+{
+ ppc_cpu_id_t myCpu;
+ ppc_cpu_revision_t myCpuRevision;
+
+ uint32_t ram_start = bsp_ram_start;
+ uint32_t ram_end = bsp_ram_end;
+ uint32_t interrupt_stack_start = ram_end - 2 * MPC55XX_INTERRUPT_STACK_SIZE;
+ uint32_t interrupt_stack_size = MPC55XX_INTERRUPT_STACK_SIZE;
+ uint32_t work_space_start = bsp_section_bss_end;
+ uint32_t work_space_end = work_space_start + rtems_configuration_get_work_space_size();
+
+ /* ESCI pad configuration */
+ SIU.PCR [89].R = 0x400;
+ SIU.PCR [90].R = 0x400;
+
+ DEBUG_PRINT( "BSP start ...\n");
+
+ /* Memory layout */
+
+ Configuration.work_space_start = work_space_start;
+
+ DEBUG_PRINT( "System clock : %i\n", mpc55xx_get_system_clock());
+ DEBUG_PRINT( "Memory start : 0x%08x\n", ram_start);
+ DEBUG_PRINT( "Memory end : 0x%08x\n", ram_end);
+ DEBUG_PRINT( "Memory size : 0x%08x\n", ram_end - ram_start);
+ DEBUG_PRINT( "Work space start : 0x%08x\n", work_space_start);
+ DEBUG_PRINT( "Work space end : 0x%08x\n", work_space_end);
+ DEBUG_PRINT( "Work space size : 0x%08x\n", work_space_end - work_space_start);
+ DEBUG_PRINT( "Interrupt stack start : 0x%08x\n", interrupt_stack_start);
+ DEBUG_PRINT( "Interrupt stack end : 0x%08x\n", interrupt_stack_start + interrupt_stack_size);
+ DEBUG_PRINT( "Interrupt stack size : 0x%08x\n", interrupt_stack_size);
+
+ if (work_space_end > interrupt_stack_start) {
+ BSP_panic( "Not enough memory for the work space");
+ }
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables so that it can be used
+ * latter...
+ */
+ myCpu = get_ppc_cpu_type();
+ myCpuRevision = get_ppc_cpu_revision();
+
+ /* Time reference value */
+ bsp_clicks_per_usec = bsp_clock_speed / 1000000;
+
+ /* Initialize External Bus Interface */
+ mpc55xx_ebi_init();
+
+ /* Initialize exceptions */
+ DEBUG_PRINT( "Initialize exceptions ...\n");
+ ppc_exc_initialize( PPC_INTERRUPT_DISABLE_MASK_DEFAULT, interrupt_stack_start, interrupt_stack_size);
+ DEBUG_DONE();
+
+ /* Initialize interrupts */
+ DEBUG_PRINT( "Initialize interrupts ...\n");
+ if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
+ BSP_panic( "Cannot initialize interrupts");
+ } else {
+ DEBUG_DONE();
+ }
+
+ DEBUG_PRINT( "BSP start done\n");
+
+ return;
+
+ /* TODO */
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+#if INSTRUCTION_CACHE_ENABLE
+ rtems_cache_enable_instruction();
+#endif
+#if DATA_CACHE_ENABLE
+ rtems_cache_enable_data();
+#endif
+}
+
+/**
+ * @brief Idle thread body.
+ */
+Thread _Thread_Idle_body( uint32_t ignored)
+{
+
+ while (1) {
+ asm volatile(
+ "mfmsr 3;"
+ "oris 3,3,4;"
+ "sync;"
+ "mtmsr 3;"
+ "isync;"
+ "ori 3,3,0;"
+ "ori 3,3,0"
+ );
+ }
+ return 0;
+}