summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorjl139090 <none@none>2008-03-26 20:38:30 -0700
committerjl139090 <none@none>2008-03-26 20:38:30 -0700
commit78ed97a7b79b59ef2ef41f190c9be35c54d90119 (patch)
treefe8dc03174f029880cd560929ac7b194cce06be9 /usr/src
parente84487aec8c2a5ab4b9a28ee814a67034361ae7b (diff)
downloadillumos-joyent-78ed97a7b79b59ef2ef41f190c9be35c54d90119.tar.gz
PSARC/2008/092 OPL Ikkaku Platform Support
6655597 Support for SPARC Enterprise Ikkaku
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c5
-rw-r--r--usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h4
-rw-r--r--usr/src/cmd/fm/schemes/mem/mem_unum.c3
-rw-r--r--usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c66
-rw-r--r--usr/src/uts/sun4u/opl/io/mc-opl.c109
-rw-r--r--usr/src/uts/sun4u/opl/os/opl.c10
-rw-r--r--usr/src/uts/sun4u/sys/opl.h8
7 files changed, 174 insertions, 31 deletions
diff --git a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c
index 0c4700a83d..685211c360 100644
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -166,6 +166,9 @@ opl_cpursrc_create(fmd_hdl_t *hdl, uint32_t cpuid)
comp = frustr + sizeof (OPL_CPU_FRU_FMRI_FF2) - 1;
(void) sscanf(comp, "%d", &cmu_num);
cmu_num /= 2;
+ } else if (strncmp(frustr, OPL_CPU_FRU_FMRI_IKKAKU,
+ sizeof (OPL_CPU_FRU_FMRI_IKKAKU) - 1) == 0) {
+ cmu_num = 0;
} else {
CMD_STAT_BUMP(bad_cpu_asru);
fmd_hdl_strfree(hdl, frustr);
diff --git a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h
index 547a9bffc3..3a10abda05 100644
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -116,6 +116,8 @@ extern cmd_list_t opl_cpu_list;
FM_FMRI_LEGACY_HC"=/MBU_A/CPUM"
#define OPL_CPU_FRU_FMRI_FF2 FM_FMRI_SCHEME_HC":///" \
FM_FMRI_LEGACY_HC"=/MBU_B/CPUM"
+#define OPL_CPU_FRU_FMRI_IKKAKU FM_FMRI_SCHEME_HC":///" \
+ FM_FMRI_LEGACY_HC"=/MBU_A"
#define STR_BUFLEN 32
#define NPAIRS 5
diff --git a/usr/src/cmd/fm/schemes/mem/mem_unum.c b/usr/src/cmd/fm/schemes/mem/mem_unum.c
index 8379d65925..d9f0a7bfc0 100644
--- a/usr/src/cmd/fm/schemes/mem/mem_unum.c
+++ b/usr/src/cmd/fm/schemes/mem/mem_unum.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,6 +93,7 @@ static const bank_dimm_t bank_dimm[] = {
{ "MB/C%*d/P%*d/%nB%*d/D%*d:%n%n", " B%*d/D%*d%n" },
{ "/MBU_A/MEMB%*d/%n%nMEM%*d%*1c%n", " MEM%*d%*1c%n" },
{ "/MBU_B/MEMB%*d/%n%nMEM%*d%*1c%n", " MEM%*d%*1c%n" },
+ { "/MBU_A/%n%nMEM%*d%*1c%n", " MEM%*d%*1c%n" },
{ "/CMU%*2d/%n%nMEM%*2d%*1c%n", " MEM%*2d%*1c%n" },
{ "MB/CMP%*d/BR%*d%n:%n%n", " CH%*d/D%*d/J%*4d%n", "/" },
{ "%n%nMB/CMP%*d/BR%*d/CH%*d/D%*d/J%*4d%n",
diff --git a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c
index 084903c4ed..aedc28018b 100644
--- a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c
+++ b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c
@@ -42,6 +42,10 @@
#define LABEL FRUNAME "#%d"
#define IOBDFRU "hc:///component=" LABEL
+#define IKKAKU_FRUNAME "MBU_A"
+#define IKKAKU_LABEL IKKAKU_FRUNAME
+#define IKKAKU_IOBDFRU "hc:///component=" IKKAKU_LABEL
+
static int opl_iob_enum(topo_mod_t *hdl, tnode_t *parent, const char *name,
topo_instance_t imin, topo_instance_t imax, void *notused1, void *notused2);
@@ -54,6 +58,13 @@ static const topo_modinfo_t IobInfo = {
IOB_ENUMR_VERS,
&Iobops};
+/* OPL model type */
+typedef enum {
+ MODEL_FF,
+ MODEL_DC,
+ MODEL_IKKAKU
+} opl_model_t;
+
void
_topo_init(topo_mod_t *modhdl)
{
@@ -148,9 +159,12 @@ opl_map_boards(topo_mod_t *mod, di_node_t opl_devtree,
/*
* Create the ioboard node. Add fru and label properties, and create room
* for child hostbridge nodes.
+ *
+ * Only IKKAKU model has different IO topology.
*/
static tnode_t *
-opl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst)
+opl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst,
+ opl_model_t opl_model)
{
int err;
tnode_t *ion;
@@ -182,13 +196,19 @@ opl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst)
}
nvlist_free(fmri);
/* Create and add FRU fmri for this ioboard */
- (void) snprintf(fmri_str, sizeof (fmri_str), IOBDFRU, inst);
+ if (opl_model == MODEL_IKKAKU)
+ (void) snprintf(fmri_str, sizeof (fmri_str), IKKAKU_IOBDFRU);
+ else
+ (void) snprintf(fmri_str, sizeof (fmri_str), IOBDFRU, inst);
if (topo_mod_str2nvl(mp, fmri_str, &fmri) == 0) {
(void) topo_node_fru_set(ion, fmri, 0, &err);
nvlist_free(fmri);
}
/* Add label for this ioboard */
- (void) snprintf(label, sizeof (label), LABEL, inst);
+ if (opl_model == MODEL_IKKAKU)
+ (void) snprintf(label, sizeof (label), IKKAKU_LABEL);
+ else
+ (void) snprintf(label, sizeof (label), LABEL, inst);
(void) topo_node_label_set(ion, label, &err);
/* Create range of hostbridges on this ioboard */
@@ -201,6 +221,29 @@ opl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst)
return (ion);
}
+/*
+ * get the OPL model name from rootnode property "model"
+ */
+static int
+opl_get_model(topo_mod_t *mp, di_node_t opl_devtree, char *model)
+{
+ char *bufp;
+ di_prom_handle_t promh = DI_PROM_HANDLE_NIL;
+
+ if (opl_devtree == DI_NODE_NIL ||
+ (promh = topo_mod_prominfo(mp)) == DI_PROM_HANDLE_NIL)
+ return (-1);
+
+ if (di_prom_prop_lookup_bytes(promh, opl_devtree, "model",
+ (unsigned char **)&bufp) != -1) {
+ (void) strlcpy(model, bufp, MAXNAMELEN);
+ return (0);
+ } else {
+ return (-1);
+ }
+
+}
+
/*ARGSUSED*/
static int
opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name,
@@ -213,6 +256,8 @@ opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name,
int lsb_to_psb[OPL_IOB_MAX];
ioboard_contents_t ioboard_list[OPL_IOB_MAX];
int retval = 0;
+ char model[MAXNAMELEN];
+ opl_model_t opl_model = MODEL_FF;
/* Validate the name is correct */
if (strcmp(name, "ioboard") != 0) {
@@ -232,6 +277,19 @@ opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name,
return (-1);
}
+ if (opl_get_model(mp, opl_devtree, model) == -1) {
+ topo_mod_dprintf(mp, "opl_get_model failed.\n");
+ } else {
+ if (strncmp(model, "FF", 2) == 0)
+ opl_model = MODEL_FF;
+ else if (strncmp(model, "DC", 2) == 0)
+ opl_model = MODEL_DC;
+ else if (strcmp(model, "IKKAKU") == 0)
+ opl_model = MODEL_IKKAKU;
+
+ topo_mod_dprintf(mp, "opl_get_model %s found.\n", model);
+ }
+
/*
* Create a mapping from logical board numbers (which are part of
* the device node bus address) to physical board numbers, so we
@@ -280,7 +338,7 @@ opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name,
continue;
}
/* Create node for this ioboard */
- ion = opl_iob_node_create(mp, parent, inst);
+ ion = opl_iob_node_create(mp, parent, inst, opl_model);
if (ion == NULL) {
topo_mod_dprintf(mp,
"enumeration of ioboard failed: %s\n",
diff --git a/usr/src/uts/sun4u/opl/io/mc-opl.c b/usr/src/uts/sun4u/opl/io/mc-opl.c
index a489050670..c1a7fafc1d 100644
--- a/usr/src/uts/sun4u/opl/io/mc-opl.c
+++ b/usr/src/uts/sun4u/opl/io/mc-opl.c
@@ -23,7 +23,7 @@
* Use is subject to license terms.
*/
/*
- * All Rights Reserved, Copyright (c) FUJITSU LIMITED 2007
+ * All Rights Reserved, Copyright (c) FUJITSU LIMITED 2008
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -157,9 +157,10 @@ static struct dev_ops mc_ops = {
*/
static enum {
- MODEL_FF1 = 0,
- MODEL_FF2 = 1,
- MODEL_DC = 2
+ MODEL_FF1,
+ MODEL_FF2,
+ MODEL_DC,
+ MODEL_IKKAKU
} plat_model = MODEL_DC; /* The default behaviour is DC */
static struct plat_model_names {
@@ -168,7 +169,8 @@ static struct plat_model_names {
} model_names[] = {
{ "MBU_A", "MEMB" },
{ "MBU_B", "MEMB" },
- { "CMU", "" }
+ { "CMU", "" },
+ { "MBU_A", "" }
};
/*
@@ -191,7 +193,7 @@ static char *mc_dc_dimm_unum_table[OPL_MAX_DIMMS] = {
};
/*
- * The DIMM Names for FF1/FF2 platforms.
+ * The DIMM Names for FF1/FF2/IKKAKU platforms.
* The index into this table is made up of (board, bank, dslot),
* Where dslot occupies bits 0-1, bank occupies 2-4 and
* board occupies the bit 5.
@@ -384,6 +386,8 @@ _init(void)
plat_model = MODEL_FF2;
else if (strncmp(model, "DC", 2) == 0)
plat_model = MODEL_DC;
+ else if (strcmp(model, "IKKAKU") == 0)
+ plat_model = MODEL_IKKAKU;
}
error = mod_install(&modlinkage);
@@ -816,10 +820,15 @@ pa_to_maddr(mc_opl_t *mcp, uint64_t pa, mc_addr_t *maddr)
* y = 0..3 (slot info).
* Z = 'A' or 'B'
*
- * UNUM format for FF2 is "/MBU_B/MEMBx/MEMyZ"
+ * UNUM format for FF2 is "/MBU_B/MEMBx/MEMyZ", where
* x = 0..7 (MEMB number)
* y = 0..3 (slot info).
* Z = 'A' or 'B'
+ *
+ * UNUM format for IKKAKU is "/MBU_A/MEMyZ", where
+ * y = 0..3 (slot info).
+ * Z = 'A' or 'B'
+ *
*/
int
mc_set_mem_unum(char *buf, int buflen, int sb, int bank,
@@ -833,7 +842,8 @@ mc_set_mem_unum(char *buf, int buflen, int sb, int bank,
cs = SLOT_TO_CS(d_slot);
- if (plat_model == MODEL_DC) {
+ switch (plat_model) {
+ case MODEL_DC:
if (mf_type == FLT_TYPE_INTERMITTENT_CE ||
mf_type == FLT_TYPE_PERMANENT_CE) {
i = BD_BK_SLOT_TO_INDEX(0, bank, d_slot);
@@ -848,7 +858,9 @@ mc_set_mem_unum(char *buf, int buflen, int sb, int bank,
mc_dc_dimm_unum_table[j],
mc_dc_dimm_unum_table[j + 1]);
}
- } else {
+ break;
+ case MODEL_FF1:
+ case MODEL_FF2:
if (mf_type == FLT_TYPE_INTERMITTENT_CE ||
mf_type == FLT_TYPE_PERMANENT_CE) {
i = BD_BK_SLOT_TO_INDEX(sb, bank, d_slot);
@@ -868,6 +880,26 @@ mc_set_mem_unum(char *buf, int buflen, int sb, int bank,
&mc_ff_dimm_unum_table[j][1],
&mc_ff_dimm_unum_table[j + 1][1]);
}
+ break;
+ case MODEL_IKKAKU:
+ if (mf_type == FLT_TYPE_INTERMITTENT_CE ||
+ mf_type == FLT_TYPE_PERMANENT_CE) {
+ i = BD_BK_SLOT_TO_INDEX(sb, bank, d_slot);
+ dimmnm = mc_ff_dimm_unum_table[i];
+ snprintf(buf, buflen, "/%s/MEM%s",
+ model_names[plat_model].unit_name, &dimmnm[1]);
+ } else {
+ i = BD_BK_SLOT_TO_INDEX(sb, bank, 0);
+ j = (cs == 0) ? i : i + 2;
+ memb_num = mc_ff_dimm_unum_table[i][0],
+ snprintf(buf, buflen, "/%s/MEM%s MEM%s",
+ model_names[plat_model].unit_name,
+ &mc_ff_dimm_unum_table[j][1],
+ &mc_ff_dimm_unum_table[j + 1][1]);
+ }
+ break;
+ default:
+ return (-1);
}
return (0);
}
@@ -2133,11 +2165,11 @@ mc_check_errors_func(mc_opl_t *mcp)
if (wrapped) {
MAC_CLEAR_MAX(mcp, i);
mcp->mc_period[ebk]++;
- if (IS_MIRROR(mcp, i))
+ if (IS_MIRROR(mcp, i)) {
MC_LOG("mirror mc period %ld on "
"/LSB%d/B%d\n", mcp->mc_period[ebk],
mcp->mc_board_num, i);
- else {
+ } else {
MC_LOG("mc period %ld on "
"/LSB%d/B%d\n", mcp->mc_period[ebk],
mcp->mc_board_num, i);
@@ -2913,6 +2945,7 @@ mc_get_mem_unum(int synd_code, uint64_t flt_addr, char *buf, int buflen,
int sb;
int bank;
int cs;
+ int rv = 0;
mc_opl_t *mcp;
char memb_num;
@@ -2939,14 +2972,17 @@ mc_get_mem_unum(int synd_code, uint64_t flt_addr, char *buf, int buflen,
return (ENXIO);
}
- if (plat_model == MODEL_DC) {
+ switch (plat_model) {
+ case MODEL_DC:
i = BD_BK_SLOT_TO_INDEX(0, bank, 0);
j = (cs == 0) ? i : i + 2;
snprintf(buf, buflen, "/%s%02d/MEM%s MEM%s",
model_names[plat_model].unit_name, sb,
mc_dc_dimm_unum_table[j],
mc_dc_dimm_unum_table[j + 1]);
- } else {
+ break;
+ case MODEL_FF2:
+ case MODEL_FF1:
i = BD_BK_SLOT_TO_INDEX(sb, bank, 0);
j = (cs == 0) ? i : i + 2;
memb_num = mc_ff_dimm_unum_table[i][0];
@@ -2955,12 +2991,23 @@ mc_get_mem_unum(int synd_code, uint64_t flt_addr, char *buf, int buflen,
model_names[plat_model].mem_name, memb_num,
&mc_ff_dimm_unum_table[j][1],
&mc_ff_dimm_unum_table[j + 1][1]);
+ break;
+ case MODEL_IKKAKU:
+ i = BD_BK_SLOT_TO_INDEX(sb, bank, 0);
+ j = (cs == 0) ? i : i + 2;
+ snprintf(buf, buflen, "/%s/MEM%s MEM%s",
+ model_names[plat_model].unit_name,
+ &mc_ff_dimm_unum_table[j][1],
+ &mc_ff_dimm_unum_table[j + 1][1]);
+ break;
+ default:
+ rv = ENXIO;
}
if (lenp) {
*lenp = strlen(buf);
}
mutex_exit(&mcmutex);
- return (0);
+ return (rv);
}
int
@@ -3368,18 +3415,26 @@ parse_unum_memory(char *unum, int *board, char *dname)
y = c[1];
z = c[2];
} else if ((c = strstr(unum, "MBU_")) != NULL) {
- /* FF1/FF2 Model */
+ /* FF1/FF2/Ikkaku Model */
c += 4;
if ((c[0] != 'A') && (c[0] != 'B')) {
return (4);
}
- if ((c = strstr(c, "MEMB")) == NULL) {
- return (5);
+ if (plat_model == MODEL_IKKAKU) {
+ /* Ikkaku Model */
+ x = '0';
+ *board = 0;
+ } else {
+ /* FF1/FF2 Model */
+ if ((c = strstr(c, "MEMB")) == NULL) {
+ return (5);
+ }
+ c += 4;
+
+ x = c[0];
+ *board = ((uint8_t)stoi(&c)) / 4;
}
- c += 4;
- x = c[0];
- *board = ((uint8_t)stoi(&c)) / 4;
if ((c = strstr(c, "MEM")) == NULL) {
return (6);
}
@@ -3453,9 +3508,15 @@ mc_set_mem_sid(mc_opl_t *mcp, char *buf, int buflen, int sb,
if (mf_type == FLT_TYPE_INTERMITTENT_CE ||
mf_type == FLT_TYPE_PERMANENT_CE) {
if (plat_model == MODEL_DC) {
+ /*
+ * All DC models
+ */
id = BD_BK_SLOT_TO_INDEX(0, bank, d_slot);
dimmnm = mc_dc_dimm_unum_table[id];
} else {
+ /*
+ * All FF and Ikkaku models
+ */
id = BD_BK_SLOT_TO_INDEX(sb, bank, d_slot);
dimmnm = mc_ff_dimm_unum_table[id];
}
@@ -3561,10 +3622,16 @@ dname_to_bankslot(char *dname, int *bank, int *slot)
int tsz;
char **tbl;
- if (plat_model == MODEL_DC) { /* DC */
+ if (plat_model == MODEL_DC) {
+ /*
+ * All DC models
+ */
tbl = mc_dc_dimm_unum_table;
tsz = OPL_MAX_DIMMS;
} else {
+ /*
+ * All FF and Ikkaku models
+ */
tbl = mc_ff_dimm_unum_table;
tsz = 2 * OPL_MAX_DIMMS;
}
diff --git a/usr/src/uts/sun4u/opl/os/opl.c b/usr/src/uts/sun4u/opl/os/opl.c
index ac892efd74..8dc6c93de0 100644
--- a/usr/src/uts/sun4u/opl/os/opl.c
+++ b/usr/src/uts/sun4u/opl/os/opl.c
@@ -86,6 +86,7 @@ static opl_model_info_t opl_models[] = {
{ "DC1", OPL_MAX_BOARDS_DC1, DC1, STD_DISPATCH_TABLE },
{ "DC2", OPL_MAX_BOARDS_DC2, DC2, EXT_DISPATCH_TABLE },
{ "DC3", OPL_MAX_BOARDS_DC3, DC3, EXT_DISPATCH_TABLE },
+ { "IKKAKU", OPL_MAX_BOARDS_IKKAKU, IKKAKU, STD_DISPATCH_TABLE },
};
static int opl_num_models = sizeof (opl_models)/sizeof (opl_model_info_t);
@@ -156,7 +157,7 @@ set_model_info()
/*
* If model not matched, it's an unknown model.
- * just return.
+ * Just return. It will default to standard dispatch tables.
*/
if (i == opl_num_models)
return;
@@ -167,7 +168,8 @@ set_model_info()
* Based on a platform model, select a dispatch table.
* Only DC2 and DC3 systems uses the alternate/extended
* TS dispatch table.
- * FF1, FF2 and DC1 systems used standard dispatch tables.
+ * IKKAKU, FF1, FF2 and DC1 systems use standard dispatch
+ * tables.
*/
ts_dispatch_extended = 1;
}
@@ -888,6 +890,10 @@ plat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp)
CHIP_ID(cpuid));
break;
+ case IKKAKU:
+ plen = snprintf(buf, buflen, "/%s", "MBU_A");
+ break;
+
default:
/* This should never happen */
return (ENODEV);
diff --git a/usr/src/uts/sun4u/sys/opl.h b/usr/src/uts/sun4u/sys/opl.h
index fe8d43f4e2..57a6351d6f 100644
--- a/usr/src/uts/sun4u/sys/opl.h
+++ b/usr/src/uts/sun4u/sys/opl.h
@@ -70,6 +70,7 @@ extern "C" {
/*
* Max. boards supported in a domain per model.
*/
+#define OPL_MAX_BOARDS_IKKAKU 1
#define OPL_MAX_BOARDS_FF1 1
#define OPL_MAX_BOARDS_FF2 2
#define OPL_MAX_BOARDS_DC1 4
@@ -78,7 +79,12 @@ extern "C" {
/* OPL model type */
typedef enum {
- FF1 = 0, FF2, DC1, DC2, DC3
+ FF1,
+ FF2,
+ DC1,
+ DC2,
+ DC3,
+ IKKAKU
} opl_type_t;
/* OPL model specific cmds selection */