1215976Sjmallett/***********************license start***************
2215976Sjmallett * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). All rights
3215976Sjmallett * reserved.
4215976Sjmallett *
5215976Sjmallett *
6215976Sjmallett * Redistribution and use in source and binary forms, with or without
7215976Sjmallett * modification, are permitted provided that the following conditions are
8215976Sjmallett * met:
9215976Sjmallett *
10215976Sjmallett *   * Redistributions of source code must retain the above copyright
11215976Sjmallett *     notice, this list of conditions and the following disclaimer.
12215976Sjmallett *
13215976Sjmallett *   * Redistributions in binary form must reproduce the above
14215976Sjmallett *     copyright notice, this list of conditions and the following
15215976Sjmallett *     disclaimer in the documentation and/or other materials provided
16215976Sjmallett *     with the distribution.
17215976Sjmallett
18215976Sjmallett *   * Neither the name of Cavium Networks nor the names of
19215976Sjmallett *     its contributors may be used to endorse or promote products
20215976Sjmallett *     derived from this software without specific prior written
21215976Sjmallett *     permission.
22215976Sjmallett
23215976Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215976Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215976Sjmallett * regulations, and may be subject to export or import  regulations in other
26215976Sjmallett * countries.
27215976Sjmallett
28215976Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29215976Sjmallett * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
30215976Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215976Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215976Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215976Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215976Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215976Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215976Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215976Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38215976Sjmallett ***********************license end**************************************/
39215976Sjmallett
40215976Sjmallett
41215976Sjmallett/**
42215976Sjmallett * @file
43215976Sjmallett *
44215976Sjmallett * Prototypes for custom error handler function not handled by the default
45215976Sjmallett * message display error function.
46215976Sjmallett *
47215976Sjmallett * <hr>$Revision: 44252 $<hr>
48215976Sjmallett */
49215976Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
50215976Sjmallett#include <asm/octeon/cvmx.h>
51215976Sjmallett#include <asm/octeon/cvmx-error.h>
52215976Sjmallett#include <asm/octeon/cvmx-error-custom.h>
53215976Sjmallett#include <asm/octeon/cvmx-helper.h>
54215976Sjmallett#include <asm/octeon/cvmx-l2c.h>
55215976Sjmallett#include <asm/octeon/cvmx-pcie.h>
56215976Sjmallett#include <asm/octeon/cvmx-pexp-defs.h>
57215976Sjmallett#include <asm/octeon/cvmx-dfa-defs.h>
58215976Sjmallett#include <asm/octeon/cvmx-gmxx-defs.h>
59215976Sjmallett#include <asm/octeon/cvmx-lmcx-defs.h>
60215976Sjmallett#include <asm/octeon/cvmx-pemx-defs.h>
61215976Sjmallett#define PRINT_ERROR(format, ...) cvmx_safe_printf("ERROR " format, ##__VA_ARGS__)
62215976Sjmallett#else
63215976Sjmallett#include "cvmx.h"
64215976Sjmallett#include "cvmx-error.h"
65215976Sjmallett#include "cvmx-error-custom.h"
66215976Sjmallett#include "cvmx-helper.h"
67215976Sjmallett#include "cvmx-l2c.h"
68215976Sjmallett#include "cvmx-pcie.h"
69215976Sjmallett#include "cvmx-interrupt.h"
70215976Sjmallett#endif
71215976Sjmallett
72215976Sjmallett/**
73215976Sjmallett * @INTERNAL
74215976Sjmallett * XAUI interfaces need to be reset whenever a local or remote fault
75215976Sjmallett * is detected. Calling autoconf takes the link through a reset.
76215976Sjmallett *
77215976Sjmallett * @param info
78215976Sjmallett *
79215976Sjmallett * @return
80215976Sjmallett */
81215976Sjmallettstatic int __cvmx_error_handle_gmxx_rxx_int_reg(const struct cvmx_error_info *info)
82215976Sjmallett{
83215976Sjmallett#ifdef CVMX_ENABLE_PKO_FUNCTIONS
84215976Sjmallett    int ipd_port = info->group_index;
85215976Sjmallett    cvmx_helper_link_autoconf(ipd_port);
86215976Sjmallett#endif
87215976Sjmallett    cvmx_write_csr(info->status_addr, info->status_mask);
88215976Sjmallett    return 1;
89215976Sjmallett}
90215976Sjmallett
91215976Sjmallett/**
92215976Sjmallett * @INTERNAL
93215976Sjmallett * When NPEI_INT_SUM[C0_LDWN] is set, the PCIe block requires a shutdown and
94215976Sjmallett * initialization to bring the link back up. This handler does this for port 0.
95215976Sjmallett * Note that config space is not enumerated again, so the devices will still be
96215976Sjmallett * unusable.
97215976Sjmallett *
98215976Sjmallett * @param info
99215976Sjmallett *
100215976Sjmallett * @return
101215976Sjmallett */
102215976Sjmallettstatic int __cvmx_error_handle_npei_int_sum_c0_ldwn(const struct cvmx_error_info *info)
103215976Sjmallett{
104215976Sjmallett    cvmx_ciu_soft_prst_t ciu_soft_prst;
105215976Sjmallett    PRINT_ERROR("NPEI_INT_SUM[C0_LDWN]: Reset request due to link0 down status.\n");
106215976Sjmallett    ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
107215976Sjmallett    if (!ciu_soft_prst.s.soft_prst)
108215976Sjmallett    {
109215976Sjmallett        /* Attempt to automatically bring the link back up */
110215976Sjmallett        cvmx_pcie_rc_shutdown(0);
111215976Sjmallett        cvmx_pcie_rc_initialize(0);
112215976Sjmallett    }
113215976Sjmallett    cvmx_write_csr(CVMX_PEXP_NPEI_INT_SUM, cvmx_read_csr(CVMX_PEXP_NPEI_INT_SUM));
114215976Sjmallett    return 1;
115215976Sjmallett}
116215976Sjmallett
117215976Sjmallett/**
118215976Sjmallett * @INTERNAL
119215976Sjmallett * When NPEI_INT_SUM[C1_LDWN] is set, the PCIe block requires a shutdown and
120215976Sjmallett * initialization to bring the link back up. This handler does this for port 1.
121215976Sjmallett * Note that config space is not enumerated again, so the devices will still be
122215976Sjmallett * unusable.
123215976Sjmallett *
124215976Sjmallett * @param info
125215976Sjmallett *
126215976Sjmallett * @return
127215976Sjmallett */
128215976Sjmallettstatic int __cvmx_error_handle_npei_int_sum_c1_ldwn(const struct cvmx_error_info *info)
129215976Sjmallett{
130215976Sjmallett    cvmx_ciu_soft_prst_t ciu_soft_prst;
131215976Sjmallett    PRINT_ERROR("NPEI_INT_SUM[C1_LDWN]: Reset request due to link1 down status.\n");
132215976Sjmallett    ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
133215976Sjmallett    if (!ciu_soft_prst.s.soft_prst)
134215976Sjmallett    {
135215976Sjmallett        /* Attempt to automatically bring the link back up */
136215976Sjmallett        cvmx_pcie_rc_shutdown(1);
137215976Sjmallett        cvmx_pcie_rc_initialize(1);
138215976Sjmallett    }
139215976Sjmallett    cvmx_write_csr(CVMX_PEXP_NPEI_INT_SUM, cvmx_read_csr(CVMX_PEXP_NPEI_INT_SUM));
140215976Sjmallett    return 1;
141215976Sjmallett}
142215976Sjmallett
143215976Sjmallett/**
144215976Sjmallett * @INTERNAL
145215976Sjmallett * Some errors require more complicated error handing functions than the
146215976Sjmallett * automatically generated functions in cvmx-error-init-*.c. This function
147215976Sjmallett * replaces these handers with hand coded functions for these special cases.
148215976Sjmallett *
149215976Sjmallett * @return Zero on success, negative on failure.
150215976Sjmallett */
151215976Sjmallettint __cvmx_error_custom_initialize(void)
152215976Sjmallett{
153215976Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
154215976Sjmallett    {
155215976Sjmallett        cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
156215976Sjmallett                            CVMX_GMXX_RXX_INT_REG(0,0), 1ull<<21 /* rem_fault */,
157215976Sjmallett                            __cvmx_error_handle_gmxx_rxx_int_reg, 0, NULL, NULL);
158215976Sjmallett        cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
159215976Sjmallett                            CVMX_GMXX_RXX_INT_REG(0,0), 1ull<<20 /* loc_fault */,
160215976Sjmallett                            __cvmx_error_handle_gmxx_rxx_int_reg, 0, NULL, NULL);
161215976Sjmallett    }
162215976Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN56XX))
163215976Sjmallett    {
164215976Sjmallett        cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
165215976Sjmallett                            CVMX_GMXX_RXX_INT_REG(0,1), 1ull<<21 /* rem_fault */,
166215976Sjmallett                            __cvmx_error_handle_gmxx_rxx_int_reg, 0, NULL, NULL);
167215976Sjmallett        cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
168215976Sjmallett                            CVMX_GMXX_RXX_INT_REG(0,1), 1ull<<20 /* loc_fault */,
169215976Sjmallett                            __cvmx_error_handle_gmxx_rxx_int_reg, 0, NULL, NULL);
170215976Sjmallett    }
171215976Sjmallett    if (octeon_has_feature(OCTEON_FEATURE_NPEI))
172215976Sjmallett    {
173215976Sjmallett        cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
174215976Sjmallett                            CVMX_PEXP_NPEI_INT_SUM, 1ull<<59 /* c0_ldwn */,
175215976Sjmallett                            __cvmx_error_handle_npei_int_sum_c0_ldwn, 0, NULL, NULL);
176215976Sjmallett        cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
177215976Sjmallett                            CVMX_PEXP_NPEI_INT_SUM, 1ull<<60 /* c1_ldwn */,
178215976Sjmallett                            __cvmx_error_handle_npei_int_sum_c1_ldwn, 0, NULL, NULL);
179215976Sjmallett    }
180215976Sjmallett
181215976Sjmallett    /* CN63XX pass 1.x has a bug where the PCIe config CRS counter does not
182215976Sjmallett        stop. Disable reporting errors from CRS */
183215976Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
184215976Sjmallett    {
185215976Sjmallett        cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(0),
186215976Sjmallett            1ull<<12);
187215976Sjmallett        cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(0),
188215976Sjmallett            1ull<<13);
189215976Sjmallett        cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(1),
190215976Sjmallett            1ull<<12);
191215976Sjmallett        cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(1),
192215976Sjmallett            1ull<<13);
193215976Sjmallett    }
194215976Sjmallett    return 0;
195215976Sjmallett}
196215976Sjmallett
197215976Sjmallett/**
198215976Sjmallett * @INTERNAL
199215976Sjmallett * DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
200215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
201215976Sjmallett *
202215976Sjmallett * @param info
203215976Sjmallett *
204215976Sjmallett * @return
205215976Sjmallett */
206215976Sjmallettint __cvmx_error_handle_dfa_err_cp2dbe(const struct cvmx_error_info *info)
207215976Sjmallett{
208215976Sjmallett    cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
209215976Sjmallett    PRINT_ERROR("DFA_ERR[CP2DBE]: DFA PP-CP2 Double Bit Error Detected\n");
210215976Sjmallett    return 1;
211215976Sjmallett}
212215976Sjmallett
213215976Sjmallett/**
214215976Sjmallett * @INTERNAL
215215976Sjmallett * DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
216215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
217215976Sjmallett *
218215976Sjmallett * @param info
219215976Sjmallett *
220215976Sjmallett * @return
221215976Sjmallett */
222215976Sjmallettint __cvmx_error_handle_dfa_err_cp2perr(const struct cvmx_error_info *info)
223215976Sjmallett{
224215976Sjmallett    cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
225215976Sjmallett    PRINT_ERROR("DFA_ERR[CP2PERR]: PP-CP2 Parity Error Detected\n");
226215976Sjmallett    return 1;
227215976Sjmallett}
228215976Sjmallett
229215976Sjmallett/**
230215976Sjmallett * @INTERNAL
231215976Sjmallett * DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
232215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
233215976Sjmallett *
234215976Sjmallett * @param info
235215976Sjmallett *
236215976Sjmallett * @return
237215976Sjmallett */
238215976Sjmallettint __cvmx_error_handle_dfa_err_cp2sbe(const struct cvmx_error_info *info)
239215976Sjmallett{
240215976Sjmallett    cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
241215976Sjmallett    PRINT_ERROR("DFA_ERR[CP2SBE]: DFA PP-CP2 Single Bit Error Corrected\n");
242215976Sjmallett    return 1;
243215976Sjmallett}
244215976Sjmallett
245215976Sjmallett/**
246215976Sjmallett * @INTERNAL
247215976Sjmallett * DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
248215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
249215976Sjmallett *
250215976Sjmallett * @param info
251215976Sjmallett *
252215976Sjmallett * @return
253215976Sjmallett */
254215976Sjmallettint __cvmx_error_handle_dfa_err_dblovf(const struct cvmx_error_info *info)
255215976Sjmallett{
256215976Sjmallett    cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
257215976Sjmallett    PRINT_ERROR("DFA_ERR[DBLOVF]: Doorbell Overflow detected\n");
258215976Sjmallett    return 1;
259215976Sjmallett}
260215976Sjmallett
261215976Sjmallett/**
262215976Sjmallett * @INTERNAL
263215976Sjmallett * DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
264215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
265215976Sjmallett *
266215976Sjmallett * @param info
267215976Sjmallett *
268215976Sjmallett * @return
269215976Sjmallett */
270215976Sjmallettint __cvmx_error_handle_dfa_err_dtedbe(const struct cvmx_error_info *info)
271215976Sjmallett{
272215976Sjmallett    cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
273215976Sjmallett    PRINT_ERROR("DFA_ERR[DTEDBE]: DFA DTE 29b Double Bit Error Detected\n");
274215976Sjmallett    return 1;
275215976Sjmallett}
276215976Sjmallett
277215976Sjmallett/**
278215976Sjmallett * @INTERNAL
279215976Sjmallett * DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
280215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
281215976Sjmallett *
282215976Sjmallett * @param info
283215976Sjmallett *
284215976Sjmallett * @return
285215976Sjmallett */
286215976Sjmallettint __cvmx_error_handle_dfa_err_dteperr(const struct cvmx_error_info *info)
287215976Sjmallett{
288215976Sjmallett    cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
289215976Sjmallett    PRINT_ERROR("DFA_ERR[DTEPERR]: DTE Parity Error Detected\n");
290215976Sjmallett    return 1;
291215976Sjmallett}
292215976Sjmallett
293215976Sjmallett/**
294215976Sjmallett * @INTERNAL
295215976Sjmallett * DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
296215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
297215976Sjmallett *
298215976Sjmallett * @param info
299215976Sjmallett *
300215976Sjmallett * @return
301215976Sjmallett */
302215976Sjmallettint __cvmx_error_handle_dfa_err_dtesbe(const struct cvmx_error_info *info)
303215976Sjmallett{
304215976Sjmallett    cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
305215976Sjmallett    PRINT_ERROR("DFA_ERR[DTESBE]: DFA DTE 29b Single Bit Error Corrected\n");
306215976Sjmallett    return 1;
307215976Sjmallett}
308215976Sjmallett
309215976Sjmallett/**
310215976Sjmallett * @INTERNAL
311215976Sjmallett * L2D_ERR contains R/W1C bits along with R/W bits. This means that it requires
312215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
313215976Sjmallett *
314215976Sjmallett * @param info
315215976Sjmallett *
316215976Sjmallett * @return
317215976Sjmallett */
318215976Sjmallettint __cvmx_error_handle_l2d_err_ded_err(const struct cvmx_error_info *info)
319215976Sjmallett{
320215976Sjmallett    cvmx_l2d_err_t derr;
321215976Sjmallett    cvmx_l2d_fadr_t fadr;
322215976Sjmallett    uint64_t syn0 = cvmx_read_csr(CVMX_L2D_FSYN0);
323215976Sjmallett    uint64_t syn1 = cvmx_read_csr(CVMX_L2D_FSYN1);
324215976Sjmallett    derr.u64 = cvmx_read_csr(CVMX_L2D_ERR);
325215976Sjmallett    fadr.u64 = cvmx_read_csr(CVMX_L2D_FADR);
326215976Sjmallett
327215976Sjmallett    PRINT_ERROR("L2D_ERR[DED_ERR] ECC double: fadr: 0x%llx, syn0:0x%llx, syn1: 0x%llx\n",
328215976Sjmallett        (unsigned long long)fadr.u64, (unsigned long long)syn0, (unsigned long long)syn1);
329215976Sjmallett    /* Flush the line that had the error */
330215976Sjmallett    cvmx_l2c_flush_line(fadr.s.fset, fadr.s.fadr >> 1);
331215976Sjmallett    cvmx_write_csr(CVMX_L2D_ERR, derr.u64);
332215976Sjmallett    return 1;
333215976Sjmallett}
334215976Sjmallett
335215976Sjmallett/**
336215976Sjmallett * @INTERNAL
337215976Sjmallett * L2D_ERR contains R/W1C bits along with R/W bits. This means that it requires
338215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
339215976Sjmallett *
340215976Sjmallett * @param info
341215976Sjmallett *
342215976Sjmallett * @return
343215976Sjmallett */
344215976Sjmallettint __cvmx_error_handle_l2d_err_sec_err(const struct cvmx_error_info *info)
345215976Sjmallett{
346215976Sjmallett    cvmx_l2d_err_t derr;
347215976Sjmallett    cvmx_l2d_fadr_t fadr;
348215976Sjmallett    uint64_t syn0 = cvmx_read_csr(CVMX_L2D_FSYN0);
349215976Sjmallett    uint64_t syn1 = cvmx_read_csr(CVMX_L2D_FSYN1);
350215976Sjmallett    derr.u64 = cvmx_read_csr(CVMX_L2D_ERR);
351215976Sjmallett    fadr.u64 = cvmx_read_csr(CVMX_L2D_FADR);
352215976Sjmallett
353215976Sjmallett    PRINT_ERROR("L2D_ERR[SEC_ERR] ECC single: fadr: 0x%llx, syn0:0x%llx, syn1: 0x%llx\n",
354215976Sjmallett        (unsigned long long)fadr.u64, (unsigned long long)syn0, (unsigned long long)syn1);
355215976Sjmallett    /* Flush the line that had the error */
356215976Sjmallett    cvmx_l2c_flush_line(fadr.s.fset, fadr.s.fadr >> 1);
357215976Sjmallett    cvmx_write_csr(CVMX_L2D_ERR, derr.u64);
358215976Sjmallett    return 1;
359215976Sjmallett}
360215976Sjmallett
361215976Sjmallett/**
362215976Sjmallett * @INTERNAL
363215976Sjmallett * L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
364215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
365215976Sjmallett *
366215976Sjmallett * @param info
367215976Sjmallett *
368215976Sjmallett * @return
369215976Sjmallett */
370215976Sjmallettint __cvmx_error_handle_l2t_err_ded_err(const struct cvmx_error_info *info)
371215976Sjmallett{
372215976Sjmallett    cvmx_l2t_err_t terr;
373215976Sjmallett    terr.u64 = cvmx_read_csr(CVMX_L2T_ERR);
374215976Sjmallett    cvmx_write_csr(CVMX_L2T_ERR, terr.u64);
375215976Sjmallett    PRINT_ERROR("L2T_ERR[DED_ERR]: double bit:\tfadr: 0x%x, fset: 0x%x, fsyn: 0x%x\n",
376215976Sjmallett                     terr.s.fadr, terr.s.fset, terr.s.fsyn);
377215976Sjmallett    if (!terr.s.fsyn)
378215976Sjmallett    {
379215976Sjmallett        /* Syndrome is zero, which means error was in non-hit line,
380215976Sjmallett            so flush all associations */
381215976Sjmallett        int i;
382215976Sjmallett        int l2_assoc = cvmx_l2c_get_num_assoc();
383215976Sjmallett
384215976Sjmallett        for (i = 0; i < l2_assoc; i++)
385215976Sjmallett            cvmx_l2c_flush_line(i, terr.s.fadr);
386215976Sjmallett    }
387215976Sjmallett    else
388215976Sjmallett        cvmx_l2c_flush_line(terr.s.fset, terr.s.fadr);
389215976Sjmallett    return 1;
390215976Sjmallett}
391215976Sjmallett
392215976Sjmallett/**
393215976Sjmallett * @INTERNAL
394215976Sjmallett * L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
395215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
396215976Sjmallett *
397215976Sjmallett * @param info
398215976Sjmallett *
399215976Sjmallett * @return
400215976Sjmallett */
401215976Sjmallettint __cvmx_error_handle_l2t_err_lckerr2(const struct cvmx_error_info *info)
402215976Sjmallett{
403215976Sjmallett    cvmx_write_csr(CVMX_L2T_ERR, cvmx_read_csr(CVMX_L2T_ERR));
404215976Sjmallett    PRINT_ERROR("L2T_ERR[LCKERR2]: HW detected a case where a Rd/Wr Miss from PP#n could not find an available/unlocked set (for replacement).\n");
405215976Sjmallett    return 1;
406215976Sjmallett}
407215976Sjmallett
408215976Sjmallett/**
409215976Sjmallett * @INTERNAL
410215976Sjmallett * L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
411215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
412215976Sjmallett *
413215976Sjmallett * @param info
414215976Sjmallett *
415215976Sjmallett * @return
416215976Sjmallett */
417215976Sjmallettint __cvmx_error_handle_l2t_err_lckerr(const struct cvmx_error_info *info)
418215976Sjmallett{
419215976Sjmallett    cvmx_write_csr(CVMX_L2T_ERR, cvmx_read_csr(CVMX_L2T_ERR));
420215976Sjmallett    PRINT_ERROR("L2T_ERR[LCKERR]: SW attempted to LOCK DOWN the last available set of the INDEX (which is ignored by HW - but reported to SW).\n");
421215976Sjmallett    return 1;
422215976Sjmallett}
423215976Sjmallett
424215976Sjmallett/**
425215976Sjmallett * @INTERNAL
426215976Sjmallett * L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
427215976Sjmallett * special handling instead of the normal __cvmx_error_display() function.
428215976Sjmallett *
429215976Sjmallett * @param info
430215976Sjmallett *
431215976Sjmallett * @return
432215976Sjmallett */
433215976Sjmallettint __cvmx_error_handle_l2t_err_sec_err(const struct cvmx_error_info *info)
434215976Sjmallett{
435215976Sjmallett    cvmx_l2t_err_t terr;
436215976Sjmallett    terr.u64 = cvmx_read_csr(CVMX_L2T_ERR);
437215976Sjmallett    cvmx_write_csr(CVMX_L2T_ERR, terr.u64);
438215976Sjmallett    PRINT_ERROR("L2T_ERR[SEC_ERR]: single bit:\tfadr: 0x%x, fset: 0x%x, fsyn: 0x%x\n",
439215976Sjmallett                 terr.s.fadr, terr.s.fset, terr.s.fsyn);
440215976Sjmallett    if (!terr.s.fsyn)
441215976Sjmallett    {
442215976Sjmallett        /* Syndrome is zero, which means error was in non-hit line,
443215976Sjmallett            so flush all associations */
444215976Sjmallett        int i;
445215976Sjmallett        int l2_assoc = cvmx_l2c_get_num_assoc();
446215976Sjmallett
447215976Sjmallett        for (i = 0; i < l2_assoc; i++)
448215976Sjmallett            cvmx_l2c_flush_line(i, terr.s.fadr);
449215976Sjmallett    }
450215976Sjmallett    else
451215976Sjmallett        cvmx_l2c_flush_line(terr.s.fset, terr.s.fadr);
452215976Sjmallett    return 1;
453215976Sjmallett}
454215976Sjmallett
455215976Sjmallett
456215976Sjmallett/**
457215976Sjmallett * @INTERNAL
458215976Sjmallett * LMCX_MEM_CFG0 contains R/W1C bits along with R/W bits. This means that it
459215976Sjmallett * requires special handling instead of the normal __cvmx_error_display()
460215976Sjmallett * function.
461215976Sjmallett *
462215976Sjmallett * @param info
463215976Sjmallett *
464215976Sjmallett * @return
465215976Sjmallett */
466215976Sjmallettstatic int __cvmx_error_handle_lmcx_mem_cfg0(const struct cvmx_error_info *info)
467215976Sjmallett{
468215976Sjmallett    int ddr_controller = info->group_index;
469215976Sjmallett    cvmx_lmcx_mem_cfg0_t mem_cfg0;
470215976Sjmallett    cvmx_lmcx_fadr_t fadr;
471215976Sjmallett    int sec_err;
472215976Sjmallett    int ded_err;
473215976Sjmallett
474215976Sjmallett    mem_cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(ddr_controller));
475215976Sjmallett    fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(ddr_controller));
476215976Sjmallett    cvmx_write_csr(CVMX_LMCX_MEM_CFG0(ddr_controller),mem_cfg0.u64);
477215976Sjmallett
478215976Sjmallett    sec_err = cvmx_dpop(mem_cfg0.s.sec_err);
479215976Sjmallett    ded_err = cvmx_dpop(mem_cfg0.s.ded_err);
480215976Sjmallett
481215976Sjmallett    if (ded_err || sec_err)
482215976Sjmallett    {
483215976Sjmallett        PRINT_ERROR("DDR%d ECC: %d Single bit corrections, %d Double bit errors\n"
484215976Sjmallett                     "DDR%d ECC:\tFailing dimm:   %u\n"
485215976Sjmallett                     "DDR%d ECC:\tFailing rank:   %u\n"
486215976Sjmallett                     "DDR%d ECC:\tFailing bank:   %u\n"
487215976Sjmallett                     "DDR%d ECC:\tFailing row:    0x%x\n"
488215976Sjmallett                     "DDR%d ECC:\tFailing column: 0x%x\n",
489215976Sjmallett                     ddr_controller, sec_err, ded_err,
490215976Sjmallett                     ddr_controller, fadr.cn38xx.fdimm,
491215976Sjmallett                     ddr_controller, fadr.cn38xx.fbunk,
492215976Sjmallett                     ddr_controller, fadr.cn38xx.fbank,
493215976Sjmallett                     ddr_controller, fadr.cn38xx.frow,
494215976Sjmallett                     ddr_controller, fadr.cn38xx.fcol);
495215976Sjmallett    }
496215976Sjmallett    return 1;
497215976Sjmallett}
498215976Sjmallett
499215976Sjmallett/**
500215976Sjmallett * @INTERNAL
501215976Sjmallett * LMCX_MEM_CFG0 contains R/W1C bits along with R/W bits. This means that it
502215976Sjmallett * requires special handling instead of the normal __cvmx_error_display()
503215976Sjmallett * function.
504215976Sjmallett *
505215976Sjmallett * @param info
506215976Sjmallett *
507215976Sjmallett * @return
508215976Sjmallett */
509215976Sjmallettint __cvmx_error_handle_lmcx_mem_cfg0_ded_err(const struct cvmx_error_info *info)
510215976Sjmallett{
511215976Sjmallett    return __cvmx_error_handle_lmcx_mem_cfg0(info);
512215976Sjmallett}
513215976Sjmallett
514215976Sjmallett/**
515215976Sjmallett * @INTERNAL
516215976Sjmallett * LMCX_MEM_CFG0 contains R/W1C bits along with R/W bits. This means that it
517215976Sjmallett * requires special handling instead of the normal __cvmx_error_display()
518215976Sjmallett * function.
519215976Sjmallett *
520215976Sjmallett * @param info
521215976Sjmallett *
522215976Sjmallett * @return
523215976Sjmallett */
524215976Sjmallettint __cvmx_error_handle_lmcx_mem_cfg0_sec_err(const struct cvmx_error_info *info)
525215976Sjmallett{
526215976Sjmallett    return __cvmx_error_handle_lmcx_mem_cfg0(info);
527215976Sjmallett}
528215976Sjmallett
529215976Sjmallett/**
530215976Sjmallett * @INTERNAL
531215976Sjmallett * POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
532215976Sjmallett * requires special handling instead of the normal __cvmx_error_display()
533215976Sjmallett * function.
534215976Sjmallett *
535215976Sjmallett * @param info
536215976Sjmallett *
537215976Sjmallett * @return
538215976Sjmallett */
539215976Sjmallettint __cvmx_error_handle_pow_ecc_err_dbe(const struct cvmx_error_info *info)
540215976Sjmallett{
541215976Sjmallett    cvmx_write_csr(CVMX_POW_ECC_ERR, cvmx_read_csr(CVMX_POW_ECC_ERR));
542215976Sjmallett    PRINT_ERROR("POW_ECC_ERR[DBE]: POW double bit error\n");
543215976Sjmallett    return 1;
544215976Sjmallett}
545215976Sjmallett
546215976Sjmallett/**
547215976Sjmallett * @INTERNAL
548215976Sjmallett * POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
549215976Sjmallett * requires special handling instead of the normal __cvmx_error_display()
550215976Sjmallett * function.
551215976Sjmallett *
552215976Sjmallett * @param info
553215976Sjmallett *
554215976Sjmallett * @return
555215976Sjmallett */
556215976Sjmallettint __cvmx_error_handle_pow_ecc_err_iop(const struct cvmx_error_info *info)
557215976Sjmallett{
558215976Sjmallett    cvmx_pow_ecc_err_t err;
559215976Sjmallett    err.u64 = cvmx_read_csr(CVMX_POW_ECC_ERR);
560215976Sjmallett    cvmx_write_csr(CVMX_POW_ECC_ERR, err.u64);
561215976Sjmallett    if (err.s.iop & (1 << 0))
562215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP0]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH/DESCH/UPD_WQP from PP in NULL_NULL state\n");
563215976Sjmallett    if (err.s.iop & (1 << 1))
564215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP1]: Received SWTAG/SWTAG_DESCH/DESCH/UPD_WQP from PP in NULL state\n");
565215976Sjmallett    if (err.s.iop & (1 << 2))
566215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP2]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH/GET_WORK from PP with pending tag switch to ORDERED or ATOMIC\n");
567215976Sjmallett    if (err.s.iop & (1 << 3))
568215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP3]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH from PP with tag specified as NULL_NULL\n");
569215976Sjmallett    if (err.s.iop & (1 << 4))
570215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP4]: Received SWTAG_FULL/SWTAG_DESCH from PP with tag specified as NULL\n");
571215976Sjmallett    if (err.s.iop & (1 << 5))
572215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP5]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH/DESCH/UPD_WQP/GET_WORK/NULL_RD from PP with GET_WORK pending\n");
573215976Sjmallett    if (err.s.iop & (1 << 6))
574215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP6]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH/DESCH/UPD_WQP/GET_WORK/NULL_RD from PP with NULL_RD pending\n");
575215976Sjmallett    if (err.s.iop & (1 << 7))
576215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP7]: Received CLR_NSCHED from PP with SWTAG_DESCH/DESCH/CLR_NSCHED pending\n");
577215976Sjmallett    if (err.s.iop & (1 << 8))
578215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP8]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH/DESCH/UPD_WQP/GET_WORK/NULL_RD from PP with CLR_NSCHED pending\n");
579215976Sjmallett    if (err.s.iop & (1 << 9))
580215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP9]: Received illegal opcode\n");
581215976Sjmallett    if (err.s.iop & (1 << 10))
582215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP10]: Received ADD_WORK with tag specified as NULL_NULL\n");
583215976Sjmallett    if (err.s.iop & (1 << 11))
584215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP11]: Received DBG load from PP with DBG load pending\n");
585215976Sjmallett    if (err.s.iop & (1 << 12))
586215976Sjmallett        PRINT_ERROR("POW_ECC_ERR[IOP12]: Received CSR load from PP with CSR load pending\n");
587215976Sjmallett    return 1;
588215976Sjmallett}
589215976Sjmallett
590215976Sjmallett/**
591215976Sjmallett * @INTERNAL
592215976Sjmallett * POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
593215976Sjmallett * requires special handling instead of the normal __cvmx_error_display()
594215976Sjmallett * function.
595215976Sjmallett *
596215976Sjmallett * @param info
597215976Sjmallett *
598215976Sjmallett * @return
599215976Sjmallett */
600215976Sjmallettint __cvmx_error_handle_pow_ecc_err_rpe(const struct cvmx_error_info *info)
601215976Sjmallett{
602215976Sjmallett    cvmx_write_csr(CVMX_POW_ECC_ERR, cvmx_read_csr(CVMX_POW_ECC_ERR));
603215976Sjmallett    PRINT_ERROR("POW_ECC_ERR[RPE]: Remote pointer error\n");
604215976Sjmallett    return 1;
605215976Sjmallett}
606215976Sjmallett
607215976Sjmallett/**
608215976Sjmallett * @INTERNAL
609215976Sjmallett * POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
610215976Sjmallett * requires special handling instead of the normal __cvmx_error_display()
611215976Sjmallett * function.
612215976Sjmallett *
613215976Sjmallett * @param info
614215976Sjmallett *
615215976Sjmallett * @return
616215976Sjmallett */
617215976Sjmallettint __cvmx_error_handle_pow_ecc_err_sbe(const struct cvmx_error_info *info)
618215976Sjmallett{
619215976Sjmallett    cvmx_write_csr(CVMX_POW_ECC_ERR, cvmx_read_csr(CVMX_POW_ECC_ERR));
620215976Sjmallett    PRINT_ERROR("POW_ECC_ERR[SBE]: POW single bit error\n");
621215976Sjmallett    return 1;
622215976Sjmallett}
623215976Sjmallett
624215976Sjmallett
625