summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/gen83xx/startup/cpuinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/gen83xx/startup/cpuinit.c')
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/startup/cpuinit.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/startup/cpuinit.c b/c/src/lib/libbsp/powerpc/gen83xx/startup/cpuinit.c
new file mode 100644
index 0000000000..c4d6f50491
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen83xx/startup/cpuinit.c
@@ -0,0 +1,216 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC83xx BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| 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. |
+| |
++-----------------------------------------------------------------+
+| this file contains the code to initialize the cpu |
+\*===============================================================*/
+/***********************************************************************/
+/* */
+/* Module: cpuinit.c */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS MPC5x00 C level startup code */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This file contains additional functions for */
+/* initializing the MPC5x00 CPU */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: MPC8260ads additional CPU initialization */
+/* Module: cpuinit.c */
+/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */
+/* Version 1.1 */
+/* Date: 10/22/2002 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* Written by Jay Monkman (jmonkman@frasca.com) */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+#include <bsp.h>
+#include <rtems/powerpc/registers.h>
+#include <mpc83xx/mpc83xx.h>
+
+#include <libcpu/mmu.h>
+#include <libcpu/spr.h>
+#include <string.h>
+
+#define USE_IMMU
+
+/* Macros for HID0 access */
+#define SET_HID0(r) __asm__ volatile ("mtspr 0x3F0,%0\n" ::"r"(r))
+#define GET_HID0(r) __asm__ volatile ("mfspr %0,0x3F0\n" :"=r"(r))
+
+#define DBAT_MTSPR(val,name) __MTSPR(val,name);
+#define SET_DBAT(n,uv,lv) {DBAT_MTSPR(lv,DBAT##n##L);DBAT_MTSPR(uv,DBAT##n##U);}
+#if defined(USE_IMMU )
+#define IBAT_MTSPR(val,name) __MTSPR(val,name);
+#define SET_IBAT(n,uv,lv) {IBAT_MTSPR(lv,IBAT##n##L);IBAT_MTSPR(uv,IBAT##n##U);}
+#endif
+
+void calc_dbat_regvals(BAT *bat_ptr,
+ uint32_t base_addr,
+ uint32_t size,
+ boolean flg_w,
+ boolean flg_i,
+ boolean flg_m,
+ boolean flg_g,
+ boolean flg_bpp)
+{
+ uint32_t block_mask;
+ uint32_t end_addr;
+
+ /*
+ * determine block mask, that overlaps the whole block
+ */
+ end_addr = base_addr+size-1;
+ block_mask = ~0;
+ while ((end_addr & block_mask) != (base_addr & block_mask)) {
+ block_mask <<= 1;
+ }
+
+ bat_ptr->batu.bepi = base_addr >> (32-15);
+ bat_ptr->batu.bl = ~(block_mask >> (28-11));
+ bat_ptr->batu.vs = 1;
+ bat_ptr->batu.vp = 1;
+
+ bat_ptr->batl.brpn = base_addr >> (32-15);
+ bat_ptr->batl.w = flg_w;
+ bat_ptr->batl.i = flg_i;
+ bat_ptr->batl.m = flg_m;
+ bat_ptr->batl.g = flg_g;
+ bat_ptr->batl.pp = flg_bpp;
+}
+
+void clear_mmu_regs(void)
+{
+ uint32_t i;
+ /*
+ * clear segment registers
+ */
+ for (i = 0;i < 16;i++) {
+ asm volatile(" mtsrin %0, %1\n"::"r" (i * 0x1000),"r"(i<<(31-3)));
+ }
+ /*
+ * clear TLBs
+ */
+ for (i = 0;i < 32;i++) {
+ asm volatile(" tlbie %0\n"::"r" (i << (31-19)));
+ }
+}
+
+void cpu_init(void)
+{
+ register unsigned long reg;
+ BAT dbat,ibat;
+
+ /*
+ * clear MMU/Segment registers
+ */
+ clear_mmu_regs();
+ /*
+ * clear caches
+ */
+ GET_HID0(reg);
+ reg |= (HID0_ICFI | HID0_DCI);
+ SET_HID0(reg);
+ reg &= ~(HID0_ICFI | HID0_DCI);
+ SET_HID0(reg);
+
+ /*
+ * set up IBAT registers in MMU
+ */
+ memset(&ibat,0,sizeof(ibat));
+ SET_IBAT(2,ibat.batu,ibat.batl);
+ SET_IBAT(3,ibat.batu,ibat.batl);
+ SET_IBAT(4,ibat.batu,ibat.batl);
+ SET_IBAT(5,ibat.batu,ibat.batl);
+ SET_IBAT(6,ibat.batu,ibat.batl);
+ SET_IBAT(7,ibat.batu,ibat.batl);
+
+ calc_dbat_regvals(&ibat,RAM_START,RAM_SIZE,0,0,0,0,BPP_RX);
+ SET_IBAT(0,ibat.batu,ibat.batl);
+ calc_dbat_regvals(&ibat,ROM_START,ROM_SIZE,0,0,0,0,BPP_RX);
+ SET_IBAT(1,ibat.batu,ibat.batl);
+
+ /*
+ * set up DBAT registers in MMU
+ */
+ memset(&dbat,0,sizeof(dbat));
+ SET_DBAT(3,dbat.batu,dbat.batl);
+ SET_DBAT(4,dbat.batu,dbat.batl);
+ SET_DBAT(5,dbat.batu,dbat.batl);
+ SET_DBAT(6,dbat.batu,dbat.batl);
+ SET_DBAT(7,dbat.batu,dbat.batl);
+
+ calc_dbat_regvals(&dbat,RAM_START,RAM_SIZE,1,0,1,0,BPP_RW);
+ SET_DBAT(0,dbat.batu,dbat.batl);
+
+ calc_dbat_regvals(&dbat,ROM_START,ROM_SIZE,1,0,1,0,BPP_RX);
+ SET_DBAT(1,dbat.batu,dbat.batl);
+
+ calc_dbat_regvals(&dbat,IMMRBAR,1024*1024,1,1,1,1,BPP_RW);
+ SET_DBAT(2,dbat.batu,dbat.batl);
+
+ /*
+ * enable data/instruction MMU in MSR
+ */
+ _write_MSR(_read_MSR() | MSR_DR/* | MSR_IR*/);
+
+ /*
+ * enable FPU in MSR
+ */
+ _write_MSR(_read_MSR() | MSR_FP);
+
+ /*
+ * in HID0:
+ * - enable dynamic power management
+ * - enable machine check interrupts
+ */
+ GET_HID0(reg);
+ reg |= (HID0_EMCP | HID0_DPM) ;
+ SET_HID0(reg);
+
+ /*
+ * enable timebase clock
+ */
+ mpc83xx.syscon.spcr |= M83xx_SYSCON_SPCR_TBEN;
+}