Ticket #2003: cpuinit.c

File cpuinit.c, 11.6 KB (added by ktaylan, on Feb 1, 2012 at 5:48:02 AM)

CPU init. functions in gen5200 bsps

Line 
1/*===============================================================*\
2| Project: RTEMS generic MPC5200 BSP                              |
3+-----------------------------------------------------------------+
4| Partially based on the code references which are named below.   |
5| Adaptions, modifications, enhancements and any recent parts of  |
6| the code are:                                                   |
7|                    Copyright (c) 2005                           |
8|                    Embedded Brains GmbH                         |
9|                    Obere Lagerstr. 30                           |
10|                    D-82178 Puchheim                             |
11|                    Germany                                      |
12|                    rtems@embedded-brains.de                     |
13+-----------------------------------------------------------------+
14| The license and distribution terms for this file may be         |
15| found in the file LICENSE in this distribution or at            |
16|                                                                 |
17| http://www.rtems.com/license/LICENSE.                           |
18|                                                                 |
19+-----------------------------------------------------------------+
20| this file contains the code to initialize the cpu               |
21\*===============================================================*/
22/***********************************************************************/
23/*                                                                     */
24/*   Module:       cpuinit.c                                           */
25/*   Date:         07/17/2003                                          */
26/*   Purpose:      RTEMS MPC5x00 C level startup code                  */
27/*                                                                     */
28/*---------------------------------------------------------------------*/
29/*                                                                     */
30/*   Description:  This file contains additional functions for         */
31/*                 initializing the MPC5x00 CPU                        */
32/*                                                                     */
33/*---------------------------------------------------------------------*/
34/*                                                                     */
35/*   Code                                                              */
36/*   References:   MPC8260ads additional CPU initialization            */
37/*   Module:       cpuinit.c                                           */
38/*   Project:      RTEMS 4.6.0pre1 / MCF8260ads BSP                    */
39/*   Version       1.1                                                 */
40/*   Date:         10/22/2002                                          */
41/*                                                                     */
42/*   Author(s) / Copyright(s):                                         */
43/*                                                                     */
44/*   Written by Jay Monkman (jmonkman@frasca.com)                      */
45/*                                                                     */
46/*---------------------------------------------------------------------*/
47/*                                                                     */
48/*   Partially based on the code references which are named above.     */
49/*   Adaptions, modifications, enhancements and any recent parts of    */
50/*   the code are under the right of                                   */
51/*                                                                     */
52/*         IPR Engineering, Dachauer Straße 38, D-80335 München        */
53/*                        Copyright(C) 2003                            */
54/*                                                                     */
55/*---------------------------------------------------------------------*/
56/*                                                                     */
57/*   IPR Engineering makes no representation or warranties with        */
58/*   respect to the performance of this computer program, and          */
59/*   specifically disclaims any responsibility for any damages,        */
60/*   special or consequential, connected with the use of this program. */
61/*                                                                     */
62/*---------------------------------------------------------------------*/
63/*                                                                     */
64/*   Version history:  1.0                                             */
65/*                                                                     */
66/***********************************************************************/
67
68#include <stdbool.h>
69#include <string.h>
70
71#include <libcpu/powerpc-utility.h>
72#include <libcpu/mmu.h>
73
74#include <bsp.h>
75#include <bsp/mpc5200.h>
76
77#define SET_DBAT( n, uv, lv) \
78  do { \
79    PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##L, lv); \
80    PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##U, uv); \
81  } while (0)
82
83#define SET_IBAT( n, uv, lv) \
84  do { \
85    PPC_SET_SPECIAL_PURPOSE_REGISTER( IBAT##n##L, lv); \
86    PPC_SET_SPECIAL_PURPOSE_REGISTER( IBAT##n##U, uv); \
87  } while (0)
88
89static void calc_dbat_regvals(
90  BAT *bat_ptr,
91  uint32_t base_addr,
92  uint32_t size,
93  bool flg_w,
94  bool flg_i,
95  bool flg_m,
96  bool flg_g,
97  uint32_t flg_bpp
98)
99{
100  uint32_t block_mask = 0xffffffff;
101  uint32_t end_addr = base_addr + size - 1;
102
103  /* Determine block mask, that overlaps the whole block */
104  while ((end_addr & block_mask) != (base_addr & block_mask)) {
105    block_mask <<= 1;
106  }
107
108  bat_ptr->batu.bepi = base_addr >> (32 - 15);
109  bat_ptr->batu.bl   = ~(block_mask >> (28 - 11));
110  bat_ptr->batu.vs   = 1;
111  bat_ptr->batu.vp   = 1;
112
113  bat_ptr->batl.brpn = base_addr  >> (32 - 15);
114  bat_ptr->batl.w    = flg_w;
115  bat_ptr->batl.i    = flg_i;
116  bat_ptr->batl.m    = flg_m;
117  bat_ptr->batl.g    = flg_g;
118  bat_ptr->batl.pp   = flg_bpp;
119}
120
121static void calc_ibat_regvals(
122  BAT *bat_ptr,
123  uint32_t base_addr,
124  uint32_t size,
125  bool flg_w,
126  bool flg_i,
127  bool flg_m,
128  bool flg_g,
129  uint32_t flg_bpp
130)
131{
132  uint32_t block_mask = 0xffffffff;
133  uint32_t end_addr = base_addr + size - 1;
134
135  /* Determine block mask, that overlaps the whole block */
136  while ((end_addr & block_mask) != (base_addr & block_mask)) {
137    block_mask <<= 1;
138  }
139
140  bat_ptr->batu.bepi = base_addr >> (32 - 15);
141  bat_ptr->batu.bl   = ~(block_mask >> (28 - 11));
142  bat_ptr->batu.vs   = 1;
143  bat_ptr->batu.vp   = 1;
144
145  bat_ptr->batl.brpn = base_addr  >> (32 - 15);
146  bat_ptr->batl.w    = flg_w;
147  bat_ptr->batl.i    = flg_i;
148  bat_ptr->batl.m    = flg_m;
149  bat_ptr->batl.g    = flg_g;
150  bat_ptr->batl.pp   = flg_bpp;
151}
152
153#if defined (BRS5L)
154void cpu_init_bsp(void)
155{
156  BAT dbat;
157
158  calc_dbat_regvals(
159    &dbat,
160    (uint32_t) bsp_ram_start,
161    (uint32_t) bsp_ram_size,
162    true,
163    false,
164    false,
165    false,
166    BPP_RW
167  );
168  SET_DBAT(0,dbat.batu,dbat.batl);
169
170  calc_dbat_regvals(
171    &dbat,
172    (uint32_t) bsp_rom_start,
173    (uint32_t) bsp_rom_size,
174    true,
175    false,
176    false,
177    false,
178    BPP_RX
179  );
180  SET_DBAT(1,dbat.batu,dbat.batl);
181
182  calc_dbat_regvals(
183    &dbat,
184    (uint32_t) MBAR,
185    128 * 1024,
186    false,
187    true,
188    false,
189    true,
190    BPP_RW
191  );
192  SET_DBAT(2,dbat.batu,dbat.batl);
193
194  calc_dbat_regvals(
195    &dbat,
196    (uint32_t) bsp_dpram_start,
197    128 * 1024,
198    false,
199    true,
200    false,
201    true,
202    BPP_RW
203  );
204  SET_DBAT(3,dbat.batu,dbat.batl);
205}
206#elif defined (HAS_UBOOT)
207void cpu_init_bsp(void)
208{
209  BAT dbat;
210  uint32_t start = 0;
211
212  /*
213   * Program BAT0 for RAM
214   */
215  calc_dbat_regvals(
216    &dbat,
217    bsp_uboot_board_info.bi_memstart,
218    bsp_uboot_board_info.bi_memsize,
219    true,
220    false,
221    false,
222    false,
223    BPP_RW
224  );
225  SET_DBAT(0,dbat.batu,dbat.batl);
226
227  /*
228   * Program BAT1 for Flash
229   *
230   * WARNING!! Some Freescale LITE5200B boards ship with a version of
231   * U-Boot that lies about the starting address of Flash.  This check
232   * corrects that.
233   */
234  if ((bsp_uboot_board_info.bi_flashstart + bsp_uboot_board_info.bi_flashsize)
235    < bsp_uboot_board_info.bi_flashstart) {
236    start = 0 - bsp_uboot_board_info.bi_flashsize;
237  } else {
238    start = bsp_uboot_board_info.bi_flashstart;
239  }
240  calc_dbat_regvals(
241    &dbat,
242    start,
243    bsp_uboot_board_info.bi_flashsize,
244    true,
245    false,
246    false,
247    false,
248    BPP_RX
249  );
250  SET_DBAT(1,dbat.batu,dbat.batl);
251
252  /*
253   * Program BAT2 for the MBAR
254   */
255  calc_dbat_regvals(
256    &dbat,
257    (uint32_t) MBAR,
258    128 * 1024,
259    false,
260    true,
261    false,
262    true,
263    BPP_RW
264  );
265  SET_DBAT(2,dbat.batu,dbat.batl);
266
267  /*
268   * If there is SRAM, program BAT3 for that memory
269   */
270  if (bsp_uboot_board_info.bi_sramsize != 0) {
271    calc_dbat_regvals(
272      &dbat,
273      bsp_uboot_board_info.bi_sramstart,
274      bsp_uboot_board_info.bi_sramsize,
275      false,
276      true,
277      true,
278      true,
279      BPP_RW
280    );
281    SET_DBAT(3,dbat.batu,dbat.batl);
282  }
283}
284#elif defined (PCM032)
285void cpu_init_bsp(void)
286{
287          BAT dbat;
288          BAT ibat;
289
290          calc_dbat_regvals(
291            &dbat,
292            (uint32_t) bsp_ram_start,
293            (uint32_t) bsp_ram_size,
294            false,
295            false,
296            false,
297            false,
298            BPP_RW
299          );
300          SET_DBAT(0,dbat.batu,dbat.batl);
301
302          calc_ibat_regvals(
303            &ibat,
304            (uint32_t) bsp_ram_start,
305            (uint32_t) bsp_ram_size,
306            false,
307            false,
308            false,
309            false,
310            BPP_RW
311          );
312          SET_IBAT(0,ibat.batu,ibat.batl);
313
314          calc_dbat_regvals(
315            &dbat,
316            (uint32_t) bsp_rom_start,
317            (uint32_t) bsp_rom_size,
318            false,
319            true,
320            false,
321            false,
322            BPP_RX
323          );
324          SET_DBAT(1,dbat.batu,dbat.batl);
325
326          calc_ibat_regvals(
327            &ibat,
328            (uint32_t) bsp_rom_start,
329            (uint32_t) bsp_rom_size,
330            false,
331            false,
332            false,
333            false,
334            BPP_RX
335          );
336          SET_IBAT(1,ibat.batu,ibat.batl);
337
338          calc_dbat_regvals(
339            &dbat,
340            (uint32_t) MBAR,
341            128 * 1024,
342            false,
343            true,
344            false,
345            false,
346            BPP_RW
347          );
348          SET_DBAT(2,dbat.batu,dbat.batl);
349
350          calc_ibat_regvals(
351            &ibat,
352            (uint32_t) MBAR,
353            128 * 1024,
354            false,
355            true,
356            false,
357            false,
358            BPP_RW
359          );
360          SET_IBAT(2,ibat.batu,ibat.batl);
361
362          calc_dbat_regvals(
363            &dbat,
364            (uint32_t) bsp_dpram_start,
365            128 * 1024,
366            false,
367            true,
368            false,
369            false,
370            BPP_RW
371          );
372          SET_DBAT(3,dbat.batu,dbat.batl);
373
374          calc_ibat_regvals(
375            &ibat,
376            (uint32_t) bsp_dpram_start,
377            128 * 1024,
378            false,
379            false,
380            false,
381            false,
382            BPP_RW
383          );
384          SET_IBAT(3,ibat.batu,ibat.batl);
385
386}
387#else
388#warning "Using BAT register values set by environment"
389#endif
390
391void cpu_init(void)
392{
393  uint32_t msr;
394
395  /* Set up DBAT registers in MMU */
396  cpu_init_bsp();
397
398  /* Read MSR */
399  msr = ppc_machine_state_register();
400
401  /* Enable instruction MMU in MSR */
402  msr |= MSR_IR;
403
404  /* Update MSR */
405  ppc_set_machine_state_register(msr);
406
407  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( HID0, HID0_ICE | HID0_ICFI);
408  PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(HID0, HID0_ICFI);
409
410  #if defined(SHOW_MORE_INIT_SETTINGS)
411    { extern void ShowBATS(void);
412      ShowBATS();
413    }
414  #endif
415
416  /* Read MSR */
417  msr = ppc_machine_state_register();
418
419  /* Enable data MMU in MSR */
420  msr |= MSR_DR;
421
422  /* Update MSR */
423  ppc_set_machine_state_register( msr);
424
425  /*
426   * Enable data cache.
427   *
428   * NOTE: TRACE32 now supports data cache for MGT5x00.
429   */
430  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( HID0, HID0_DCE);
431}