diff options
author | gavinm <none@none> | 2006-11-24 01:54:59 -0800 |
---|---|---|
committer | gavinm <none@none> | 2006-11-24 01:54:59 -0800 |
commit | 4156fc34b973159b0334e05ae5ec19344487bdc0 (patch) | |
tree | cb5476c983800a14bd9e655ecdfff41933b4546c /usr/src/common/mc | |
parent | aa3da23c1e735ce968058c7dfd8b0480e31d4e3d (diff) | |
download | illumos-joyent-4156fc34b973159b0334e05ae5ec19344487bdc0.tar.gz |
6474853 Solaris should be cognizant of the platform while attempting to turn off smi mc polling
6489753 mc_amd.h not quite ready for revision G
6491720 DC/IC/BU system infill only capture physical <39:6>
6495485 i86pc/cpu/scripts do not get clobbered
Diffstat (limited to 'usr/src/common/mc')
-rw-r--r-- | usr/src/common/mc/mc-amd/mcamd_api.h | 2 | ||||
-rw-r--r-- | usr/src/common/mc/mc-amd/mcamd_err.c | 10 | ||||
-rw-r--r-- | usr/src/common/mc/mc-amd/mcamd_err.h | 8 | ||||
-rw-r--r-- | usr/src/common/mc/mc-amd/mcamd_patounum.c | 56 |
4 files changed, 46 insertions, 30 deletions
diff --git a/usr/src/common/mc/mc-amd/mcamd_api.h b/usr/src/common/mc/mc-amd/mcamd_api.h index 977b9dfe94..4053199ebd 100644 --- a/usr/src/common/mc/mc-amd/mcamd_api.h +++ b/usr/src/common/mc/mc-amd/mcamd_api.h @@ -197,7 +197,7 @@ union mcamd_dimm_offset_un { extern const char *mcamd_get_propname(mcamd_propcode_t); extern int mcamd_patounum(struct mcamd_hdl *, mcamd_node_t *, uint64_t, - uint32_t, int, mc_unum_t *); + uint8_t, uint8_t, uint32_t, int, mc_unum_t *); extern int mcamd_unumtopa(struct mcamd_hdl *, mcamd_node_t *, mc_unum_t *, uint64_t *); extern int mc_pa_to_offset(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *, diff --git a/usr/src/common/mc/mc-amd/mcamd_err.c b/usr/src/common/mc/mc-amd/mcamd_err.c index d0e1666423..689e556cd4 100644 --- a/usr/src/common/mc/mc-amd/mcamd_err.c +++ b/usr/src/common/mc/mc-amd/mcamd_err.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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 * or http://www.opensolaris.org/os/licensing. @@ -31,8 +30,9 @@ static const char *const _mcamd_errlist[] = { "Invalid syndrome", /* EMCAMD_SYNDINVALID */ "Invalid configuration tree", /* EMCAMD_TREEINVALID */ - "Address not found" /* EMCAMD_NOADDR */ - "Operation not supported" /* EMCAMD_NOTSUP */ + "Address not found", /* EMCAMD_NOADDR */ + "Operation not supported", /* EMCAMD_NOTSUP */ + "Too few valid address bits", /* EMCAMD_INSUFF_RES */ }; static const int _mcamd_nerr = sizeof (_mcamd_errlist) / diff --git a/usr/src/common/mc/mc-amd/mcamd_err.h b/usr/src/common/mc/mc-amd/mcamd_err.h index f9a762e211..f9dc53f32d 100644 --- a/usr/src/common/mc/mc-amd/mcamd_err.h +++ b/usr/src/common/mc/mc-amd/mcamd_err.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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 * or http://www.opensolaris.org/os/licensing. @@ -38,7 +37,8 @@ enum { EMCAMD_SYNDINVALID = EMCAMD_BASE, /* invalid syndrome */ EMCAMD_TREEINVALID, /* invalid configuration tree */ EMCAMD_NOADDR, /* address not found */ - EMCAMD_NOTSUP /* operation not supported */ + EMCAMD_NOTSUP, /* operation not supported */ + EMCAMD_INSUFF_RES /* insufficient resolution */ }; extern const char *mcamd_errmsg(struct mcamd_hdl *); diff --git a/usr/src/common/mc/mc-amd/mcamd_patounum.c b/usr/src/common/mc/mc-amd/mcamd_patounum.c index b58a751d60..594af7e7cc 100644 --- a/usr/src/common/mc/mc-amd/mcamd_patounum.c +++ b/usr/src/common/mc/mc-amd/mcamd_patounum.c @@ -36,6 +36,8 @@ #include <mcamd_api.h> #include <mcamd_err.h> +#define MC_SYSADDR_MSB 39 +#define MC_SYSADDR_LSB 3 #define CSDIMM1 0x1 #define CSDIMM2 0x2 @@ -342,7 +344,7 @@ unum_fill(struct mcamd_hdl *hdl, mcamd_node_t *cs, int which, */ static int mc_whichdimm(struct mcamd_hdl *hdl, mcamd_node_t *cs, uint64_t pa, - uint32_t synd, int syndtype) + uint8_t valid_lo, uint32_t synd, int syndtype) { int lobit, hibit, data, check; uint64_t dimm1, dimm2; @@ -379,14 +381,22 @@ mc_whichdimm(struct mcamd_hdl *hdl, mcamd_node_t *cs, uint64_t pa, /* * 64/8 ECC is checked separately for the upper and lower * halves, so even an uncorrectable error is contained within - * one of the two halves. The error address is accurate to - * 8 bytes, so bit 4 distinguises upper from lower. + * one of the two halves. If we have sufficient address resolution + * then we can determine which DIMM. */ if (syndtype == AMD_SYNDTYPE_ECC) { - mcamd_dprintf(hdl, MCAMD_DBG_FLOW, "mc_whichdimm: 64/8 ECC " - "and PA 0x%llx is in %s half\n", pa, - pa & 8 ? "lower" : "upper"); - return (pa & 8 ? CSDIMM2 : CSDIMM1); + if (valid_lo <= MC_SYSADDR_LSB) { + mcamd_dprintf(hdl, MCAMD_DBG_FLOW, "mc_whichdimm: 64/8 " + "ECC in 128-bit mode, PA 0x%llx is in %s half\n", + pa, pa & 0x8 ? "upper" : "lower"); + return (pa & 0x8 ? CSDIMM2 : CSDIMM1); + } else { + mcamd_dprintf(hdl, MCAMD_DBG_FLOW, "mc_whichdimm: " + "64/8 ECC in 128-bit mode, PA 0x%llx with least " + "significant valid bit %d cannot be resolved to " + "a single DIMM\n", pa, valid_lo); + return (mcamd_set_errno(hdl, EMCAMD_INSUFF_RES)); + } } /* @@ -430,7 +440,8 @@ mc_whichdimm(struct mcamd_hdl *hdl, mcamd_node_t *cs, uint64_t pa, */ static int mc_bkdg_patounum(struct mcamd_hdl *hdl, mcamd_node_t *mc, uint64_t pa, - uint32_t synd, int syndtype, mc_unum_t *unump) + uint8_t valid_lo, uint32_t synd, int syndtype, + mc_unum_t *unump) { int which; uint64_t mcnum, rev; @@ -565,8 +576,8 @@ mc_bkdg_patounum(struct mcamd_hdl *hdl, mcamd_node_t *mc, uint64_t pa, if ((sparecs = cs_sparedto(hdl, cs, mc)) != NULL) cs = sparecs; - if ((which = mc_whichdimm(hdl, cs, pa, synd, - syndtype)) < 0) + if ((which = mc_whichdimm(hdl, cs, pa, valid_lo, + synd, syndtype)) < 0) return (-1); /* errno is set for us */ /* @@ -597,7 +608,7 @@ mc_bkdg_patounum(struct mcamd_hdl *hdl, mcamd_node_t *mc, uint64_t pa, /*ARGSUSED*/ static int mc_patounum(struct mcamd_hdl *hdl, mcamd_node_t *mc, uint64_t pa, - uint32_t synd, int syndtype, mc_unum_t *unump) + uint8_t valid_lo, uint32_t synd, int syndtype, mc_unum_t *unump) { uint64_t iaddr; mcamd_node_t *cs, *sparecs; @@ -612,7 +623,8 @@ mc_patounum(struct mcamd_hdl *hdl, mcamd_node_t *mc, uint64_t pa, * difficult to review against the BKDG approach. */ mcamd_dprintf(hdl, MCAMD_DBG_FLOW, "BKDG brute-force method begins\n"); - bkdgres = mc_bkdg_patounum(hdl, mc, pa, synd, syndtype, &bkdg_unum); + bkdgres = mc_bkdg_patounum(hdl, mc, pa, valid_lo, synd, + syndtype, &bkdg_unum); mcamd_dprintf(hdl, MCAMD_DBG_FLOW, "BKDG brute-force method ends\n"); #endif @@ -639,7 +651,8 @@ mc_patounum(struct mcamd_hdl *hdl, mcamd_node_t *mc, uint64_t pa, cs = sparecs; } - if ((which = mc_whichdimm(hdl, cs, pa, synd, syndtype)) < 0) + if ((which = mc_whichdimm(hdl, cs, pa, valid_lo, synd, + syndtype)) < 0) return (-1); /* errno is set for us */ if (unum_fill(hdl, cs, which, iaddr, unump, 1) < 0) @@ -676,24 +689,27 @@ mc_patounum(struct mcamd_hdl *hdl, mcamd_node_t *mc, uint64_t pa, int mcamd_patounum(struct mcamd_hdl *hdl, mcamd_node_t *root, uint64_t pa, - uint32_t synd, int syndtype, mc_unum_t *unump) + uint8_t valid_hi, uint8_t valid_lo, uint32_t synd, int syndtype, + mc_unum_t *unump) { mcamd_node_t *mc; mcamd_dprintf(hdl, MCAMD_DBG_FLOW, "mcamd_patounum: pa=0x%llx, " "synd=0x%x, syndtype=%d\n", pa, synd, syndtype); - /* - * Consider allowing syndrome 0 to act as a generic multibit - * syndrome. For example icache inf_sys_ecc1 captures an address - * but no syndrome - we can still resolve this to a dimm or dimms. - */ + if (valid_hi < MC_SYSADDR_MSB) { + mcamd_dprintf(hdl, MCAMD_DBG_FLOW, "mcamd_patounum: require " + "pa<%d> to be valid\n", MC_SYSADDR_MSB); + return (mcamd_set_errno(hdl, EMCAMD_INSUFF_RES)); + } + if (!mcamd_synd_validate(hdl, synd, syndtype)) return (mcamd_set_errno(hdl, EMCAMD_SYNDINVALID)); for (mc = mcamd_mc_next(hdl, root, NULL); mc != NULL; mc = mcamd_mc_next(hdl, root, mc)) { - if (mc_patounum(hdl, mc, pa, synd, syndtype, unump) == 0) + if (mc_patounum(hdl, mc, pa, valid_lo, synd, + syndtype, unump) == 0) return (0); if (mcamd_errno(hdl) != EMCAMD_NOADDR) |