/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* Ereport-handling routines for memory errors
*/
#include <cmd_mem.h>
#include <cmd_dimm.h>
#include <cmd_bank.h>
#include <cmd_page.h>
#include <cmd_cpu.h>
#include <cmd.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <sys/cheetahregs.h>
#include <sys/errclassify.h>
/* Jalapeno-specific values from cheetahregs.h */
/*ARGSUSED*/
{
if (synd == CH_POISON_SYND_FROM_XXU_WRITE ||
"discarding UE due to magic syndrome %x\n", synd);
return (CMD_EVD_UNUSED);
}
return (CMD_EVD_OK);
}
static cmd_evdisp_t
{
char *typenm;
if (nvlist_lookup_pairs(nvl, 0,
NULL) != 0)
return (CMD_EVD_BAD);
&disp) != 0)
minorvers = 0;
}
/*ARGSUSED*/
{
}
/*ARGSUSED*/
{
}
{
}
/*
* create either a CE or a UE, as appropriate. Before dispatching the
* joined event to the xE handler, we need to generate the FMRI for the
* named DIMM. While one of the events may already contain a resource FMRI,
* said FMRI is incomplete. The detector didn't have the necessary
* information (the AFAR, the AFSR, *and* the syndrome) needed to create
* a DIMM-level FMRI.
*/
static cmd_evdisp_t
{
int rc;
return (CMD_EVD_UNUSED);
return (rc);
}
static cmd_iorxefrx_t *
{
"rf->rf_det_agentid = %lx, afsr_agentid = %lx\n"
"rf->rf_afsr_agentid = %lx, det_agentid = %lx\n",
continue;
/*
* For IOxEs we are unable to match based on both the detector
* and the captured Agent Id in the AFSR, because the bridge
* captures it's own Agent Id instead of the remote CPUs.
*
* Also, the LSB of Tomatillo's jpid is aliased for each chip
* and therefore needs to be factored out of our matching.
*/
CMD_ERRCL_ISIOXE(errcl)) &&
return (rf);
/*
* Check for both here since IOxE is not involved
*/
return (rf);
}
return (NULL);
}
/*
* Got an RxE or an FRx. FRx ereports can be matched with RxE ereports and
* vice versa. FRx ereports can also be matched with IOxE ereports.
*/
{
char *typenm;
int rc;
if (nvlist_lookup_pairs(nvl, 0,
NULL) != 0) {
return (CMD_EVD_BAD);
}
minorvers = 0;
return (CMD_EVD_UNUSED);
}
return (CMD_EVD_UNUSED);
}
if (isrxe) {
} else {
}
return (CMD_EVD_OK);
}
/*
* Found a match. Send a synthesized ereport to the appropriate
* routine.
*/
if (isrxe) {
hdlr);
} else {
hdlr);
}
return (rc);
}
/*
* is possible.
*
* Note that for fire ereports we don't receive AFSR, AFAR, AFAR-Status
* and SYND values but we can derive the AFAR from the payload value
* FIRE_JBC_JITEL1. We may receive a TYPNM value.
*/
static cmd_evdisp_t
{
char *portid_str;
int rc;
/*
* Lookup device path of host bridge.
*/
/*
* get Jbus port id from the device path
*/
/*
* Extract the afar from the payload
*/
&typenm) == 0)
/*
* 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.
*/
return (CMD_EVD_OK);
}
return (rc);
}
static cmd_evdisp_t
{
char *typenm;
char *portid_str;
int rc;
if (nvlist_lookup_pairs(nvl, 0,
NULL) != 0) {
return (CMD_EVD_BAD);
}
minorvers = 0;
/*
* Lookup device path of host bridge.
*/
/*
* get Jbus port id from the device path
*/
/*
* Only 4 bits of the Jbus AID are sent on the Jbus. MSB is the one
* that is chosen not to make the trip. This is not in any of the Jbus
* or Tomatillo documents and was discovered during testing and verified
* by Jalapeno H/W designer.
*/
/*
* 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.
*/
return (CMD_EVD_OK);
}
return (rc);
}
/* IOxE ereports that don't need matching with FRx ereports */
static cmd_evdisp_t
{
char *typenm;
if (nvlist_lookup_pairs(nvl, 0,
NULL) != 0)
return (CMD_EVD_BAD);
minorvers = 0;
rsrc));
}
{
}
{
matchmask));
matchmask));
} else
}
/*ARGSUSED*/
{
/*
* Secondary IOxE's can't be used to identify failed or failing
* resources, as they don't contain enough information. Ignore them.
*/
return (CMD_EVD_OK);
}
/*ARGSUSED*/
{
return (sysconf(_SC_PHYS_PAGES));
}
/*
* sun4u bit position as function of e_synd,
* from JPS1 Implementation Supplement table P-7
* Encode bit positions as follows:
* 0-127 data bits 0-127
* 128-136 check bits 0-8 (Cn = 128+n)
* no error or multibit error = -1 (not valid CE)
*/
int esynd2bit [] = {
-1, 128, 129, -1, 130, -1, -1, 47,
131, -1, -1, 53, -1, 41, 29, -1, /* 000-00F */
132, -1, -1, 50, -1, 38, 25, -1,
-1, 33, 24, -1, 11, -1, -1, 16, /* 010-01F */
133, -1, -1, 46, -1, 37, 19, -1,
-1, 31, 32, -1, 7, -1, -1, 10, /* 020-02F */
-1, 40, 13, -1, 59, -1, -1, 66,
-1, -1, -1, 0, -1, 67, 71, -1, /* 030-03F */
134, -1, -1, 43, -1, 36, 18, -1,
-1, 49, 15, -1, 63, -1, -1, 6, /* 040-04F */
-1, 44, 28, -1, -1, -1, -1, 52,
68, -1, -1, 62, -1, -1, -1, -1, /* 050-05F */
-1, 26, 106, -1, 64, -1, -1, 2,
120, -1, -1, -1, -1, -1, -1, -1, /* 060-06F */
116, -1, -1, -1, -1, -1, -1, -1,
-1, 58, 54, -1, -1, -1, -1, -1, /* 070-07F */
135, -1, -1, 42, -1, 35, 17, -1,
-1, 45, 14, -1, 21, -1, -1, 5, /* 080-08F */
-1, 27, -1, -1, 99, -1, -1, 3,
114, -1, -1, 20, -1, -1, -1, -1, /* 090-09F */
-1, 23, 113, -1, 112, -1, -1, 51,
95, -1, -1, -1, -1, -1, -1, -1, /* 0A0-0AF */
103, -1, -1, -1, -1, -1, -1, -1,
-1, 48, -1, -1, 73, -1, -1, -1, /* 0B0-0BF */
-1, 22, 110, -1, 109, -1, -1, 9,
108, -1, -1, -1, -1, -1, -1, -1, /* 0C0-0CF */
102, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, /* 0D0-0DF */
98, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, /* 0E0-0EF */
-1, -1, -1, -1, -1, -1, -1, -1,
56, -1, -1, -1, -1, -1, -1, -1, /* 0F0-0FF */
136, -1, -1, 39, -1, 34, 105, -1,
-1, 30, 104, -1, 101, -1, -1, 4, /* 100-10F */
-1, -1, 100, -1, 83, -1, -1, 12,
87, -1, -1, 57, -1, -1, -1, -1, /* 110-11F */
-1, 97, 82, -1, 78, -1, -1, 1,
96, -1, -1, -1, -1, -1, -1, -1, /* 120-12F */
94, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 79, -1, 69, -1, -1, -1, /* 130-13F */
-1, 93, 92, -1, 91, -1, -1, 8,
90, -1, -1, -1, -1, -1, -1, -1, /* 140-14F */
89, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, /* 150-15F */
86, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, /* 160-16F */
-1, -1, -1, -1, -1, -1, -1, -1,
60, -1, -1, -1, -1, -1, -1, -1, /* 170-17F */
-1, 88, 85, -1, 84, -1, -1, 55,
81, -1, -1, -1, -1, -1, -1, -1, /* 180-18F */
77, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, /* 190-19F */
74, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, /* 1A0-1AF */
-1, 70, 107, -1, 65, -1, -1, -1,
127, -1, -1, -1, -1, -1, -1, -1, /* 1B0-1BF */
80, -1, -1, 72, -1, 119, 118, -1,
-1, 126, 76, -1, 125, -1, -1, -1, /* 1C0-1CF */
-1, 115, 124, -1, 75, -1, -1, -1,
61, -1, -1, -1, -1, -1, -1, -1, /* 1D0-1DF */
-1, 123, 122, -1, 121, -1, -1, -1,
117, -1, -1, -1, -1, -1, -1, -1, /* 1E0-1EF */
111, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 /* 1F0-1FF */
};
-1, 140, 141, -1,
142, -1, -1, 137,
143, -1, -1, 138,
-1, 139, -1, -1
};
int
}
const char *fmd_fmri_get_platform();
const char *slotname[] = {
"Slot A", "Slot B", "Slot C", "Slot D"};
typedef struct fault_info {
int count;
} fault_info_t;
struct plat2id_map {
char *platnm;
int id;
} id_plat[] = {
{"SUNW,Sun-Fire-15000", 1},
{"SUNW,Sun-Fire", 2},
{"SUNW,Netra-T12", 2},
{"SUNW,Sun-Fire-480R", 3},
{"SUNW,Sun-Fire-V490", 3},
{"SUNW,Sun-Fire-V440", 3},
{"SUNW,Sun-Fire-V445", 3},
{"SUNW,Netra-440", 3},
{"SUNW,Sun-Fire-880", 4},
{"SUNW,Sun-Fire-V890", 4},
{NULL, 0}
};
/*ARGSUSED*/
void
{
}
/*ARGSUSED*/
int
{
return (1);
}
static int
{
const char *platname;
int i;
break;
}
}
return (id);
}
static int
{
int boardid;
switch (id) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
if ((cpuid % 2) == 0)
else
break;
default:
boardid = 5;
break;
}
return (boardid);
}
static void
{
int i, j, k, idj;
int max_rpt;
return;
for (i = 0, j = 0; i < CMD_MAX_CKWDS; i++) {
j++;
}
break;
}
break;
}
for (i = 0; i < CMD_MAX_CKWDS; i++) {
j++;
}
if (j >= max_rpt)
break;
}
if (j >= max_rpt)
break;
}
for (i = 0, k = 0; i < max_rpt; i++) {
continue;
sizeof (fault_info_t), FMD_SLEEP);
if (fault_list[k] == NULL)
break;
for (j = i + 1; j < max_rpt; j++) {
continue;
fault_list[k]->count++;
}
}
k++;
}
}
/*ARGSUSED*/
static nvlist_t *
{
int err;
return (NULL);
return (NULL);
if (err != 0) {
return (NULL);
}
return (NULL);
}
if (err != 0) {
return (NULL);
}
return (fru);
}
/*
* Startcat, Serengeti, V4xx, and V8xx: fault the system boards of
* the detectors in proportion to the number of ereports out of 8
* Other systems: fault the detectors in proportion to the number of
* ereports out of 8
*/
void
{
char *cpustr;
if (fault_list == NULL)
return;
for (i = 0; i < max_rpt; i++)
fault_list[i] = NULL;
type = cmd_get_platform();
for (i = 0; i < max_rpt; i++) {
if (fault_list[i] == NULL)
continue;
switch (type) {
case 1:
break;
case 2:
break;
case 3:
case 4:
break;
default:
== 0) {
}
break;
}
if (fault_cpu) {
break;
}
} else {
break;
}
/* free up memory */
}
for (i = 0; i < max_rpt; i++) {
if (fault_list[i] != NULL)
}
}