diff options
author | jl139090 <none@none> | 2008-03-26 20:38:30 -0700 |
---|---|---|
committer | jl139090 <none@none> | 2008-03-26 20:38:30 -0700 |
commit | 78ed97a7b79b59ef2ef41f190c9be35c54d90119 (patch) | |
tree | fe8dc03174f029880cd560929ac7b194cce06be9 /usr/src | |
parent | e84487aec8c2a5ab4b9a28ee814a67034361ae7b (diff) | |
download | illumos-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.c | 5 | ||||
-rw-r--r-- | usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_opl.h | 4 | ||||
-rw-r--r-- | usr/src/cmd/fm/schemes/mem/mem_unum.c | 3 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c | 66 | ||||
-rw-r--r-- | usr/src/uts/sun4u/opl/io/mc-opl.c | 109 | ||||
-rw-r--r-- | usr/src/uts/sun4u/opl/os/opl.c | 10 | ||||
-rw-r--r-- | usr/src/uts/sun4u/sys/opl.h | 8 |
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 */ |