Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:04

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsARMLPC32XX
0007  *
0008  * @brief Startup code.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2009, 2013 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
0037 
0038 #include <bsp.h>
0039 #include <bsp/start.h>
0040 #include <bsp/lpc32xx.h>
0041 #include <bsp/mmu.h>
0042 #include <bsp/arm-cp15-start.h>
0043 #include <bsp/linker-symbols.h>
0044 #include <bsp/uart-output-char.h>
0045 
0046 #ifdef LPC32XX_DISABLE_READ_WRITE_DATA_CACHE
0047   #define LPC32XX_MMU_READ_WRITE_DATA LPC32XX_MMU_READ_WRITE
0048 #else
0049   #define LPC32XX_MMU_READ_WRITE_DATA LPC32XX_MMU_READ_WRITE_CACHED
0050 #endif
0051 
0052 #ifdef LPC32XX_DISABLE_READ_ONLY_PROTECTION
0053   #define LPC32XX_MMU_READ_ONLY_DATA LPC32XX_MMU_READ_WRITE_CACHED
0054   #define LPC32XX_MMU_CODE LPC32XX_MMU_READ_WRITE_CACHED
0055 #else
0056   #define LPC32XX_MMU_READ_ONLY_DATA LPC32XX_MMU_READ_ONLY_CACHED
0057   #define LPC32XX_MMU_CODE LPC32XX_MMU_READ_ONLY_CACHED
0058 #endif
0059 
0060 #ifndef LPC32XX_DISABLE_MMU
0061   static const BSP_START_DATA_SECTION arm_cp15_start_section_config
0062     lpc32xx_mmu_config_table [] = {
0063     {
0064       .begin = (uint32_t) bsp_section_fast_text_begin,
0065       .end = (uint32_t) bsp_section_fast_text_end,
0066       .flags = LPC32XX_MMU_CODE
0067     }, {
0068       .begin = (uint32_t) bsp_section_fast_data_begin,
0069       .end = (uint32_t) bsp_section_fast_data_end,
0070       .flags = LPC32XX_MMU_READ_WRITE_DATA
0071 #ifdef LPC32XX_SCRATCH_AREA_SIZE
0072     }, {
0073       .begin = (uint32_t) &lpc32xx_scratch_area [0],
0074       .end = (uint32_t) &lpc32xx_scratch_area [LPC32XX_SCRATCH_AREA_SIZE],
0075       .flags = LPC32XX_MMU_READ_ONLY_DATA
0076 #endif
0077     }, {
0078       .begin = (uint32_t) bsp_section_start_begin,
0079       .end = (uint32_t) bsp_section_start_end,
0080       .flags = LPC32XX_MMU_CODE
0081     }, {
0082       .begin = (uint32_t) bsp_section_vector_begin,
0083       .end = (uint32_t) bsp_section_vector_end,
0084       .flags = LPC32XX_MMU_READ_WRITE_CACHED
0085     }, {
0086       .begin = (uint32_t) bsp_section_text_begin,
0087       .end = (uint32_t) bsp_section_text_end,
0088       .flags = LPC32XX_MMU_CODE
0089     }, {
0090       .begin = (uint32_t) bsp_section_rodata_begin,
0091       .end = (uint32_t) bsp_section_rodata_end,
0092       .flags = LPC32XX_MMU_READ_ONLY_DATA
0093     }, {
0094       .begin = (uint32_t) bsp_section_data_begin,
0095       .end = (uint32_t) bsp_section_data_end,
0096       .flags = LPC32XX_MMU_READ_WRITE_DATA
0097     }, {
0098       .begin = (uint32_t) bsp_section_bss_begin,
0099       .end = (uint32_t) bsp_section_bss_end,
0100       .flags = LPC32XX_MMU_READ_WRITE_DATA
0101     }, {
0102       .begin = (uint32_t) bsp_section_work_begin,
0103       .end = (uint32_t) bsp_section_work_end,
0104       .flags = LPC32XX_MMU_READ_WRITE_DATA
0105     }, {
0106       .begin = (uint32_t) bsp_section_stack_begin,
0107       .end = (uint32_t) bsp_section_stack_end,
0108       .flags = LPC32XX_MMU_READ_WRITE_DATA
0109     }, {
0110       .begin = 0x0U,
0111       .end = 0x100000U,
0112       .flags = LPC32XX_MMU_READ_ONLY_CACHED
0113     }, {
0114       .begin = 0x20000000U,
0115       .end = 0x200c0000U,
0116       .flags = LPC32XX_MMU_READ_WRITE
0117     }, {
0118       .begin = 0x30000000U,
0119       .end = 0x32000000U,
0120       .flags = LPC32XX_MMU_READ_WRITE
0121     }, {
0122       .begin = 0x40000000U,
0123       .end = 0x40100000U,
0124       .flags = LPC32XX_MMU_READ_WRITE
0125     }, {
0126       .begin = (uint32_t) lpc32xx_magic_zero_begin,
0127       .end = (uint32_t) lpc32xx_magic_zero_end,
0128       .flags = LPC32XX_MMU_READ_WRITE_DATA
0129     }
0130   };
0131 #endif
0132 
0133 static BSP_START_TEXT_SECTION void setup_mmu_and_cache(void)
0134 {
0135   uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
0136     ARM_CP15_CTRL_I | ARM_CP15_CTRL_R | ARM_CP15_CTRL_C
0137       | ARM_CP15_CTRL_V | ARM_CP15_CTRL_M,
0138     ARM_CP15_CTRL_S | ARM_CP15_CTRL_A
0139   );
0140 
0141   arm_cp15_cache_invalidate();
0142 
0143   #ifndef LPC32XX_DISABLE_MMU
0144     arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
0145       ctrl,
0146       (uint32_t *) bsp_translation_table_base,
0147       LPC32XX_MMU_CLIENT_DOMAIN,
0148       &lpc32xx_mmu_config_table [0],
0149       RTEMS_ARRAY_SIZE(lpc32xx_mmu_config_table)
0150     );
0151   #endif
0152 }
0153 
0154 BSP_START_TEXT_SECTION bool lpc32xx_start_pll_setup(
0155   uint32_t hclkpll_ctrl,
0156   uint32_t hclkdiv_ctrl,
0157   bool force
0158 )
0159 {
0160   uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
0161   bool settings_ok =
0162     ((LPC32XX_HCLKPLL_CTRL ^ hclkpll_ctrl) & BSP_MSK32(1, 16)) == 0
0163       && ((LPC32XX_HCLKDIV_CTRL ^ hclkdiv_ctrl) & BSP_MSK32(0, 8)) == 0;
0164 
0165   if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) == 0 || (!settings_ok && force)) {
0166     /* Disable HCLK PLL output */
0167     LPC32XX_PWR_CTRL = pwr_ctrl & ~PWR_NORMAL_RUN_MODE;
0168 
0169     /* Configure HCLK PLL */
0170     LPC32XX_HCLKPLL_CTRL = hclkpll_ctrl;
0171     while ((LPC32XX_HCLKPLL_CTRL & HCLK_PLL_LOCK) == 0) {
0172       /* Wait */
0173     }
0174 
0175     /* Setup HCLK divider */
0176     LPC32XX_HCLKDIV_CTRL = hclkdiv_ctrl;
0177 
0178     /* Enable HCLK PLL output */
0179     LPC32XX_PWR_CTRL = pwr_ctrl | PWR_NORMAL_RUN_MODE;
0180   }
0181 
0182   return settings_ok;
0183 }
0184 
0185 #if LPC32XX_OSCILLATOR_MAIN != 13000000U
0186   #error "unexpected main oscillator frequency"
0187 #endif
0188 
0189 static BSP_START_TEXT_SECTION void setup_pll(void)
0190 {
0191   uint32_t hclkpll_ctrl = LPC32XX_HCLKPLL_CTRL_INIT_VALUE;
0192   uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL_INIT_VALUE;
0193 
0194   lpc32xx_start_pll_setup(hclkpll_ctrl, hclkdiv_ctrl, false);
0195 }
0196 
0197 BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
0198 {
0199   setup_pll();
0200 }
0201 
0202 static BSP_START_TEXT_SECTION void stop_dma_activities(void)
0203 {
0204   #ifdef LPC32XX_STOP_GPDMA
0205     LPC32XX_DO_STOP_GPDMA;
0206   #endif
0207 
0208   #ifdef LPC32XX_STOP_ETHERNET
0209     LPC32XX_DO_STOP_ETHERNET;
0210   #endif
0211 
0212   #ifdef LPC32XX_STOP_USB
0213     LPC32XX_DO_STOP_USB;
0214   #endif
0215 }
0216 
0217 static BSP_START_TEXT_SECTION void setup_uarts(void)
0218 {
0219   LPC32XX_UART_CTRL = 0x0;
0220   LPC32XX_UART_LOOP = 0x0;
0221 
0222   #ifdef LPC32XX_UART_5_BAUD
0223     LPC32XX_UARTCLK_CTRL |= 1U << 2;
0224     LPC32XX_U5CLK = LPC32XX_CONFIG_U5CLK;
0225     LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 8, 9);
0226     BSP_CONSOLE_UART_INIT(0x01);
0227   #endif
0228 }
0229 
0230 static BSP_START_TEXT_SECTION void setup_timer(void)
0231 {
0232   volatile lpc_timer *timer = LPC32XX_STANDARD_TIMER;
0233 
0234   LPC32XX_TIMCLK_CTRL1 = (1U << 2) | (1U << 3);
0235 
0236   timer->tcr = LPC_TIMER_TCR_RST;
0237   timer->ctcr = 0x0;
0238   timer->pr = 0x0;
0239   timer->ir = 0xff;
0240   timer->mcr = 0x0;
0241   timer->ccr = 0x0;
0242   timer->tcr = LPC_TIMER_TCR_EN;
0243 }
0244 
0245 BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
0246 {
0247   stop_dma_activities();
0248   bsp_start_copy_sections();
0249   setup_mmu_and_cache();
0250   setup_uarts();
0251   setup_timer();
0252   bsp_start_clear_bss();
0253 }