Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsARMTMS570
0007  *
0008  * @brief This source file contains the bsp_start_hook_0() implementation.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2023 embedded brains GmbH & Co. KG
0013  * Copyright (C) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
0014  *
0015  * Czech Technical University in Prague
0016  * Zikova 1903/4
0017  * 166 36 Praha 6
0018  * Czech Republic
0019  *
0020  * Redistribution and use in source and binary forms, with or without
0021  * modification, are permitted provided that the following conditions
0022  * are met:
0023  * 1. Redistributions of source code must retain the above copyright
0024  *    notice, this list of conditions and the following disclaimer.
0025  * 2. Redistributions in binary form must reproduce the above copyright
0026  *    notice, this list of conditions and the following disclaimer in the
0027  *    documentation and/or other materials provided with the distribution.
0028  *
0029  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0030  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0032  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0033  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0034  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0035  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0036  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0037  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0038  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0039  * POSSIBILITY OF SUCH DAMAGE.
0040  */
0041 
0042 #include <stdint.h>
0043 #include <bsp.h>
0044 #include <bsp/start.h>
0045 #include <bsp/tms570.h>
0046 
0047 #include <bsp/tms570_selftest.h>
0048 #include <bsp/tms570_selftest_parity.h>
0049 #include <bsp/tms570_hwinit.h>
0050 #include <bsp/ti_herc/errata_SSWF021_45.h>
0051 
0052 #define PBIST_March13N_SP        0x00000008U  /**< March13 N Algo for 1 Port mem */
0053 
0054 /* Use assembly code to avoid using the stack */
0055 __attribute__((__naked__)) void bsp_start_hook_0( void )
0056 {
0057   __asm__ volatile (
0058     /* Check if we run in SRAM */
0059     "ldr r0, =#" RTEMS_XSTRING( TMS570_MEMORY_SRAM_ORIGIN ) "\n"
0060     "ldr r1, =#" RTEMS_XSTRING( TMS570_MEMORY_SRAM_SIZE ) "\n"
0061     "sub r0, lr, r0\n"
0062     "cmp r1, r0\n"
0063     "blt 1f\n"
0064 
0065     /*
0066      * Initialize the SRAM if we are not running in SRAM.  While we are called,
0067      * non-volatile register r7 is not used by start.S.
0068      */
0069     "movs r0, #0x1\n"
0070     "mov r7, lr\n"
0071     "bl tms570_memory_init\n"
0072     "mov lr, r7\n"
0073 
0074     /* Jump to the high level start hook */
0075     "1: b tms570_start_hook_0\n"
0076   );
0077 }
0078 
0079 static RTEMS_USED void tms570_start_hook_0( void )
0080 {
0081 #if TMS570_VARIANT == 3137
0082   /*
0083    * Work Around for Errata DEVICE#140: ( Only on Rev A silicon)
0084    *
0085    * Errata Description:
0086    *            The Core Compare Module(CCM-R4) may cause nERROR to be asserted after a cold power-on
0087    * Workaround:
0088    *            Clear ESM Group2 Channel 2 error in ESMSR2 and Compare error in CCMSR register
0089    */
0090   if ( TMS570_SYS1.DEVID == 0x802AAD05U ) {
0091     _esmCcmErrorsClear_();
0092   }
0093 #endif
0094 
0095 #if TMS570_VARIANT == 4357
0096   uint32_t pll_result;
0097 
0098   do {
0099     pll_result = _errata_SSWF021_45_both_plls(10);
0100   } while (pll_result != 0 && pll_result != 4);
0101 #endif
0102 
0103   /* Enable CPU Event Export */
0104   /* This allows the CPU to signal any single-bit or double-bit errors detected
0105    * by its ECC logic for accesses to program flash or data RAM.
0106    */
0107   _coreEnableEventBusExport_();
0108 
0109 #if TMS570_VARIANT == 3137
0110   /* Workaround for Errata CORTEXR4 66 */
0111   _errata_CORTEXR4_66_();
0112 
0113   /* Workaround for Errata CORTEXR4 57 */
0114   _errata_CORTEXR4_57_();
0115 #endif
0116 
0117   /*
0118    * Check if there were ESM group3 errors during power-up.
0119    * These could occur during eFuse auto-load or during reads from flash OTP
0120    * during power-up. Device operation is not reliable and not recommended
0121    * in this case.
0122    * An ESM group3 error only drives the nERROR pin low. An external circuit
0123    * that monitors the nERROR pin must take the appropriate action to ensure that
0124    * the system is placed in a safe state, as determined by the application.
0125    */
0126   if ( ( TMS570_ESM.SR[ 2 ] ) != 0U ) {
0127     /*SAFETYMCUSW 5 C MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
0128     /*SAFETYMCUSW 26 S MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
0129     /*SAFETYMCUSW 28 D MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
0130 #if TMS570_VARIANT == 4357
0131     /*
0132      * During code-loading/debug-resets SR[2][4] may get set (indicates double
0133      * ECC error in internal RAM) ignore for now as its resolved with ESM
0134      * init/reset below.
0135      */
0136     if ((TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_DBGRST) == 0) {
0137       for (;; ) {
0138       }           /* Wait */
0139     }
0140 #else
0141     for (;; ) {
0142     }           /* Wait */
0143 #endif
0144   }
0145 
0146   /* Initialize System - Clock, Flash settings with Efuse self check */
0147   tms570_system_hw_init();
0148 
0149   /* Workaround for Errata PBIST#4 */
0150   /* FIXME */
0151   //errata_PBIST_4();
0152 
0153   /*
0154    * Run a diagnostic check on the memory self-test controller.
0155    * This function chooses a RAM test algorithm and runs it on an on-chip ROM.
0156    * The memory self-test is expected to fail. The function ensures that the PBIST controller
0157    * is capable of detecting and indicating a memory self-test failure.
0158    */
0159   tms570_pbist_self_check();
0160 
0161   /* Run PBIST on STC ROM */
0162   tms570_pbist_run_and_check( (uint32_t) STC_ROM_PBIST_RAM_GROUP,
0163     ( (uint32_t) PBIST_TripleReadSlow | (uint32_t) PBIST_TripleReadFast ) );
0164 
0165   /* Run PBIST on PBIST ROM */
0166   tms570_pbist_run_and_check( (uint32_t) PBIST_ROM_PBIST_RAM_GROUP,
0167     ( (uint32_t) PBIST_TripleReadSlow | (uint32_t) PBIST_TripleReadFast ) );
0168 
0169   if ( !tms570_running_from_tcram() ) {
0170     /*
0171      * The next sequence tests TCRAM, main TMS570 system operation RAM area.
0172      * The tests are destructive, lead the first to fill memory by 0xc5c5c5c5
0173      * and then to clear it to zero. The sequence is obliviously incompatible
0174      * with RTEMS image running from TCRAM area (code clears itself).
0175      *
0176      * But TCRAM clear leads to overwrite of stack which is used to store
0177      * value of bsp_start_hook_0 call return address from link register.
0178      *
0179      * If the bsp_start_hook_0 by jump to bsp_start_hook_0_done
0180      * then generated C code does not use any variable which
0181      * is stores on stack and code works OK even that memory
0182      * is cleared during bsp_start_hook_0 execution.
0183      *
0184      * The last assumption is a little fragile in respect to
0185      * code and compiler changes.
0186      */
0187 
0188     /* Disable RAM ECC before doing PBIST for Main RAM */
0189     _coreDisableRamEcc_();
0190 
0191     /* Run PBIST on CPU RAM.
0192      * The PBIST controller needs to be configured separately for single-port and dual-port SRAMs.
0193      * The CPU RAM is a single-port memory. The actual "RAM Group" for all on-chip SRAMs is defined in the
0194      * device datasheet.
0195      */
0196     tms570_pbist_run_and_check( 0x08300020U,   /* ESRAM Single Port PBIST */
0197       (uint32_t) PBIST_March13N_SP );
0198 
0199     /*
0200      * Enable ECC checking for TCRAM accesses.
0201      * This function enables the CPU's ECC logic for accesses to B0TCM and B1TCM.
0202      */
0203     _coreEnableRamEcc_();
0204   } /* end of the code skipped for tms570_running_from_tcram() */
0205 
0206   /* Start PBIST on all dual-port memories */
0207   /* NOTE : Please Refer DEVICE DATASHEET for the list of Supported Dual port Memories.
0208      PBIST test performed only on the user selected memories in HALCoGen's GUI SAFETY INIT tab.
0209    */
0210   tms570_pbist_run( (uint32_t) 0x00000000U | /* EMAC RAM */
0211     (uint32_t) 0x00000000U |                 /* USB RAM */
0212     (uint32_t) 0x00000800U |                 /* DMA RAM */
0213     (uint32_t) 0x00000200U |                 /* VIM RAM */
0214     (uint32_t) 0x00000040U |                 /* MIBSPI1 RAM */
0215     (uint32_t) 0x00000080U |                 /* MIBSPI3 RAM */
0216     (uint32_t) 0x00000100U |                 /* MIBSPI5 RAM */
0217     (uint32_t) 0x00000004U |                 /* CAN1 RAM */
0218     (uint32_t) 0x00000008U |                 /* CAN2 RAM */
0219     (uint32_t) 0x00000010U |                 /* CAN3 RAM */
0220     (uint32_t) 0x00000400U |                 /* ADC1 RAM */
0221     (uint32_t) 0x00020000U |                 /* ADC2 RAM */
0222     (uint32_t) 0x00001000U |                 /* HET1 RAM */
0223     (uint32_t) 0x00040000U |                 /* HET2 RAM */
0224     (uint32_t) 0x00002000U |                 /* HTU1 RAM */
0225     (uint32_t) 0x00080000U |                 /* HTU2 RAM */
0226     (uint32_t) 0x00004000U |                 /* RTP RAM */
0227     (uint32_t) 0x00008000U,                  /* FRAY RAM */
0228     (uint32_t) PBIST_March13N_DP );
0229 
0230   if ( !tms570_running_from_tcram() ) {
0231 
0232 #if TMS570_VARIANT == 3137
0233     /* Test the CPU ECC mechanism for RAM accesses.
0234      * The checkBxRAMECC functions cause deliberate single-bit and double-bit errors in TCRAM accesses
0235      * by corrupting 1 or 2 bits in the ECC. Reading from the TCRAM location with a 2-bit error
0236      * in the ECC causes a data abort exception. The data abort handler is written to look for
0237      * deliberately caused exception and to return the code execution to the instruction
0238      * following the one that caused the abort.
0239      */
0240     tms570_check_tcram_ecc();
0241 #endif
0242 
0243     /* Wait for PBIST for CPU RAM to be completed */
0244     /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
0245     while ( tms570_pbist_is_test_completed() != TRUE ) {
0246     }                                                  /* Wait */
0247 
0248     /* Check if CPU RAM passed the self-test */
0249     if ( tms570_pbist_is_test_passed() != TRUE ) {
0250       /* CPU RAM failed the self-test.
0251        * Need custom handler to check the memory failure
0252        * and to take the appropriate next step.
0253        */
0254       tms570_pbist_fail();
0255     }
0256 
0257   } /* end of the code skipped for tms570_running_from_tcram() */
0258 
0259   /* Disable PBIST clocks and disable memory self-test mode */
0260   tms570_pbist_stop();
0261 
0262   /* Release the MibSPI1 modules from local reset.
0263    * This will cause the MibSPI1 RAMs to get initialized along with the parity memory.
0264    */
0265   TMS570_SPI1.GCR0 = TMS570_SPI_GCR0_nRESET;
0266 
0267   /* Release the MibSPI3 modules from local reset.
0268    * This will cause the MibSPI3 RAMs to get initialized along with the parity memory.
0269    */
0270   TMS570_SPI3.GCR0 = TMS570_SPI_GCR0_nRESET;
0271 
0272   /* Release the MibSPI5 modules from local reset.
0273    * This will cause the MibSPI5 RAMs to get initialized along with the parity memory.
0274    */
0275   TMS570_SPI5.GCR0 = TMS570_SPI_GCR0_nRESET;
0276 
0277   /* Enable parity on selected RAMs */
0278   tms570_enable_parity();
0279 
0280   /* Initialize all on-chip SRAMs except for MibSPIx RAMs
0281    * The MibSPIx modules have their own auto-initialization mechanism which is triggered
0282    * as soon as the modules are brought out of local reset.
0283    */
0284   /* The system module auto-init will hang on the MibSPI RAM if the module is still in local reset.
0285    */
0286   /* NOTE : Please Refer DEVICE DATASHEET for the list of Supported Memories and their channel numbers.
0287             Memory Initialization is perfomed only on the user selected memories in HALCoGen's GUI SAFETY INIT tab.
0288    */
0289   tms570_memory_init(
0290     ( UINT32_C(1) << 1 ) |                /* DMA RAM */
0291     ( UINT32_C(1) << 2 ) |                /* VIM RAM */
0292     ( UINT32_C(1) << 5 ) |                /* CAN1 RAM */
0293     ( UINT32_C(1) << 6 ) |                /* CAN2 RAM */
0294     ( UINT32_C(1) << 10 ) |               /* CAN3 RAM */
0295     ( UINT32_C(1) << 8 ) |                /* ADC1 RAM */
0296     ( UINT32_C(1) << 14 ) |               /* ADC2 RAM */
0297     ( UINT32_C(1) << 3 ) |                /* HET1 RAM */
0298     ( UINT32_C(1) << 4 ) |                /* HTU1 RAM */
0299     ( UINT32_C(1) << 15 ) |               /* HET2 RAM */
0300     ( UINT32_C(1) << 16 )                 /* HTU2 RAM */
0301   );
0302 
0303   /* Disable parity */
0304   tms570_disable_parity();
0305 
0306   /*
0307    * Test the parity protection mechanism for peripheral RAMs
0308    * Refer DEVICE DATASHEET for the list of Supported Memories
0309    * with parity.
0310    */
0311 
0312   tms570_selftest_par_run( tms570_selftest_par_list,
0313     tms570_selftest_par_list_size );
0314 
0315 #if 0
0316   /*
0317    * RTEMS VIM initialization is implemented by the function
0318    * bsp_interrupt_facility_initialize(). RTEMS does not
0319    * gain performance from use of vectors targets provided
0320    * directly by VIM. RTEMS require to route all interrupts
0321    * through _ARMV4_Exception_interrupt handler.
0322    *
0323    * But actual RTEMS VIM initialization lefts some registers
0324    * default values untouched. All registers values should be
0325    * ensured/configured in future probably.
0326    */
0327 
0328   /* Enable IRQ offset via Vic controller */
0329   _coreEnableIrqVicOffset_();
0330 
0331   /* Initialize VIM table */
0332   vimInit();
0333 #endif
0334 
0335   /* Configure system response to error conditions signaled to the ESM group1 */
0336   tms570_esm_init();
0337 
0338   tms570_emif_sdram_init();
0339 
0340   /* Configures and enables the ARM-core Memory Protection Unit (MPU) */
0341   _mpuInit_();
0342 
0343 #if 1
0344   /*
0345    * Do not depend on link register to be restored to
0346    * correct value from stack. If TCRAM self test is enabled
0347    * the all stack content is zeroed there.
0348    */
0349   bsp_start_hook_0_done();
0350 #endif
0351 }
0352 
0353 /*
0354  * Chip specific list of peripherals which should be tested
0355  * for functional RAM parity reporting
0356  */
0357 const tms570_selftest_par_desc_t *const
0358 tms570_selftest_par_list[] = {
0359   &tms570_selftest_par_het1_desc,
0360   &tms570_selftest_par_htu1_desc,
0361   &tms570_selftest_par_het2_desc,
0362   &tms570_selftest_par_htu2_desc,
0363   &tms570_selftest_par_adc1_desc,
0364   &tms570_selftest_par_adc2_desc,
0365   &tms570_selftest_par_can1_desc,
0366   &tms570_selftest_par_can2_desc,
0367   &tms570_selftest_par_can3_desc,
0368   &tms570_selftest_par_vim_desc,
0369   &tms570_selftest_par_dma_desc,
0370   &tms570_selftest_par_spi1_desc,
0371   &tms570_selftest_par_spi3_desc,
0372   &tms570_selftest_par_spi5_desc,
0373 };
0374 
0375 const int tms570_selftest_par_list_size =
0376   RTEMS_ARRAY_SIZE( tms570_selftest_par_list );