fsl_xecc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright 2019-2020 NXP
  3. * All rights reserved.
  4. *
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_xecc.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.xecc"
  15. #endif
  16. /*******************************************************************************
  17. * Prototypes
  18. ******************************************************************************/
  19. /*******************************************************************************
  20. * Variables
  21. ******************************************************************************/
  22. /*******************************************************************************
  23. * Code
  24. ******************************************************************************/
  25. /*!
  26. * brief XECC module initialization function.
  27. *
  28. * param base XECC base address.
  29. */
  30. void XECC_Init(XECC_Type *base, const xecc_config_t *config)
  31. {
  32. /* Enable all the interrupt status */
  33. base->ERR_STAT_EN = kXECC_AllInterruptsStatusEnable;
  34. /* Clear all the interrupt status */
  35. base->ERR_STATUS = kXECC_AllInterruptsFlag;
  36. /* Disable all the interrpt */
  37. base->ERR_SIG_EN = 0U;
  38. /* Set ECC regions, which are 4KB aligned */
  39. base->ECC_BASE_ADDR0 = config->Region0BaseAddress >> 12U;
  40. base->ECC_END_ADDR0 = config->Region0EndAddress >> 12U;
  41. base->ECC_BASE_ADDR1 = config->Region1BaseAddress >> 12U;
  42. base->ECC_END_ADDR1 = config->Region1EndAddress >> 12U;
  43. base->ECC_BASE_ADDR2 = config->Region2BaseAddress >> 12U;
  44. base->ECC_END_ADDR2 = config->Region2EndAddress >> 12U;
  45. base->ECC_BASE_ADDR3 = config->Region3BaseAddress >> 12U;
  46. base->ECC_END_ADDR3 = config->Region3EndAddress >> 12U;
  47. /* Enable ECC function */
  48. base->ECC_CTRL = XECC_ECC_CTRL_ECC_EN(config->enableXECC);
  49. base->ECC_CTRL |= XECC_ECC_CTRL_WECC_EN(config->enableWriteECC);
  50. base->ECC_CTRL |= XECC_ECC_CTRL_RECC_EN(config->enableReadECC);
  51. base->ECC_CTRL |= XECC_ECC_CTRL_SWAP_EN(config->enableSwap);
  52. /* Make sure XECC register configuration operation has been done. */
  53. __DSB();
  54. }
  55. /*!
  56. * brief Deinitializes the XECC.
  57. *
  58. */
  59. void XECC_Deinit(XECC_Type *base)
  60. {
  61. /* Disable ECC function */
  62. base->ECC_CTRL &= ~XECC_ECC_CTRL_ECC_EN(1);
  63. }
  64. void XECC_GetDefaultConfig(xecc_config_t *config)
  65. {
  66. assert(NULL != config);
  67. /* Initializes the configure structure to zero. */
  68. (void)memset(config, 0, sizeof(*config));
  69. /* Default XECC function */
  70. config->enableXECC = false;
  71. /* Default write ECC function */
  72. config->enableWriteECC = false;
  73. /* Default read ECC function */
  74. config->enableReadECC = false;
  75. /* Default swap function */
  76. config->enableSwap = false;
  77. /* ECC region 0 base address */
  78. config->Region0BaseAddress = 0U;
  79. /* ECC region 0 end address */
  80. config->Region0EndAddress = 0U;
  81. /* ECC region 1 base address */
  82. config->Region1BaseAddress = 0U;
  83. /* ECC region 1 end address */
  84. config->Region1EndAddress = 0U;
  85. /* ECC region 2 base address */
  86. config->Region2BaseAddress = 0U;
  87. /* ECC region 2 end address */
  88. config->Region2EndAddress = 0U;
  89. /* ECC region 3 base address */
  90. config->Region3BaseAddress = 0U;
  91. /* ECC region 3 end address */
  92. config->Region3EndAddress = 0U;
  93. }
  94. /* Mainly use for debug, it can be deprecated when release */
  95. status_t XECC_ErrorInjection(XECC_Type *base, uint32_t errordata, uint8_t erroreccdata)
  96. {
  97. status_t status = kStatus_Success;
  98. if ((errordata != 0x00U) || (erroreccdata != 0x00U))
  99. {
  100. /* error data injection */
  101. base->ERR_DATA_INJ = errordata;
  102. /* error ecc code injection */
  103. base->ERR_ECC_INJ = erroreccdata;
  104. /* Make sure injection operation has been done. */
  105. __DSB();
  106. }
  107. else
  108. {
  109. status = kStatus_Fail;
  110. }
  111. return status;
  112. }
  113. void XECC_GetSingleErrorInfo(XECC_Type *base, xecc_single_error_info_t *info)
  114. {
  115. assert(info != NULL);
  116. info->singleErrorAddress = base->SINGLE_ERR_ADDR;
  117. info->singleErrorData = base->SINGLE_ERR_DATA;
  118. info->singleErrorEccCode = base->SINGLE_ERR_ECC;
  119. info->singleErrorBitField = base->SINGLE_ERR_BIT_FIELD;
  120. info->singleErrorBitPos = base->SINGLE_ERR_POS;
  121. }
  122. void XECC_GetMultiErrorInfo(XECC_Type *base, xecc_multi_error_info_t *info)
  123. {
  124. assert(info != NULL);
  125. info->multiErrorAddress = base->MULTI_ERR_ADDR;
  126. info->multiErrorData = base->MULTI_ERR_DATA;
  127. info->multiErrorEccCode = base->MULTI_ERR_ECC;
  128. info->multiErrorBitField = base->MULTI_ERR_BIT_FIELD;
  129. }