source: rtems/c/src/lib/libbsp/arm/lpc32xx/startup/bspstarthooks.c @ 6daba81

4.115
Last change on this file since 6daba81 was 3103d4cb, checked in by Sebastian Huber <sebastian.huber@…>, on 06/23/10 at 08:27:57

2010-06-23 Sebastian Huber <sebastian.huber@…>

  • make/custom/lpc32xx_mzx_boot_int.cfg, startup/linkcmds.lpc32xx_mzx_boot_int: Removed files.
  • include/boot.h, include/emc.h, include/i2c.h, include/nand-mlc.h, make/custom/lpc32xx_mzx.cfg, make/custom/lpc32xx_mzx_stage_1.cfg, make/custom/lpc32xx_mzx_stage_2.cfg, misc/boot.c, misc/emc.c, misc/i2c.c, misc/nand-mlc.c, misc/nand-mlc-read-blocks.c, misc/nand-mlc-write-blocks.c, misc/restart.c, startup/linkcmds.lpc32xx, startup/linkcmds.lpc32xx_mzx, startup/linkcmds.lpc32xx_mzx_stage_1, startup/linkcmds.lpc32xx_mzx_stage_2: New files.
  • configure.ac, Makefile.am, preinstall.am: Reflect changes above.
  • include/bsp.h, include/lpc32xx.h, irq/irq.c, rtc/rtc-config.c, startup/bspstart.c, startup/bspstarthooks.c, startup/linkcmds.lpc32xx_phycore: Changes throughout.
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc32xx
5 *
6 * @brief Startup code.
7 */
8
9/*
10 * Copyright (c) 2009
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.com/license/LICENSE.
20 */
21
22#include <stdbool.h>
23
24#include <bspopts.h>
25#include <bsp/start.h>
26#include <bsp/lpc32xx.h>
27#include <bsp/mmu.h>
28#include <bsp/linker-symbols.h>
29#include <bsp/uart-output-char.h>
30
31#ifdef LPC32XX_DISABLE_READ_WRITE_DATA_CACHE
32  #define LPC32XX_MMU_READ_WRITE_DATA LPC32XX_MMU_READ_WRITE
33#else
34  #define LPC32XX_MMU_READ_WRITE_DATA LPC32XX_MMU_READ_WRITE_CACHED
35#endif
36
37#ifdef LPC32XX_DISABLE_READ_ONLY_PROTECTION
38  #define LPC32XX_MMU_READ_ONLY_DATA LPC32XX_MMU_READ_WRITE_CACHED
39  #define LPC32XX_MMU_CODE LPC32XX_MMU_READ_WRITE_CACHED
40#else
41  #define LPC32XX_MMU_READ_ONLY_DATA LPC32XX_MMU_READ_ONLY_CACHED
42  #define LPC32XX_MMU_CODE LPC32XX_MMU_READ_ONLY_CACHED
43#endif
44
45LINKER_SYMBOL(lpc32xx_translation_table_base);
46
47static void BSP_START_SECTION clear_bss(void)
48{
49  const int *end = (const int *) bsp_section_bss_end;
50  int *out = (int *) bsp_section_bss_begin;
51
52  /* Clear BSS */
53  while (out != end) {
54    *out = 0;
55    ++out;
56  }
57}
58
59#ifndef LPC32XX_DISABLE_MMU
60  typedef struct {
61    uint32_t begin;
62    uint32_t end;
63    uint32_t flags;
64  } lpc32xx_mmu_config;
65
66  static const BSP_START_DATA_SECTION lpc32xx_mmu_config
67    lpc32xx_mmu_config_table [] = {
68    {
69      .begin = (uint32_t) bsp_section_start_begin,
70      .end = (uint32_t) bsp_section_start_end,
71      .flags = LPC32XX_MMU_CODE
72    }, {
73      .begin = (uint32_t) bsp_section_vector_begin,
74      .end = (uint32_t) bsp_section_vector_end,
75      .flags = LPC32XX_MMU_READ_WRITE_CACHED
76    }, {
77      .begin = (uint32_t) bsp_section_text_begin,
78      .end = (uint32_t) bsp_section_text_end,
79      .flags = LPC32XX_MMU_CODE
80    }, {
81      .begin = (uint32_t) bsp_section_rodata_begin,
82      .end = (uint32_t) bsp_section_rodata_end,
83      .flags = LPC32XX_MMU_READ_ONLY_DATA
84    }, {
85      .begin = (uint32_t) bsp_section_data_begin,
86      .end = (uint32_t) bsp_section_data_end,
87      .flags = LPC32XX_MMU_READ_WRITE_DATA
88    }, {
89      .begin = (uint32_t) bsp_section_fast_begin,
90      .end = (uint32_t) bsp_section_fast_end,
91      .flags = LPC32XX_MMU_CODE
92    }, {
93      .begin = (uint32_t) bsp_section_bss_begin,
94      .end = (uint32_t) bsp_section_bss_end,
95      .flags = LPC32XX_MMU_READ_WRITE_DATA
96    }, {
97      .begin = (uint32_t) bsp_section_work_begin,
98      .end = (uint32_t) bsp_section_work_end,
99      .flags = LPC32XX_MMU_READ_WRITE_DATA
100    }, {
101      .begin = (uint32_t) bsp_section_stack_begin,
102      .end = (uint32_t) bsp_section_stack_end,
103      .flags = LPC32XX_MMU_READ_WRITE_DATA
104    }, {
105      .begin = 0x0U,
106      .end = 0x100000U,
107      .flags = LPC32XX_MMU_READ_ONLY_CACHED
108    }, {
109      .begin = 0x20000000U,
110      .end = 0x200c0000U,
111      .flags = LPC32XX_MMU_READ_WRITE
112    }, {
113      .begin = 0x30000000U,
114      .end = 0x32000000U,
115      .flags = LPC32XX_MMU_READ_WRITE
116    }, {
117      .begin = 0x40000000U,
118      .end = 0x40100000U,
119      .flags = LPC32XX_MMU_READ_WRITE
120    }, {
121      .begin = (uint32_t) lpc32xx_magic_zero_begin,
122      .end = (uint32_t) lpc32xx_magic_zero_end,
123      .flags = LPC32XX_MMU_READ_WRITE_DATA
124    }
125  };
126
127  static void BSP_START_SECTION set_translation_table_entries(
128    uint32_t *ttb,
129    const lpc32xx_mmu_config *config
130  )
131  {
132    uint32_t i = ARM_MMU_SECT_GET_INDEX(config->begin);
133    uint32_t iend =
134      ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(config->end));
135
136    if (config->begin != config->end) {
137      while (i < iend) {
138        ttb [i] = (i << ARM_MMU_SECT_BASE_SHIFT) | config->flags;
139        ++i;
140      }
141    }
142  }
143
144  static void BSP_START_SECTION
145    setup_translation_table_and_enable_mmu(uint32_t ctrl)
146  {
147    uint32_t const dac =
148      ARM_CP15_DAC_DOMAIN(LPC32XX_MMU_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT);
149    uint32_t *const ttb = (uint32_t *) lpc32xx_translation_table_base;
150    size_t const config_entry_count =
151      sizeof(lpc32xx_mmu_config_table) / sizeof(lpc32xx_mmu_config_table [0]);
152    size_t i = 0;
153
154    arm_cp15_set_domain_access_control(dac);
155    arm_cp15_set_translation_table_base(ttb);
156
157    /* Initialize translation table with invalid entries */
158    for (i = 0; i < ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT; ++i) {
159      ttb [i] = 0;
160    }
161
162    for (i = 0; i < config_entry_count; ++i) {
163      set_translation_table_entries(ttb, &lpc32xx_mmu_config_table [i]);
164    }
165
166    /* Enable MMU and cache */
167    ctrl |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M;
168    arm_cp15_set_control(ctrl);
169  }
170#endif
171
172static void BSP_START_SECTION setup_mmu_and_cache(void)
173{
174  uint32_t ctrl = 0;
175
176  /* Disable MMU and cache, basic settings */
177  ctrl = arm_cp15_get_control();
178  ctrl &= ~(ARM_CP15_CTRL_I | ARM_CP15_CTRL_R | ARM_CP15_CTRL_C
179    | ARM_CP15_CTRL_V | ARM_CP15_CTRL_M);
180  ctrl |= ARM_CP15_CTRL_S | ARM_CP15_CTRL_A;
181  arm_cp15_set_control(ctrl);
182
183  arm_cp15_cache_invalidate();
184  arm_cp15_tlb_invalidate();
185
186  #ifndef LPC32XX_DISABLE_MMU
187    setup_translation_table_and_enable_mmu(ctrl);
188  #endif
189}
190
191#if LPC32XX_OSCILLATOR_MAIN != 13000000U
192  #error "unexpected main oscillator frequency"
193#endif
194
195static void BSP_START_SECTION setup_pll(void)
196{
197  uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
198
199  if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) == 0) {
200    /* Enable HCLK PLL */
201    LPC32XX_HCLKPLL_CTRL = HCLK_PLL_POWER | HCLK_PLL_DIRECT | HCLK_PLL_M(16 - 1);
202    while ((LPC32XX_HCLKPLL_CTRL & HCLK_PLL_LOCK) == 0) {
203      /* Wait */
204    }
205
206    /* Setup HCLK divider */
207    LPC32XX_HCLKDIV_CTRL = HCLK_DIV_HCLK(2 - 1) | HCLK_DIV_PERIPH_CLK(16 - 1);
208
209    /* Enable HCLK PLL output */
210    LPC32XX_PWR_CTRL = pwr_ctrl | PWR_NORMAL_RUN_MODE;
211  }
212}
213
214void BSP_START_SECTION bsp_start_hook_0(void)
215{
216  setup_pll();
217  setup_mmu_and_cache();
218}
219
220static void BSP_START_SECTION setup_uarts(void)
221{
222  uint32_t uartclk_ctrl = 0;
223
224  #ifdef LPC32XX_CONFIG_U3CLK
225    uartclk_ctrl |= 1U << 0;
226    LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK;
227  #endif
228  #ifdef LPC32XX_CONFIG_U4CLK
229    uartclk_ctrl |= 1U << 1;
230    LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK;
231  #endif
232  #ifdef LPC32XX_CONFIG_U5CLK
233    uartclk_ctrl |= 1U << 2;
234    LPC32XX_U5CLK = LPC32XX_CONFIG_U5CLK;
235  #endif
236  #ifdef LPC32XX_CONFIG_U6CLK
237    uartclk_ctrl |= 1U << 3;
238    LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK;
239  #endif
240
241  #ifdef LPC32XX_CONFIG_UART_CLKMODE
242    LPC32XX_UART_CLKMODE = LPC32XX_CONFIG_UART_CLKMODE;
243  #endif
244
245  LPC32XX_UARTCLK_CTRL = uartclk_ctrl;
246  LPC32XX_UART_CTRL = 0x0;
247  LPC32XX_UART_LOOP = 0x0;
248
249  #ifdef LPC32XX_CONFIG_U5CLK
250    /* Clock is already set in LPC32XX_U5CLK */
251    BSP_CONSOLE_UART_INIT(0x01);
252  #endif
253}
254
255static void BSP_START_SECTION setup_timer(void)
256{
257  volatile lpc_timer *timer = LPC32XX_STANDARD_TIMER;
258
259  LPC32XX_TIMCLK_CTRL1 = (1U << 2) | (1U << 3);
260
261  timer->tcr = LPC_TIMER_TCR_RST;
262  timer->ctcr = 0x0;
263  timer->pr = 0x0;
264  timer->ir = 0xff;
265  timer->mcr = 0x0;
266  timer->ccr = 0x0;
267  timer->tcr = LPC_TIMER_TCR_EN;
268}
269
270void BSP_START_SECTION bsp_start_hook_1(void)
271{
272  setup_uarts();
273  setup_timer();
274
275  /* Copy .text section */
276  arm_cp15_instruction_cache_invalidate();
277  bsp_start_memcpy(
278    (int *) bsp_section_text_begin,
279    (const int *) bsp_section_text_load_begin,
280    (size_t) bsp_section_text_size
281  );
282
283  /* Copy .rodata section */
284  arm_cp15_instruction_cache_invalidate();
285  bsp_start_memcpy(
286    (int *) bsp_section_rodata_begin,
287    (const int *) bsp_section_rodata_load_begin,
288    (size_t) bsp_section_rodata_size
289  );
290
291  /* Copy .data section */
292  arm_cp15_instruction_cache_invalidate();
293  bsp_start_memcpy(
294    (int *) bsp_section_data_begin,
295    (const int *) bsp_section_data_load_begin,
296    (size_t) bsp_section_data_size
297  );
298
299  /* Copy .fast section */
300  arm_cp15_instruction_cache_invalidate();
301  bsp_start_memcpy(
302    (int *) bsp_section_fast_begin,
303    (const int *) bsp_section_fast_load_begin,
304    (size_t) bsp_section_fast_size
305  );
306
307  /* Clear .bss section */
308  clear_bss();
309
310  /* At this point we can use objects outside the .start section */
311}
Note: See TracBrowser for help on using the repository browser.