@@ -54,6 +54,32 @@ static struct {
*/
static struct lock xscom_lock = LOCK_UNLOCKED;
+static bool create_xscom_rw_addr_elog = true;
+
+static inline void log_xscom_rw_error(uint32_t gcid, uint32_t pcb_addr,
+ unsigned int stat,
+ bool is_write)
+{
+ /*
+ * If the failure is due to incorrect address, and we the
+ * caller doesn't want elog to be created, log the error in
+ * msglog and return.
+ */
+ if (stat == 4 && !create_xscom_rw_addr_elog) {
+ prlog(PR_WARNING,
+ "XSCOM: %s error gcid=0x%x pcb_addr=0x%x stat=0x%x\n",
+ is_write ? "write" : "read",
+ gcid, pcb_addr, stat);
+
+ return;
+ }
+
+ log_simple_error(&e_info(OPAL_RC_XSCOM_RW),
+ "XSCOM: %s error gcid=0x%x pcb_addr=0x%x stat=0x%x\n",
+ is_write ? "write" : "read",
+ gcid, pcb_addr, stat);
+}
+
static inline void *xscom_addr(uint32_t gcid, uint32_t pcb_addr)
{
struct proc_chip *chip = get_chip(gcid);
@@ -272,10 +298,7 @@ static int64_t xscom_handle_error(uint64_t hmer, uint32_t gcid, uint32_t pcb_add
break;
}
- /* XXX: Create error log entry ? */
- log_simple_error(&e_info(OPAL_RC_XSCOM_RW),
- "XSCOM: %s error gcid=0x%x pcb_addr=0x%x stat=0x%x\n",
- is_write ? "write" : "read", gcid, pcb_addr, stat);
+ log_xscom_rw_error(gcid, pcb_addr, stat, is_write);
/* We need to reset the XSCOM or we'll hang on the next access */
xscom_reset(gcid, false);