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

4.115
Last change on this file since c9562c5 was c9562c5, checked in by Sebastian Huber <sebastian.huber@…>, on 12/18/12 at 10:18:40

bsp/lpc32xx: Add UART_CLKMODE settings

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