17aec1d6eScindi /* 27aec1d6eScindi * CDDL HEADER START 37aec1d6eScindi * 47aec1d6eScindi * The contents of this file are subject to the terms of the 57aec1d6eScindi * Common Development and Distribution License (the "License"). 67aec1d6eScindi * You may not use this file except in compliance with the License. 77aec1d6eScindi * 87aec1d6eScindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97aec1d6eScindi * or http://www.opensolaris.org/os/licensing. 107aec1d6eScindi * See the License for the specific language governing permissions 117aec1d6eScindi * and limitations under the License. 127aec1d6eScindi * 137aec1d6eScindi * When distributing Covered Code, include this CDDL HEADER in each 147aec1d6eScindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157aec1d6eScindi * If applicable, add the following below this CDDL HEADER, with the 167aec1d6eScindi * fields enclosed by brackets "[]" replaced with your own identifying 177aec1d6eScindi * information: Portions Copyright [yyyy] [name of copyright owner] 187aec1d6eScindi * 197aec1d6eScindi * CDDL HEADER END 207aec1d6eScindi */ 217aec1d6eScindi 227aec1d6eScindi /* 2310569901Sgavinm * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 247aec1d6eScindi * Use is subject to license terms. 257aec1d6eScindi */ 267aec1d6eScindi 277aec1d6eScindi #include <unistd.h> 28*e4b86885SCheng Sean Ye #include <fcntl.h> 297aec1d6eScindi #include <stdio.h> 307aec1d6eScindi #include <stdlib.h> 318a40a695Sgavinm #include <stdarg.h> 327aec1d6eScindi #include <string.h> 337aec1d6eScindi #include <strings.h> 347aec1d6eScindi #include <limits.h> 357aec1d6eScindi #include <alloca.h> 367aec1d6eScindi #include <kstat.h> 377aec1d6eScindi #include <errno.h> 387aec1d6eScindi #include <libnvpair.h> 397aec1d6eScindi #include <sys/types.h> 407aec1d6eScindi #include <sys/bitmap.h> 417aec1d6eScindi #include <sys/processor.h> 427aec1d6eScindi #include <sys/param.h> 437aec1d6eScindi #include <sys/fm/protocol.h> 447aec1d6eScindi #include <sys/systeminfo.h> 457aec1d6eScindi #include <sys/mc.h> 468a40a695Sgavinm #include <sys/mc_amd.h> 4720c794b3Sgavinm #include <sys/mc_intel.h> 48*e4b86885SCheng Sean Ye #include <sys/devfm.h> 49*e4b86885SCheng Sean Ye #include <fm/fmd_agent.h> 507aec1d6eScindi #include <fm/topo_mod.h> 517aec1d6eScindi 527aec1d6eScindi #include "chip.h" 537aec1d6eScindi 54bac58072Sgavinm #define MAX_DIMMNUM 7 55bac58072Sgavinm #define MAX_CSNUM 7 56bac58072Sgavinm 577aec1d6eScindi /* 587aec1d6eScindi * Enumerates the processing chips, or sockets, (as distinct from cores) in a 597aec1d6eScindi * system. For each chip found, the necessary nodes (one or more cores, and 607aec1d6eScindi * possibly a memory controller) are constructed underneath. 617aec1d6eScindi */ 627aec1d6eScindi 6320c794b3Sgavinm static int chip_enum(topo_mod_t *, tnode_t *, const char *, 6420c794b3Sgavinm topo_instance_t, topo_instance_t, void *, void *); 658a40a695Sgavinm 660eb822a1Scindi static const topo_modops_t chip_ops = 670eb822a1Scindi { chip_enum, NULL}; 680eb822a1Scindi static const topo_modinfo_t chip_info = 699dd0f810Scindi { CHIP_NODE_NAME, FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops }; 700eb822a1Scindi 710eb822a1Scindi static const topo_pgroup_info_t chip_pgroup = 729dd0f810Scindi { PGNAME(CHIP), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; 73*e4b86885SCheng Sean Ye 74*e4b86885SCheng Sean Ye static const topo_pgroup_info_t core_pgroup = 75*e4b86885SCheng Sean Ye { PGNAME(CORE), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; 76*e4b86885SCheng Sean Ye 77*e4b86885SCheng Sean Ye static const topo_pgroup_info_t strand_pgroup = 78*e4b86885SCheng Sean Ye { PGNAME(STRAND), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; 798a40a695Sgavinm 8020c794b3Sgavinm static const topo_method_t chip_methods[] = { 814557a2a1Srobj { SIMPLE_CHIP_LBL, "Property method", 0, 824557a2a1Srobj TOPO_STABILITY_INTERNAL, simple_chip_label}, 834557a2a1Srobj { G4_CHIP_LBL, "Property method", 0, 844557a2a1Srobj TOPO_STABILITY_INTERNAL, g4_chip_label}, 852cb5535aSrobj { A4FPLUS_CHIP_LBL, "Property method", 0, 862cb5535aSrobj TOPO_STABILITY_INTERNAL, a4fplus_chip_label}, 874557a2a1Srobj { NULL } 884557a2a1Srobj }; 894557a2a1Srobj 90*e4b86885SCheng Sean Ye static const topo_method_t strands_retire_methods[] = { 91*e4b86885SCheng Sean Ye { TOPO_METH_RETIRE, TOPO_METH_RETIRE_DESC, 92*e4b86885SCheng Sean Ye TOPO_METH_RETIRE_VERSION, TOPO_STABILITY_INTERNAL, 93*e4b86885SCheng Sean Ye retire_strands }, 94*e4b86885SCheng Sean Ye { TOPO_METH_UNRETIRE, TOPO_METH_UNRETIRE_DESC, 95*e4b86885SCheng Sean Ye TOPO_METH_UNRETIRE_VERSION, TOPO_STABILITY_INTERNAL, 96*e4b86885SCheng Sean Ye unretire_strands }, 97*e4b86885SCheng Sean Ye { TOPO_METH_SERVICE_STATE, TOPO_METH_SERVICE_STATE_DESC, 98*e4b86885SCheng Sean Ye TOPO_METH_SERVICE_STATE_VERSION, TOPO_STABILITY_INTERNAL, 99*e4b86885SCheng Sean Ye service_state_strands }, 100*e4b86885SCheng Sean Ye { TOPO_METH_UNUSABLE, TOPO_METH_UNUSABLE_DESC, 101*e4b86885SCheng Sean Ye TOPO_METH_UNUSABLE_VERSION, TOPO_STABILITY_INTERNAL, 102*e4b86885SCheng Sean Ye unusable_strands }, 103*e4b86885SCheng Sean Ye { NULL } 104*e4b86885SCheng Sean Ye }; 105*e4b86885SCheng Sean Ye 1067aec1d6eScindi int 1077aec1d6eScindi _topo_init(topo_mod_t *mod) 1087aec1d6eScindi { 1090eb822a1Scindi if (getenv("TOPOCHIPDBG")) 1100eb822a1Scindi topo_mod_setdebug(mod); 1117aec1d6eScindi topo_mod_dprintf(mod, "initializing chip enumerator\n"); 1127aec1d6eScindi 1130eb822a1Scindi if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) { 1148a40a695Sgavinm whinge(mod, NULL, "failed to register hc: " 1157aec1d6eScindi "%s\n", topo_mod_errmsg(mod)); 1167aec1d6eScindi return (-1); /* mod errno set */ 1177aec1d6eScindi } 1187aec1d6eScindi 1197aec1d6eScindi return (0); 1207aec1d6eScindi } 1217aec1d6eScindi 1227aec1d6eScindi void 1237aec1d6eScindi _topo_fini(topo_mod_t *mod) 1247aec1d6eScindi { 1257aec1d6eScindi topo_mod_unregister(mod); 1267aec1d6eScindi } 1277aec1d6eScindi 128*e4b86885SCheng Sean Ye boolean_t 129*e4b86885SCheng Sean Ye is_xpv(void) 130e3d60c9bSAdrian Frost { 131*e4b86885SCheng Sean Ye static int r = -1; 132*e4b86885SCheng Sean Ye char platform[MAXNAMELEN]; 133e3d60c9bSAdrian Frost 134*e4b86885SCheng Sean Ye if (r != -1) 135*e4b86885SCheng Sean Ye return (r == 0); 136e3d60c9bSAdrian Frost 137*e4b86885SCheng Sean Ye (void) sysinfo(SI_PLATFORM, platform, sizeof (platform)); 138*e4b86885SCheng Sean Ye r = strcmp(platform, "i86xpv"); 139*e4b86885SCheng Sean Ye return (r == 0); 140*e4b86885SCheng Sean Ye } 141e3d60c9bSAdrian Frost 142*e4b86885SCheng Sean Ye static tnode_t * 143*e4b86885SCheng Sean Ye create_node(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth, char *name, 144*e4b86885SCheng Sean Ye topo_instance_t inst) 145*e4b86885SCheng Sean Ye { 146*e4b86885SCheng Sean Ye nvlist_t *fmri; 147*e4b86885SCheng Sean Ye tnode_t *cnode; 148e3d60c9bSAdrian Frost 149*e4b86885SCheng Sean Ye if (mkrsrc(mod, pnode, name, inst, auth, &fmri) != 0) { 150*e4b86885SCheng Sean Ye whinge(mod, NULL, "create_node: mkrsrc failed\n"); 151*e4b86885SCheng Sean Ye return (NULL); 152e3d60c9bSAdrian Frost } 153*e4b86885SCheng Sean Ye cnode = topo_node_bind(mod, pnode, name, inst, fmri); 154*e4b86885SCheng Sean Ye nvlist_free(fmri); 155*e4b86885SCheng Sean Ye if (cnode == NULL) 156*e4b86885SCheng Sean Ye whinge(mod, NULL, "create_node: node bind failed for %s %d\n", 157*e4b86885SCheng Sean Ye name, (int)inst); 158e3d60c9bSAdrian Frost 159*e4b86885SCheng Sean Ye return (cnode); 160e3d60c9bSAdrian Frost } 161e3d60c9bSAdrian Frost 162e3d60c9bSAdrian Frost static int 163*e4b86885SCheng Sean Ye create_strand(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu, nvlist_t *auth) 164e3d60c9bSAdrian Frost { 165*e4b86885SCheng Sean Ye tnode_t *strand; 166*e4b86885SCheng Sean Ye int32_t strandid, cpuid; 167e3d60c9bSAdrian Frost int err, nerr = 0; 168*e4b86885SCheng Sean Ye nvlist_t *fmri; 169e3d60c9bSAdrian Frost 170*e4b86885SCheng Sean Ye if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_STRAND_ID, 171*e4b86885SCheng Sean Ye &strandid)) != 0) { 172*e4b86885SCheng Sean Ye whinge(mod, NULL, "create_strand: lookup strand_id failed: " 173*e4b86885SCheng Sean Ye "%s\n", strerror(err)); 174e3d60c9bSAdrian Frost return (-1); 175*e4b86885SCheng Sean Ye } 176e3d60c9bSAdrian Frost 177*e4b86885SCheng Sean Ye if ((strand = topo_node_lookup(pnode, STRAND_NODE_NAME, strandid)) 178*e4b86885SCheng Sean Ye != NULL) { 179*e4b86885SCheng Sean Ye whinge(mod, NULL, "create_strand: duplicate tuple found\n"); 180*e4b86885SCheng Sean Ye return (-1); 181*e4b86885SCheng Sean Ye } 182e3d60c9bSAdrian Frost 183*e4b86885SCheng Sean Ye if ((strand = create_node(mod, pnode, auth, STRAND_NODE_NAME, 184*e4b86885SCheng Sean Ye strandid)) == NULL) 185*e4b86885SCheng Sean Ye return (-1); 186e3d60c9bSAdrian Frost 187*e4b86885SCheng Sean Ye /* 188*e4b86885SCheng Sean Ye * Inherit FRU from core node, in native use cpu scheme ASRU, 189*e4b86885SCheng Sean Ye * in xpv, use hc scheme ASRU. 190*e4b86885SCheng Sean Ye */ 191*e4b86885SCheng Sean Ye (void) topo_node_fru_set(strand, NULL, 0, &err); 192*e4b86885SCheng Sean Ye if (is_xpv()) { 193*e4b86885SCheng Sean Ye if (topo_node_resource(strand, &fmri, &err) == -1) { 194*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_strand: " 195*e4b86885SCheng Sean Ye "topo_node_resource failed\n"); 196*e4b86885SCheng Sean Ye } else { 197*e4b86885SCheng Sean Ye (void) topo_node_asru_set(strand, fmri, 0, &err); 198e3d60c9bSAdrian Frost nvlist_free(fmri); 199e3d60c9bSAdrian Frost } 200*e4b86885SCheng Sean Ye } else { 201*e4b86885SCheng Sean Ye if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) { 202*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_strand: lookup cpuid " 203*e4b86885SCheng Sean Ye "failed\n"); 204*e4b86885SCheng Sean Ye } else { 205*e4b86885SCheng Sean Ye if ((fmri = cpu_fmri_create(mod, cpuid, NULL, 0)) 206*e4b86885SCheng Sean Ye != NULL) { 207*e4b86885SCheng Sean Ye (void) topo_node_asru_set(strand, fmri, 208*e4b86885SCheng Sean Ye 0, &err); 209*e4b86885SCheng Sean Ye nvlist_free(fmri); 210*e4b86885SCheng Sean Ye } else { 211*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_strand: " 212*e4b86885SCheng Sean Ye "cpu_fmri_create() failed\n"); 213*e4b86885SCheng Sean Ye } 214*e4b86885SCheng Sean Ye } 215*e4b86885SCheng Sean Ye } 216e3d60c9bSAdrian Frost 217*e4b86885SCheng Sean Ye if (topo_method_register(mod, strand, strands_retire_methods) < 0) 218*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_strand: " 219*e4b86885SCheng Sean Ye "topo_method_register failed\n"); 220e3d60c9bSAdrian Frost 221*e4b86885SCheng Sean Ye (void) topo_pgroup_create(strand, &strand_pgroup, &err); 222*e4b86885SCheng Sean Ye nerr -= add_nvlist_longprops(mod, strand, cpu, PGNAME(STRAND), NULL, 223*e4b86885SCheng Sean Ye STRAND_CHIP_ID, STRAND_CORE_ID, STRAND_CPU_ID, NULL); 224e3d60c9bSAdrian Frost 225*e4b86885SCheng Sean Ye return (err == 0 && nerr == 0 ? 0 : -1); 226e3d60c9bSAdrian Frost } 227e3d60c9bSAdrian Frost 2287aec1d6eScindi static int 229*e4b86885SCheng Sean Ye create_core(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu, nvlist_t *auth) 2307aec1d6eScindi { 231*e4b86885SCheng Sean Ye tnode_t *core; 232*e4b86885SCheng Sean Ye int32_t coreid, cpuid; 23335c358f7Sgavinm int err, nerr = 0; 234*e4b86885SCheng Sean Ye nvlist_t *fmri; 2357aec1d6eScindi 236*e4b86885SCheng Sean Ye if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_CORE_ID, &coreid)) 237*e4b86885SCheng Sean Ye != 0) { 238*e4b86885SCheng Sean Ye whinge(mod, NULL, "create_core: lookup core_id failed: %s\n", 239*e4b86885SCheng Sean Ye strerror(err)); 2407aec1d6eScindi return (-1); 241*e4b86885SCheng Sean Ye } 242*e4b86885SCheng Sean Ye if ((core = topo_node_lookup(pnode, CORE_NODE_NAME, coreid)) == NULL) { 243*e4b86885SCheng Sean Ye if ((core = create_node(mod, pnode, auth, CORE_NODE_NAME, 244*e4b86885SCheng Sean Ye coreid)) == NULL) 245*e4b86885SCheng Sean Ye return (-1); 2467aec1d6eScindi 2478a40a695Sgavinm /* 248*e4b86885SCheng Sean Ye * Inherit FRU from the chip node, for native, we use hc 249*e4b86885SCheng Sean Ye * scheme ASRU for the core node. 2508a40a695Sgavinm */ 251*e4b86885SCheng Sean Ye (void) topo_node_fru_set(core, NULL, 0, &err); 252*e4b86885SCheng Sean Ye if (is_xpv()) { 253*e4b86885SCheng Sean Ye if (topo_node_resource(core, &fmri, &err) == -1) { 254*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_core: " 255*e4b86885SCheng Sean Ye "topo_node_resource failed\n"); 256*e4b86885SCheng Sean Ye } else { 257*e4b86885SCheng Sean Ye (void) topo_node_asru_set(core, fmri, 0, &err); 258*e4b86885SCheng Sean Ye nvlist_free(fmri); 259*e4b86885SCheng Sean Ye } 2607aec1d6eScindi } 261*e4b86885SCheng Sean Ye if (topo_method_register(mod, core, strands_retire_methods) < 0) 262*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_core: " 263*e4b86885SCheng Sean Ye "topo_method_register failed\n"); 264*e4b86885SCheng Sean Ye 265*e4b86885SCheng Sean Ye (void) topo_pgroup_create(core, &core_pgroup, &err); 266*e4b86885SCheng Sean Ye nerr -= add_nvlist_longprop(mod, core, cpu, PGNAME(CORE), 267*e4b86885SCheng Sean Ye CORE_CHIP_ID, NULL); 2687aec1d6eScindi 269*e4b86885SCheng Sean Ye if (topo_node_range_create(mod, core, STRAND_NODE_NAME, 270*e4b86885SCheng Sean Ye 0, 255) != 0) 271*e4b86885SCheng Sean Ye return (-1); 272*e4b86885SCheng Sean Ye } 2738a40a695Sgavinm 274*e4b86885SCheng Sean Ye if (! is_xpv()) { 2758a40a695Sgavinm /* 276*e4b86885SCheng Sean Ye * In native mode, we're in favor of cpu scheme ASRU for 277*e4b86885SCheng Sean Ye * printing reason. More work needs to be done to support 278*e4b86885SCheng Sean Ye * multi-strand cpu: the ASRU will be a list of cpuid then. 2798a40a695Sgavinm */ 280*e4b86885SCheng Sean Ye if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) { 281*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_core: lookup cpuid " 2828a40a695Sgavinm "failed\n"); 283*e4b86885SCheng Sean Ye } else { 284*e4b86885SCheng Sean Ye if ((fmri = cpu_fmri_create(mod, cpuid, NULL, 0)) 285*e4b86885SCheng Sean Ye != NULL) { 286*e4b86885SCheng Sean Ye (void) topo_node_asru_set(core, fmri, 0, &err); 287*e4b86885SCheng Sean Ye nvlist_free(fmri); 288*e4b86885SCheng Sean Ye } else { 289*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_core: " 290*e4b86885SCheng Sean Ye "cpu_fmri_create() failed\n"); 291*e4b86885SCheng Sean Ye } 2927aec1d6eScindi } 2937aec1d6eScindi } 2947aec1d6eScindi 295*e4b86885SCheng Sean Ye err = create_strand(mod, core, cpu, auth); 296*e4b86885SCheng Sean Ye 297*e4b86885SCheng Sean Ye return (err == 0 && nerr == 0 ? 0 : -1); 2987aec1d6eScindi } 2997aec1d6eScindi 3007aec1d6eScindi static int 301*e4b86885SCheng Sean Ye create_chip(topo_mod_t *mod, tnode_t *pnode, topo_instance_t min, 302*e4b86885SCheng Sean Ye topo_instance_t max, nvlist_t *cpu, nvlist_t *auth, 303e3d60c9bSAdrian Frost int mc_offchip) 3047aec1d6eScindi { 305*e4b86885SCheng Sean Ye tnode_t *chip; 306*e4b86885SCheng Sean Ye int32_t chipid; 307*e4b86885SCheng Sean Ye nvlist_t *fmri = NULL; 308*e4b86885SCheng Sean Ye int err, nerr = 0; 309*e4b86885SCheng Sean Ye int32_t fms[3]; 310*e4b86885SCheng Sean Ye const char *vendor = NULL; 3117aec1d6eScindi 312*e4b86885SCheng Sean Ye if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_CHIP_ID, &chipid)) 313*e4b86885SCheng Sean Ye != 0) { 314*e4b86885SCheng Sean Ye whinge(mod, NULL, "create_chip: lookup chip_id failed: %s\n", 315*e4b86885SCheng Sean Ye strerror(err)); 316*e4b86885SCheng Sean Ye return (-1); 3177aec1d6eScindi } 3187aec1d6eScindi 319*e4b86885SCheng Sean Ye if (chipid < min || chipid > max) 320*e4b86885SCheng Sean Ye return (-1); 3217aec1d6eScindi 322*e4b86885SCheng Sean Ye if ((chip = topo_node_lookup(pnode, CHIP_NODE_NAME, chipid)) == NULL) { 323*e4b86885SCheng Sean Ye if ((chip = create_node(mod, pnode, auth, CHIP_NODE_NAME, 324*e4b86885SCheng Sean Ye chipid)) == NULL) 325*e4b86885SCheng Sean Ye return (-1); 3267aec1d6eScindi 327*e4b86885SCheng Sean Ye if (topo_method_register(mod, chip, chip_methods) < 0) 328*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_chip: " 329*e4b86885SCheng Sean Ye "topo_method_register failed\n"); 3307aec1d6eScindi 331*e4b86885SCheng Sean Ye if (topo_node_resource(chip, &fmri, &err) == -1) { 332*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_chip: " 333*e4b86885SCheng Sean Ye "topo_node_resource failed\n"); 334*e4b86885SCheng Sean Ye } else { 335*e4b86885SCheng Sean Ye (void) topo_node_fru_set(chip, fmri, 0, &err); 3367aec1d6eScindi nvlist_free(fmri); 3377aec1d6eScindi } 3387aec1d6eScindi 339*e4b86885SCheng Sean Ye (void) topo_pgroup_create(chip, &chip_pgroup, &err); 340*e4b86885SCheng Sean Ye nerr -= add_nvlist_strprop(mod, chip, cpu, PGNAME(CHIP), 341*e4b86885SCheng Sean Ye CHIP_VENDOR_ID, &vendor); 342*e4b86885SCheng Sean Ye nerr -= add_nvlist_longprops(mod, chip, cpu, PGNAME(CHIP), 343*e4b86885SCheng Sean Ye fms, CHIP_FAMILY, CHIP_MODEL, CHIP_STEPPING, NULL); 3444557a2a1Srobj 345*e4b86885SCheng Sean Ye if (topo_method_register(mod, chip, strands_retire_methods) < 0) 346*e4b86885SCheng Sean Ye whinge(mod, &nerr, "create_chip: " 347*e4b86885SCheng Sean Ye "topo_method_register failed\n"); 3487aec1d6eScindi 349*e4b86885SCheng Sean Ye if (topo_node_range_create(mod, chip, CORE_NODE_NAME, 350*e4b86885SCheng Sean Ye 0, 255) != 0) 351*e4b86885SCheng Sean Ye return (-1); 352*e4b86885SCheng Sean Ye } 3537aec1d6eScindi 354*e4b86885SCheng Sean Ye err = create_core(mod, chip, cpu, auth); 3559dd0f810Scindi 356*e4b86885SCheng Sean Ye /* 357*e4b86885SCheng Sean Ye * Create memory-controller node under a chip for architectures 358*e4b86885SCheng Sean Ye * that may have on-chip memory-controller(s). 359*e4b86885SCheng Sean Ye */ 360*e4b86885SCheng Sean Ye if (vendor != NULL && strcmp(vendor, "AuthenticAMD") == 0) 361*e4b86885SCheng Sean Ye amd_mc_create(mod, chip, MCT_NODE_NAME, auth, 362*e4b86885SCheng Sean Ye fms[0], fms[1], fms[2], &nerr); 363*e4b86885SCheng Sean Ye else if (!mc_offchip) 364*e4b86885SCheng Sean Ye onchip_mc_create(mod, chip, MCT_NODE_NAME, auth); 3657aec1d6eScindi 366*e4b86885SCheng Sean Ye return (err == 0 && nerr == 0 ? 0 : -1); 367*e4b86885SCheng Sean Ye } 368e3d60c9bSAdrian Frost 369*e4b86885SCheng Sean Ye /*ARGSUSED*/ 370*e4b86885SCheng Sean Ye static int 371*e4b86885SCheng Sean Ye create_chips(topo_mod_t *mod, tnode_t *pnode, const char *name, 372*e4b86885SCheng Sean Ye topo_instance_t min, topo_instance_t max, void *arg, nvlist_t *auth, 373*e4b86885SCheng Sean Ye int mc_offchip) 374*e4b86885SCheng Sean Ye { 375*e4b86885SCheng Sean Ye fmd_agent_hdl_t *hdl; 376*e4b86885SCheng Sean Ye nvlist_t **cpus; 377*e4b86885SCheng Sean Ye int nerr = 0; 378*e4b86885SCheng Sean Ye uint_t i, ncpu; 37920c794b3Sgavinm 380*e4b86885SCheng Sean Ye if (strcmp(name, CHIP_NODE_NAME) != 0) 381*e4b86885SCheng Sean Ye return (0); 382*e4b86885SCheng Sean Ye 383*e4b86885SCheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL) 384*e4b86885SCheng Sean Ye return (-1); 385*e4b86885SCheng Sean Ye if (fmd_agent_physcpu_info(hdl, &cpus, &ncpu) != 0) { 386*e4b86885SCheng Sean Ye whinge(mod, NULL, "create_chip: fmd_agent_physcpu_info " 387*e4b86885SCheng Sean Ye "failed: %s\n", fmd_agent_errmsg(hdl)); 388*e4b86885SCheng Sean Ye fmd_agent_close(hdl); 389*e4b86885SCheng Sean Ye return (-1); 3907aec1d6eScindi } 391*e4b86885SCheng Sean Ye fmd_agent_close(hdl); 3927aec1d6eScindi 393*e4b86885SCheng Sean Ye for (i = 0; i < ncpu; i++) { 394*e4b86885SCheng Sean Ye nerr -= create_chip(mod, pnode, min, max, cpus[i], auth, 395*e4b86885SCheng Sean Ye mc_offchip); 396*e4b86885SCheng Sean Ye nvlist_free(cpus[i]); 397*e4b86885SCheng Sean Ye } 398*e4b86885SCheng Sean Ye umem_free(cpus, sizeof (nvlist_t *) * ncpu); 3997aec1d6eScindi 4008a40a695Sgavinm if (nerr == 0) { 4018a40a695Sgavinm return (0); 4028a40a695Sgavinm } else { 4037aec1d6eScindi (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM); 4048a40a695Sgavinm return (-1); 4058a40a695Sgavinm } 4067aec1d6eScindi } 4077aec1d6eScindi 4080eb822a1Scindi /*ARGSUSED*/ 4097aec1d6eScindi static int 4107aec1d6eScindi chip_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, 4110eb822a1Scindi topo_instance_t min, topo_instance_t max, void *arg, void *notused) 4127aec1d6eScindi { 4130eb822a1Scindi int rv = 0; 4140eb822a1Scindi nvlist_t *auth = NULL; 415e3d60c9bSAdrian Frost int offchip_mc; 416*e4b86885SCheng Sean Ye char buf[BUFSIZ]; 417*e4b86885SCheng Sean Ye const char *dom0 = "control_d"; 418*e4b86885SCheng Sean Ye 419*e4b86885SCheng Sean Ye /* 420*e4b86885SCheng Sean Ye * Create nothing if we're running in domU. 421*e4b86885SCheng Sean Ye */ 422*e4b86885SCheng Sean Ye if (sysinfo(SI_PLATFORM, buf, sizeof (buf)) == -1) 423*e4b86885SCheng Sean Ye return (-1); 424*e4b86885SCheng Sean Ye 425*e4b86885SCheng Sean Ye if (strncmp(buf, "i86pc", sizeof (buf)) != 0 && 426*e4b86885SCheng Sean Ye strncmp(buf, "i86xpv", sizeof (buf)) != 0) 427*e4b86885SCheng Sean Ye return (0); 428*e4b86885SCheng Sean Ye 429*e4b86885SCheng Sean Ye if (strncmp(buf, "i86xpv", sizeof (buf)) == 0) { 430*e4b86885SCheng Sean Ye int fd = open("/dev/xen/domcaps", O_RDONLY); 431*e4b86885SCheng Sean Ye 432*e4b86885SCheng Sean Ye if (fd != -1) { 433*e4b86885SCheng Sean Ye if (read(fd, buf, sizeof (buf)) <= 0 || 434*e4b86885SCheng Sean Ye strncmp(buf, dom0, strlen(dom0)) != 0) { 435*e4b86885SCheng Sean Ye (void) close(fd); 436*e4b86885SCheng Sean Ye return (0); 437*e4b86885SCheng Sean Ye } 438*e4b86885SCheng Sean Ye (void) close(fd); 439*e4b86885SCheng Sean Ye } 440*e4b86885SCheng Sean Ye } 4410eb822a1Scindi 4420eb822a1Scindi auth = topo_mod_auth(mod, pnode); 4437aec1d6eScindi 444e3d60c9bSAdrian Frost offchip_mc = mc_offchip_open(); 4459dd0f810Scindi if (strcmp(name, CHIP_NODE_NAME) == 0) 446*e4b86885SCheng Sean Ye rv = create_chips(mod, pnode, name, min, max, NULL, auth, 447e3d60c9bSAdrian Frost offchip_mc); 4487aec1d6eScindi 449e3d60c9bSAdrian Frost if (offchip_mc) 45020c794b3Sgavinm (void) mc_offchip_create(mod, pnode, "memory-controller", auth); 45120c794b3Sgavinm 4520eb822a1Scindi nvlist_free(auth); 4530eb822a1Scindi 4540eb822a1Scindi return (rv); 4557aec1d6eScindi } 456