aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorVipin K Parashar <vipin@linux.vnet.ibm.com>2016-08-07 00:38:00 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-08-25 14:58:39 +1000
commit51b9eeb66ebbd1706248d8f2277afa9b7dcdbc3b (patch)
treecb33e49500b1499cbcb6af23b871c4fdf73c082c /hw
parenta0a22b9883741b53c85fcea08a94bbdac892a9a3 (diff)
downloadskiboot-51b9eeb66ebbd1706248d8f2277afa9b7dcdbc3b.zip
skiboot-51b9eeb66ebbd1706248d8f2277afa9b7dcdbc3b.tar.gz
skiboot-51b9eeb66ebbd1706248d8f2277afa9b7dcdbc3b.tar.bz2
lpc: Log LPC SYNC errors as unrecoverable ones for manufacturing
High volume of SYNC errors onto LPC bus cause degraded system performance and are likely due to bad hardware present onto system. Thus once LPC SYNC errors cross a certain threshold, OPAL should log them onto BMC as unrecoverable errors in manufacturing mode. This will help manufacturing screen bad parts, causing such errors. Cc: stable Signed-off-by: Vipin K Parashar <vipin@linux.vnet.ibm.com> [stewart@linux.vnet.ibm.com: s/mfg/manufacturing/] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/lpc.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/hw/lpc.c b/hw/lpc.c
index 7b6071d..5c5b7c6 100644
--- a/hw/lpc.c
+++ b/hw/lpc.c
@@ -25,6 +25,7 @@
#include <timebase.h>
#include <errorlog.h>
#include <opal-api.h>
+#include <platform.h>
#include <psi.h>
//#define DBG_IRQ(fmt...) prerror(fmt)
@@ -42,6 +43,11 @@ DEFINE_LOG_ENTRY(OPAL_RC_LPC_SYNC, OPAL_PLATFORM_ERR_EVT, OPAL_LPC,
OPAL_MISC_SUBSYSTEM, OPAL_PREDICTIVE_ERR_GENERAL,
OPAL_NA);
+/* Used exclusively in manufacturing mode */
+DEFINE_LOG_ENTRY(OPAL_RC_LPC_SYNC_PERF, OPAL_PLATFORM_ERR_EVT, OPAL_LPC,
+ OPAL_MISC_SUBSYSTEM, OPAL_UNRECOVERABLE_ERR_DEGRADE_PERF,
+ OPAL_NA);
+
#define ECCB_CTL 0 /* b0020 -> b00200 */
#define ECCB_STAT 2 /* b0022 -> b00210 */
#define ECCB_DATA 3 /* b0023 -> b00218 */
@@ -126,6 +132,9 @@ struct lpcm {
uint32_t sirq_rmasks[4];
};
+
+#define LPC_BUS_DEGRADED_PERF_THRESHOLD 5
+
struct lpc_client_entry {
struct list_node node;
const struct lpc_client *clt;
@@ -775,6 +784,8 @@ static void lpc_dispatch_reset(struct lpcm *lpc)
static void lpc_dispatch_err_irqs(struct lpcm *lpc, uint32_t irqs)
{
const char *sync_err = "Unknown LPC error";
+ static int lpc_bus_err_count;
+ struct opal_err_info *info;
uint32_t err_addr;
int rc;
@@ -803,13 +814,21 @@ static void lpc_dispatch_err_irqs(struct lpcm *lpc, uint32_t irqs)
rc = opb_read(lpc, lpc_reg_opb_base + LPC_HC_ERROR_ADDRESS,
&err_addr, 4);
+
+ lpc_bus_err_count++;
+ if (manufacturing_mode && (lpc_bus_err_count > LPC_BUS_DEGRADED_PERF_THRESHOLD))
+ info = &e_info(OPAL_RC_LPC_SYNC_PERF);
+ else
+ info = &e_info(OPAL_RC_LPC_SYNC);
+
+
if (rc)
- log_simple_error(&e_info(OPAL_RC_LPC_SYNC), "LPC[%03x]: %s "
+ log_simple_error(info, "LPC[%03x]: %s "
"Error reading error address register\n",
lpc->chip_id, sync_err);
else
- log_simple_error(&e_info(OPAL_RC_LPC_SYNC), "LPC[%03x]: %s "
- "Error address reg: 0x%08x\n",
+ log_simple_error(info, "LPC[%03x]: %s Error address reg: "
+ "0x%08x\n",
lpc->chip_id, sync_err, err_addr);
}