]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_ecc.c
Added project for Altera Cyclone V SoC, currently running from internal RAM.
[freertos] / FreeRTOS / Demo / CORTEX_A9_Cyclone_V_SoC_DK / Altera_Code / HardwareLibrary / alt_ecc.c
1 /******************************************************************************\r
2  *\r
3  * Copyright 2013 Altera Corporation. All Rights Reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions are met:\r
7  *\r
8  * 1. Redistributions of source code must retain the above copyright notice,\r
9  * this list of conditions and the following disclaimer.\r
10  *\r
11  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
12  * this list of conditions and the following disclaimer in the documentation\r
13  * and/or other materials provided with the distribution.\r
14  *\r
15  * 3. The name of the author may not be used to endorse or promote products\r
16  * derived from this software without specific prior written permission.\r
17  *\r
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR\r
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO\r
21  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
23  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
26  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
27  * OF SUCH DAMAGE.\r
28  *\r
29  ******************************************************************************/\r
30 \r
31 #include <stdio.h>\r
32 #include "alt_ecc.h"\r
33 #include "socal/alt_sysmgr.h"\r
34 #include "socal/hps.h"\r
35 #include "socal/socal.h"\r
36 \r
37 /////\r
38 \r
39 // NOTE: To enable debugging output, delete the next line and uncomment the\r
40 //   line after.\r
41 #define dprintf(...)\r
42 // #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)\r
43 \r
44 /////\r
45 \r
46 #ifndef ALT_MMU_SMALL_PAGE_SIZE\r
47 #define ALT_MMU_SMALL_PAGE_SIZE (4 * 1024)\r
48 #endif\r
49 \r
50 //\r
51 // This block of memory is scratch space used to scrub any ECC protected memory. It\r
52 // is the size of the largest block of memory required aligned to the strictest\r
53 // alignment.\r
54 //  - L2 Data : Up to size of L2 way + size of L1 => 64 KiB + 32 KiB. Must be\r
55 //    aligned to MMU small page boundary to be properly pageable. (largest RAM,\r
56 //    strictest alignment)\r
57 //  - OCRAM   : Size of OCRAM => 64 KiB.\r
58 //  - DMA     : 0B.\r
59 //  - QSPI    : 2 KiB.\r
60 //\r
61 static char block[(64 + 32) * 1024] __attribute__ ((aligned (ALT_MMU_SMALL_PAGE_SIZE)));\r
62 \r
63 __attribute__((weak)) ALT_STATUS_CODE alt_cache_l2_ecc_start(void * block, size_t size)\r
64 {\r
65     return ALT_E_SUCCESS;\r
66 }\r
67 \r
68 static ALT_STATUS_CODE alt_ocram_ecc_start(void * block, size_t size);\r
69 \r
70 __attribute__((weak)) ALT_STATUS_CODE alt_dma_ecc_start(void * block, size_t size)\r
71 {\r
72     return ALT_E_SUCCESS;\r
73 }\r
74 \r
75 __attribute__((weak)) ALT_STATUS_CODE alt_qspi_ecc_start(void * block, size_t size)\r
76 {\r
77     return ALT_E_SUCCESS;\r
78 }\r
79 \r
80 ALT_STATUS_CODE alt_ecc_start(const ALT_ECC_RAM_ENUM_t ram_block)\r
81 {\r
82     void *   ecc_addr;\r
83     uint32_t ecc_bits;\r
84 \r
85     switch (ram_block)\r
86     {\r
87     case ALT_ECC_RAM_L2_DATA:\r
88         return alt_cache_l2_ecc_start(block, sizeof(block));\r
89 \r
90     case ALT_ECC_RAM_OCRAM:\r
91         return alt_ocram_ecc_start(block, sizeof(block));\r
92 \r
93     case ALT_ECC_RAM_USB0:\r
94         ecc_addr = ALT_SYSMGR_ECC_USB0_ADDR;\r
95         ecc_bits = ALT_SYSMGR_ECC_USB0_EN_SET_MSK;\r
96         break;\r
97     case ALT_ECC_RAM_USB1:\r
98         ecc_addr = ALT_SYSMGR_ECC_USB1_ADDR;\r
99         ecc_bits = ALT_SYSMGR_ECC_USB1_EN_SET_MSK;\r
100         break;\r
101     case ALT_ECC_RAM_EMAC0:\r
102         ecc_addr = ALT_SYSMGR_ECC_EMAC0_ADDR;\r
103         ecc_bits = ALT_SYSMGR_ECC_EMAC0_EN_SET_MSK;\r
104         break;\r
105     case ALT_ECC_RAM_EMAC1:\r
106         ecc_addr = ALT_SYSMGR_ECC_EMAC1_ADDR;\r
107         ecc_bits = ALT_SYSMGR_ECC_EMAC1_EN_SET_MSK;\r
108         break;\r
109     case ALT_ECC_RAM_DMA:\r
110         return alt_dma_ecc_start(block, sizeof(block));\r
111 \r
112     case ALT_ECC_RAM_CAN0:\r
113         ecc_addr = ALT_SYSMGR_ECC_CAN0_ADDR;\r
114         ecc_bits = ALT_SYSMGR_ECC_CAN0_EN_SET_MSK;\r
115         break;\r
116     case ALT_ECC_RAM_CAN1:\r
117         ecc_addr = ALT_SYSMGR_ECC_CAN1_ADDR;\r
118         ecc_bits = ALT_SYSMGR_ECC_CAN1_EN_SET_MSK;\r
119         break;\r
120     case ALT_ECC_RAM_NAND:\r
121         ecc_addr = ALT_SYSMGR_ECC_NAND_ADDR;\r
122         ecc_bits = ALT_SYSMGR_ECC_NAND_EN_SET_MSK;\r
123         break;\r
124     case ALT_ECC_RAM_QSPI:\r
125         return alt_qspi_ecc_start(block, sizeof(block));\r
126 \r
127     case ALT_ECC_RAM_SDMMC:\r
128         ecc_addr = ALT_SYSMGR_ECC_SDMMC_ADDR;\r
129         ecc_bits = ALT_SYSMGR_ECC_SDMMC_EN_SET_MSK;\r
130         break;\r
131     default:\r
132         return ALT_E_ERROR;\r
133     }\r
134 \r
135     alt_setbits_word(ecc_addr, ecc_bits);\r
136 \r
137     return ALT_E_SUCCESS;\r
138 }\r
139 \r
140 ALT_STATUS_CODE alt_ecc_stop(const ALT_ECC_RAM_ENUM_t ram_block)\r
141 {\r
142     void *   ecc_addr;\r
143     uint32_t ecc_bits;\r
144 \r
145     switch (ram_block)\r
146     {\r
147     case ALT_ECC_RAM_L2_DATA:\r
148         ecc_addr = ALT_SYSMGR_ECC_L2_ADDR;\r
149         ecc_bits = ALT_SYSMGR_ECC_L2_EN_SET_MSK;\r
150         break;\r
151     case ALT_ECC_RAM_OCRAM:\r
152         ecc_addr = ALT_SYSMGR_ECC_OCRAM_ADDR;\r
153         ecc_bits = ALT_SYSMGR_ECC_OCRAM_EN_SET_MSK;\r
154         break;\r
155     case ALT_ECC_RAM_USB0:\r
156         ecc_addr = ALT_SYSMGR_ECC_USB0_ADDR;\r
157         ecc_bits = ALT_SYSMGR_ECC_USB0_EN_SET_MSK;\r
158         break;\r
159     case ALT_ECC_RAM_USB1:\r
160         ecc_addr = ALT_SYSMGR_ECC_USB1_ADDR;\r
161         ecc_bits = ALT_SYSMGR_ECC_USB1_EN_SET_MSK;\r
162         break;\r
163     case ALT_ECC_RAM_EMAC0:\r
164         ecc_addr = ALT_SYSMGR_ECC_EMAC0_ADDR;\r
165         ecc_bits = ALT_SYSMGR_ECC_EMAC0_EN_SET_MSK;\r
166         break;\r
167     case ALT_ECC_RAM_EMAC1:\r
168         ecc_addr = ALT_SYSMGR_ECC_EMAC1_ADDR;\r
169         ecc_bits = ALT_SYSMGR_ECC_EMAC1_EN_SET_MSK;\r
170         break;\r
171     case ALT_ECC_RAM_DMA:\r
172         ecc_addr = ALT_SYSMGR_ECC_DMA_ADDR;\r
173         ecc_bits = ALT_SYSMGR_ECC_DMA_EN_SET_MSK;\r
174         break;\r
175     case ALT_ECC_RAM_CAN0:\r
176         ecc_addr = ALT_SYSMGR_ECC_CAN0_ADDR;\r
177         ecc_bits = ALT_SYSMGR_ECC_CAN0_EN_SET_MSK;\r
178         break;\r
179     case ALT_ECC_RAM_CAN1:\r
180         ecc_addr = ALT_SYSMGR_ECC_CAN1_ADDR;\r
181         ecc_bits = ALT_SYSMGR_ECC_CAN1_EN_SET_MSK;\r
182         break;\r
183     case ALT_ECC_RAM_NAND:\r
184         ecc_addr = ALT_SYSMGR_ECC_NAND_ADDR;\r
185         ecc_bits = ALT_SYSMGR_ECC_NAND_EN_SET_MSK;\r
186         break;\r
187     case ALT_ECC_RAM_QSPI:\r
188         ecc_addr = ALT_SYSMGR_ECC_QSPI_ADDR;\r
189         ecc_bits = ALT_SYSMGR_ECC_QSPI_EN_SET_MSK;\r
190         break;\r
191     case ALT_ECC_RAM_SDMMC:\r
192         ecc_addr = ALT_SYSMGR_ECC_SDMMC_ADDR;\r
193         ecc_bits = ALT_SYSMGR_ECC_SDMMC_EN_SET_MSK;\r
194         break;\r
195     default:\r
196         return ALT_E_ERROR;\r
197     }\r
198 \r
199     alt_clrbits_word(ecc_addr, ecc_bits);\r
200 \r
201     return ALT_E_SUCCESS;\r
202 }\r
203 \r
204 ALT_STATUS_CODE alt_ecc_is_enabled(const ALT_ECC_RAM_ENUM_t ram_block)\r
205 {\r
206     void *   ecc_addr;\r
207     uint32_t ecc_bits;\r
208 \r
209     switch (ram_block)\r
210     {\r
211     case ALT_ECC_RAM_L2_DATA:\r
212         ecc_addr = ALT_SYSMGR_ECC_L2_ADDR;\r
213         ecc_bits = ALT_SYSMGR_ECC_L2_EN_SET_MSK;\r
214         break;\r
215     case ALT_ECC_RAM_OCRAM:\r
216         ecc_addr = ALT_SYSMGR_ECC_OCRAM_ADDR;\r
217         ecc_bits = ALT_SYSMGR_ECC_OCRAM_EN_SET_MSK;\r
218         break;\r
219     case ALT_ECC_RAM_USB0:\r
220         ecc_addr = ALT_SYSMGR_ECC_USB0_ADDR;\r
221         ecc_bits = ALT_SYSMGR_ECC_USB0_EN_SET_MSK;\r
222         break;\r
223     case ALT_ECC_RAM_USB1:\r
224         ecc_addr = ALT_SYSMGR_ECC_USB1_ADDR;\r
225         ecc_bits = ALT_SYSMGR_ECC_USB1_EN_SET_MSK;\r
226         break;\r
227     case ALT_ECC_RAM_EMAC0:\r
228         ecc_addr = ALT_SYSMGR_ECC_EMAC0_ADDR;\r
229         ecc_bits = ALT_SYSMGR_ECC_EMAC0_EN_SET_MSK;\r
230         break;\r
231     case ALT_ECC_RAM_EMAC1:\r
232         ecc_addr = ALT_SYSMGR_ECC_EMAC1_ADDR;\r
233         ecc_bits = ALT_SYSMGR_ECC_EMAC1_EN_SET_MSK;\r
234         break;\r
235     case ALT_ECC_RAM_DMA:\r
236         ecc_addr = ALT_SYSMGR_ECC_DMA_ADDR;\r
237         ecc_bits = ALT_SYSMGR_ECC_DMA_EN_SET_MSK;\r
238         break;\r
239     case ALT_ECC_RAM_CAN0:\r
240         ecc_addr = ALT_SYSMGR_ECC_CAN0_ADDR;\r
241         ecc_bits = ALT_SYSMGR_ECC_CAN0_EN_SET_MSK;\r
242         break;\r
243     case ALT_ECC_RAM_CAN1:\r
244         ecc_addr = ALT_SYSMGR_ECC_CAN1_ADDR;\r
245         ecc_bits = ALT_SYSMGR_ECC_CAN1_EN_SET_MSK;\r
246         break;\r
247     case ALT_ECC_RAM_NAND:\r
248         ecc_addr = ALT_SYSMGR_ECC_NAND_ADDR;\r
249         ecc_bits = ALT_SYSMGR_ECC_NAND_EN_SET_MSK;\r
250         break;\r
251     case ALT_ECC_RAM_QSPI:\r
252         ecc_addr = ALT_SYSMGR_ECC_QSPI_ADDR;\r
253         ecc_bits = ALT_SYSMGR_ECC_QSPI_EN_SET_MSK;\r
254         break;\r
255     case ALT_ECC_RAM_SDMMC:\r
256         ecc_addr = ALT_SYSMGR_ECC_SDMMC_ADDR;\r
257         ecc_bits = ALT_SYSMGR_ECC_SDMMC_EN_SET_MSK;\r
258         break;\r
259     default:\r
260         return ALT_E_ERROR;\r
261     }\r
262 \r
263     if (alt_read_word(ecc_addr) & ecc_bits)\r
264     {\r
265         return ALT_E_TRUE;\r
266     }\r
267     else\r
268     {\r
269         return ALT_E_FALSE;\r
270     }\r
271 }\r
272 \r
273 /////\r
274 \r
275 ALT_STATUS_CODE alt_ecc_status_get(const ALT_ECC_RAM_ENUM_t ram_block,\r
276                                    uint32_t *status)\r
277 {\r
278     uint32_t ecc_bits;\r
279     uint32_t ecc_mask = 0;\r
280 \r
281     switch (ram_block)\r
282     {\r
283 //    case ALT_ECC_RAM_L2_DATA:\r
284 \r
285     case ALT_ECC_RAM_OCRAM:\r
286         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_OCRAM_ADDR);\r
287         if (ecc_bits & ALT_SYSMGR_ECC_OCRAM_SERR_SET_MSK)\r
288         {\r
289             ecc_mask |= ALT_ECC_ERROR_OCRAM_SERR;\r
290         }\r
291         if (ecc_bits & ALT_SYSMGR_ECC_OCRAM_DERR_SET_MSK)\r
292         {\r
293             ecc_mask |= ALT_ECC_ERROR_OCRAM_DERR;\r
294         }\r
295         break;\r
296 \r
297     case ALT_ECC_RAM_USB0:\r
298         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_USB0_ADDR);\r
299         if (ecc_bits & ALT_SYSMGR_ECC_USB0_SERR_SET_MSK)\r
300         {\r
301             ecc_mask |= ALT_ECC_ERROR_USB0_SERR;\r
302         }\r
303         if (ecc_bits & ALT_SYSMGR_ECC_USB0_DERR_SET_MSK)\r
304         {\r
305             ecc_mask |= ALT_ECC_ERROR_USB0_DERR;\r
306         }\r
307         break;\r
308 \r
309     case ALT_ECC_RAM_USB1:\r
310         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_USB1_ADDR);\r
311         if (ecc_bits & ALT_SYSMGR_ECC_USB1_SERR_SET_MSK)\r
312         {\r
313             ecc_mask |= ALT_ECC_ERROR_USB1_SERR;\r
314         }\r
315         if (ecc_bits & ALT_SYSMGR_ECC_USB1_DERR_SET_MSK)\r
316         {\r
317             ecc_mask |= ALT_ECC_ERROR_USB1_DERR;\r
318         }\r
319         break;\r
320 \r
321     case ALT_ECC_RAM_EMAC0:\r
322         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_EMAC0_ADDR);\r
323         if (ecc_bits & ALT_SYSMGR_ECC_EMAC0_TXFIFOSERR_SET_MSK)\r
324         {\r
325             ecc_mask |= ALT_ECC_ERROR_EMAC0_TX_FIFO_SERR;\r
326         }\r
327         if (ecc_bits & ALT_SYSMGR_ECC_EMAC0_TXFIFODERR_SET_MSK)\r
328         {\r
329             ecc_mask |= ALT_ECC_ERROR_EMAC0_TX_FIFO_DERR;\r
330         }\r
331         if (ecc_bits & ALT_SYSMGR_ECC_EMAC0_RXFIFOSERR_SET_MSK)\r
332         {\r
333             ecc_mask |= ALT_ECC_ERROR_EMAC0_RX_FIFO_SERR;\r
334         }\r
335         if (ecc_bits & ALT_SYSMGR_ECC_EMAC0_RXFIFODERR_SET_MSK)\r
336         {\r
337             ecc_mask |= ALT_ECC_ERROR_EMAC0_RX_FIFO_DERR;\r
338         }\r
339         break;\r
340 \r
341     case ALT_ECC_RAM_EMAC1:\r
342         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_EMAC1_ADDR);\r
343         if (ecc_bits & ALT_SYSMGR_ECC_EMAC1_TXFIFOSERR_SET_MSK)\r
344         {\r
345             ecc_mask |= ALT_ECC_ERROR_EMAC1_TX_FIFO_SERR;\r
346         }\r
347         if (ecc_bits & ALT_SYSMGR_ECC_EMAC1_TXFIFODERR_SET_MSK)\r
348         {\r
349             ecc_mask |= ALT_ECC_ERROR_EMAC1_TX_FIFO_DERR;\r
350         }\r
351         if (ecc_bits & ALT_SYSMGR_ECC_EMAC1_RXFIFOSERR_SET_MSK)\r
352         {\r
353             ecc_mask |= ALT_ECC_ERROR_EMAC1_RX_FIFO_SERR;\r
354         }\r
355         if (ecc_bits & ALT_SYSMGR_ECC_EMAC1_RXFIFODERR_SET_MSK)\r
356         {\r
357             ecc_mask |= ALT_ECC_ERROR_EMAC1_RX_FIFO_DERR;\r
358         }\r
359         break;\r
360 \r
361     case ALT_ECC_RAM_DMA:\r
362         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_DMA_ADDR);\r
363         if (ecc_bits & ALT_SYSMGR_ECC_DMA_SERR_SET_MSK)\r
364         {\r
365             ecc_mask |= ALT_ECC_ERROR_DMA_SERR;\r
366         }\r
367         if (ecc_bits & ALT_SYSMGR_ECC_DMA_DERR_SET_MSK)\r
368         {\r
369             ecc_mask |= ALT_ECC_ERROR_DMA_DERR;\r
370         }\r
371         break;\r
372 \r
373     case ALT_ECC_RAM_CAN0:\r
374         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_CAN0_ADDR);\r
375         if (ecc_bits & ALT_SYSMGR_ECC_CAN0_SERR_SET_MSK)\r
376         {\r
377             ecc_mask |= ALT_ECC_ERROR_CAN0_SERR;\r
378         }\r
379         if (ecc_bits & ALT_SYSMGR_ECC_CAN0_DERR_SET_MSK)\r
380         {\r
381             ecc_mask |= ALT_ECC_ERROR_CAN0_DERR;\r
382         }\r
383         break;\r
384 \r
385     case ALT_ECC_RAM_CAN1:\r
386         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_CAN1_ADDR);\r
387         if (ecc_bits & ALT_SYSMGR_ECC_CAN1_SERR_SET_MSK)\r
388         {\r
389             ecc_mask |= ALT_ECC_ERROR_CAN1_SERR;\r
390         }\r
391         if (ecc_bits & ALT_SYSMGR_ECC_CAN1_DERR_SET_MSK)\r
392         {\r
393             ecc_mask |= ALT_ECC_ERROR_CAN1_DERR;\r
394         }\r
395         break;\r
396 \r
397     case ALT_ECC_RAM_NAND:\r
398         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_NAND_ADDR);\r
399         if (ecc_bits & ALT_SYSMGR_ECC_NAND_ECCBUFSERR_SET_MSK)\r
400         {\r
401             ecc_mask |= ALT_ECC_ERROR_NAND_BUFFER_SERR;\r
402         }\r
403         if (ecc_bits & ALT_SYSMGR_ECC_NAND_ECCBUFDERR_SET_MSK)\r
404         {\r
405             ecc_mask |= ALT_ECC_ERROR_NAND_BUFFER_DERR;\r
406         }\r
407         if (ecc_bits & ALT_SYSMGR_ECC_NAND_WRFIFOSERR_SET_MSK)\r
408         {\r
409             ecc_mask |= ALT_ECC_ERROR_NAND_WR_FIFO_SERR;\r
410         }\r
411         if (ecc_bits & ALT_SYSMGR_ECC_NAND_WRFIFODERR_SET_MSK)\r
412         {\r
413             ecc_mask |= ALT_ECC_ERROR_NAND_WR_FIFO_DERR;\r
414         }\r
415         if (ecc_bits & ALT_SYSMGR_ECC_NAND_RDFIFOSERR_SET_MSK)\r
416         {\r
417             ecc_mask |= ALT_ECC_ERROR_NAND_RD_FIFO_SERR;\r
418         }\r
419         if (ecc_bits & ALT_SYSMGR_ECC_NAND_RDFIFODERR_SET_MSK)\r
420         {\r
421             ecc_mask |= ALT_ECC_ERROR_NAND_RD_FIFO_DERR;\r
422         }\r
423         break;\r
424 \r
425     case ALT_ECC_RAM_QSPI:\r
426         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_QSPI_ADDR);\r
427         if (ecc_bits & ALT_SYSMGR_ECC_QSPI_SERR_SET_MSK)\r
428         {\r
429             ecc_mask |= ALT_ECC_ERROR_QSPI_SERR;\r
430         }\r
431         if (ecc_bits & ALT_SYSMGR_ECC_QSPI_DERR_SET_MSK)\r
432         {\r
433             ecc_mask |= ALT_ECC_ERROR_QSPI_DERR;\r
434         }\r
435         break;\r
436 \r
437     case ALT_ECC_RAM_SDMMC:\r
438         ecc_bits = alt_read_word(ALT_SYSMGR_ECC_SDMMC_ADDR);\r
439         if (ecc_bits & ALT_SYSMGR_ECC_SDMMC_SERRPORTA_SET_MSK)\r
440         {\r
441             ecc_mask |= ALT_ECC_ERROR_SDMMC_PORT_A_SERR;\r
442         }\r
443         if (ecc_bits & ALT_SYSMGR_ECC_SDMMC_DERRPORTA_SET_MSK)\r
444         {\r
445             ecc_mask |= ALT_ECC_ERROR_SDMMC_PORT_A_DERR;\r
446         }\r
447         if (ecc_bits & ALT_SYSMGR_ECC_SDMMC_SERRPORTB_SET_MSK)\r
448         {\r
449             ecc_mask |= ALT_ECC_ERROR_SDMMC_PORT_B_SERR;\r
450         }\r
451         if (ecc_bits & ALT_SYSMGR_ECC_SDMMC_DERRPORTB_SET_MSK)\r
452         {\r
453             ecc_mask |= ALT_ECC_ERROR_SDMMC_PORT_B_DERR;\r
454         }\r
455         break;\r
456 \r
457     default:\r
458         return ALT_E_ERROR;\r
459     }\r
460 \r
461     *status = ecc_mask;\r
462 \r
463     return ALT_E_SUCCESS;\r
464 }\r
465 \r
466 ALT_STATUS_CODE alt_ecc_status_clear(const ALT_ECC_RAM_ENUM_t ram_block, \r
467                                      const uint32_t ecc_mask)\r
468 {\r
469     void *   ecc_addr;\r
470     uint32_t ecc_bits = 0;\r
471 \r
472     switch (ram_block)\r
473     {\r
474 //    case ALT_ECC_RAM_L2_DATA:\r
475 \r
476     case ALT_ECC_RAM_OCRAM:\r
477         ecc_addr = ALT_SYSMGR_ECC_OCRAM_ADDR;\r
478 \r
479         if (ecc_mask & ALT_ECC_ERROR_OCRAM_SERR)\r
480         {\r
481             ecc_bits |= ALT_SYSMGR_ECC_OCRAM_SERR_SET_MSK;\r
482         }\r
483         if (ecc_mask & ALT_ECC_ERROR_OCRAM_DERR)\r
484         {\r
485             ecc_bits |= ALT_SYSMGR_ECC_OCRAM_DERR_SET_MSK;\r
486         }\r
487         break;\r
488 \r
489     case ALT_ECC_RAM_USB0:\r
490         ecc_addr = ALT_SYSMGR_ECC_USB0_ADDR;\r
491 \r
492         if (ecc_mask & ALT_ECC_ERROR_USB0_SERR)\r
493         {\r
494             ecc_bits |= ALT_SYSMGR_ECC_USB0_SERR_SET_MSK;\r
495         }\r
496         if (ecc_mask & ALT_ECC_ERROR_USB0_DERR)\r
497         {\r
498             ecc_bits |= ALT_SYSMGR_ECC_USB0_DERR_SET_MSK;\r
499         }\r
500         break;\r
501 \r
502     case ALT_ECC_RAM_USB1:\r
503         ecc_addr = ALT_SYSMGR_ECC_USB1_ADDR;\r
504 \r
505         if (ecc_mask & ALT_ECC_ERROR_USB1_SERR)\r
506         {\r
507             ecc_bits |= ALT_SYSMGR_ECC_USB1_SERR_SET_MSK;\r
508         }\r
509         if (ecc_mask & ALT_ECC_ERROR_USB1_DERR)\r
510         {\r
511             ecc_bits |= ALT_SYSMGR_ECC_USB1_DERR_SET_MSK;\r
512         }\r
513         break;\r
514 \r
515     case ALT_ECC_RAM_EMAC0:\r
516         ecc_addr = ALT_SYSMGR_ECC_EMAC0_ADDR;\r
517 \r
518         if (ecc_mask & ALT_ECC_ERROR_EMAC0_TX_FIFO_SERR)\r
519         {\r
520             ecc_bits |= ALT_SYSMGR_ECC_EMAC0_TXFIFOSERR_SET_MSK;\r
521         }\r
522         if (ecc_mask & ALT_ECC_ERROR_EMAC0_TX_FIFO_DERR)\r
523         {\r
524             ecc_bits |= ALT_SYSMGR_ECC_EMAC0_TXFIFODERR_SET_MSK;\r
525         }\r
526         if (ecc_mask & ALT_ECC_ERROR_EMAC0_RX_FIFO_SERR)\r
527         {\r
528             ecc_bits |= ALT_SYSMGR_ECC_EMAC0_RXFIFOSERR_SET_MSK;\r
529         }\r
530         if (ecc_mask & ALT_ECC_ERROR_EMAC0_RX_FIFO_DERR)\r
531         {\r
532             ecc_bits |= ALT_SYSMGR_ECC_EMAC0_RXFIFODERR_SET_MSK;\r
533         }\r
534         break;\r
535 \r
536     case ALT_ECC_RAM_EMAC1:\r
537         ecc_addr = ALT_SYSMGR_ECC_EMAC1_ADDR;\r
538 \r
539         if (ecc_mask & ALT_ECC_ERROR_EMAC1_TX_FIFO_SERR)\r
540         {\r
541             ecc_bits |= ALT_SYSMGR_ECC_EMAC1_TXFIFOSERR_SET_MSK;\r
542         }\r
543         if (ecc_mask & ALT_ECC_ERROR_EMAC1_TX_FIFO_DERR)\r
544         {\r
545             ecc_bits |= ALT_SYSMGR_ECC_EMAC1_TXFIFODERR_SET_MSK;\r
546         }\r
547         if (ecc_mask & ALT_ECC_ERROR_EMAC1_RX_FIFO_SERR)\r
548         {\r
549             ecc_bits |= ALT_SYSMGR_ECC_EMAC1_RXFIFOSERR_SET_MSK;\r
550         }\r
551         if (ecc_mask & ALT_ECC_ERROR_EMAC1_RX_FIFO_DERR)\r
552         {\r
553             ecc_bits |= ALT_SYSMGR_ECC_EMAC1_RXFIFODERR_SET_MSK;\r
554         }\r
555         break;\r
556 \r
557     case ALT_ECC_RAM_DMA:\r
558         ecc_addr = ALT_SYSMGR_ECC_DMA_ADDR;\r
559 \r
560         if (ecc_mask & ALT_ECC_ERROR_DMA_SERR)\r
561         {\r
562             ecc_bits |= ALT_SYSMGR_ECC_DMA_SERR_SET_MSK;\r
563         }\r
564         if (ecc_mask & ALT_ECC_ERROR_DMA_DERR)\r
565         {\r
566             ecc_bits |= ALT_SYSMGR_ECC_DMA_DERR_SET_MSK;\r
567         }\r
568         break;\r
569 \r
570     case ALT_ECC_RAM_CAN0:\r
571         ecc_addr = ALT_SYSMGR_ECC_CAN0_ADDR;\r
572 \r
573         if (ecc_mask & ALT_ECC_ERROR_CAN0_SERR)\r
574         {\r
575             ecc_bits |= ALT_SYSMGR_ECC_CAN0_SERR_SET_MSK;\r
576         }\r
577         if (ecc_mask & ALT_ECC_ERROR_CAN0_DERR)\r
578         {\r
579             ecc_bits |= ALT_SYSMGR_ECC_CAN0_DERR_SET_MSK;\r
580         }\r
581         break;\r
582 \r
583     case ALT_ECC_RAM_CAN1:\r
584         ecc_addr = ALT_SYSMGR_ECC_CAN1_ADDR;\r
585 \r
586         if (ecc_mask & ALT_ECC_ERROR_CAN1_SERR)\r
587         {\r
588             ecc_bits |= ALT_SYSMGR_ECC_CAN1_SERR_SET_MSK;\r
589         }\r
590         if (ecc_mask & ALT_ECC_ERROR_CAN1_DERR)\r
591         {\r
592             ecc_bits |= ALT_SYSMGR_ECC_CAN1_DERR_SET_MSK;\r
593         }\r
594         break;\r
595 \r
596     case ALT_ECC_RAM_NAND:\r
597         ecc_addr = ALT_SYSMGR_ECC_NAND_ADDR;\r
598 \r
599         if (ecc_mask & ALT_ECC_ERROR_NAND_BUFFER_SERR)\r
600         {\r
601             ecc_bits |= ALT_SYSMGR_ECC_NAND_ECCBUFSERR_SET_MSK;\r
602         }\r
603         if (ecc_mask & ALT_ECC_ERROR_NAND_BUFFER_DERR)\r
604         {\r
605             ecc_bits |= ALT_SYSMGR_ECC_NAND_ECCBUFDERR_SET_MSK;\r
606         }\r
607         if (ecc_mask & ALT_ECC_ERROR_NAND_WR_FIFO_SERR)\r
608         {\r
609             ecc_bits |= ALT_SYSMGR_ECC_NAND_WRFIFOSERR_SET_MSK;\r
610         }\r
611         if (ecc_mask & ALT_ECC_ERROR_NAND_WR_FIFO_DERR)\r
612         {\r
613             ecc_bits |= ALT_SYSMGR_ECC_NAND_WRFIFODERR_SET_MSK;\r
614         }\r
615         if (ecc_mask & ALT_ECC_ERROR_NAND_RD_FIFO_SERR)\r
616         {\r
617             ecc_bits |= ALT_SYSMGR_ECC_NAND_RDFIFOSERR_SET_MSK;\r
618         }\r
619         if (ecc_mask & ALT_ECC_ERROR_NAND_RD_FIFO_DERR)\r
620         {\r
621             ecc_bits |= ALT_SYSMGR_ECC_NAND_RDFIFODERR_SET_MSK;\r
622         }\r
623         break;\r
624 \r
625     case ALT_ECC_RAM_QSPI:\r
626         ecc_addr = ALT_SYSMGR_ECC_QSPI_ADDR;\r
627 \r
628         if (ecc_mask & ALT_ECC_ERROR_QSPI_SERR)\r
629         {\r
630             ecc_bits |= ALT_SYSMGR_ECC_QSPI_SERR_SET_MSK;\r
631         }\r
632         if (ecc_mask & ALT_ECC_ERROR_QSPI_DERR)\r
633         {\r
634             ecc_bits |= ALT_SYSMGR_ECC_QSPI_DERR_SET_MSK;\r
635         }\r
636         break;\r
637 \r
638     case ALT_ECC_RAM_SDMMC:\r
639         ecc_addr = ALT_SYSMGR_ECC_SDMMC_ADDR;\r
640 \r
641         if (ecc_mask & ALT_ECC_ERROR_SDMMC_PORT_A_SERR)\r
642         {\r
643             ecc_bits |= ALT_SYSMGR_ECC_SDMMC_SERRPORTA_SET_MSK;\r
644         }\r
645         if (ecc_mask & ALT_ECC_ERROR_SDMMC_PORT_A_DERR)\r
646         {\r
647             ecc_bits |= ALT_SYSMGR_ECC_SDMMC_DERRPORTA_SET_MSK;\r
648         }\r
649         if (ecc_mask & ALT_ECC_ERROR_SDMMC_PORT_B_SERR)\r
650         {\r
651             ecc_bits |= ALT_SYSMGR_ECC_SDMMC_SERRPORTB_SET_MSK;\r
652         }\r
653         if (ecc_mask & ALT_ECC_ERROR_SDMMC_PORT_B_DERR)\r
654         {\r
655             ecc_bits |= ALT_SYSMGR_ECC_SDMMC_DERRPORTB_SET_MSK;\r
656         }\r
657         break;\r
658 \r
659     default:\r
660         return ALT_E_ERROR;\r
661     }\r
662 \r
663     // Bit 1 is always ECC enable.\r
664     // Be sure not to clear other conditions that may be active but not requested to be cleared.\r
665     alt_write_word(ecc_addr, (alt_read_word(ecc_addr) & (1 << 0)) | ecc_bits);\r
666 \r
667     return ALT_E_SUCCESS;\r
668 }\r
669 \r
670 /////\r
671 \r
672 ALT_STATUS_CODE alt_ecc_serr_inject(const ALT_ECC_RAM_ENUM_t ram_block)\r
673 {\r
674     void *   ecc_addr;\r
675     uint32_t ecc_bits;\r
676 \r
677     switch (ram_block)\r
678     {\r
679     case ALT_ECC_RAM_L2_DATA:\r
680         ecc_addr = ALT_SYSMGR_ECC_L2_ADDR;\r
681         ecc_bits = ALT_SYSMGR_ECC_L2_INJS_SET_MSK;\r
682         break;\r
683     case ALT_ECC_RAM_OCRAM:\r
684         ecc_addr = ALT_SYSMGR_ECC_OCRAM_ADDR;\r
685         ecc_bits = ALT_SYSMGR_ECC_OCRAM_INJS_SET_MSK;\r
686         break;\r
687     case ALT_ECC_RAM_USB0:\r
688         ecc_addr = ALT_SYSMGR_ECC_USB0_ADDR;\r
689         ecc_bits = ALT_SYSMGR_ECC_USB0_INJS_SET_MSK;\r
690         break;\r
691     case ALT_ECC_RAM_USB1:\r
692         ecc_addr = ALT_SYSMGR_ECC_USB1_ADDR;\r
693         ecc_bits = ALT_SYSMGR_ECC_USB1_INJS_SET_MSK;\r
694         break;\r
695     case ALT_ECC_RAM_EMAC0:\r
696         ecc_addr = ALT_SYSMGR_ECC_EMAC0_ADDR;\r
697         ecc_bits =   ALT_SYSMGR_ECC_EMAC0_TXFIFOINJS_SET_MSK\r
698                    | ALT_SYSMGR_ECC_EMAC0_RXFIFOINJS_SET_MSK;\r
699         break;\r
700     case ALT_ECC_RAM_EMAC1:\r
701         ecc_addr = ALT_SYSMGR_ECC_EMAC1_ADDR;\r
702         ecc_bits =   ALT_SYSMGR_ECC_EMAC1_TXFIFOINJS_SET_MSK\r
703                    | ALT_SYSMGR_ECC_EMAC1_RXFIFOINJS_SET_MSK;\r
704         break;\r
705     case ALT_ECC_RAM_DMA:\r
706         ecc_addr = ALT_SYSMGR_ECC_DMA_ADDR;\r
707         ecc_bits = ALT_SYSMGR_ECC_DMA_INJS_SET_MSK;\r
708         break;\r
709     case ALT_ECC_RAM_CAN0:\r
710         ecc_addr = ALT_SYSMGR_ECC_CAN0_ADDR;\r
711         ecc_bits = ALT_SYSMGR_ECC_CAN0_INJS_SET_MSK;\r
712         break;\r
713     case ALT_ECC_RAM_CAN1:\r
714         ecc_addr = ALT_SYSMGR_ECC_CAN1_ADDR;\r
715         ecc_bits = ALT_SYSMGR_ECC_CAN1_INJS_SET_MSK;\r
716         break;\r
717     case ALT_ECC_RAM_NAND:\r
718         ecc_addr = ALT_SYSMGR_ECC_NAND_ADDR;\r
719         ecc_bits =   ALT_SYSMGR_ECC_NAND_ECCBUFINJS_SET_MSK\r
720                    | ALT_SYSMGR_ECC_NAND_WRFIFOINJS_SET_MSK\r
721                    | ALT_SYSMGR_ECC_NAND_RDFIFOINJS_SET_MSK;\r
722         break;\r
723     case ALT_ECC_RAM_QSPI:\r
724         ecc_addr = ALT_SYSMGR_ECC_QSPI_ADDR;\r
725         ecc_bits = ALT_SYSMGR_ECC_QSPI_INJS_SET_MSK;\r
726         break;\r
727     case ALT_ECC_RAM_SDMMC:\r
728         ecc_addr = ALT_SYSMGR_ECC_SDMMC_ADDR;\r
729         ecc_bits =   ALT_SYSMGR_ECC_SDMMC_INJSPORTA_SET_MSK\r
730                    | ALT_SYSMGR_ECC_SDMMC_INJSPORTB_SET_MSK;\r
731         break;\r
732     default:\r
733         return ALT_E_ERROR;\r
734     }\r
735 \r
736     uint32_t reg = alt_read_word(ecc_addr);\r
737     alt_write_word(ecc_addr, reg | ecc_bits);\r
738     alt_write_word(ecc_addr, reg);\r
739 \r
740     return ALT_E_SUCCESS;\r
741 }\r
742 \r
743 ALT_STATUS_CODE alt_ecc_derr_inject(const ALT_ECC_RAM_ENUM_t ram_block)\r
744 {\r
745     void *   ecc_addr;\r
746     uint32_t ecc_bits;\r
747 \r
748     switch (ram_block)\r
749     {\r
750     case ALT_ECC_RAM_L2_DATA:\r
751         ecc_addr = ALT_SYSMGR_ECC_L2_ADDR;\r
752         ecc_bits = ALT_SYSMGR_ECC_L2_INJD_SET_MSK;\r
753         break;\r
754     case ALT_ECC_RAM_OCRAM:\r
755         ecc_addr = ALT_SYSMGR_ECC_OCRAM_ADDR;\r
756         ecc_bits = ALT_SYSMGR_ECC_OCRAM_INJD_SET_MSK;\r
757         break;\r
758     case ALT_ECC_RAM_USB0:\r
759         ecc_addr = ALT_SYSMGR_ECC_USB0_ADDR;\r
760         ecc_bits = ALT_SYSMGR_ECC_USB0_INJD_SET_MSK;\r
761         break;\r
762     case ALT_ECC_RAM_USB1:\r
763         ecc_addr = ALT_SYSMGR_ECC_USB1_ADDR;\r
764         ecc_bits = ALT_SYSMGR_ECC_USB1_INJD_SET_MSK;\r
765         break;\r
766     case ALT_ECC_RAM_EMAC0:\r
767         ecc_addr = ALT_SYSMGR_ECC_EMAC0_ADDR;\r
768         ecc_bits =   ALT_SYSMGR_ECC_EMAC0_TXFIFOINJD_SET_MSK\r
769                    | ALT_SYSMGR_ECC_EMAC0_RXFIFOINJD_SET_MSK;\r
770         break;\r
771     case ALT_ECC_RAM_EMAC1:\r
772         ecc_addr = ALT_SYSMGR_ECC_EMAC1_ADDR;\r
773         ecc_bits =   ALT_SYSMGR_ECC_EMAC1_TXFIFOINJD_SET_MSK\r
774                    | ALT_SYSMGR_ECC_EMAC1_RXFIFOINJD_SET_MSK;\r
775         break;\r
776     case ALT_ECC_RAM_DMA:\r
777         ecc_addr = ALT_SYSMGR_ECC_DMA_ADDR;\r
778         ecc_bits = ALT_SYSMGR_ECC_DMA_INJD_SET_MSK;\r
779         break;\r
780     case ALT_ECC_RAM_CAN0:\r
781         ecc_addr = ALT_SYSMGR_ECC_CAN0_ADDR;\r
782         ecc_bits = ALT_SYSMGR_ECC_CAN0_INJD_SET_MSK;\r
783         break;\r
784     case ALT_ECC_RAM_CAN1:\r
785         ecc_addr = ALT_SYSMGR_ECC_CAN1_ADDR;\r
786         ecc_bits = ALT_SYSMGR_ECC_CAN1_INJD_SET_MSK;\r
787         break;\r
788     case ALT_ECC_RAM_NAND:\r
789         ecc_addr = ALT_SYSMGR_ECC_NAND_ADDR;\r
790         ecc_bits =   ALT_SYSMGR_ECC_NAND_ECCBUFINJD_SET_MSK\r
791                    | ALT_SYSMGR_ECC_NAND_WRFIFOINJD_SET_MSK\r
792                    | ALT_SYSMGR_ECC_NAND_RDFIFOINJD_SET_MSK;\r
793         break;\r
794     case ALT_ECC_RAM_QSPI:\r
795         ecc_addr = ALT_SYSMGR_ECC_QSPI_ADDR;\r
796         ecc_bits = ALT_SYSMGR_ECC_QSPI_INJD_SET_MSK;\r
797         break;\r
798     case ALT_ECC_RAM_SDMMC:\r
799         ecc_addr = ALT_SYSMGR_ECC_SDMMC_ADDR;\r
800         ecc_bits =   ALT_SYSMGR_ECC_SDMMC_INJDPORTA_SET_MSK\r
801                    | ALT_SYSMGR_ECC_SDMMC_INJDPORTB_SET_MSK;\r
802         break;\r
803     default:\r
804         return ALT_E_ERROR;\r
805     }\r
806 \r
807     uint32_t reg = alt_read_word(ecc_addr);\r
808     alt_write_word(ecc_addr, reg | ecc_bits);\r
809     alt_write_word(ecc_addr, reg);\r
810 \r
811     return ALT_E_SUCCESS;\r
812 }\r
813 \r
814 /////\r
815 \r
816 static ALT_STATUS_CODE alt_ocram_ecc_start(void * block, size_t size)\r
817 {\r
818     // CASE 163685: Overflow in ALT_OCRAM_UB_ADDR.\r
819     // const uint32_t ocram_size = ((uint32_t)ALT_OCRAM_UB_ADDR - (uint32_t)ALT_OCRAM_LB_ADDR) + 1;\r
820     const uint32_t ocram_size = ((uint32_t)0xffffffff - (uint32_t)ALT_OCRAM_LB_ADDR) + 1;\r
821     dprintf("DEBUG[ECC][OCRAM]: OCRAM Size = 0x%lx.\n", ocram_size);\r
822 \r
823     // Verify buffer is large enough to contain the entire contents of OCRAM.\r
824     if (size < ocram_size)\r
825     {\r
826         return ALT_E_ERROR;\r
827     }\r
828 \r
829     // Verify buffer is word aligned.\r
830     if ((uintptr_t)block & (sizeof(uint32_t) - 1))\r
831     {\r
832         return ALT_E_ERROR;\r
833     }\r
834 \r
835     // Read the contents of OCRAM into the provided buffer\r
836 \r
837     uint32_t * block_iter = block;\r
838     uint32_t * ocram_iter = ALT_OCRAM_ADDR;\r
839     uint32_t   size_counter = ocram_size;\r
840 \r
841     while (size_counter)\r
842     {\r
843         *block_iter = alt_read_word(ocram_iter);\r
844         ++block_iter;\r
845         ++ocram_iter;\r
846         size_counter -= sizeof(*ocram_iter);\r
847     }\r
848 \r
849     // Enable ECC\r
850 \r
851     alt_setbits_word(ALT_SYSMGR_ECC_OCRAM_ADDR, ALT_SYSMGR_ECC_OCRAM_EN_SET_MSK);\r
852 \r
853     // Write back contents of OCRAM from buffer to OCRAM\r
854 \r
855     block_iter   = block;\r
856     ocram_iter   = ALT_OCRAM_ADDR;\r
857     size_counter = ocram_size;\r
858 \r
859     while (size_counter)\r
860     {\r
861         alt_write_word(ocram_iter, *block_iter);\r
862         ++block_iter;\r
863         ++ocram_iter;\r
864         size_counter -= sizeof(*ocram_iter);\r
865     }\r
866 \r
867     // Clear any pending spurious interrupts\r
868 \r
869     alt_write_word(ALT_SYSMGR_ECC_OCRAM_ADDR,\r
870                      ALT_SYSMGR_ECC_OCRAM_EN_SET_MSK\r
871                    | ALT_SYSMGR_ECC_OCRAM_SERR_SET_MSK\r
872                    | ALT_SYSMGR_ECC_OCRAM_DERR_SET_MSK);\r
873 \r
874     return ALT_E_SUCCESS;\r
875 }\r