diff options
author | jc25722 <none@none> | 2006-06-22 10:53:48 -0700 |
---|---|---|
committer | jc25722 <none@none> | 2006-06-22 10:53:48 -0700 |
commit | 54d9a2593fde02a00a43f74dbbc438402369fd6a (patch) | |
tree | da9af7d8cb363c361bc35c71e53c9dcdc23565f1 /usr/src | |
parent | e4ac07a33b07da3635a7a16ac8fccab07c33380a (diff) | |
download | illumos-joyent-54d9a2593fde02a00a43f74dbbc438402369fd6a.tar.gz |
6400152 No fault event is produced in the presence of an ereport containing adequate payload information.
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c | 4 | ||||
-rw-r--r-- | usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c | 88 |
2 files changed, 90 insertions, 2 deletions
diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c index 46e3d0bee8..01ab05e51e 100644 --- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c +++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c @@ -135,6 +135,8 @@ static cmd_subscriber_t cmd_subscribers[] = { { "ereport.io.*.ecc.s-dwce", cmd_ioxe_sec }, { "ereport.io.*.ecc.s-drue", cmd_ioxe_sec }, { "ereport.io.*.ecc.s-dwue", cmd_ioxe_sec }, + { "ereport.io.fire.jbc.ce_asyn", cmd_ioxe, CMD_ERRCL_IOCE }, + { "ereport.io.fire.jbc.ue_asyn", cmd_ioxe, CMD_ERRCL_IOUE }, { "ereport.asic.*.cds.cds-dp", cmd_dp_cds }, { "ereport.asic.*.dx.dx-dp", cmd_dp_dx }, { "ereport.asic.*.sdi.sdi-dp", cmd_dp_ex }, @@ -524,6 +526,8 @@ _fmd_init(fmd_hdl_t *hdl) fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-cpu"); fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-path"); #endif + fmd_hdl_subscribe(hdl, "ereport.io.fire.jbc.ce_asyn"); + fmd_hdl_subscribe(hdl, "ereport.io.fire.jbc.ue_asyn"); bzero(&cmd, sizeof (cmd_t)); diff --git a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c index 0cea97a3c1..00fc261cbc 100644 --- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c +++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_memerr_arch.c @@ -57,6 +57,10 @@ #define USIIIi_AFSR_JREQ_SHIFT 24 #define TOM_AID_MATCH_MASK 0xe +#define FIRE_AID 0xe +#define FIRE_JBC_ADDR_MASK 0x000007ffffffffffull +#define FIRE_JBC_JITEL1 "jbc-jitel1" + /*ARGSUSED*/ cmd_evdisp_t cmd_mem_synd_check(fmd_hdl_t *hdl, uint64_t afar, uint8_t afar_status, @@ -186,8 +190,8 @@ iorxefrx_match(fmd_hdl_t *hdl, cmd_errcl_t errcl, cmd_errcl_t matchmask, */ if ((CMD_ERRCL_ISIOXE(rf->rf_errcl) || CMD_ERRCL_ISIOXE(errcl)) && - ((rf->rf_afsr_agentid & TOM_AID_MATCH_MASK) == - (afsr_agentid & TOM_AID_MATCH_MASK))) + ((rf->rf_afsr_agentid & TOM_AID_MATCH_MASK) == + (afsr_agentid & TOM_AID_MATCH_MASK))) return (rf); /* @@ -292,6 +296,83 @@ cmd_rxefrx_common(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, return (rc); } +/* + * This fire IOxE must be matched with an FRx before UE/CE processing + * is possible. + * + * Note that for fire ereports we don't receive AFSR, AFAR, AFAR-Status, + * SYND and TYPNM values but we can derive the AFAR from the payload + * value FIRE_JBC_JITEL1 + */ +static cmd_evdisp_t +cmd_ioxefrx_fire(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, + const char *class, cmd_errcl_t errcl, cmd_errcl_t matchmask) +{ + cmd_xe_handler_f *hdlr; + cmd_iorxefrx_t *rfmatch, *rferr; + uint64_t afar; + int isce = CMD_ERRCL_MATCH(errcl, CMD_ERRCL_IOCE); + char *portid_str; + char *path = NULL; + nvlist_t *det = NULL; + int rc; + + rferr = fmd_hdl_zalloc(hdl, sizeof (cmd_iorxefrx_t), FMD_SLEEP); + + /* + * Lookup device path of host bridge. + */ + (void) nvlist_lookup_nvlist(nvl, FM_EREPORT_DETECTOR, &det); + (void) nvlist_lookup_string(det, FM_FMRI_DEV_PATH, &path); + + /* + * get Jbus port id from the device path + */ + portid_str = strrchr(path, '@') + 1; + rferr->rf_det_agentid = strtol(portid_str, NULL, 16); + + rferr->rf_errcl = errcl; + rferr->rf_afsr_agentid = FIRE_AID; + rferr->rf_afar_status = AFLT_STAT_VALID; + rferr->rf_synd_status = AFLT_STAT_VALID; + + /* + * Extract the afar from the payload + */ + (void) nvlist_lookup_uint64(nvl, FIRE_JBC_JITEL1, &afar); + rferr->rf_afar = afar & FIRE_JBC_ADDR_MASK; + + rferr->rf_afsr = NULL; + rferr->rf_synd = NULL; + + + /* + * Need to send in the io_jpid that we get from the device path above + * for both the det_agentid and the afsr_agentid, since the CPU does not + * capture the same address as the bridge. The bridge has the LSB + * aliased and the CPU is missing the MSB. + */ + if ((rfmatch = iorxefrx_match(hdl, rferr->rf_errcl, matchmask, + rferr->rf_det_agentid, rferr->rf_afsr_agentid)) == NULL) { + cmd_iorxefrx_queue(hdl, rferr); + return (CMD_EVD_OK); + } + + /* Found a match. Synthesize an ereport for UE/CE processing. */ + fmd_hdl_debug(hdl, "matched %cE %llx with %llx\n", "UC"[isce], + rferr->rf_errcl, rfmatch->rf_errcl); + + hdlr = (isce ? cmd_ce_common : cmd_ue_common); + rc = iorxefrx_synthesize(hdl, ep, nvl, class, rferr->rf_afar, + rferr->rf_afar_status, rfmatch->rf_afsr, rfmatch->rf_synd, + rfmatch->rf_synd_status, rferr->rf_type, rferr->rf_disp, hdlr); + + cmd_iorxefrx_free(hdl, rfmatch); + fmd_hdl_free(hdl, rferr, sizeof (cmd_iorxefrx_t)); + + return (rc); +} + /* This IOxE must be matched with an FRx before UE/CE processing is possible */ static cmd_evdisp_t cmd_ioxefrx_common(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, @@ -427,6 +508,9 @@ cmd_ioxe(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class, if (fmd_nvl_class_match(hdl, nvl, "ereport.io.tom.*")) { return (cmd_ioxefrx_common(hdl, ep, nvl, class, clcode, matchmask)); + } else if (fmd_nvl_class_match(hdl, nvl, "ereport.io.fire.*")) { + return (cmd_ioxefrx_fire(hdl, ep, nvl, class, clcode, + matchmask)); } else return (ioxe_common(hdl, ep, nvl, class, clcode)); } |