Remove some files not used by the FreeBSD kernel which have been adding quite
a bit of bloat to the kernel source tree's size.
This commit is contained in:
parent
8a5350984f
commit
964fdce070
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=232915
@ -1,264 +0,0 @@
|
||||
/***********************license start***************
|
||||
* Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
|
||||
* reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
|
||||
* * Neither the name of Cavium Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
|
||||
* This Software, including technical data, may be subject to U.S. export control
|
||||
* laws, including the U.S. Export Administration Act and its associated
|
||||
* regulations, and may be subject to export or import regulations in other
|
||||
* countries.
|
||||
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
|
||||
* THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
|
||||
* DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
|
||||
* SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
|
||||
* VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
|
||||
* CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
|
||||
* PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
|
||||
***********************license end**************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Utility functions for working with the CSR database
|
||||
*
|
||||
* <hr>$Revision: 70030 $<hr>
|
||||
*/
|
||||
#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
|
||||
#define PRINTF printk
|
||||
#include <asm/octeon/cvmx.h>
|
||||
#include <asm/octeon/cvmx-csr-db.h>
|
||||
#else
|
||||
#define PRINTF printf
|
||||
#include "cvmx.h"
|
||||
#include "cvmx-csr-db.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Figure out which database to use for this chip. The passed
|
||||
* identifier can be a processor ID or a PCI ID.
|
||||
*
|
||||
* @param identifier processor ID or a PCI ID
|
||||
*
|
||||
* @return index into the csr db
|
||||
*/
|
||||
int cvmx_db_get_chipindex(int identifier)
|
||||
{
|
||||
/* First try and see if the identifier is a Processor ID */
|
||||
switch (identifier & 0xffff00)
|
||||
{
|
||||
case 0x000d0600: /* CN50XX */
|
||||
return 8;
|
||||
case 0x000d0400: /* CN56XX */
|
||||
return 7;
|
||||
case 0x000d0300: /* CN58XX */
|
||||
return 5;
|
||||
case 0x000d0000: /* CN38XX */
|
||||
return 3;
|
||||
case 0x000d0100: /* CN31XX */
|
||||
return 1;
|
||||
case 0x000d0200: /* CN3010 */
|
||||
return 2;
|
||||
case 0x000d0700: /* CN52XX */
|
||||
return 10;
|
||||
case 0x000d9300: /* CN61XX */
|
||||
return 11;
|
||||
case 0x000d9000: /* CN63XX */
|
||||
return 13;
|
||||
case 0x000d9200: /* CN66XX */
|
||||
return 14;
|
||||
case 0x000d9100: /* CN68XX */
|
||||
return 16;
|
||||
case 0x000d9400: /* CNF71XX */
|
||||
return 17;
|
||||
}
|
||||
|
||||
/* Next try PCI device IDs */
|
||||
switch (identifier)
|
||||
{
|
||||
case 0x0003177d: /* CN38XX Pass 1 */
|
||||
return 0;
|
||||
case 0x0004177d: /* CN38XX Pass 2 */
|
||||
return 0;
|
||||
case 0x0005177d: /* CN38XX Pass 3 */
|
||||
return 3;
|
||||
case 0x1001177d: /* Thunder */
|
||||
return 3;
|
||||
case 0x0020177d: /* CN31XX Pass 1 */
|
||||
return 1;
|
||||
case 0x0030177d: /* CN30XX Pass 1 */
|
||||
return 2;
|
||||
case 0x0040177d: /* CN58XX Pass 2 */
|
||||
return 5;
|
||||
case 0x0050177d: /* CN56XX Pass 2 */
|
||||
return 7;
|
||||
case 0x0070177d: /* CN50XX Pass 1 */
|
||||
return 8;
|
||||
case 0x0080177d: /* CN52XX Pass 2 */
|
||||
return 10;
|
||||
case 0x0093177d: /* CN61XX Pass 2 */
|
||||
return 11;
|
||||
case 0x0090177d: /* CN63XX Pass 2 */
|
||||
return 13;
|
||||
case 0x0092177d: /* CN66XX Pass 1 */
|
||||
return 14;
|
||||
case 0x0091177d: /* CN68XX Pass 2 */
|
||||
return 16;
|
||||
case 0x0094177d: /* CNF71XX Pass 1 */
|
||||
return 17;
|
||||
}
|
||||
|
||||
/* Default to Pass 3 if we don't know */
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
#ifndef CVMX_BUILD_FOR_LINUX_KERNEL
|
||||
/**
|
||||
* Get the CSR DB entry for the passed Octeon model and CSR name. The
|
||||
* model can either be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param name CSR name to lookup
|
||||
*
|
||||
* @return CSR DB entry or NULL on failure
|
||||
*/
|
||||
const CVMX_CSR_DB_ADDRESS_TYPE *cvmx_csr_db_get(int identifier, const char *name)
|
||||
{
|
||||
int chip = cvmx_db_get_chipindex(identifier);
|
||||
int i=0;
|
||||
if (strncasecmp(name, "CVMX_", 5) == 0)
|
||||
name += 5;
|
||||
while (cvmx_csr_db_addresses[chip][i].name)
|
||||
{
|
||||
if (strcasecmp(name, cvmx_csr_db_addresses[chip][i].name) == 0)
|
||||
return &(cvmx_csr_db_addresses[chip][i]);
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __cvmx_csr_db_decode_csr(int chip, int index, uint64_t value)
|
||||
{
|
||||
int field;
|
||||
int csr = cvmx_csr_db_addresses[chip][index].csroff;
|
||||
PRINTF("%s(0x%016llx) = 0x%016llx\n", cvmx_csr_db_addresses[chip][index].name, (unsigned long long)cvmx_csr_db_addresses[chip][index].address, (unsigned long long)value);
|
||||
for (field=cvmx_csr_db[chip][csr].fieldoff+cvmx_csr_db[chip][csr].numfields-1; field>=cvmx_csr_db[chip][csr].fieldoff; field--)
|
||||
{
|
||||
uint64_t v = (value >> cvmx_csr_db_fields[chip][field].startbit);
|
||||
if(cvmx_csr_db_fields[chip][field].sizebits < 64)
|
||||
v = v & ~((~0x0ull) << cvmx_csr_db_fields[chip][field].sizebits);
|
||||
if (cvmx_csr_db_fields[chip][field].sizebits == 1)
|
||||
PRINTF(" [ %2d] %-20s = %10llu (0x%llx)\n",
|
||||
cvmx_csr_db_fields[chip][field].startbit, cvmx_csr_db_fields[chip][field].name,
|
||||
(unsigned long long)v, (unsigned long long)v);
|
||||
else
|
||||
PRINTF(" [%2d:%2d] %-20s = %10llu (0x%llx)\n",
|
||||
cvmx_csr_db_fields[chip][field].startbit + cvmx_csr_db_fields[chip][field].sizebits - 1,
|
||||
cvmx_csr_db_fields[chip][field].startbit,
|
||||
cvmx_csr_db_fields[chip][field].name,
|
||||
(unsigned long long)v, (unsigned long long)v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a CSR value into named bitfields. The model can either
|
||||
* be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param address CSR address being decoded
|
||||
* @param value Value to decode
|
||||
*/
|
||||
void cvmx_csr_db_decode(int identifier, uint64_t address, uint64_t value)
|
||||
{
|
||||
int chip = cvmx_db_get_chipindex(identifier);
|
||||
int index=0;
|
||||
/* Strip off the upper 8 bits since they are normally mips addressing
|
||||
modes */
|
||||
address &= (1ull<<56)-1;
|
||||
while (cvmx_csr_db_addresses[chip][index].name)
|
||||
{
|
||||
if (cvmx_csr_db_addresses[chip][index].address == address)
|
||||
__cvmx_csr_db_decode_csr(chip, index, value);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a CSR value into named bitfields. The model can either
|
||||
* be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param name CSR name to decode
|
||||
* @param value Value to decode
|
||||
*/
|
||||
void cvmx_csr_db_decode_by_name(int identifier, const char *name, uint64_t value)
|
||||
{
|
||||
int chip = cvmx_db_get_chipindex(identifier);
|
||||
int index=0;
|
||||
while (cvmx_csr_db_addresses[chip][index].name)
|
||||
{
|
||||
if (strcasecmp(name, cvmx_csr_db_addresses[chip][index].name) == 0)
|
||||
{
|
||||
__cvmx_csr_db_decode_csr(chip, index, value);
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef CVMX_BUILD_FOR_LINUX_KERNEL
|
||||
/**
|
||||
* Print a list of csrs begimning with a prefix. The
|
||||
* model can either be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param prefix Beginning prefix to look for
|
||||
*/
|
||||
void cvmx_csr_db_display_list(int identifier, const char *prefix)
|
||||
{
|
||||
int i, len;
|
||||
int chip = cvmx_db_get_chipindex(identifier);
|
||||
if (prefix == NULL)
|
||||
prefix = "";
|
||||
if (strncasecmp(prefix, "CVMX_", 5) == 0)
|
||||
prefix += 5;
|
||||
len = strlen(prefix);
|
||||
|
||||
i=0;
|
||||
while (cvmx_csr_db_addresses[chip][i].name)
|
||||
{
|
||||
if (strncasecmp(prefix, cvmx_csr_db_addresses[chip][i].name, len) == 0)
|
||||
PRINTF("%s\n", cvmx_csr_db_addresses[chip][i].name);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,194 +0,0 @@
|
||||
/***********************license start***************
|
||||
* Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
|
||||
* reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
|
||||
* * Neither the name of Cavium Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
|
||||
* This Software, including technical data, may be subject to U.S. export control
|
||||
* laws, including the U.S. Export Administration Act and its associated
|
||||
* regulations, and may be subject to export or import regulations in other
|
||||
* countries.
|
||||
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
|
||||
* THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
|
||||
* DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
|
||||
* SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
|
||||
* VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
|
||||
* CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
|
||||
* PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
|
||||
***********************license end**************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef __CVMX_CSR_DB_H__
|
||||
#define __CVMX_CSR_DB_H__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Interface for the Octeon CSR database.
|
||||
*
|
||||
*
|
||||
* <hr>$Revision: 70030 $<hr>
|
||||
*
|
||||
*/
|
||||
#if !defined(CVMX_BUILD_FOR_LINUX_KERNEL) && !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)
|
||||
#include "cvmx-platform.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CVMX_CSR_DB_TYPE_RSL, /**< Octeon internal address, but indirect and slow (not used for addresses) */
|
||||
CVMX_CSR_DB_TYPE_NCB, /**< Octeon internal address */
|
||||
CVMX_CSR_DB_TYPE_PCI_NCB, /**< Can be accessed through PCI BAR0, also an NCB alias (not used for addresses) */
|
||||
CVMX_CSR_DB_TYPE_PCICONFIG, /**< PCI Config, also an NCB alias */
|
||||
CVMX_CSR_DB_TYPE_PCI, /**< PCI BAR0 (only) */
|
||||
CVMX_CSR_DB_TYPE_PEXP, /**< PCIe BAR 0 address only */
|
||||
CVMX_CSR_DB_TYPE_PEXP_NCB, /**< NCB-direct and PCIe BAR0 address */
|
||||
CVMX_CSR_DB_TYPE_PCICONFIGEP, /**< PCIe config address (EP mode) + indirect through PESC*_CFG_RD/PESC*_CFG_WR */
|
||||
CVMX_CSR_DB_TYPE_PCICONFIGRC, /**< PCICONFIGRC - PCIe config address (RC mode) + indirect through PESC*_CFG_RD/PESC*_CFG_WR */
|
||||
CVMX_CSR_DB_TYPE_SRIOMAINT /**< SRIOMAINT - SRIO maintenance registers */
|
||||
} CVMX_CSR_DB_TYPE_FIELD;
|
||||
|
||||
/**
|
||||
* the structure for the cvmx_csr_db_addresses[] array that
|
||||
* holds all possible Octeon CSR addresses
|
||||
*/
|
||||
typedef struct {
|
||||
char * name; /**< CSR name at the supplied address */
|
||||
uint64_t address; /**< Address = octeon internal, PCI BAR0 relative, PCI CONFIG relative */
|
||||
CVMX_CSR_DB_TYPE_FIELD type:8; /**< the type */
|
||||
uint8_t widthbits; /**< the width of the CSR in bits */
|
||||
uint16_t csroff; /**< position of the CSR in cvmx_csr_db[] */
|
||||
} __attribute__ ((packed)) CVMX_CSR_DB_ADDRESS_TYPE;
|
||||
|
||||
/**
|
||||
* the structure for the cvmx_csr_db_fields[] array that
|
||||
* holds all possible Octeon CSR fields
|
||||
*/
|
||||
typedef struct {
|
||||
char * name; /**< name of the field */
|
||||
uint8_t startbit; /**< starting bit position of the field */
|
||||
uint8_t sizebits; /**< the size of the field in bits */
|
||||
uint16_t csroff; /**< position of the CSR containing the field in cvmx_csr_db[] (get alias from there) */
|
||||
char * type; /**< the type of the field R/W, R/W1C, ... */
|
||||
uint8_t rst_unp; /**< set if the reset value is unknown */
|
||||
uint8_t typ_unp; /**< set if the typical value is unknown */
|
||||
uint64_t rst_val; /**< the reset value of the field */
|
||||
uint64_t typ_val; /**< the typical value of the field */
|
||||
} __attribute__ ((packed)) CVMX_CSR_DB_FIELD_TYPE;
|
||||
|
||||
/**
|
||||
* the structure for the cvmx_csr_db[] array that holds all
|
||||
* possible Octeon CSR forms
|
||||
*/
|
||||
typedef struct {
|
||||
char *basename; /**< the base name of the CSR */
|
||||
CVMX_CSR_DB_TYPE_FIELD type:8; /**< the type */
|
||||
uint8_t widthbits; /**< the width of the CSR in bits */
|
||||
uint16_t addoff; /**< the position of the first address in cvmx_csr_db_csr_addresses[] (numblocks*indexnum is #) */
|
||||
uint8_t numfields; /**< the number of fields in the CSR (and in cvmx_csr_db_csr_fields[]) */
|
||||
uint16_t fieldoff; /**< the position of the first field in cvmx_csr_db_csr_fields[] */
|
||||
} __attribute__ ((packed)) CVMX_CSR_DB_TYPE;
|
||||
|
||||
|
||||
/**
|
||||
* This NULL terminated array contains the CVMX_CSR_DB_TYPE
|
||||
* arrays for each chip. Each array entry is another NULL
|
||||
* terminated array of CSRs.
|
||||
*/
|
||||
extern const CVMX_CSR_DB_TYPE *cvmx_csr_db[];
|
||||
|
||||
/**
|
||||
* This NULL terminated array contains the CVMX_CSR_DB_ADDRESS_TYPE
|
||||
* arrays for each chip. Each array entry is another NULL
|
||||
* terminated array of CSR addresses.
|
||||
*/
|
||||
extern const CVMX_CSR_DB_ADDRESS_TYPE *cvmx_csr_db_addresses[];
|
||||
|
||||
/**
|
||||
* This NULL terminated array contains the CVMX_CSR_DB_FIELD_TYPE
|
||||
* arrays for each chip. Each array entry is another NULL
|
||||
* terminated array of CSR fields.
|
||||
*/
|
||||
extern const CVMX_CSR_DB_FIELD_TYPE *cvmx_csr_db_fields[];
|
||||
|
||||
/**
|
||||
* Figure out which database to use for this chip. The passed
|
||||
* identifier can be a processor ID or a PCI ID.
|
||||
*
|
||||
* @param identifier processor ID or a PCI ID
|
||||
*
|
||||
* @return index into the csr db
|
||||
*/
|
||||
extern int cvmx_db_get_chipindex(int identifier);
|
||||
|
||||
/**
|
||||
* Get the CSR DB entry for the passed Octeon model and CSR name. The
|
||||
* model can either be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param name CSR name to lookup
|
||||
*
|
||||
* @return CSR DB entry or NULL on failure
|
||||
*/
|
||||
extern const CVMX_CSR_DB_ADDRESS_TYPE *cvmx_csr_db_get(int identifier, const char *name);
|
||||
|
||||
/**
|
||||
* Decode a CSR value into named bitfields. The model can either
|
||||
* be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param address CSR address being decoded
|
||||
* @param value Value to decode
|
||||
*/
|
||||
extern void cvmx_csr_db_decode(int identifier, uint64_t address, uint64_t value);
|
||||
|
||||
/**
|
||||
* Decode a CSR value into named bitfields. The model can either
|
||||
* be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param name CSR name to decode
|
||||
* @param value Value to decode
|
||||
*/
|
||||
extern void cvmx_csr_db_decode_by_name(int identifier, const char *name, uint64_t value);
|
||||
|
||||
/**
|
||||
* Print a list of csrs begimning with a prefix. The
|
||||
* model can either be specified as a processor id or PCI id.
|
||||
*
|
||||
* @param identifier Identifer to choose the CSR DB with
|
||||
* @param prefix Beginning prefix to look for
|
||||
*/
|
||||
extern void cvmx_csr_db_display_list(int identifier, const char *prefix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,889 +0,0 @@
|
||||
/***********************license start***************
|
||||
* Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
|
||||
* reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
|
||||
* * Neither the name of Cavium Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
|
||||
* This Software, including technical data, may be subject to U.S. export control
|
||||
* laws, including the U.S. Export Administration Act and its associated
|
||||
* regulations, and may be subject to export or import regulations in other
|
||||
* countries.
|
||||
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
|
||||
* THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
|
||||
* DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
|
||||
* SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
|
||||
* VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
|
||||
* CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
|
||||
* PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
|
||||
***********************license end**************************************/
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Prototypes for custom error handler function not handled by the default
|
||||
* message display error function.
|
||||
*
|
||||
* <hr>$Revision: 44252 $<hr>
|
||||
*/
|
||||
#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
|
||||
#include <asm/octeon/cvmx.h>
|
||||
#include <asm/octeon/cvmx-error.h>
|
||||
#include <asm/octeon/cvmx-error-custom.h>
|
||||
#include <asm/octeon/cvmx-helper.h>
|
||||
#include <asm/octeon/cvmx-l2c.h>
|
||||
#include <asm/octeon/cvmx-pcie.h>
|
||||
#include <asm/octeon/cvmx-pexp-defs.h>
|
||||
#include <asm/octeon/cvmx-dfa-defs.h>
|
||||
#include <asm/octeon/cvmx-gmxx-defs.h>
|
||||
#include <asm/octeon/cvmx-lmcx-defs.h>
|
||||
#include <asm/octeon/cvmx-pemx-defs.h>
|
||||
#include <asm/octeon/cvmx-sriox-defs.h>
|
||||
#define PRINT_ERROR(format, ...) cvmx_safe_printf("ERROR " format, ##__VA_ARGS__)
|
||||
#else
|
||||
#include "cvmx.h"
|
||||
#include "cvmx-error.h"
|
||||
#include "cvmx-error-custom.h"
|
||||
#include "cvmx-helper.h"
|
||||
#include "cvmx-l2c.h"
|
||||
#include "cvmx-pcie.h"
|
||||
#include "cvmx-interrupt.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* XAUI interfaces need to be reset whenever a local or remote fault
|
||||
* is detected. Calling autoconf takes the link through a reset.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static int __cvmx_error_handle_gmxx_rxx_int_reg(const struct cvmx_error_info *info)
|
||||
{
|
||||
#ifdef CVMX_ENABLE_PKO_FUNCTIONS
|
||||
int ipd_port = info->group_index;
|
||||
switch(ipd_port)
|
||||
{
|
||||
case 0x800:
|
||||
ipd_port = 0x840;
|
||||
break;
|
||||
case 0xa00:
|
||||
ipd_port = 0xa40;
|
||||
break;
|
||||
case 0xb00:
|
||||
ipd_port = 0xb40;
|
||||
break;
|
||||
case 0xc00:
|
||||
ipd_port = 0xc40;
|
||||
break;
|
||||
}
|
||||
cvmx_helper_link_autoconf(ipd_port);
|
||||
#endif
|
||||
cvmx_write_csr(info->status_addr, info->status_mask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* When NPEI_INT_SUM[C0_LDWN] is set, the PCIe block requires a shutdown and
|
||||
* initialization to bring the link back up. This handler does this for port 0.
|
||||
* Note that config space is not enumerated again, so the devices will still be
|
||||
* unusable.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static int __cvmx_error_handle_npei_int_sum_c0_ldwn(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_ciu_soft_prst_t ciu_soft_prst;
|
||||
PRINT_ERROR("NPEI_INT_SUM[C0_LDWN]: Reset request due to link0 down status.\n");
|
||||
ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
|
||||
if (!ciu_soft_prst.s.soft_prst)
|
||||
{
|
||||
/* Attempt to automatically bring the link back up */
|
||||
cvmx_pcie_rc_shutdown(0);
|
||||
cvmx_pcie_rc_initialize(0);
|
||||
}
|
||||
cvmx_write_csr(CVMX_PEXP_NPEI_INT_SUM, cvmx_read_csr(CVMX_PEXP_NPEI_INT_SUM));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* When NPEI_INT_SUM[C1_LDWN] is set, the PCIe block requires a shutdown and
|
||||
* initialization to bring the link back up. This handler does this for port 1.
|
||||
* Note that config space is not enumerated again, so the devices will still be
|
||||
* unusable.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static int __cvmx_error_handle_npei_int_sum_c1_ldwn(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_ciu_soft_prst_t ciu_soft_prst;
|
||||
PRINT_ERROR("NPEI_INT_SUM[C1_LDWN]: Reset request due to link1 down status.\n");
|
||||
ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
|
||||
if (!ciu_soft_prst.s.soft_prst)
|
||||
{
|
||||
/* Attempt to automatically bring the link back up */
|
||||
cvmx_pcie_rc_shutdown(1);
|
||||
cvmx_pcie_rc_initialize(1);
|
||||
}
|
||||
cvmx_write_csr(CVMX_PEXP_NPEI_INT_SUM, cvmx_read_csr(CVMX_PEXP_NPEI_INT_SUM));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define DECODE_FAILING_ADDRESS
|
||||
//#define DECODE_FAILING_BIT
|
||||
|
||||
#ifdef DECODE_FAILING_BIT
|
||||
#define _Db(x) (x) /* Data Bit */
|
||||
#define _Ec(x) (0x100+x) /* ECC Bit */
|
||||
#define _Ad(x) (0x200+x) /* Address Bit */
|
||||
#define _Bu(x) (0x400+x) /* Burst */
|
||||
#define _Un() (-1) /* Unused */
|
||||
/* Use ECC Code as index to lookup corrected bit */
|
||||
const static short lmc_syndrome_bits[256] = {
|
||||
/* __ 0 __ __ 1 __ __ 2 __ __ 3 __ __ 4 __ __ 5 __ __ 6 __ __ 7 __ __ 8 __ __ 9 __ __ A __ __ B __ __ C __ __ D __ __ E __ __ F __ */
|
||||
/* 00: */ _Un( ), _Ec( 0), _Ec( 1), _Un( ), _Ec( 2), _Un( ), _Un( ), _Un( ), _Ec( 3), _Un( ), _Un( ), _Db(17), _Un( ), _Un( ), _Db(16), _Un( ),
|
||||
/* 10: */ _Ec( 4), _Un( ), _Un( ), _Db(18), _Un( ), _Db(19), _Db(20), _Un( ), _Un( ), _Db(21), _Db(22), _Un( ), _Db(23), _Un( ), _Un( ), _Un( ),
|
||||
/* 20: */ _Ec( 5), _Un( ), _Un( ), _Db( 8), _Un( ), _Db( 9), _Db(10), _Un( ), _Un( ), _Db(11), _Db(12), _Un( ), _Db(13), _Un( ), _Un( ), _Un( ),
|
||||
/* 30: */ _Un( ), _Db(14), _Un( ), _Un( ), _Db(15), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Ad(34), _Un( ),
|
||||
/* 40: */ _Ec( 6), _Un( ), _Un( ), _Un( ), _Un( ), _Ad( 7), _Ad( 8), _Un( ), _Un( ), _Ad( 9), _Db(33), _Un( ), _Ad(10), _Un( ), _Un( ), _Db(32),
|
||||
/* 50: */ _Un( ), _Ad(11), _Db(34), _Un( ), _Db(35), _Un( ), _Un( ), _Db(36), _Db(37), _Un( ), _Un( ), _Db(38), _Un( ), _Db(39), _Ad(12), _Un( ),
|
||||
/* 60: */ _Un( ), _Ad(13), _Db(56), _Un( ), _Db(57), _Un( ), _Un( ), _Db(58), _Db(59), _Un( ), _Un( ), _Db(60), _Un( ), _Db(61), _Ad(14), _Un( ),
|
||||
/* 70: */ _Db(62), _Un( ), _Un( ), _Ad(15), _Un( ), _Db(63), _Ad(16), _Un( ), _Un( ), _Ad(17), _Ad(18), _Un( ), _Ad(19), _Un( ), _Ad(20), _Un( ),
|
||||
/* 80: */ _Ec( 7), _Un( ), _Un( ), _Ad(21), _Un( ), _Ad(22), _Ad(23), _Un( ), _Un( ), _Ad(24), _Db(49), _Un( ), _Ad(25), _Un( ), _Un( ), _Db(48),
|
||||
/* 90: */ _Un( ), _Ad(26), _Db(50), _Un( ), _Db(51), _Un( ), _Un( ), _Db(52), _Db(53), _Un( ), _Un( ), _Db(54), _Un( ), _Db(55), _Ad(27), _Un( ),
|
||||
/* A0: */ _Un( ), _Ad(28), _Db(40), _Un( ), _Db(41), _Un( ), _Un( ), _Db(42), _Db(43), _Un( ), _Un( ), _Db(44), _Un( ), _Db(45), _Ad(29), _Un( ),
|
||||
/* B0: */ _Db(46), _Un( ), _Un( ), _Ad(30), _Un( ), _Db(47), _Ad(31), _Un( ), _Un( ), _Ad(32), _Ad(33), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ),
|
||||
/* C0: */ _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Db( 1), _Un( ), _Un( ), _Db( 0), _Un( ),
|
||||
/* D0: */ _Un( ), _Un( ), _Un( ), _Db( 2), _Un( ), _Db( 3), _Db( 4), _Un( ), _Un( ), _Db( 5), _Db( 6), _Un( ), _Db( 7), _Un( ), _Un( ), _Un( ),
|
||||
/* E0: */ _Un( ), _Un( ), _Un( ), _Db(24), _Un( ), _Db(25), _Db(26), _Un( ), _Un( ), _Db(27), _Db(28), _Un( ), _Db(29), _Un( ), _Un( ), _Un( ),
|
||||
/* F0: */ _Un( ), _Db(30), _Un( ), _Un( ), _Db(31), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( ), _Un( )
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* This error bit handler clears the status and prints failure infomation.
|
||||
*
|
||||
* @param info Error register to check
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static int __cvmx_cn6xxx_lmc_ecc_error_display(const cvmx_error_info_t *info)
|
||||
{
|
||||
#ifdef DECODE_FAILING_ADDRESS
|
||||
cvmx_lmcx_config_t lmc_config;
|
||||
uint64_t fadr_physical, fadr_data;
|
||||
#endif
|
||||
|
||||
int ddr_controller = info->group_index;
|
||||
cvmx_lmcx_int_t lmc_int;
|
||||
cvmx_lmcx_fadr_t fadr;
|
||||
cvmx_lmcx_ecc_synd_t ecc_synd;
|
||||
int sec_err;
|
||||
int ded_err;
|
||||
int syndrome = -1;
|
||||
int phase;
|
||||
|
||||
lmc_int.u64 = cvmx_read_csr(CVMX_LMCX_INT(ddr_controller));
|
||||
fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(ddr_controller));
|
||||
ecc_synd.u64 = cvmx_read_csr(CVMX_LMCX_ECC_SYND(ddr_controller));
|
||||
/* This assumes that all bits in the status register are RO or R/W1C */
|
||||
cvmx_write_csr(info->status_addr, info->status_mask);
|
||||
|
||||
#ifdef DECODE_FAILING_ADDRESS
|
||||
lmc_config.u64 = cvmx_read_csr(CVMX_LMCX_CONFIG(ddr_controller));
|
||||
#endif
|
||||
|
||||
sec_err = lmc_int.s.sec_err;
|
||||
ded_err = lmc_int.s.ded_err;
|
||||
|
||||
phase = ded_err ? ded_err : sec_err; /* Double bit errors take precedence. */
|
||||
|
||||
switch (phase) {
|
||||
case 1:
|
||||
syndrome = ecc_synd.cn63xx.mrdsyn0;
|
||||
break;
|
||||
case 2:
|
||||
syndrome = ecc_synd.cn63xx.mrdsyn1;
|
||||
break;
|
||||
case 4:
|
||||
syndrome = ecc_synd.cn63xx.mrdsyn2;
|
||||
break;
|
||||
case 8:
|
||||
syndrome = ecc_synd.cn63xx.mrdsyn3;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DECODE_FAILING_ADDRESS
|
||||
fadr_physical = (uint64_t)fadr.cn63xx.fdimm << (lmc_config.s.pbank_lsb + 28);
|
||||
fadr_physical |= (uint64_t)fadr.cn63xx.frow << (lmc_config.s.row_lsb + 14);
|
||||
fadr_physical |= (uint64_t)fadr.cn63xx.fbank << 7;
|
||||
fadr_physical |= (uint64_t)(fadr.cn63xx.fcol&0xf) << 3;
|
||||
fadr_physical |= (uint64_t)(fadr.cn63xx.fcol>>4) << 10;
|
||||
|
||||
fadr_data = *(uint64_t*)cvmx_phys_to_ptr(fadr_physical);
|
||||
#endif
|
||||
|
||||
PRINT_ERROR("LMC%d ECC: sec_err:%d ded_err:%d\n"
|
||||
"LMC%d ECC:\tFailing dimm: %u\n"
|
||||
"LMC%d ECC:\tFailing rank: %u\n"
|
||||
"LMC%d ECC:\tFailing bank: %u\n"
|
||||
"LMC%d ECC:\tFailing row: 0x%x\n"
|
||||
"LMC%d ECC:\tFailing column: 0x%x\n"
|
||||
"LMC%d ECC:\tsyndrome: 0x%x"
|
||||
#ifdef DECODE_FAILING_BIT
|
||||
", bit: %d"
|
||||
#endif
|
||||
"\n"
|
||||
#ifdef DECODE_FAILING_ADDRESS
|
||||
"Failing Address: 0x%016llx, Data: 0x%016llx\n"
|
||||
#endif
|
||||
, /* Comma */
|
||||
ddr_controller, sec_err, ded_err,
|
||||
ddr_controller, fadr.cn63xx.fdimm,
|
||||
ddr_controller, fadr.cn63xx.fbunk,
|
||||
ddr_controller, fadr.cn63xx.fbank,
|
||||
ddr_controller, fadr.cn63xx.frow,
|
||||
ddr_controller, fadr.cn63xx.fcol,
|
||||
ddr_controller, syndrome
|
||||
#ifdef DECODE_FAILING_BIT
|
||||
, /* Comma */
|
||||
lmc_syndrome_bits[syndrome]
|
||||
#endif
|
||||
#ifdef DECODE_FAILING_ADDRESS
|
||||
, /* Comma */
|
||||
(unsigned long long) fadr_physical, (unsigned long long) fadr_data
|
||||
#endif
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* Some errors require more complicated error handing functions than the
|
||||
* automatically generated functions in cvmx-error-init-*.c. This function
|
||||
* replaces these handers with hand coded functions for these special cases.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int __cvmx_error_custom_initialize(void)
|
||||
{
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX))
|
||||
{
|
||||
int lmc;
|
||||
for (lmc = 0; lmc < CVMX_L2C_TADS; lmc++)
|
||||
{
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN68XX))
|
||||
{
|
||||
cvmx_lmcx_dll_ctl2_t ctl;
|
||||
ctl.u64 = cvmx_read_csr(CVMX_LMCX_DLL_CTL2(lmc));
|
||||
if (ctl.s.intf_en == 0)
|
||||
continue;
|
||||
}
|
||||
cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
|
||||
CVMX_LMCX_INT(lmc), 0xfull<<1 /* sec_err */,
|
||||
__cvmx_cn6xxx_lmc_ecc_error_display, 0, NULL, NULL);
|
||||
cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
|
||||
CVMX_LMCX_INT(lmc), 0xfull<<5 /* ded_err */,
|
||||
__cvmx_cn6xxx_lmc_ecc_error_display, 0, NULL, NULL);
|
||||
if (!OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
|
||||
CVMX_L2C_TADX_INT(lmc), (1ull << i),
|
||||
__cvmx_error_handle_63XX_l2_ecc, 0, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN52XX)
|
||||
|| OCTEON_IS_MODEL(OCTEON_CN56XX)
|
||||
|| OCTEON_IS_MODEL(OCTEON_CN6XXX)
|
||||
|| OCTEON_IS_MODEL(OCTEON_CNF7XXX))
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Install special handler for all the interfaces, these are
|
||||
specific to XAUI interface */
|
||||
for (i = 0; i < CVMX_HELPER_MAX_GMX; i++)
|
||||
{
|
||||
if ((OCTEON_IS_MODEL(OCTEON_CN63XX)
|
||||
|| OCTEON_IS_MODEL(OCTEON_CN52XX)
|
||||
|| OCTEON_IS_MODEL(OCTEON_CNF71XX))
|
||||
&& i == 1)
|
||||
continue;
|
||||
cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
|
||||
CVMX_GMXX_RXX_INT_REG(0,i), 1ull<<21 /* rem_fault */,
|
||||
__cvmx_error_handle_gmxx_rxx_int_reg, 0, NULL, NULL);
|
||||
cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
|
||||
CVMX_GMXX_RXX_INT_REG(0,i), 1ull<<20 /* loc_fault */,
|
||||
__cvmx_error_handle_gmxx_rxx_int_reg, 0, NULL, NULL);
|
||||
}
|
||||
}
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN56XX))
|
||||
{
|
||||
cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
|
||||
CVMX_PEXP_NPEI_INT_SUM, 1ull<<59 /* c0_ldwn */,
|
||||
__cvmx_error_handle_npei_int_sum_c0_ldwn, 0, NULL, NULL);
|
||||
cvmx_error_change_handler(CVMX_ERROR_REGISTER_IO64,
|
||||
CVMX_PEXP_NPEI_INT_SUM, 1ull<<60 /* c1_ldwn */,
|
||||
__cvmx_error_handle_npei_int_sum_c1_ldwn, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
/* CN63XX pass 1.x has a bug where the PCIe config CRS counter does not
|
||||
stop. Disable reporting errors from CRS */
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
|
||||
{
|
||||
cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(0),
|
||||
1ull<<12);
|
||||
cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(0),
|
||||
1ull<<13);
|
||||
cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(1),
|
||||
1ull<<12);
|
||||
cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_PEMX_INT_SUM(1),
|
||||
1ull<<13);
|
||||
}
|
||||
/* According to the workaround for errata SRIO-15282, clearing
|
||||
SRIOx_INT_ENABLE[MAC_BUF]. */
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0) && OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_1))
|
||||
{
|
||||
cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_SRIOX_INT_ENABLE(0), 1ull<<22);
|
||||
cvmx_error_disable(CVMX_ERROR_REGISTER_IO64, CVMX_SRIOX_INT_ENABLE(1), 1ull<<22);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_dfa_err_cp2dbe(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
|
||||
PRINT_ERROR("DFA_ERR[CP2DBE]: DFA PP-CP2 Double Bit Error Detected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_dfa_err_cp2perr(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
|
||||
PRINT_ERROR("DFA_ERR[CP2PERR]: PP-CP2 Parity Error Detected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_dfa_err_cp2sbe(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
|
||||
PRINT_ERROR("DFA_ERR[CP2SBE]: DFA PP-CP2 Single Bit Error Corrected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_dfa_err_dblovf(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
|
||||
PRINT_ERROR("DFA_ERR[DBLOVF]: Doorbell Overflow detected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_dfa_err_dtedbe(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
|
||||
PRINT_ERROR("DFA_ERR[DTEDBE]: DFA DTE 29b Double Bit Error Detected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_dfa_err_dteperr(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
|
||||
PRINT_ERROR("DFA_ERR[DTEPERR]: DTE Parity Error Detected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* DFA_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_dfa_err_dtesbe(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_DFA_ERR, cvmx_read_csr(CVMX_DFA_ERR));
|
||||
PRINT_ERROR("DFA_ERR[DTESBE]: DFA DTE 29b Single Bit Error Corrected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* L2D_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_l2d_err_ded_err(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_l2d_err_t derr;
|
||||
cvmx_l2d_fadr_t fadr;
|
||||
uint64_t syn0 = cvmx_read_csr(CVMX_L2D_FSYN0);
|
||||
uint64_t syn1 = cvmx_read_csr(CVMX_L2D_FSYN1);
|
||||
derr.u64 = cvmx_read_csr(CVMX_L2D_ERR);
|
||||
fadr.u64 = cvmx_read_csr(CVMX_L2D_FADR);
|
||||
|
||||
PRINT_ERROR("L2D_ERR[DED_ERR] ECC double: fadr: 0x%llx, syn0:0x%llx, syn1: 0x%llx\n",
|
||||
(unsigned long long)fadr.u64, (unsigned long long)syn0, (unsigned long long)syn1);
|
||||
/* Flush the line that had the error */
|
||||
cvmx_l2c_flush_line(fadr.s.fset, fadr.s.fadr >> 1);
|
||||
cvmx_write_csr(CVMX_L2D_ERR, derr.u64);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* L2D_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_l2d_err_sec_err(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_l2d_err_t derr;
|
||||
cvmx_l2d_fadr_t fadr;
|
||||
uint64_t syn0 = cvmx_read_csr(CVMX_L2D_FSYN0);
|
||||
uint64_t syn1 = cvmx_read_csr(CVMX_L2D_FSYN1);
|
||||
derr.u64 = cvmx_read_csr(CVMX_L2D_ERR);
|
||||
fadr.u64 = cvmx_read_csr(CVMX_L2D_FADR);
|
||||
|
||||
PRINT_ERROR("L2D_ERR[SEC_ERR] ECC single: fadr: 0x%llx, syn0:0x%llx, syn1: 0x%llx\n",
|
||||
(unsigned long long)fadr.u64, (unsigned long long)syn0, (unsigned long long)syn1);
|
||||
/* Flush the line that had the error */
|
||||
cvmx_l2c_flush_line(fadr.s.fset, fadr.s.fadr >> 1);
|
||||
cvmx_write_csr(CVMX_L2D_ERR, derr.u64);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_l2t_err_ded_err(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_l2t_err_t terr;
|
||||
terr.u64 = cvmx_read_csr(CVMX_L2T_ERR);
|
||||
cvmx_write_csr(CVMX_L2T_ERR, terr.u64);
|
||||
PRINT_ERROR("L2T_ERR[DED_ERR]: double bit:\tfadr: 0x%x, fset: 0x%x, fsyn: 0x%x\n",
|
||||
terr.s.fadr, terr.s.fset, terr.s.fsyn);
|
||||
if (!terr.s.fsyn)
|
||||
{
|
||||
/* Syndrome is zero, which means error was in non-hit line,
|
||||
so flush all associations */
|
||||
int i;
|
||||
int l2_assoc = cvmx_l2c_get_num_assoc();
|
||||
|
||||
for (i = 0; i < l2_assoc; i++)
|
||||
cvmx_l2c_flush_line(i, terr.s.fadr);
|
||||
}
|
||||
else
|
||||
cvmx_l2c_flush_line(terr.s.fset, terr.s.fadr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_l2t_err_lckerr2(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_L2T_ERR, cvmx_read_csr(CVMX_L2T_ERR));
|
||||
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");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_l2t_err_lckerr(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_L2T_ERR, cvmx_read_csr(CVMX_L2T_ERR));
|
||||
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");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* L2T_ERR contains R/W1C bits along with R/W bits. This means that it requires
|
||||
* special handling instead of the normal __cvmx_error_display() function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_l2t_err_sec_err(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_l2t_err_t terr;
|
||||
terr.u64 = cvmx_read_csr(CVMX_L2T_ERR);
|
||||
cvmx_write_csr(CVMX_L2T_ERR, terr.u64);
|
||||
PRINT_ERROR("L2T_ERR[SEC_ERR]: single bit:\tfadr: 0x%x, fset: 0x%x, fsyn: 0x%x\n",
|
||||
terr.s.fadr, terr.s.fset, terr.s.fsyn);
|
||||
if (!terr.s.fsyn)
|
||||
{
|
||||
/* Syndrome is zero, which means error was in non-hit line,
|
||||
so flush all associations */
|
||||
int i;
|
||||
int l2_assoc = cvmx_l2c_get_num_assoc();
|
||||
|
||||
for (i = 0; i < l2_assoc; i++)
|
||||
cvmx_l2c_flush_line(i, terr.s.fadr);
|
||||
}
|
||||
else
|
||||
cvmx_l2c_flush_line(terr.s.fset, terr.s.fadr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* LMCX_MEM_CFG0 contains R/W1C bits along with R/W bits. This means that it
|
||||
* requires special handling instead of the normal __cvmx_error_display()
|
||||
* function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static int __cvmx_error_handle_lmcx_mem_cfg0(const struct cvmx_error_info *info)
|
||||
{
|
||||
int ddr_controller = info->group_index;
|
||||
cvmx_lmcx_mem_cfg0_t mem_cfg0;
|
||||
cvmx_lmcx_fadr_t fadr;
|
||||
int sec_err;
|
||||
int ded_err;
|
||||
|
||||
mem_cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(ddr_controller));
|
||||
fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(ddr_controller));
|
||||
cvmx_write_csr(CVMX_LMCX_MEM_CFG0(ddr_controller),mem_cfg0.u64);
|
||||
|
||||
sec_err = cvmx_dpop(mem_cfg0.s.sec_err);
|
||||
ded_err = cvmx_dpop(mem_cfg0.s.ded_err);
|
||||
|
||||
if (ded_err || sec_err)
|
||||
{
|
||||
PRINT_ERROR("DDR%d ECC: %d Single bit corrections, %d Double bit errors\n"
|
||||
"DDR%d ECC:\tFailing dimm: %u\n"
|
||||
"DDR%d ECC:\tFailing rank: %u\n"
|
||||
"DDR%d ECC:\tFailing bank: %u\n"
|
||||
"DDR%d ECC:\tFailing row: 0x%x\n"
|
||||
"DDR%d ECC:\tFailing column: 0x%x\n",
|
||||
ddr_controller, sec_err, ded_err,
|
||||
ddr_controller, fadr.cn38xx.fdimm,
|
||||
ddr_controller, fadr.cn38xx.fbunk,
|
||||
ddr_controller, fadr.cn38xx.fbank,
|
||||
ddr_controller, fadr.cn38xx.frow,
|
||||
ddr_controller, fadr.cn38xx.fcol);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* LMCX_MEM_CFG0 contains R/W1C bits along with R/W bits. This means that it
|
||||
* requires special handling instead of the normal __cvmx_error_display()
|
||||
* function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_lmcx_mem_cfg0_ded_err(const struct cvmx_error_info *info)
|
||||
{
|
||||
return __cvmx_error_handle_lmcx_mem_cfg0(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* LMCX_MEM_CFG0 contains R/W1C bits along with R/W bits. This means that it
|
||||
* requires special handling instead of the normal __cvmx_error_display()
|
||||
* function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_lmcx_mem_cfg0_sec_err(const struct cvmx_error_info *info)
|
||||
{
|
||||
return __cvmx_error_handle_lmcx_mem_cfg0(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
|
||||
* requires special handling instead of the normal __cvmx_error_display()
|
||||
* function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_pow_ecc_err_dbe(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_POW_ECC_ERR, cvmx_read_csr(CVMX_POW_ECC_ERR));
|
||||
PRINT_ERROR("POW_ECC_ERR[DBE]: POW double bit error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
|
||||
* requires special handling instead of the normal __cvmx_error_display()
|
||||
* function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_pow_ecc_err_iop(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_pow_ecc_err_t err;
|
||||
err.u64 = cvmx_read_csr(CVMX_POW_ECC_ERR);
|
||||
cvmx_write_csr(CVMX_POW_ECC_ERR, err.u64);
|
||||
if (err.s.iop & (1 << 0))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP0]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH/DESCH/UPD_WQP from PP in NULL_NULL state\n");
|
||||
if (err.s.iop & (1 << 1))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP1]: Received SWTAG/SWTAG_DESCH/DESCH/UPD_WQP from PP in NULL state\n");
|
||||
if (err.s.iop & (1 << 2))
|
||||
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");
|
||||
if (err.s.iop & (1 << 3))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP3]: Received SWTAG/SWTAG_FULL/SWTAG_DESCH from PP with tag specified as NULL_NULL\n");
|
||||
if (err.s.iop & (1 << 4))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP4]: Received SWTAG_FULL/SWTAG_DESCH from PP with tag specified as NULL\n");
|
||||
if (err.s.iop & (1 << 5))
|
||||
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");
|
||||
if (err.s.iop & (1 << 6))
|
||||
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");
|
||||
if (err.s.iop & (1 << 7))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP7]: Received CLR_NSCHED from PP with SWTAG_DESCH/DESCH/CLR_NSCHED pending\n");
|
||||
if (err.s.iop & (1 << 8))
|
||||
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");
|
||||
if (err.s.iop & (1 << 9))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP9]: Received illegal opcode\n");
|
||||
if (err.s.iop & (1 << 10))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP10]: Received ADD_WORK with tag specified as NULL_NULL\n");
|
||||
if (err.s.iop & (1 << 11))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP11]: Received DBG load from PP with DBG load pending\n");
|
||||
if (err.s.iop & (1 << 12))
|
||||
PRINT_ERROR("POW_ECC_ERR[IOP12]: Received CSR load from PP with CSR load pending\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
|
||||
* requires special handling instead of the normal __cvmx_error_display()
|
||||
* function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_pow_ecc_err_rpe(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_POW_ECC_ERR, cvmx_read_csr(CVMX_POW_ECC_ERR));
|
||||
PRINT_ERROR("POW_ECC_ERR[RPE]: Remote pointer error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* POW_ECC_ERR contains R/W1C bits along with R/W bits. This means that it
|
||||
* requires special handling instead of the normal __cvmx_error_display()
|
||||
* function.
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_pow_ecc_err_sbe(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_write_csr(CVMX_POW_ECC_ERR, cvmx_read_csr(CVMX_POW_ECC_ERR));
|
||||
PRINT_ERROR("POW_ECC_ERR[SBE]: POW single bit error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
*
|
||||
* @param info
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_handle_63XX_l2_ecc(const struct cvmx_error_info *info)
|
||||
{
|
||||
cvmx_l2c_err_tdtx_t l2c_err_tdt;
|
||||
cvmx_l2c_err_ttgx_t l2c_err_ttg;
|
||||
cvmx_l2c_err_vbfx_t l2c_err_vbf;
|
||||
cvmx_l2c_tadx_int_t tadx_int;
|
||||
tadx_int.u64 = cvmx_read_csr(CVMX_L2C_TADX_INT(0));
|
||||
l2c_err_tdt.u64 = cvmx_read_csr(CVMX_L2C_ERR_TDTX(0));
|
||||
l2c_err_ttg.u64 = cvmx_read_csr(CVMX_L2C_ERR_TTGX(0));
|
||||
l2c_err_vbf.u64 = cvmx_read_csr(CVMX_L2C_ERR_VBFX(0));
|
||||
cvmx_write_csr(CVMX_L2C_TADX_INT(0), tadx_int.u64);
|
||||
|
||||
if (tadx_int.cn63xx.l2ddbe || tadx_int.cn63xx.l2dsbe)
|
||||
{
|
||||
/* L2 Data error */
|
||||
|
||||
|
||||
if (tadx_int.cn63xx.l2dsbe)
|
||||
{
|
||||
/* l2c_err_tdt.cn63xx.wayidx formated same as CACHE instruction arg */
|
||||
CVMX_CACHE_WBIL2I((l2c_err_tdt.u64 & 0x1fff80) | (1ULL << 63), 0);
|
||||
CVMX_SYNC;
|
||||
PRINT_ERROR("L2C_TADX_INT(0)[L2DSBE]: Data Single-Bit Error\n");
|
||||
}
|
||||
if (tadx_int.cn63xx.l2ddbe)
|
||||
{
|
||||
/* TODO - fatal error, for now, flush so error cleared..... */
|
||||
CVMX_CACHE_WBIL2I((l2c_err_tdt.u64 & 0x1fff80) | (1ULL << 63), 0);
|
||||
CVMX_SYNC;
|
||||
PRINT_ERROR("L2C_TADX_INT(0)[L2DDBE]: Data Double-Bit Error\n");
|
||||
}
|
||||
PRINT_ERROR("CVMX_L2C_ERR_TDT: 0x%llx\n", (unsigned long long)l2c_err_tdt.u64);
|
||||
}
|
||||
if (tadx_int.cn63xx.tagdbe || tadx_int.cn63xx.tagsbe)
|
||||
{
|
||||
/* L2 Tag error */
|
||||
if (tadx_int.cn63xx.tagsbe)
|
||||
{
|
||||
CVMX_CACHE_WBIL2I((l2c_err_ttg.u64 & 0x1fff80) | (1ULL << 63), 0);
|
||||
CVMX_SYNC;
|
||||
PRINT_ERROR("L2C_TADX_INT(0)[TAGSBE]: Tag Single-Bit Error\n");
|
||||
}
|
||||
if (tadx_int.cn63xx.tagdbe)
|
||||
{
|
||||
/* TODO - fatal error, for now, flush so error cleared..... */
|
||||
CVMX_CACHE_WBIL2I((l2c_err_ttg.u64 & 0x1fff80) | (1ULL << 63), 0);
|
||||
CVMX_SYNC;
|
||||
PRINT_ERROR("L2C_TADX_INT(0)[TAGDBE]: Tag Double-Bit Error\n");
|
||||
}
|
||||
PRINT_ERROR("CVMX_L2C_ERR_TTG: 0x%llx\n", (unsigned long long)l2c_err_ttg.u64);
|
||||
}
|
||||
if (tadx_int.cn63xx.vbfdbe || tadx_int.cn63xx.vbfsbe)
|
||||
{
|
||||
/* L2 Victim buffer error */
|
||||
if (tadx_int.cn63xx.vbfsbe)
|
||||
{
|
||||
/* No action here, hardware fixed up on write to DRAM */
|
||||
PRINT_ERROR("L2C_TADX_INT(0)[VBFSBE]: VBF Single-Bit Error\n");
|
||||
}
|
||||
if (tadx_int.cn63xx.vbfdbe)
|
||||
{
|
||||
/* TODO - fatal error. Bad data written to DRAM. */
|
||||
PRINT_ERROR("L2C_TADX_INT(0)[VBFDBE]: VBF Double-Bit Error\n");
|
||||
}
|
||||
PRINT_ERROR("CVMX_L2C_ERR_VBF: 0x%llx\n", (unsigned long long)l2c_err_vbf.u64);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/***********************license start***************
|
||||
* Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
|
||||
* reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
|
||||
* * Neither the name of Cavium Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
|
||||
* This Software, including technical data, may be subject to U.S. export control
|
||||
* laws, including the U.S. Export Administration Act and its associated
|
||||
* regulations, and may be subject to export or import regulations in other
|
||||
* countries.
|
||||
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
|
||||
* THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
|
||||
* DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
|
||||
* SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
|
||||
* VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
|
||||
* CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
|
||||
* PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
|
||||
***********************license end**************************************/
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Prototypes for custom error handler function not handled by the default
|
||||
* message display error function.
|
||||
*
|
||||
* <hr>$Revision: 44252 $<hr>
|
||||
*/
|
||||
#ifndef __CVMX_ERROR_CUSTOM_H__
|
||||
#define __CVMX_ERROR_CUSTOM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* Some errors require more complicated error handing functions
|
||||
* than the automatically generated functions in cvmx-error-init-*.c.
|
||||
* This function replaces these handers with hand coded functions
|
||||
* for these special cases.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int __cvmx_error_custom_initialize(void);
|
||||
|
||||
int __cvmx_error_handle_dfa_err_cp2dbe(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_dfa_err_cp2perr(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_dfa_err_cp2sbe(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_dfa_err_dblovf(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_dfa_err_dtedbe(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_dfa_err_dteperr(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_dfa_err_dtesbe(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_l2d_err_ded_err(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_l2d_err_sec_err(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_l2t_err_ded_err(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_l2t_err_lckerr2(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_l2t_err_lckerr(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_l2t_err_sec_err(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_lmcx_mem_cfg0_ded_err(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_lmcx_mem_cfg0_sec_err(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_pow_ecc_err_dbe(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_pow_ecc_err_iop(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_pow_ecc_err_rpe(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_pow_ecc_err_sbe(const struct cvmx_error_info *info);
|
||||
int __cvmx_error_handle_63XX_l2_ecc(const struct cvmx_error_info *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,773 +0,0 @@
|
||||
/***********************license start***************
|
||||
* Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
|
||||
* reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
|
||||
* * Neither the name of Cavium Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
|
||||
* This Software, including technical data, may be subject to U.S. export control
|
||||
* laws, including the U.S. Export Administration Act and its associated
|
||||
* regulations, and may be subject to export or import regulations in other
|
||||
* countries.
|
||||
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
|
||||
* THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
|
||||
* DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
|
||||
* SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
|
||||
* VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
|
||||
* CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
|
||||
* PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
|
||||
***********************license end**************************************/
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Interface to the Octeon extended error status.
|
||||
*
|
||||
* <hr>$Revision: 44252 $<hr>
|
||||
*/
|
||||
#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
|
||||
#include <asm/octeon/cvmx.h>
|
||||
#include <asm/octeon/cvmx-error.h>
|
||||
#include <asm/octeon/cvmx-error-custom.h>
|
||||
#include <asm/octeon/cvmx-pcie.h>
|
||||
#include <asm/octeon/cvmx-srio.h>
|
||||
#include <asm/octeon/cvmx-ciu2-defs.h>
|
||||
#include <asm/octeon/cvmx-dfm-defs.h>
|
||||
#include <asm/octeon/cvmx-lmcx-defs.h>
|
||||
#include <asm/octeon/cvmx-pexp-defs.h>
|
||||
#else
|
||||
#include "cvmx.h"
|
||||
#include "cvmx-error.h"
|
||||
#include "cvmx-error-custom.h"
|
||||
#include "cvmx-pcie.h"
|
||||
#include "cvmx-srio.h"
|
||||
#include "cvmx-interrupt.h"
|
||||
#endif
|
||||
|
||||
#define MAX_TABLE_SIZE 1024 /* Max number of error status bits we can support */
|
||||
|
||||
extern int cvmx_error_initialize_cnf71xx(void);
|
||||
extern int cvmx_error_initialize_cn68xx(void);
|
||||
extern int cvmx_error_initialize_cn68xxp1(void);
|
||||
extern int cvmx_error_initialize_cn66xx(void);
|
||||
extern int cvmx_error_initialize_cn63xx(void);
|
||||
extern int cvmx_error_initialize_cn63xxp1(void);
|
||||
extern int cvmx_error_initialize_cn61xx(void);
|
||||
extern int cvmx_error_initialize_cn58xxp1(void);
|
||||
extern int cvmx_error_initialize_cn58xx(void);
|
||||
extern int cvmx_error_initialize_cn56xxp1(void);
|
||||
extern int cvmx_error_initialize_cn56xx(void);
|
||||
extern int cvmx_error_initialize_cn50xx(void);
|
||||
extern int cvmx_error_initialize_cn52xxp1(void);
|
||||
extern int cvmx_error_initialize_cn52xx(void);
|
||||
extern int cvmx_error_initialize_cn38xxp2(void);
|
||||
extern int cvmx_error_initialize_cn38xx(void);
|
||||
extern int cvmx_error_initialize_cn31xx(void);
|
||||
extern int cvmx_error_initialize_cn30xx(void);
|
||||
|
||||
/* Each entry in this array represents a status bit function or chain */
|
||||
static CVMX_SHARED cvmx_error_info_t __cvmx_error_table[MAX_TABLE_SIZE];
|
||||
static CVMX_SHARED int __cvmx_error_table_size = 0;
|
||||
static CVMX_SHARED cvmx_error_flags_t __cvmx_error_flags;
|
||||
|
||||
#define REG_MATCH(h, reg_type, status_addr, status_mask) \
|
||||
((h->reg_type == reg_type) && (h->status_addr == status_addr) && (h->status_mask == status_mask))
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* Read a status or enable register from the hardware
|
||||
*
|
||||
* @param reg_type Register type to read
|
||||
* @param addr Address to read
|
||||
*
|
||||
* @return Result of the read
|
||||
*/
|
||||
static uint64_t __cvmx_error_read_hw(cvmx_error_register_t reg_type, uint64_t addr)
|
||||
{
|
||||
switch (reg_type)
|
||||
{
|
||||
case __CVMX_ERROR_REGISTER_NONE:
|
||||
return 0;
|
||||
case CVMX_ERROR_REGISTER_IO64:
|
||||
return cvmx_read_csr(addr);
|
||||
case CVMX_ERROR_REGISTER_IO32:
|
||||
return cvmx_read64_uint32(addr ^ 4);
|
||||
case CVMX_ERROR_REGISTER_PCICONFIG:
|
||||
return cvmx_pcie_cfgx_read(addr>>32, addr&0xffffffffull);
|
||||
case CVMX_ERROR_REGISTER_SRIOMAINT:
|
||||
{
|
||||
uint32_t r;
|
||||
if (cvmx_srio_config_read32(addr>>32, 0, -1, 0, 0, addr&0xffffffffull, &r))
|
||||
return 0;
|
||||
else
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* Write a status or enable register to the hardware
|
||||
*
|
||||
* @param reg_type Register type to write
|
||||
* @param addr Address to write
|
||||
* @param value Value to write
|
||||
*/
|
||||
static void __cvmx_error_write_hw(cvmx_error_register_t reg_type, uint64_t addr, uint64_t value)
|
||||
{
|
||||
switch (reg_type)
|
||||
{
|
||||
case __CVMX_ERROR_REGISTER_NONE:
|
||||
return;
|
||||
case CVMX_ERROR_REGISTER_IO64:
|
||||
cvmx_write_csr(addr, value);
|
||||
return;
|
||||
case CVMX_ERROR_REGISTER_IO32:
|
||||
cvmx_write64_uint32(addr ^ 4, value);
|
||||
return;
|
||||
case CVMX_ERROR_REGISTER_PCICONFIG:
|
||||
cvmx_pcie_cfgx_write(addr>>32, addr&0xffffffffull, value);
|
||||
return;
|
||||
case CVMX_ERROR_REGISTER_SRIOMAINT:
|
||||
{
|
||||
cvmx_srio_config_write32(addr>>32, 0, -1, 0, 0, addr&0xffffffffull, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* Function for processing non leaf error status registers. This function
|
||||
* calls all handlers for this passed register and all children linked
|
||||
* to it.
|
||||
*
|
||||
* @param info Error register to check
|
||||
*
|
||||
* @return Number of error status bits found or zero if no bits were set.
|
||||
*/
|
||||
int __cvmx_error_decode(const cvmx_error_info_t *info)
|
||||
{
|
||||
uint64_t status;
|
||||
uint64_t enable;
|
||||
int i;
|
||||
int handled = 0;
|
||||
|
||||
/* Read the status and enable state */
|
||||
status = __cvmx_error_read_hw(info->reg_type, info->status_addr);
|
||||
if (info->enable_addr)
|
||||
enable = __cvmx_error_read_hw(info->reg_type, info->enable_addr);
|
||||
else
|
||||
enable = 0;
|
||||
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
const cvmx_error_info_t *h = &__cvmx_error_table[i];
|
||||
uint64_t masked_status = status;
|
||||
|
||||
/* If this is a child of the current register then recurse and process
|
||||
the child */
|
||||
if ((h->parent.reg_type == info->reg_type) &&
|
||||
(h->parent.status_addr == info->status_addr) &&
|
||||
(status & h->parent.status_mask))
|
||||
handled += __cvmx_error_decode(h);
|
||||
|
||||
if ((h->reg_type != info->reg_type) || (h->status_addr != info->status_addr))
|
||||
continue;
|
||||
|
||||
/* If the corresponding enable bit is not set then we have nothing to do */
|
||||
if (h->enable_addr && h->enable_mask)
|
||||
{
|
||||
if (!(enable & h->enable_mask))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Apply the mask to eliminate irrelevant bits */
|
||||
if (h->status_mask)
|
||||
masked_status &= h->status_mask;
|
||||
|
||||
/* Finally call the handler function unless it is this function */
|
||||
if (masked_status && h->func && (h->func != __cvmx_error_decode))
|
||||
handled += h->func(h);
|
||||
}
|
||||
/* Ths should be the total errors found */
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* This error bit handler simply prints a message and clears the status bit
|
||||
*
|
||||
* @param info Error register to check
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_display(const cvmx_error_info_t *info)
|
||||
{
|
||||
const char *message = (const char *)(long)info->user_info;
|
||||
/* This assumes that all bits in the status register are RO or R/W1C */
|
||||
__cvmx_error_write_hw(info->reg_type, info->status_addr, info->status_mask);
|
||||
cvmx_safe_printf("%s", message);
|
||||
|
||||
/* Clear the source to reduce the chance for spurious interrupts. */
|
||||
|
||||
/* CN68XX has an CIU-15786 errata that accessing the ACK registers
|
||||
* can stop interrupts from propagating
|
||||
*/
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN68XX))
|
||||
cvmx_read_csr(CVMX_CIU2_INTR_CIU_READY);
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN68XX))
|
||||
cvmx_read_csr(CVMX_CIU2_ACK_PPX_IP4(cvmx_get_core_num()));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initalize the error status system. This should be called once
|
||||
* before any other functions are called. This function adds default
|
||||
* handlers for most all error events but does not enable them. Later
|
||||
* calls to cvmx_error_enable() are needed.
|
||||
*
|
||||
* @param flags Optional flags.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_initialize(cvmx_error_flags_t flags)
|
||||
{
|
||||
__cvmx_error_flags = flags;
|
||||
if (OCTEON_IS_MODEL(OCTEON_CNF71XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cnf71xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN68XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn68xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1_X))
|
||||
{
|
||||
if (cvmx_error_initialize_cn68xxp1())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN66XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn66xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn63xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
|
||||
{
|
||||
if (cvmx_error_initialize_cn63xxp1())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN61XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn61xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS1_X))
|
||||
{
|
||||
if (cvmx_error_initialize_cn58xxp1())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN58XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn58xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
|
||||
{
|
||||
if (cvmx_error_initialize_cn56xxp1())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN56XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn56xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn50xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X))
|
||||
{
|
||||
if (cvmx_error_initialize_cn52xxp1())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn52xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
|
||||
{
|
||||
if (cvmx_error_initialize_cn38xxp2())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN38XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn38xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn31xx())
|
||||
return -1;
|
||||
}
|
||||
else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
|
||||
{
|
||||
if (cvmx_error_initialize_cn30xx())
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cvmx_warn("cvmx_error_initialize() needs update for this Octeon model\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__cvmx_error_custom_initialize())
|
||||
return -1;
|
||||
|
||||
/* Enable all of the purely internal error sources by default */
|
||||
cvmx_error_enable_group(CVMX_ERROR_GROUP_INTERNAL, 0);
|
||||
|
||||
/* According to workaround for errata KEY-14814 in cn63xx, clearing
|
||||
SLI_INT_SUM[RML_TO] after enabling KEY interrupts */
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
|
||||
cvmx_write_csr(CVMX_PEXP_SLI_INT_SUM, 1);
|
||||
|
||||
/* Enable DDR error reporting based on the memory controllers */
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN56XX))
|
||||
{
|
||||
cvmx_l2c_cfg_t l2c_cfg;
|
||||
l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
|
||||
if (l2c_cfg.s.dpres0)
|
||||
cvmx_error_enable_group(CVMX_ERROR_GROUP_LMC, 0);
|
||||
if (l2c_cfg.s.dpres1)
|
||||
cvmx_error_enable_group(CVMX_ERROR_GROUP_LMC, 1);
|
||||
}
|
||||
else
|
||||
cvmx_error_enable_group(CVMX_ERROR_GROUP_LMC, 0);
|
||||
|
||||
/* Enable error interrupts for other LMC only if it is
|
||||
available. */
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN68XX))
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
cvmx_lmcx_dll_ctl2_t ctl2;
|
||||
ctl2.u64 = cvmx_read_csr(CVMX_LMCX_DLL_CTL2(i));
|
||||
if (ctl2.s.intf_en)
|
||||
cvmx_error_enable_group(CVMX_ERROR_GROUP_LMC, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable DFM error reporting based on feature availablility */
|
||||
if (octeon_has_feature(OCTEON_FEATURE_DFM))
|
||||
{
|
||||
/* Only configure interrupts if DFM clock is enabled. */
|
||||
cvmx_dfm_fnt_sclk_t dfm_fnt_sclk;
|
||||
dfm_fnt_sclk.u64 = cvmx_read_csr(CVMX_DFM_FNT_SCLK);
|
||||
if (!dfm_fnt_sclk.s.sclkdis)
|
||||
{
|
||||
cvmx_error_enable_group(CVMX_ERROR_GROUP_DFM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Old PCI parts don't have a common PCI init, so enable error
|
||||
reporting if the bootloader told us we are a PCI host. PCIe
|
||||
is handled when cvmx_pcie_rc_initialize is called */
|
||||
if (!octeon_has_feature(OCTEON_FEATURE_PCIE) &&
|
||||
(cvmx_sysinfo_get()->bootloader_config_flags & CVMX_BOOTINFO_CFG_FLAG_PCI_HOST))
|
||||
cvmx_error_enable_group(CVMX_ERROR_GROUP_PCI, 0);
|
||||
|
||||
/* Call poll once to clear out any pending interrupts */
|
||||
cvmx_error_poll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll the error status registers and call the appropriate error
|
||||
* handlers. This should be called in the RSL interrupt handler
|
||||
* for your application or operating system.
|
||||
*
|
||||
* @return Number of error handlers called. Zero means this call
|
||||
* found no errors and was spurious.
|
||||
*/
|
||||
int cvmx_error_poll(void)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
/* Call all handlers that don't have a parent */
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
if (__cvmx_error_table[i].parent.reg_type == __CVMX_ERROR_REGISTER_NONE)
|
||||
count += __cvmx_error_decode(&__cvmx_error_table[i]);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register to be called when an error status bit is set. Most users
|
||||
* will not need to call this function as cvmx_error_initialize()
|
||||
* registers default handlers for most error conditions. This function
|
||||
* is normally used to add more handlers without changing the existing
|
||||
* handlers.
|
||||
*
|
||||
* @param new_info Information about the handler for a error register. The
|
||||
* structure passed is copied and can be destroyed after the
|
||||
* call. All members of the structure must be populated, even the
|
||||
* parent information.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_add(const cvmx_error_info_t *new_info)
|
||||
{
|
||||
if (__cvmx_error_table_size >= MAX_TABLE_SIZE)
|
||||
{
|
||||
cvmx_warn("cvmx-error table full\n");
|
||||
return -1;
|
||||
}
|
||||
__cvmx_error_table[__cvmx_error_table_size] = *new_info;
|
||||
__cvmx_error_table_size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all handlers for a status register and mask. Normally
|
||||
* this function should not be called. Instead a new handler should be
|
||||
* installed to replace the existing handler. In the even that all
|
||||
* reporting of a error bit should be removed, then use this
|
||||
* function.
|
||||
*
|
||||
* @param reg_type Type of the status register to remove
|
||||
* @param status_addr
|
||||
* Status register to remove.
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* removed.
|
||||
* @param old_info If not NULL, this is filled with information about the handler
|
||||
* that was removed.
|
||||
*
|
||||
* @return Zero on success, negative on failure (not found).
|
||||
*/
|
||||
int cvmx_error_remove(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask,
|
||||
cvmx_error_info_t *old_info)
|
||||
{
|
||||
int found = 0;
|
||||
int i;
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
cvmx_error_info_t *h = &__cvmx_error_table[i];
|
||||
if (!REG_MATCH(h, reg_type, status_addr, status_mask))
|
||||
continue;
|
||||
if (old_info)
|
||||
*old_info = *h;
|
||||
memset(h, 0, sizeof(*h));
|
||||
found = 1;
|
||||
}
|
||||
if (found)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
cvmx_warn("cvmx-error remove couldn't find requested register\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the function and user_info for an existing error status
|
||||
* register. This function should be used to replace the default
|
||||
* handler with an application specific version as needed.
|
||||
*
|
||||
* @param reg_type Type of the status register to change
|
||||
* @param status_addr
|
||||
* Status register to change.
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* changed.
|
||||
* @param new_func New function to use to handle the error status
|
||||
* @param new_user_info
|
||||
* New user info parameter for the function
|
||||
* @param old_func If not NULL, the old function is returned. Useful for restoring
|
||||
* the old handler.
|
||||
* @param old_user_info
|
||||
* If not NULL, the old user info parameter.
|
||||
*
|
||||
* @return Zero on success, negative on failure
|
||||
*/
|
||||
int cvmx_error_change_handler(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask,
|
||||
cvmx_error_func_t new_func, uint64_t new_user_info,
|
||||
cvmx_error_func_t *old_func, uint64_t *old_user_info)
|
||||
{
|
||||
int found = 0;
|
||||
int i;
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
cvmx_error_info_t *h = &__cvmx_error_table[i];
|
||||
if (!REG_MATCH(h, reg_type, status_addr, status_mask))
|
||||
continue;
|
||||
if (old_func)
|
||||
*old_func = h->func;
|
||||
if (old_user_info)
|
||||
*old_user_info = h->user_info;
|
||||
h->func = new_func;
|
||||
h->user_info = new_user_info;
|
||||
found = 1;
|
||||
}
|
||||
if (found)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
cvmx_warn("cvmx-error change couldn't find requested register\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable all error registers for a logical group. This should be
|
||||
* called whenever a logical group is brought online.
|
||||
*
|
||||
* @param group Logical group to enable
|
||||
* @param group_index
|
||||
* Index for the group as defined in the cvmx_error_group_t
|
||||
* comments.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_enable_group(cvmx_error_group_t group, int group_index)
|
||||
{
|
||||
int i;
|
||||
uint64_t enable;
|
||||
|
||||
if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
const cvmx_error_info_t *h = &__cvmx_error_table[i];
|
||||
/* SGMII and XAUI has different ipd_port, use the same group_index
|
||||
for both the interfaces */
|
||||
switch(group_index)
|
||||
{
|
||||
case 0x840:
|
||||
group_index = 0x800;
|
||||
break;
|
||||
case 0xa40:
|
||||
group_index = 0xa00;
|
||||
break;
|
||||
case 0xb40:
|
||||
group_index = 0xb00;
|
||||
break;
|
||||
case 0xc40:
|
||||
group_index = 0xc00;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Skip entries that have a different group or group index. We
|
||||
also skip entries that don't have an enable */
|
||||
if ((h->group != group) || (h->group_index != group_index) || (!h->enable_addr))
|
||||
continue;
|
||||
/* Skip entries that have flags that don't match the user's
|
||||
selected flags */
|
||||
if (h->flags && (h->flags != (h->flags & __cvmx_error_flags)))
|
||||
continue;
|
||||
/* Update the enables for this entry */
|
||||
enable = __cvmx_error_read_hw(h->reg_type, h->enable_addr);
|
||||
if (h->reg_type == CVMX_ERROR_REGISTER_PCICONFIG)
|
||||
enable &= ~h->enable_mask; /* PCI bits have reversed polarity */
|
||||
else
|
||||
enable |= h->enable_mask;
|
||||
__cvmx_error_write_hw(h->reg_type, h->enable_addr, enable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all error registers for a logical group. This should be
|
||||
* called whenever a logical group is brought offline. Many blocks
|
||||
* will report spurious errors when offline unless this function
|
||||
* is called.
|
||||
*
|
||||
* @param group Logical group to disable
|
||||
* @param group_index
|
||||
* Index for the group as defined in the cvmx_error_group_t
|
||||
* comments.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_disable_group(cvmx_error_group_t group, int group_index)
|
||||
{
|
||||
int i;
|
||||
uint64_t enable;
|
||||
|
||||
if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
const cvmx_error_info_t *h = &__cvmx_error_table[i];
|
||||
|
||||
/* SGMII and XAUI has different ipd_port, use the same group_index
|
||||
for both the interfaces */
|
||||
switch(group_index)
|
||||
{
|
||||
case 0x840:
|
||||
group_index = 0x800;
|
||||
break;
|
||||
case 0xa40:
|
||||
group_index = 0xa00;
|
||||
break;
|
||||
case 0xb40:
|
||||
group_index = 0xb00;
|
||||
break;
|
||||
case 0xc40:
|
||||
group_index = 0xc00;
|
||||
break;
|
||||
}
|
||||
/* Skip entries that have a different group or group index. We
|
||||
also skip entries that don't have an enable */
|
||||
if ((h->group != group) || (h->group_index != group_index) || (!h->enable_addr))
|
||||
continue;
|
||||
/* Update the enables for this entry */
|
||||
enable = __cvmx_error_read_hw(h->reg_type, h->enable_addr);
|
||||
if (h->reg_type == CVMX_ERROR_REGISTER_PCICONFIG)
|
||||
enable |= h->enable_mask; /* PCI bits have reversed polarity */
|
||||
else
|
||||
enable &= ~h->enable_mask;
|
||||
__cvmx_error_write_hw(h->reg_type, h->enable_addr, enable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable all handlers for a specific status register mask.
|
||||
*
|
||||
* @param reg_type Type of the status register
|
||||
* @param status_addr
|
||||
* Status register address
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* enabled.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_enable(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask)
|
||||
{
|
||||
int found = 0;
|
||||
int i;
|
||||
uint64_t enable;
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
cvmx_error_info_t *h = &__cvmx_error_table[i];
|
||||
if (!REG_MATCH(h, reg_type, status_addr, status_mask) || !h->enable_addr)
|
||||
continue;
|
||||
enable = __cvmx_error_read_hw(h->reg_type, h->enable_addr);
|
||||
if (h->reg_type == CVMX_ERROR_REGISTER_PCICONFIG)
|
||||
enable &= ~h->enable_mask; /* PCI bits have reversed polarity */
|
||||
else
|
||||
enable |= h->enable_mask;
|
||||
__cvmx_error_write_hw(h->reg_type, h->enable_addr, enable);
|
||||
h->flags &= ~CVMX_ERROR_FLAGS_DISABLED;
|
||||
found = 1;
|
||||
}
|
||||
if (found)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
cvmx_warn("cvmx-error enable couldn't find requested register\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all handlers for a specific status register and mask.
|
||||
*
|
||||
* @param reg_type Type of the status register
|
||||
* @param status_addr
|
||||
* Status register address
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* disabled.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_disable(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask)
|
||||
{
|
||||
int found = 0;
|
||||
int i;
|
||||
uint64_t enable;
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
cvmx_error_info_t *h = &__cvmx_error_table[i];
|
||||
if (!REG_MATCH(h, reg_type, status_addr, status_mask) || !h->enable_addr)
|
||||
continue;
|
||||
enable = __cvmx_error_read_hw(h->reg_type, h->enable_addr);
|
||||
if (h->reg_type == CVMX_ERROR_REGISTER_PCICONFIG)
|
||||
enable |= h->enable_mask; /* PCI bits have reversed polarity */
|
||||
else
|
||||
enable &= ~h->enable_mask;
|
||||
__cvmx_error_write_hw(h->reg_type, h->enable_addr, enable);
|
||||
h->flags |= CVMX_ERROR_FLAGS_DISABLED;
|
||||
found = 1;
|
||||
}
|
||||
if (found)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
cvmx_warn("cvmx-error disable couldn't find requested register\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the handler for a specific status register and mask
|
||||
*
|
||||
* @param status_addr
|
||||
* Status register address
|
||||
*
|
||||
* @return Return the handler on success or null on failure.
|
||||
*/
|
||||
cvmx_error_info_t *cvmx_error_get_index(uint64_t status_addr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < __cvmx_error_table_size; i++)
|
||||
{
|
||||
if (__cvmx_error_table[i].status_addr == status_addr)
|
||||
return &__cvmx_error_table[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@ -1,330 +0,0 @@
|
||||
/***********************license start***************
|
||||
* Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
|
||||
* reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
|
||||
* * Neither the name of Cavium Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
|
||||
* This Software, including technical data, may be subject to U.S. export control
|
||||
* laws, including the U.S. Export Administration Act and its associated
|
||||
* regulations, and may be subject to export or import regulations in other
|
||||
* countries.
|
||||
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
|
||||
* THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
|
||||
* DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
|
||||
* SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
|
||||
* VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
|
||||
* CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
|
||||
* PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
|
||||
***********************license end**************************************/
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Interface to the Octeon extended error status.
|
||||
*
|
||||
* <hr>$Revision: 44252 $<hr>
|
||||
*/
|
||||
#ifndef __CVMX_ERROR_H__
|
||||
#define __CVMX_ERROR_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* There are generally many error status bits associated with a
|
||||
* single logical group. The enumeration below is used to
|
||||
* communicate high level groups to the error infastructure so
|
||||
* error status bits can be enable or disabled in large groups.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CVMX_ERROR_GROUP_INTERNAL, /* All internal blocks that can always be enabled */
|
||||
CVMX_ERROR_GROUP_ETHERNET, /* All errors related to network traffic that should be enabled when a port is up. Indexed by IPD number */
|
||||
CVMX_ERROR_GROUP_MGMT_PORT, /* All errors related to the management ethernet ports that should be enabled when a port is up. Indexed by port number (0-1) */
|
||||
CVMX_ERROR_GROUP_PCI, /* All errors related to PCI/PCIe when the bus is up. Index by port number (0-1) */
|
||||
CVMX_ERROR_GROUP_SRIO, /* All errors related to SRIO when the bus is up. Index by port number (0-1) */
|
||||
CVMX_ERROR_GROUP_USB, /* All errors related to USB when the port is enabled. Index by port number (0-1) */
|
||||
CVMX_ERROR_GROUP_LMC, /* All errors related to LMC when the controller is enabled. Index by controller number (0-1) */
|
||||
CVMX_ERROR_GROUP_ILK, /* All errors related to ILK when the controller is enabled. Index by controller number (0-1) */
|
||||
CVMX_ERROR_GROUP_DFM, /* All errors related to DFM when the controller is enabled. */
|
||||
} cvmx_error_group_t;
|
||||
|
||||
/**
|
||||
* When registering for interest in an error status register, the
|
||||
* type of the register needs to be known by cvmx-error. Most
|
||||
* registers are either IO64 or IO32, but some blocks contain
|
||||
* registers that can't be directly accessed. A good example of
|
||||
* would be PCIe extended error state stored in config space.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
__CVMX_ERROR_REGISTER_NONE, /* Used internally */
|
||||
CVMX_ERROR_REGISTER_IO64, /* Status and enable registers are Octeon 64bit CSRs */
|
||||
CVMX_ERROR_REGISTER_IO32, /* Status and enable registers are Octeon 32bit CSRs */
|
||||
CVMX_ERROR_REGISTER_PCICONFIG, /* Status and enable registers are in PCI config space */
|
||||
CVMX_ERROR_REGISTER_SRIOMAINT, /* Status and enable registers are in SRIO maintenance space */
|
||||
} cvmx_error_register_t;
|
||||
|
||||
/**
|
||||
* Flags representing special handling for some error registers.
|
||||
* These flags are passed to cvmx_error_initialize() to control
|
||||
* the handling of bits where the same flags were passed to the
|
||||
* added cvmx_error_info_t.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CVMX_ERROR_FLAGS_ECC_SINGLE_BIT = 1<<0, /* This is a ECC single bit error. Normally these can be ignored */
|
||||
CVMX_ERROR_FLAGS_CORRECTABLE = 1<<1, /* Some blocks have errors that can be silently corrected. This flags reports these */
|
||||
CVMX_ERROR_FLAGS_DISABLED = 1<<2, /* Flag used to signal a register should not be enable as part of the groups */
|
||||
} cvmx_error_flags_t;
|
||||
|
||||
struct cvmx_error_info;
|
||||
/**
|
||||
* Error handling functions must have the following prototype.
|
||||
*/
|
||||
typedef int (*cvmx_error_func_t)(const struct cvmx_error_info *info);
|
||||
|
||||
/**
|
||||
* This structure is passed to all error handling functions.
|
||||
*/
|
||||
typedef struct cvmx_error_info
|
||||
{
|
||||
cvmx_error_register_t reg_type; /* Type of registers used for the error */
|
||||
uint64_t status_addr; /* The address of the status register */
|
||||
uint64_t status_mask; /* Mask to apply to status register to detect asserted error */
|
||||
uint64_t enable_addr; /* The address of the enable register */
|
||||
uint64_t enable_mask; /* Mask to apply to enable register to allow error detection */
|
||||
cvmx_error_flags_t flags; /* Flags indicating special handling of this error */
|
||||
cvmx_error_group_t group; /* Group to associate this error register with */
|
||||
int group_index; /* Group index to associate this error register with */
|
||||
cvmx_error_func_t func; /* Function to call when the error is detected */
|
||||
uint64_t user_info; /* User supplied information for the error handler */
|
||||
struct
|
||||
{
|
||||
cvmx_error_register_t reg_type; /* Type of parent's register */
|
||||
uint64_t status_addr; /* The address of the parent's register */
|
||||
uint64_t status_mask; /* Mask to apply to parent's register */
|
||||
} parent;
|
||||
} cvmx_error_info_t;
|
||||
|
||||
/**
|
||||
* Initalize the error status system. This should be called once
|
||||
* before any other functions are called. This function adds default
|
||||
* handlers for most all error events but does not enable them. Later
|
||||
* calls to cvmx_error_enable() are needed.
|
||||
*
|
||||
* @param flags Optional flags.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_initialize(cvmx_error_flags_t flags);
|
||||
|
||||
/**
|
||||
* Poll the error status registers and call the appropriate error
|
||||
* handlers. This should be called in the RSL interrupt handler
|
||||
* for your application or operating system.
|
||||
*
|
||||
* @return Number of error handlers called. Zero means this call
|
||||
* found no errors and was spurious.
|
||||
*/
|
||||
int cvmx_error_poll(void);
|
||||
|
||||
/**
|
||||
* Register to be called when an error status bit is set. Most users
|
||||
* will not need to call this function as cvmx_error_initialize()
|
||||
* registers default handlers for most error conditions. This function
|
||||
* is normally used to add more handlers without changing the existing
|
||||
* handlers.
|
||||
*
|
||||
* @param new_info Information about the handler for a error register. The
|
||||
* structure passed is copied and can be destroyed after the
|
||||
* call. All members of the structure must be populated, even the
|
||||
* parent information.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_add(const cvmx_error_info_t *new_info);
|
||||
|
||||
/**
|
||||
* Remove all handlers for a status register and mask. Normally
|
||||
* this function should not be called. Instead a new handler should be
|
||||
* installed to replace the existing handler. In the even that all
|
||||
* reporting of a error bit should be removed, then use this
|
||||
* function.
|
||||
*
|
||||
* @param reg_type Type of the status register to remove
|
||||
* @param status_addr
|
||||
* Status register to remove.
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* removed.
|
||||
* @param old_info If not NULL, this is filled with information about the handler
|
||||
* that was removed.
|
||||
*
|
||||
* @return Zero on success, negative on failure (not found).
|
||||
*/
|
||||
int cvmx_error_remove(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask,
|
||||
cvmx_error_info_t *old_info);
|
||||
|
||||
/**
|
||||
* Change the function and user_info for an existing error status
|
||||
* register. This function should be used to replace the default
|
||||
* handler with an application specific version as needed.
|
||||
*
|
||||
* @param reg_type Type of the status register to change
|
||||
* @param status_addr
|
||||
* Status register to change.
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* changed.
|
||||
* @param new_func New function to use to handle the error status
|
||||
* @param new_user_info
|
||||
* New user info parameter for the function
|
||||
* @param old_func If not NULL, the old function is returned. Useful for restoring
|
||||
* the old handler.
|
||||
* @param old_user_info
|
||||
* If not NULL, the old user info parameter.
|
||||
*
|
||||
* @return Zero on success, negative on failure
|
||||
*/
|
||||
int cvmx_error_change_handler(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask,
|
||||
cvmx_error_func_t new_func, uint64_t new_user_info,
|
||||
cvmx_error_func_t *old_func, uint64_t *old_user_info);
|
||||
|
||||
/**
|
||||
* Enable all error registers for a logical group. This should be
|
||||
* called whenever a logical group is brought online.
|
||||
*
|
||||
* @param group Logical group to enable
|
||||
* @param group_index
|
||||
* Index for the group as defined in the cvmx_error_group_t
|
||||
* comments.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
#ifndef CVMX_BUILD_FOR_UBOOT
|
||||
int cvmx_error_enable_group(cvmx_error_group_t group, int group_index);
|
||||
#else
|
||||
/* Rather than conditionalize the calls throughout the executive to not enable
|
||||
interrupts in Uboot, simply make the enable function do nothing */
|
||||
static inline int cvmx_error_enable_group(cvmx_error_group_t group, int group_index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Disable all error registers for a logical group. This should be
|
||||
* called whenever a logical group is brought offline. Many blocks
|
||||
* will report spurious errors when offline unless this function
|
||||
* is called.
|
||||
*
|
||||
* @param group Logical group to disable
|
||||
* @param group_index
|
||||
* Index for the group as defined in the cvmx_error_group_t
|
||||
* comments.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
#ifndef CVMX_BUILD_FOR_UBOOT
|
||||
int cvmx_error_disable_group(cvmx_error_group_t group, int group_index);
|
||||
#else
|
||||
/* Rather than conditionalize the calls throughout the executive to not disable
|
||||
interrupts in Uboot, simply make the enable function do nothing */
|
||||
static inline int cvmx_error_disable_group(cvmx_error_group_t group, int group_index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Enable all handlers for a specific status register mask.
|
||||
*
|
||||
* @param reg_type Type of the status register
|
||||
* @param status_addr
|
||||
* Status register address
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* enabled.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_enable(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask);
|
||||
|
||||
/**
|
||||
* Disable all handlers for a specific status register and mask.
|
||||
*
|
||||
* @param reg_type Type of the status register
|
||||
* @param status_addr
|
||||
* Status register address
|
||||
* @param status_mask
|
||||
* All handlers for this status register with this mask will be
|
||||
* disabled.
|
||||
*
|
||||
* @return Zero on success, negative on failure.
|
||||
*/
|
||||
int cvmx_error_disable(cvmx_error_register_t reg_type,
|
||||
uint64_t status_addr, uint64_t status_mask);
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* Function for processing non leaf error status registers. This function
|
||||
* calls all handlers for this passed register and all children linked
|
||||
* to it.
|
||||
*
|
||||
* @param info Error register to check
|
||||
*
|
||||
* @return Number of error status bits found or zero if no bits were set.
|
||||
*/
|
||||
int __cvmx_error_decode(const cvmx_error_info_t *info);
|
||||
|
||||
/**
|
||||
* @INTERNAL
|
||||
* This error bit handler simply prints a message and clears the status bit
|
||||
*
|
||||
* @param info Error register to check
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int __cvmx_error_display(const cvmx_error_info_t *info);
|
||||
|
||||
/**
|
||||
* Find the handler for a specific status register and mask
|
||||
*
|
||||
* @param status_addr
|
||||
* Status register address
|
||||
*
|
||||
* @return Return the handler on success or null on failure.
|
||||
*/
|
||||
cvmx_error_info_t *cvmx_error_get_index(uint64_t status_addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -76,7 +76,9 @@
|
||||
#include <asm/octeon/cvmx-wqe.h>
|
||||
#else
|
||||
#include "cvmx.h"
|
||||
#if !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)
|
||||
#include "cvmx-csr-db.h"
|
||||
#endif
|
||||
#include "cvmx-pcie.h"
|
||||
#include "cvmx-sysinfo.h"
|
||||
#include "cvmx-swap.h"
|
||||
|
@ -59,8 +59,10 @@
|
||||
#else
|
||||
#include "cvmx.h"
|
||||
#include "cvmx-twsi.h"
|
||||
#if !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)
|
||||
#include "cvmx-csr-db.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#define PRINT_TWSI_CONFIG
|
||||
#ifdef PRINT_TWSI_CONFIG
|
||||
|
@ -72,7 +72,9 @@
|
||||
#include "cvmx-usb.h"
|
||||
#include "cvmx-helper.h"
|
||||
#include "cvmx-helper-board.h"
|
||||
#if !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)
|
||||
#include "cvmx-csr-db.h"
|
||||
#endif
|
||||
#include "cvmx-swap.h"
|
||||
#if !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)
|
||||
#include "cvmx-error.h"
|
||||
|
Loading…
Reference in New Issue
Block a user