Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-3-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsARMTMS570
0007  *
0008  * @brief This source file contains the selftest support implementation.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2023 embedded brains GmbH & Co. KG
0013  * Copyright (C) 2022 Airbus U.S. Space & Defense, Inc
0014  * Copyright (C) 2009-2015 Texas Instruments Incorporated - www.ti.com
0015  *
0016  *
0017  *  Redistribution and use in source and binary forms, with or without
0018  *  modification, are permitted provided that the following conditions
0019  *  are met:
0020  *
0021  *    Redistributions of source code must retain the above copyright
0022  *    notice, this list of conditions and the following disclaimer.
0023  *
0024  *    Redistributions in binary form must reproduce the above copyright
0025  *    notice, this list of conditions and the following disclaimer in the
0026  *    documentation and/or other materials provided with the
0027  *    distribution.
0028  *
0029  *    Neither the name of Texas Instruments Incorporated nor the names of
0030  *    its contributors may be used to endorse or promote products derived
0031  *    from this software without specific prior written permission.
0032  *
0033  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0034  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0035  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0036  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0037  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0038  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0039  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0040  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0041  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0042  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0043  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0044  *
0045  */
0046 
0047 #include <stdint.h>
0048 #include <stdbool.h>
0049 #include <stddef.h>
0050 #include <bsp/tms570.h>
0051 #include <bsp/tms570_selftest.h>
0052 #include <bsp/tms570_hwinit.h>
0053 
0054 /*
0055  * According to the TMS570LS3137 (HCLK max 180MHz, VCLK max 100MHz) and
0056  * TMS570LC4357 (GCLK1 max 300MHz, VCLK max 110MHz, HCLK max 150MHz)
0057  * datasheets, the PBIST ROM clock frequency is limited to 90MHz.
0058  *
0059  * For LS3137 PBIST ROM clock frequency = HCLK  / (1 << MSTGCR[9:8])
0060  *
0061  * For LC4357 PBIST ROM clock frequency = GCLK1 / (1 << MSTGCR[9:8])
0062  */
0063 #if TMS570_VARIANT == 4357
0064 #define MSTGCR_ENABLE_MEMORY_SELF_TEST 0x0000020a
0065 #define MSTGCR_DISABLE_MEMORY_SELF_TEST 0x00000205
0066 #define PBIST_RESET_DELAY (64 * 4)
0067 #else
0068 #define MSTGCR_ENABLE_MEMORY_SELF_TEST 0x0000010a
0069 #define MSTGCR_DISABLE_MEMORY_SELF_TEST 0x00000105
0070 #define PBIST_RESET_DELAY (32 * 2)
0071 #endif
0072 
0073 static void tms570_pbist_reset_delay( void )
0074 {
0075   for ( int i = 0; i < PBIST_RESET_DELAY; ++i ) {
0076     __asm__ volatile ( "" );
0077   }
0078 }
0079 
0080 /**
0081  * @brief Checks to see if the EFUSE Stuck at zero test is completed successfully (HCG:efcStuckZeroTest).
0082  /
0083  * @return 1 if EFUSE Stuck at zero test completed, otherwise 0.
0084  *
0085  * Checks to see if the EFUSE Stuck at zero test is completed successfully.
0086  */
0087 /* SourceId : SELFTEST_SourceId_012 */
0088 /* DesignId : SELFTEST_DesignId_014 */
0089 /* Requirements : HL_SR402 */
0090 bool tms570_efc_stuck_zero( void )
0091 {
0092   uint32_t esm_estatus4, esm_estatus1;
0093 
0094   bool result = false;
0095 
0096   uint32_t output_enable = TMS570_EFUSE_EFCBOUND_Self_Test_Error_OE |
0097                            TMS570_EFUSE_EFCBOUND_Single_Bit_Error_OE |
0098                            TMS570_EFUSE_EFCBOUND_Instruction_Error_OE |
0099                            TMS570_EFUSE_EFCBOUND_Autoload_Error_OE;
0100 
0101   uint32_t error_checks = TMS570_EFUSE_EFCBOUND_EFC_Single_Bit_Error |
0102                           TMS570_EFUSE_EFCBOUND_EFC_Instruction_Error |
0103                           TMS570_EFUSE_EFCBOUND_EFC_Autoload_Error |
0104                           TMS570_EFUSE_EFCBOUND_EFC_Self_Test_Error;
0105 
0106   /* configure the output enable for auto load error , instruction info,
0107        instruction error, and self test error using boundary register
0108        and drive values one across all the errors */
0109   TMS570_EFUSE.EFCBOUND = output_enable | error_checks;
0110 
0111   /* Read from the pin register. This register holds the current values
0112        of above errors. This value should be 0x5c00.If not at least one of
0113        the above errors is stuck at 0. */
0114   if ( ( TMS570_EFUSE.EFCPINS & 0x5C00U ) == 0x5C00U ) {
0115     esm_estatus4 = TMS570_ESM.SR4;
0116     esm_estatus1 = TMS570_ESM.SR[ 2U ];
0117 
0118     /* check if the ESM group1 channel 41 is set and group3 channel 1 is set */
0119     if ( ( ( esm_estatus4 & 0x200U ) == 0x200U ) &&
0120          ( ( esm_estatus1 & 0x2U ) == 0x2U ) ) {
0121       /* stuck-at-zero test passed */
0122       result = true;
0123     }
0124   }
0125 
0126   /* put the pins back low */
0127   TMS570_EFUSE.EFCBOUND = output_enable;
0128 
0129   /* clear group1 flag */
0130   TMS570_ESM.SR4 = 0x200U;
0131 
0132   /* clear group3 flag */
0133   TMS570_ESM.SR[ 2U ] = 0x2U;
0134 
0135   /* The nERROR pin will become inactive once the LTC counter expires */
0136   TMS570_ESM.EKR = 0x5U;
0137 
0138   return result;
0139 }
0140 
0141 /**
0142  * @brief EFUSE module self check Driver (HCG:efcSelfTest)
0143  *
0144  * This function self checks the EFSUE module.
0145  */
0146 /* SourceId : SELFTEST_SourceId_013 */
0147 /* DesignId : SELFTEST_DesignId_013 */
0148 /* Requirements : HL_SR402 */
0149 void tms570_efc_self_test( void )
0150 {
0151   /* configure self-test cycles */
0152   TMS570_EFUSE.EFC_ST_CY = 0x258U;
0153 
0154   /* configure self-test signature */
0155   TMS570_EFUSE.EFC_ST_SIG = 0x5362F97FU;
0156 
0157   /* configure boundary register to start ECC self-test */
0158   TMS570_EFUSE.EFCBOUND = 0x00002000 |
0159                           TMS570_EFUSE_EFCBOUND_Input_Enable( 0xF );
0160 }
0161 
0162 /**
0163  * @brief EFUSE module self check Driver (HCG:checkefcSelfTest)
0164  *
0165  * @return Returns TRUE if EFC Selftest was a PASS, else FALSE
0166  *
0167  * This function returns the status of efcSelfTest.
0168  * Note: This function can be called only after calling efcSelfTest
0169  */
0170 /* SourceId : SELFTEST_SourceId_014 */
0171 /* DesignId : SELFTEST_DesignId_015 */
0172 /* Requirements : HL_SR403 */
0173 bool tms570_efc_check_self_test( void )
0174 {
0175   bool result = false;
0176 
0177   uint32_t efc_pins, efc_error;
0178   uint32_t esmCh40Stat, esmCh41Stat = 0U;
0179 
0180   /* wait until EFC self-test is done */
0181   /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
0182   while ( ( TMS570_EFUSE.EFCPINS & TMS570_EFUSE_EFCPINS_EFC_Selftest_Done ) ==
0183           0U ) {
0184   }                                                                               /* Wait */
0185 
0186   /* check if EFC self-test error occurred */
0187   efc_pins = TMS570_EFUSE.EFCPINS;
0188   efc_error = TMS570_EFUSE.EFC_ERR_STAT;
0189 
0190   if ( ( ( efc_pins & TMS570_EFUSE_EFCPINS_EFC_Selftest_Error ) == 0U ) &&
0191        ( ( efc_error & 0x1FU ) == 0U ) ) {
0192     /* check if EFC self-test error is set */
0193     esmCh40Stat = TMS570_ESM.SR4 & 0x100U;
0194     esmCh41Stat = TMS570_ESM.SR4 & 0x200U;
0195 
0196     if ( ( esmCh40Stat == 0U ) && ( esmCh41Stat == 0U ) ) {
0197       result = true;
0198     }
0199   }
0200 
0201   return result;
0202 }
0203 
0204 /**
0205  * @brief EFUSE module self check Driver (HCG:efcCheck)
0206  * @return Returns 0 if no error was detected during autoload and Stuck At Zero Test passed
0207  *                 1 if no error was detected during autoload but Stuck At Zero Test failed
0208  *                 2 if there was a single-bit error detected during autoload
0209  *                 3 if some other error occurred during autoload
0210  *
0211  *   This function self checks the EFUSE module.
0212  */
0213 /* SourceId : SELFTEST_SourceId_011 */
0214 /* DesignId : SELFTEST_DesignId_012 */
0215 /* Requirements : HL_SR402 */
0216 uint32_t tms570_efc_check( void )
0217 {
0218   uint32_t efc_status = 0U;
0219   uint32_t status;
0220 
0221   /* read the EFC Error Status Register */
0222   efc_status = TMS570_EFUSE.EFC_ERR_STAT;
0223 
0224   if ( efc_status == 0x0U ) {
0225     /* run stuck-at-zero test and check if it passed */
0226     if ( tms570_efc_stuck_zero() == true ) {
0227       /* start EFC ECC logic self-test */
0228       tms570_efc_self_test();
0229       status = 0U;
0230     } else {
0231       /* EFC output is stuck-at-zero, device operation unreliable */
0232       bsp_selftest_fail_notification( EFCCHECK_FAIL1 );
0233       status = 1U;
0234     }
0235   }
0236   /* EFC Error Register is not zero */
0237   else {
0238     /* one-bit error detected during autoload */
0239     if ( efc_status == 0x15U ) {
0240       /* start EFC ECC logic self-test */
0241       tms570_efc_self_test();
0242       status = 2U;
0243     } else {
0244       /* Some other EFC error was detected */
0245       bsp_selftest_fail_notification( EFCCHECK_FAIL1 );
0246       status = 3U;
0247     }
0248   }
0249 
0250   return status;
0251 }
0252 
0253 /**
0254  * @brief PBIST self test Driver (HCG:pbistSelfCheck)
0255  *
0256  * This function is called to perform PBIST self test.
0257  */
0258 /* SourceId : SELFTEST_SourceId_005 */
0259 /* DesignId : SELFTEST_DesignId_005 */
0260 /* Requirements : HL_SR399 */
0261 void tms570_pbist_self_check( void )
0262 {
0263   uint32_t          PBIST_wait_done_loop = 0U;
0264 
0265   /* Run a diagnostic check on the memory self-test controller */
0266   /* First set up the PBIST ROM clock as this clock frequency is limited to 90MHz */
0267 
0268   /* Disable PBIST clocks and ROM clock */
0269   TMS570_PBIST.PACT = 0x0U;
0270 
0271   /* Disable memory self controller */
0272   TMS570_SYS1.MSTGCR = MSTGCR_DISABLE_MEMORY_SELF_TEST;
0273 
0274   /* Disable Memory Initialization controller */
0275   TMS570_SYS1.MINITGCR = 0x5U;
0276 
0277   /* Enable memory self controller */
0278   TMS570_SYS1.MSTGCR = MSTGCR_ENABLE_MEMORY_SELF_TEST;
0279 
0280   /* Clear PBIST Done */
0281   TMS570_SYS1.MSTCGSTAT = 0x1U;
0282 
0283   /* Enable PBIST controller */
0284   TMS570_SYS1.MSIENA = 0x1U;
0285 
0286   tms570_pbist_reset_delay();
0287 
0288   /* Enable PBIST clocks and ROM clock */
0289   TMS570_PBIST.PACT = 0x1U;
0290 
0291   /* CPU control of PBIST */
0292   TMS570_PBIST.DLR = 0x10U;
0293 
0294   /* Custom always fail algo, this will not use the ROM and just set a fail */
0295   TMS570_PBIST.RAMT = 0x00002000U;
0296   *(volatile uint32_t *) 0xFFFFE400U = 0x4C000001U;
0297   *(volatile uint32_t *) 0xFFFFE440U = 0x00000075U;
0298   *(volatile uint32_t *) 0xFFFFE404U = 0x4C000002U;
0299   *(volatile uint32_t *) 0xFFFFE444U = 0x00000075U;
0300   *(volatile uint32_t *) 0xFFFFE408U = 0x4C000003U;
0301   *(volatile uint32_t *) 0xFFFFE448U = 0x00000075U;
0302   *(volatile uint32_t *) 0xFFFFE40CU = 0x4C000004U;
0303   *(volatile uint32_t *) 0xFFFFE44CU = 0x00000075U;
0304   *(volatile uint32_t *) 0xFFFFE410U = 0x4C000005U;
0305   *(volatile uint32_t *) 0xFFFFE450U = 0x00000075U;
0306   *(volatile uint32_t *) 0xFFFFE414U = 0x4C000006U;
0307   *(volatile uint32_t *) 0xFFFFE454U = 0x00000075U;
0308   *(volatile uint32_t *) 0xFFFFE418U = 0x00000000U;
0309   *(volatile uint32_t *) 0xFFFFE458U = 0x00000001U;
0310 
0311   /* PBIST_RUN */
0312   ( &TMS570_PBIST.DLR )[ 2 ] = 1;
0313 
0314   /* wait until memory self-test done is indicated */
0315   /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
0316   while ( ( TMS570_SYS1.MSTCGSTAT & 0x1U ) != 0x1U )
0317     PBIST_wait_done_loop++;
0318 
0319   /* Wait */
0320 
0321   /* Check for the failure */
0322   if ( ( TMS570_PBIST.FSRF0 & 0x1U ) != 0x1U ) {
0323     /* No failure was indicated even if the always fail algorithm was run*/
0324     bsp_selftest_fail_notification( PBISTSELFCHECK_FAIL1 );
0325   } else {
0326     /* Check that the algorithm executed in the expected amount of time. */
0327     /* This time is dependent on the ROMCLKDIV selected above            */
0328     if ( PBIST_wait_done_loop >= 2U ) {
0329       bsp_selftest_fail_notification( PBISTSELFCHECK_FAIL2 );
0330     }
0331 
0332     /* Disable PBIST clocks and ROM clock */
0333     TMS570_PBIST.PACT = 0x0U;
0334 
0335     /* Disable PBIST */
0336     TMS570_SYS1.MSTGCR &= 0xFFFFFFF0U;
0337     TMS570_SYS1.MSTGCR |= 0x5U;
0338   }
0339 }
0340 
0341 /**
0342  * @brief CPU self test Driver (HCG:pbistRun)
0343  * @param[in] raminfoL   - Select the list of RAM to be tested.
0344  * @param[in] algomask   - Select the list of Algorithm to be run.
0345  *
0346  * This function performs Memory Built-in Self test using PBIST module.
0347  */
0348 /* SourceId : SELFTEST_SourceId_006 */
0349 /* DesignId : SELFTEST_DesignId_006 */
0350 /* Requirements : HL_SR400 */
0351 void tms570_pbist_run(
0352   uint32_t raminfoL,
0353   uint32_t algomask
0354 )
0355 {
0356   /* Disable memory self controller */
0357   TMS570_SYS1.MSTGCR = MSTGCR_DISABLE_MEMORY_SELF_TEST;
0358 
0359   /* Disable Memory Initialization controller */
0360   TMS570_SYS1.MINITGCR = 0x5U;
0361 
0362   /* Enable PBIST controller */
0363   TMS570_SYS1.MSIENA = 0x1U;
0364 
0365   /* Enable memory self controller */
0366   TMS570_SYS1.MSTGCR = MSTGCR_ENABLE_MEMORY_SELF_TEST;
0367 
0368   tms570_pbist_reset_delay();
0369 
0370   /* Enable PBIST clocks and ROM clock */
0371   TMS570_PBIST.PACT = 0x1U;
0372 
0373   /* Select all algorithms to be tested */
0374   TMS570_PBIST.ALGO = algomask;
0375 
0376   /* Select RAM groups */
0377   TMS570_PBIST.RINFOL = raminfoL;
0378 
0379   /* Select all RAM groups */
0380   TMS570_PBIST.RINFOUL = 0x00000000U;
0381 
0382   /* ROM contents will not override RINFOx settings */
0383   TMS570_PBIST.OVER = 0x0U;
0384 
0385   /* Algorithm code is loaded from ROM */
0386   TMS570_PBIST.ROM = 0x3U;
0387 
0388   /* Start PBIST */
0389   TMS570_PBIST.DLR = 0x14U;
0390 }
0391 
0392 /**
0393  *  @brief Routine to stop PBIST test enabled (HCG:pbistStop)
0394  *
0395  *  This function is called to stop PBIST after test is performed.
0396  */
0397 /* SourceId : SELFTEST_SourceId_007 */
0398 /* DesignId : SELFTEST_DesignId_007 */
0399 /* Requirements : HL_SR523 */
0400 void tms570_pbist_stop( void )
0401 {
0402   /* disable pbist clocks and ROM clock */
0403   TMS570_PBIST.PACT = 0x0U;
0404   TMS570_SYS1.MSTGCR &= 0xFFFFFFF0U;
0405   TMS570_SYS1.MSTGCR |= 0x5U;
0406 }
0407 
0408 /**
0409  * @brief Checks to see if the PBIST test is completed (HCG:pbistIsTestCompleted)
0410  * @return 1 if PBIST test completed, otherwise 0.
0411  *
0412  * Checks to see if the PBIST test is completed.
0413  */
0414 /* SourceId : SELFTEST_SourceId_008 */
0415 /* DesignId : SELFTEST_DesignId_008 */
0416 /* Requirements : HL_SR401 */
0417 bool tms570_pbist_is_test_completed( void )
0418 {
0419   return ( ( TMS570_SYS1.MSTCGSTAT & 0x1U ) != 0U );
0420 }
0421 
0422 /**
0423  * @brief Checks to see if the PBIST test is completed successfully (HCG:pbistIsTestPassed)
0424  * @return 1 if PBIST test passed, otherwise 0.
0425  *
0426  * Checks to see if the PBIST test is completed successfully.
0427  */
0428 /* SourceId : SELFTEST_SourceId_009 */
0429 /* DesignId : SELFTEST_DesignId_009 */
0430 /* Requirements : HL_SR401 */
0431 bool tms570_pbist_is_test_passed( void )
0432 {
0433   bool status;
0434 
0435   if ( TMS570_PBIST.FSRF0 == 0U ) {
0436     status = true;
0437   } else {
0438     status = false;
0439   }
0440 
0441   return status;
0442 }
0443 
0444 /**
0445  * Helper method that will run a pbist test and blocks until it finishes
0446  * Reduces code duplication in start system start hooks
0447  */
0448 void tms570_pbist_run_and_check(uint32_t raminfoL, uint32_t algomask)
0449 {
0450   /* Run PBIST on region */
0451   tms570_pbist_run(raminfoL, algomask);
0452 
0453   /* Wait for PBIST for region to be completed */
0454   /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
0455   while (!tms570_pbist_is_test_completed()) {
0456   }                                                  /* Wait */
0457 
0458   /* Check if PBIST on region passed the self-test */
0459   if (!tms570_pbist_is_test_passed()) {
0460     /* PBIST and region failed the self-test.
0461      * Need custom handler to check the memory failure
0462      * and to take the appropriate next step.
0463      */
0464     tms570_pbist_fail();
0465   }
0466 
0467   /* Disable PBIST clocks and disable memory self-test mode */
0468   tms570_pbist_stop();
0469 }
0470 
0471 /**
0472  * @brief Checks to see if the PBIST Port test is completed successfully (HCG:pbistPortTestStatus)
0473  * @param[in] port   - Select the port to get the status.
0474  * @return 1 if PBIST Port test completed successfully, otherwise 0.
0475  *
0476  * Checks to see if the selected PBIST Port test is completed successfully.
0477  */
0478 /* SourceId : SELFTEST_SourceId_010 */
0479 /* DesignId : SELFTEST_DesignId_010 */
0480 /* Requirements : HL_SR401 */
0481 bool tms570_pbist_port_test_status( uint32_t port )
0482 {
0483   bool status;
0484 
0485   if ( port == (uint32_t) PBIST_PORT0 ) {
0486     status = ( TMS570_PBIST.FSRF0 == 0U );
0487   } else {
0488     /* Invalid Input */
0489     status = false;
0490   }
0491 
0492   return status;
0493 }
0494 
0495 /**
0496  * @brief Reaction to PBIST failure (HCG:pbistFail)
0497  *
0498  * @return Void.
0499  */
0500 /* SourceId : SELFTEST_SourceId_042 */
0501 /* DesignId : SELFTEST_DesignId_011 */
0502 /* Requirements : HL_SR401 */
0503 void tms570_pbist_fail( void )
0504 {
0505   uint32_t PBIST_RAMT, PBIST_FSRA0, PBIST_FSRDL0;
0506 
0507   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
0508   PBIST_RAMT = TMS570_PBIST.RAMT;
0509   PBIST_FSRA0 = TMS570_PBIST.FSRA0;
0510   PBIST_FSRDL0 = TMS570_PBIST.FSRDL0;
0511 
0512   if ( tms570_pbist_port_test_status( (uint32_t) PBIST_PORT0 ) != true ) {
0513     uint32_t groupSelect = ( PBIST_RAMT & 0xFF000000U ) >> 24U;
0514     uint32_t dataSelect = ( PBIST_RAMT & 0x00FF0000U ) >> 16U;
0515     uint32_t address = PBIST_FSRA0;
0516     uint32_t data = PBIST_FSRDL0;
0517     tms570_memory_port0_fail_notification( groupSelect,
0518       dataSelect,
0519       address,
0520       data );
0521   } else {
0522 /*SAFETYMCUSW 5 C MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
0523 /*SAFETYMCUSW 26 S MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
0524 /*SAFETYMCUSW 28 D MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
0525     for (;; ) {
0526     }           /* Wait */
0527   }
0528 }
0529 
0530 /**
0531  * @brief Memory Initialization Driver (HCG:memoryInit)
0532  *
0533  * This function is called to perform Memory initialization of selected RAM's.
0534  */
0535 /* SourceId : SELFTEST_SourceId_002 */
0536 /* DesignId : SELFTEST_DesignId_004 */
0537 /* Requirements : HL_SR396 */
0538 __attribute__((__naked__)) void tms570_memory_init( uint32_t ram )
0539 {
0540   __asm__ volatile (
0541     /* Load memory controller base address */
0542     "ldr r1, =#0xffffff00\n"
0543     /* Enable Memory Hardware Initialization (MINITGCR) */
0544     "movs r2, #0xa\n"
0545     "str r2, [r1, #0x5c]\n"
0546     /* Enable Memory Hardware Initialization for selected RAM's (MSIENA) */
0547     "str r0, [r1, #0x60]\n"
0548     /* Wait until Memory Hardware Initialization completes (MSTCGSTAT) */
0549     /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
0550     "1: ldr r2, [r1, #0x68]\n"
0551     "tst r2, #0x100\n"
0552     "beq 1b\n"
0553     /* Disable Memory Hardware Initialization (MINITGCR) */
0554     "movs r2, #0x5\n"
0555     "str r2, [r1, #0x5c]\n"
0556     /* Return */
0557     "bx lr\n"
0558   );
0559 }
0560 
0561 volatile uint32_t *const
0562 tms570_esm_group_channel_to_sr_table[ 4 ][ 2 ] = {
0563   { NULL, NULL },
0564   { &TMS570_ESM.SR[ 0 ], &TMS570_ESM.SR4 },
0565   { &TMS570_ESM.SR[ 1 ], NULL },
0566   { &TMS570_ESM.SR[ 2 ], NULL },
0567 };
0568 
0569 /**
0570  * @brief Routine to clear specified error channel signalling bit
0571  * @param[in] grp   - ESM error channels group
0572  * @param[in] chan  - ESM error channel number inside specified group
0573  */
0574 void tms570_esm_channel_sr_clear(
0575   unsigned grp,
0576   unsigned chan
0577 )
0578 {
0579   volatile uint32_t *sr_reg;
0580 
0581   sr_reg = tms570_esm_group_channel_to_sr_table[ grp ][ chan >> 5 ];
0582 
0583   if ( sr_reg != NULL )
0584     *sr_reg = 1 << (chan & 0x1f);
0585 }
0586 
0587 /** tms570_esm_channel_sr_get
0588  * @brief Routine to test is specified error channel is signalling error
0589  * @param[in] grp   - ESM error channels group
0590  * @param[in] chan  - ESM error channel number inside specified group
0591  */
0592 int tms570_esm_channel_sr_get(
0593   unsigned grp,
0594   unsigned chan
0595 )
0596 {
0597   volatile uint32_t *sr_reg;
0598 
0599   sr_reg = tms570_esm_group_channel_to_sr_table[ grp ][ chan >> 5 ];
0600 
0601   if ( sr_reg != NULL )
0602     return *sr_reg & ( 1 << ( chan & 0x1f ) );
0603   else
0604     return 0;
0605 }
0606 
0607 /**
0608  * @brief Enable peripheral RAM parity (HCG:enableParity)
0609  *
0610  * This function enables RAM parity for all peripherals for which RAM parity check is enabled.
0611  * This function is called before memoryInit in the startup
0612  *
0613  */
0614 void tms570_enable_parity( void )
0615 {
0616   TMS570_DMA.DMAPCR = 0xAU;                   /* Enable DMA RAM parity */
0617   TMS570_VIM.PARCTL = 0xAU;                   /* Enable VIM RAM parity */
0618   TMS570_DCAN1.CTL = ((uint32_t)0xAU << 10U) | 1U; /* Enable CAN1 RAM parity */
0619   TMS570_DCAN2.CTL = ((uint32_t)0xAU << 10U) | 1U; /* Enable CAN2 RAM parity */
0620   TMS570_DCAN3.CTL = ((uint32_t)0xAU << 10U) | 1U; /* Enable CAN3 RAM parity */
0621   TMS570_ADC1.PARCR = 0xAU;                   /* Enable ADC1 RAM parity */
0622   TMS570_ADC2.PARCR = 0xAU;                   /* Enable ADC2 RAM parity */
0623   TMS570_NHET1.PCR  = 0xAU;                   /* Enable HET1 RAM parity */
0624   TMS570_HTU1.PCR   = 0xAU;                   /* Enable HTU1 RAM parity */
0625   TMS570_NHET2.PCR  = 0xAU;                   /* Enable HET2 RAM parity */
0626   TMS570_HTU2.PCR   = 0xAU;                   /* Enable HTU2 RAM parity */
0627 }
0628 
0629 /**
0630  * @brief Disable peripheral RAM parity (HCG:disableParity)
0631  *
0632  * This function disables RAM parity for all peripherals for which RAM parity check is enabled.
0633  * This function is called after memoryInit in the startup
0634  *
0635  */
0636 void tms570_disable_parity( void )
0637 {
0638   TMS570_DMA.DMAPCR = 0x5U;                   /* Disable DMA RAM parity */
0639   TMS570_VIM.PARCTL = 0x5U;                   /* Disable VIM RAM parity */
0640   TMS570_DCAN1.CTL = ((uint32_t)0x5U << 10U) | 1U; /* Disable CAN1 RAM parity */
0641   TMS570_DCAN2.CTL = ((uint32_t)0x5U << 10U) | 1U; /* Disable CAN2 RAM parity */
0642   TMS570_DCAN3.CTL = ((uint32_t)0x5U << 10U) | 1U; /* Disable CAN3 RAM parity */
0643   TMS570_ADC1.PARCR = 0x5U;                   /* Disable ADC1 RAM parity */
0644   TMS570_ADC2.PARCR = 0x5U;                   /* Disable ADC2 RAM parity */
0645   TMS570_NHET1.PCR  = 0x5U;                   /* Disable HET1 RAM parity */
0646   TMS570_HTU1.PCR   = 0x5U;                   /* Disable HTU1 RAM parity */
0647   TMS570_NHET2.PCR  = 0x5U;                   /* Disable HET2 RAM parity */
0648   TMS570_HTU2.PCR   = 0x5U;                   /* Disable HTU2 RAM parity */
0649 }