source: rtems/bsps/powerpc/gen83xx/start/cpuinit.c

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * RTEMS generic MPC83xx BSP
3 *
4 * This file contains the code to initialize the cpu.
5 */
6
7/*
8 * Copyright (c) 2003 IPR Engineering
9 * Copyright (c) 2005 embedded brains GmbH & Co. KG
10 *
11 * The license and distribution terms for this file may be
12 * found in the file LICENSE in this distribution or at
13 * http://www.rtems.org/license/LICENSE.
14 */
15
16#include <stdbool.h>
17#include <string.h>
18
19#include <libcpu/powerpc-utility.h>
20#include <libcpu/mmu.h>
21
22#include <mpc83xx/mpc83xx.h>
23
24#include <bsp.h>
25#include <bsp/u-boot.h>
26
27#define SET_DBAT( n, uv, lv) \
28  do { \
29    PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##L, lv); \
30    PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##U, uv); \
31  } while (0)
32
33#define SET_IBAT( n, uv, lv) \
34  do { \
35    PPC_SET_SPECIAL_PURPOSE_REGISTER( IBAT##n##L, lv); \
36    PPC_SET_SPECIAL_PURPOSE_REGISTER( IBAT##n##U, uv); \
37  } while (0)
38
39static void calc_dbat_regvals(
40  BAT *bat_ptr,
41  uint32_t base_addr,
42  uint32_t size,
43  bool flg_w,
44  bool flg_i,
45  bool flg_m,
46  bool flg_g,
47  uint32_t flg_bpp
48)
49{
50  uint32_t block_mask = 0xffffffff;
51  uint32_t end_addr = base_addr + size - 1;
52
53  /* Determine block mask, that overlaps the whole block */
54  while ((end_addr & block_mask) != (base_addr & block_mask)) {
55    block_mask <<= 1;
56  }
57
58  bat_ptr->batu.bepi = base_addr >> (32 - 15);
59  bat_ptr->batu.bl   = ~(block_mask >> (28 - 11));
60  bat_ptr->batu.vs   = 1;
61  bat_ptr->batu.vp   = 1;
62
63  bat_ptr->batl.brpn = base_addr  >> (32 - 15);
64  bat_ptr->batl.w    = flg_w;
65  bat_ptr->batl.i    = flg_i;
66  bat_ptr->batl.m    = flg_m;
67  bat_ptr->batl.g    = flg_g;
68  bat_ptr->batl.pp   = flg_bpp;
69}
70
71static void clear_mmu_regs( void)
72{
73  uint32_t i;
74
75  /* Clear segment registers */
76  for (i = 0;i < 16;i++) {
77    __asm__ volatile( "mtsrin %0, %1\n" : : "r" (i * 0x1000), "r" (i << (31 - 3)));
78  }
79
80  /* Clear TLBs */
81  for (i = 0;i < 32;i++) {
82    __asm__ volatile( "tlbie %0, 0\n" : : "r" (i << (31 - 19)));
83  }
84}
85
86void cpu_init( void)
87{
88  BAT dbat, ibat;
89  uint32_t msr;
90  uint32_t hid0;
91
92  /* Clear MMU and segment registers */
93  clear_mmu_regs();
94
95  /* Clear caches */
96  PPC_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
97  if ((hid0 & (HID0_ICE | HID0_DCE)) == 0) {
98    hid0 &= ~(HID0_ILOCK | HID0_DLOCK | HID0_ICE | HID0_DCE);
99    PPC_SET_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
100    hid0 |= HID0_ICFI | HID0_DCI;
101    PPC_SET_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
102    hid0 &= ~(HID0_ICFI | HID0_DCI);
103    PPC_SET_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
104  }
105
106  /*
107   * Set up IBAT registers in MMU
108   */
109
110  memset(&ibat, 0, sizeof( ibat));
111  SET_IBAT( 2, ibat.batu, ibat.batl);
112  SET_IBAT( 3, ibat.batu, ibat.batl);
113  SET_IBAT( 4, ibat.batu, ibat.batl);
114  SET_IBAT( 5, ibat.batu, ibat.batl);
115  SET_IBAT( 6, ibat.batu, ibat.batl);
116  SET_IBAT( 7, ibat.batu, ibat.batl);
117
118  calc_dbat_regvals(
119    &ibat,
120    #ifdef HAS_UBOOT
121      bsp_uboot_board_info.bi_memstart,
122      bsp_uboot_board_info.bi_memsize,
123    #else /* HAS_UBOOT */
124      (uint32_t) bsp_ram_start,
125      (uint32_t) bsp_ram_size,
126    #endif /* HAS_UBOOT */
127    false,
128    false,
129    false,
130    false,
131    BPP_RX
132  );
133  SET_IBAT( 0, ibat.batu, ibat.batl);
134
135  calc_dbat_regvals(
136    &ibat,
137    #ifdef HAS_UBOOT
138      bsp_uboot_board_info.bi_flashstart,
139      bsp_uboot_board_info.bi_flashsize,
140    #else /* HAS_UBOOT */
141      (uint32_t) bsp_rom_start,
142      (uint32_t) bsp_rom_size,
143    #endif /* HAS_UBOOT */
144    false,
145    false,
146    false,
147    false,
148    BPP_RX
149  );
150  SET_IBAT( 1, ibat.batu, ibat.batl);
151
152  /*
153   * Set up DBAT registers in MMU
154   */
155
156  memset(&dbat, 0, sizeof( dbat));
157  SET_DBAT( 3, dbat.batu, dbat.batl);
158  SET_DBAT( 4, dbat.batu, dbat.batl);
159  SET_DBAT( 5, dbat.batu, dbat.batl);
160  SET_DBAT( 6, dbat.batu, dbat.batl);
161  SET_DBAT( 7, dbat.batu, dbat.batl);
162
163  calc_dbat_regvals(
164    &dbat,
165    #ifdef HAS_UBOOT
166      bsp_uboot_board_info.bi_memstart,
167      bsp_uboot_board_info.bi_memsize,
168    #else /* HAS_UBOOT */
169      (uint32_t) bsp_ram_start,
170      (uint32_t) bsp_ram_size,
171    #endif /* HAS_UBOOT */
172    false,
173    false,
174    false,
175    false,
176    BPP_RW
177  );
178  SET_DBAT( 0, dbat.batu, dbat.batl);
179
180  calc_dbat_regvals(
181    &dbat,
182    #ifdef HAS_UBOOT
183      bsp_uboot_board_info.bi_flashstart,
184      bsp_uboot_board_info.bi_flashsize,
185    #else /* HAS_UBOOT */
186      (uint32_t) bsp_rom_start,
187      (uint32_t) bsp_rom_size,
188    #endif /* HAS_UBOOT */
189    #ifdef MPC83XX_HAS_NAND_LP_FLASH_ON_CS0
190      false,
191      true,
192      false,
193      true,
194      BPP_RW
195    #else
196      true,
197      false,
198      false,
199      false,
200      BPP_RX
201    #endif
202  );
203  SET_DBAT( 1, dbat.batu, dbat.batl);
204
205  calc_dbat_regvals(
206    &dbat,
207    #ifdef HAS_UBOOT
208      bsp_uboot_board_info.bi_immrbar,
209    #else /* HAS_UBOOT */
210      (uint32_t) IMMRBAR,
211    #endif /* HAS_UBOOT */
212    #if MPC83XX_CHIP_TYPE / 10 == 830
213      2 * 1024 * 1024,
214    #else
215      1024 * 1024,
216    #endif
217    false,
218    true,
219    false,
220    true,
221    BPP_RW
222  );
223  SET_DBAT( 2, dbat.batu, dbat.batl);
224
225#if defined(MPC83XX_BOARD_HSC_CM01)
226  calc_dbat_regvals(
227    &dbat,
228    FPGA_START,
229    FPGA_SIZE,
230    true,
231    true,
232    true,
233    false,
234    BPP_RW
235  );
236  SET_DBAT(3,dbat.batu,dbat.batl);
237#endif
238
239#ifdef MPC83XX_BOARD_MPC8313ERDB
240  /* Enhanced Local Bus Controller (eLBC) */
241  calc_dbat_regvals(
242    &dbat,
243    0xfa000000,
244    128 * 1024,
245    false,
246    true,
247    false,
248    true,
249    BPP_RW
250  );
251  SET_DBAT( 3, dbat.batu, dbat.batl);
252#endif /* MPC83XX_BOARD_MPC8313ERDB */
253
254  /* Read MSR */
255  msr = ppc_machine_state_register();
256
257  /* Enable data and instruction MMU in MSR */
258  msr |= MSR_DR | MSR_IR;
259
260  /* Enable FPU in MSR */
261  msr |= MSR_FP;
262
263  /* Update MSR */
264  ppc_set_machine_state_register( msr);
265
266  /*
267   * In HID0:
268   *  - Enable dynamic power management
269   *  - Enable machine check interrupts
270   */
271  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( HID0, HID0_EMCP | HID0_DPM);
272
273  /* Enable timebase clock */
274  mpc83xx.syscon.spcr |= M83xx_SYSCON_SPCR_TBEN;
275}
Note: See TracBrowser for help on using the repository browser.