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