Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsPowerPCMPC55XX
0007  *
0008  * @brief Early initialization code.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2008, 2012 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 #include <bsp/mpc55xx-config.h>
0037 #include <bsp/linker-symbols.h>
0038 
0039 /* This function is defined in start.S */
0040 BSP_START_TEXT_SECTION void mpc55xx_start_load_section(
0041   void *dst,
0042   const void *src,
0043   size_t n
0044 );
0045 
0046 static BSP_START_TEXT_SECTION void mpc55xx_start_mmu(void)
0047 {
0048   #ifdef MPC55XX_BOOTFLAGS
0049     /* If the low bit of bootflag 0 is clear don't change the MMU.  */
0050     bool do_mmu_config = (mpc55xx_bootflag_0 [0] & 1) != 0;
0051   #else
0052     bool do_mmu_config = true;
0053   #endif
0054 
0055   if (do_mmu_config) {
0056     mpc55xx_start_mmu_apply_config(
0057       &mpc55xx_start_config_mmu [0],
0058       mpc55xx_start_config_mmu_count [0]
0059     );
0060   }
0061 }
0062 
0063 static BSP_START_TEXT_SECTION void mpc55xx_start_internal_ram(void)
0064 {
0065   #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
0066     /* Initialize internal SRAM to zero (ECC) */
0067     bsp_start_zero(
0068       (char *) bsp_ram_start + MPC55XX_EARLY_STACK_SIZE,
0069       (size_t) bsp_ram_size - MPC55XX_EARLY_STACK_SIZE
0070     );
0071     #ifdef MPC55XX_HAS_SECOND_INTERNAL_RAM_AREA
0072       bsp_start_zero(&bsp_ram_1_start [0], (size_t) bsp_ram_1_size);
0073     #endif
0074   #else
0075     bsp_start_zero(
0076       bsp_section_sbss_begin,
0077       (size_t) bsp_section_sbss_size
0078     );
0079     bsp_start_zero(
0080       bsp_section_bss_begin,
0081       (size_t) bsp_section_bss_size
0082     );
0083   #endif
0084 }
0085 
0086 static BSP_START_TEXT_SECTION void mpc55xx_start_load_nocache_section(void)
0087 {
0088   mpc55xx_start_load_section(
0089     bsp_section_nocache_begin,
0090     bsp_section_nocache_load_begin,
0091     (size_t) bsp_section_nocache_size
0092   );
0093   rtems_cache_flush_multiple_data_lines(
0094     bsp_section_nocache_begin,
0095     (size_t) bsp_section_nocache_size
0096   );
0097 }
0098 
0099 static BSP_START_TEXT_SECTION void mpc55xx_start_mode_change(void)
0100 {
0101   #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
0102     #ifdef MPC55XX_HAS_MODE_CONTROL
0103       uint32_t mctl_key1 = 0x5af0;
0104       uint32_t mctl_key2 = 0xa50f;
0105       int i = 0;
0106 
0107       /* Clear any pending RGM status */
0108       RGM.FES.R = 0xffff;
0109       RGM.DES.R = 0xffff;
0110 
0111       /* Make sure XOSC and PLLs are on in RUN0 state */
0112       ME.DRUN_MC.R = 0x001f0074;
0113       ME.RUN_MC [0].R = 0x001f0074;
0114 
0115       /*
0116        * Make sure all peripherals are active in DRUN and RUN0 state.
0117        *
0118        * FIXME: This might be optimized to reduce power consumtion.
0119        */
0120       for (i = 0; i < 8; ++i) {
0121         ME_RUN_PC_32B_tag run_pc = { .R = ME.RUN_PC [i].R };
0122 
0123         run_pc.B.DRUN = 1;
0124         run_pc.B.RUN0 = 1;
0125 
0126         ME.RUN_PC [i].R = run_pc.R;
0127       }
0128 
0129       /* Switch to RUN0 state */
0130       ME.MCTL.R = 0x40000000 | mctl_key1;
0131       ME.MCTL.R = 0x40000000 | mctl_key2;
0132 
0133       while (ME.GS.B.S_MTRANS) {
0134         /* Wait for mode switch to be completed */
0135       }
0136     #endif
0137   #endif
0138 }
0139 
0140 static BSP_START_TEXT_SECTION void mpc55xx_start_siu(void)
0141 {
0142   size_t i = 0;
0143 
0144   for (i = 0; i < mpc55xx_start_config_siu_pcr_count [0]; ++i) {
0145      const mpc55xx_siu_pcr_config *e = &mpc55xx_start_config_siu_pcr [i];
0146      int j = e->index;
0147      int n = j + e->count;
0148      uint8_t gpdo = e->output;
0149      uint16_t pcr = e->pcr.R;
0150 
0151      while (j < n) {
0152        SIU.GPDO [j].R = gpdo;
0153        SIU.PCR [j].R = pcr;
0154        ++j;
0155      }
0156   }
0157 }
0158 
0159 static BSP_START_TEXT_SECTION void mpc55xx_start_ebi_chip_select(void)
0160 {
0161   #ifdef MPC55XX_HAS_EBI
0162     size_t i = 0;
0163 
0164     for (i = 0; i < mpc55xx_start_config_ebi_cs_count [0]; ++i) {
0165       EBI.CS [i] = mpc55xx_start_config_ebi_cs [i];
0166     }
0167 
0168     for (i = 0; i < mpc55xx_start_config_ebi_cal_cs_count [0]; ++i) {
0169       EBI.CAL_CS [i] = mpc55xx_start_config_ebi_cal_cs [i];
0170     }
0171   #endif
0172 }
0173 
0174 static BSP_START_TEXT_SECTION void mpc55xx_start_ebi(void)
0175 {
0176   #ifdef MPC55XX_HAS_EBI
0177     size_t i = 0;
0178 
0179     for (i = 0; i < mpc55xx_start_config_ebi_count [0]; ++i) {
0180       SIU.ECCR.B.EBDF = mpc55xx_start_config_ebi [i].siu_eccr_ebdf;
0181       EBI.MCR.R = mpc55xx_start_config_ebi [i].ebi_mcr.R;
0182     }
0183   #endif
0184 }
0185 
0186 #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
0187 static BSP_START_TEXT_SECTION bool
0188 mpc55xx_start_is_in_internal_ram(const void *addr)
0189 {
0190   return (size_t) addr - (size_t) bsp_ram_start < (size_t) bsp_ram_size;
0191 }
0192 #endif
0193 
0194 static BSP_START_TEXT_SECTION void mpc55xx_start_clear_bss(void)
0195 {
0196   #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
0197     if (!mpc55xx_start_is_in_internal_ram(bsp_section_sbss_begin)) {
0198       bsp_start_zero(
0199         bsp_section_sbss_begin,
0200         (size_t) bsp_section_sbss_size
0201       );
0202     }
0203 
0204     if (!mpc55xx_start_is_in_internal_ram(bsp_section_bss_begin)) {
0205       bsp_start_zero(
0206         bsp_section_bss_begin,
0207         (size_t) bsp_section_bss_size
0208       );
0209     }
0210   #endif
0211 }
0212 
0213 BSP_START_TEXT_SECTION void mpc55xx_start_early(void)
0214 {
0215   mpc55xx_start_watchdog();
0216   mpc55xx_start_clock();
0217   mpc55xx_start_flash();
0218   #if defined(BSP_DATA_CACHE_ENABLED) || defined(BSP_INSTRUCTION_CACHE_ENABLED)
0219     mpc55xx_start_cache();
0220   #endif
0221   mpc55xx_start_internal_ram();
0222   mpc55xx_start_load_nocache_section();
0223   mpc55xx_start_mmu();
0224   mpc55xx_start_mode_change();
0225   mpc55xx_start_siu();
0226   mpc55xx_start_ebi_chip_select();
0227   mpc55xx_start_ebi();
0228   mpc55xx_start_clear_bss();
0229 }