11c42de6dSgd78059 /* 21c42de6dSgd78059 * CDDL HEADER START 31c42de6dSgd78059 * 41c42de6dSgd78059 * The contents of this file are subject to the terms of the 51c42de6dSgd78059 * Common Development and Distribution License (the "License"). 61c42de6dSgd78059 * You may not use this file except in compliance with the License. 71c42de6dSgd78059 * 81c42de6dSgd78059 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91c42de6dSgd78059 * or http://www.opensolaris.org/os/licensing. 101c42de6dSgd78059 * See the License for the specific language governing permissions 111c42de6dSgd78059 * and limitations under the License. 121c42de6dSgd78059 * 131c42de6dSgd78059 * When distributing Covered Code, include this CDDL HEADER in each 141c42de6dSgd78059 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151c42de6dSgd78059 * If applicable, add the following below this CDDL HEADER, with the 161c42de6dSgd78059 * fields enclosed by brackets "[]" replaced with your own identifying 171c42de6dSgd78059 * information: Portions Copyright [yyyy] [name of copyright owner] 181c42de6dSgd78059 * 191c42de6dSgd78059 * CDDL HEADER END 201c42de6dSgd78059 */ 211c42de6dSgd78059 /* 22*88294e09SRichard Bean * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 231c42de6dSgd78059 * Use is subject to license terms. 241c42de6dSgd78059 */ 251c42de6dSgd78059 261c42de6dSgd78059 /* 271c42de6dSgd78059 * CPU functions to the Safari Configurator (gptwo_cpu) 281c42de6dSgd78059 */ 291c42de6dSgd78059 301c42de6dSgd78059 #include <sys/types.h> 311c42de6dSgd78059 #include <sys/cred.h> 321c42de6dSgd78059 #include <sys/mman.h> 331c42de6dSgd78059 #include <sys/kmem.h> 341c42de6dSgd78059 #include <sys/conf.h> 351c42de6dSgd78059 #include <sys/ddi.h> 361c42de6dSgd78059 #include <sys/sunddi.h> 371c42de6dSgd78059 #include <sys/sunndi.h> 381c42de6dSgd78059 #include <sys/modctl.h> 391c42de6dSgd78059 #include <sys/stat.h> 401c42de6dSgd78059 #include <sys/param.h> 411c42de6dSgd78059 #include <sys/autoconf.h> 421c42de6dSgd78059 #include <sys/ksynch.h> 431c42de6dSgd78059 #include <sys/promif.h> 441c42de6dSgd78059 #include <sys/ndi_impldefs.h> 451c42de6dSgd78059 #include <sys/ddi_impldefs.h> 461c42de6dSgd78059 #include <sys/machsystm.h> 471c42de6dSgd78059 #include <sys/gp2cfg.h> 481c42de6dSgd78059 #include <sys/gptwo_cpu.h> 491c42de6dSgd78059 #include <sys/cheetahregs.h> 501c42de6dSgd78059 511c42de6dSgd78059 #ifdef DEBUG 521c42de6dSgd78059 int gptwo_cpu_debug = 0; 531c42de6dSgd78059 541c42de6dSgd78059 static void debug(char *, uintptr_t, uintptr_t, 551c42de6dSgd78059 uintptr_t, uintptr_t, uintptr_t); 561c42de6dSgd78059 571c42de6dSgd78059 #define GPTWO_DEBUG0(level, flag, s) if (gptwo_cpu_debug >= level) \ 581c42de6dSgd78059 cmn_err(flag, s) 591c42de6dSgd78059 #define GPTWO_DEBUG1(level, flag, fmt, a1) if (gptwo_cpu_debug >= level) \ 601c42de6dSgd78059 debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0); 611c42de6dSgd78059 #define GPTWO_DEBUG2(level, flag, fmt, a1, a2) if (gptwo_cpu_debug >= level) \ 621c42de6dSgd78059 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0); 631c42de6dSgd78059 #define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3) \ 641c42de6dSgd78059 if (gptwo_cpu_debug >= level) \ 651c42de6dSgd78059 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), (uintptr_t)(a3), 0, 0); 661c42de6dSgd78059 #else 671c42de6dSgd78059 #define GPTWO_DEBUG0(level, flag, s) 681c42de6dSgd78059 #define GPTWO_DEBUG1(level, flag, fmt, a1) 691c42de6dSgd78059 #define GPTWO_DEBUG2(level, flag, fmt, a1, a2) 701c42de6dSgd78059 #define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3) 711c42de6dSgd78059 #endif 721c42de6dSgd78059 731c42de6dSgd78059 /* 741c42de6dSgd78059 * Devinfo branch create arg 751c42de6dSgd78059 */ 761c42de6dSgd78059 struct bca { 771c42de6dSgd78059 spcd_t *pcd; 781c42de6dSgd78059 uint_t portid; 791c42de6dSgd78059 uint_t cpuid; 801c42de6dSgd78059 uint_t coreid; 811c42de6dSgd78059 uint_t impl; 821c42de6dSgd78059 dev_info_t *new_child; 831c42de6dSgd78059 }; 841c42de6dSgd78059 851c42de6dSgd78059 static dev_info_t *gptwocfg_create_cpu_node(dev_info_t *, spcd_t *, 861c42de6dSgd78059 uint_t, uint_t, uint_t, uint_t); 871c42de6dSgd78059 static dev_info_t *gptwocfg_create_mc_node(dev_info_t *, spcd_t *, uint_t); 881c42de6dSgd78059 static dev_info_t *gptwocfg_create_cmp_node(dev_info_t *, spcd_t *, uint_t); 891c42de6dSgd78059 static int gptwocfg_create_core_node(dev_info_t *, spcd_t *, uint_t, uint_t); 901c42de6dSgd78059 static int set_mc_props(dev_info_t *new_child, void *arg, uint_t flags); 911c42de6dSgd78059 static int set_cmp_props(dev_info_t *new_child, void *arg, uint_t flags); 921c42de6dSgd78059 static int set_cpu_props(dev_info_t *new_child, void *arg, uint_t flags); 931c42de6dSgd78059 static int set_cpu_common_props(dev_info_t *new_child, struct bca *bcp); 941c42de6dSgd78059 static int set_cpu_us3_props(dev_info_t *new_child, struct bca *bcp); 951c42de6dSgd78059 static int set_cpu_us4_props(dev_info_t *new_child, struct bca *bcp); 961c42de6dSgd78059 static void get_new_child(dev_info_t *rdip, void *arg, uint_t flags); 971c42de6dSgd78059 981c42de6dSgd78059 991c42de6dSgd78059 /* 1001c42de6dSgd78059 * Module linkage information for the kernel. 1011c42de6dSgd78059 */ 1021c42de6dSgd78059 1031c42de6dSgd78059 extern struct mod_ops mod_miscops; 1041c42de6dSgd78059 1051c42de6dSgd78059 static struct modlmisc modlmisc = { 1061c42de6dSgd78059 &mod_miscops, /* Type of module */ 107*88294e09SRichard Bean "gptwo->cpu configurator", 1081c42de6dSgd78059 }; 1091c42de6dSgd78059 1101c42de6dSgd78059 static struct modlinkage modlinkage = { 1111c42de6dSgd78059 MODREV_1, (void *)&modlmisc, NULL 1121c42de6dSgd78059 }; 1131c42de6dSgd78059 1141c42de6dSgd78059 int 1151c42de6dSgd78059 _init(void) 1161c42de6dSgd78059 { 1171c42de6dSgd78059 int err = 0; 1181c42de6dSgd78059 1191c42de6dSgd78059 /* register device with the configurator */ 1201c42de6dSgd78059 gptwocfg_register_ops(SAFPTYPE_CPU, gptwocfg_configure_cpu, NULL); 1211c42de6dSgd78059 1221c42de6dSgd78059 if ((err = mod_install(&modlinkage)) != 0) { 1231c42de6dSgd78059 GPTWO_DEBUG1(1, CE_WARN, "gptwo_cpu (CPU/MC Functions) " 1241c42de6dSgd78059 "failed to load, error=%d\n", err); 1251c42de6dSgd78059 gptwocfg_unregister_ops(SAFPTYPE_CPU); 1261c42de6dSgd78059 } else { 1271c42de6dSgd78059 GPTWO_DEBUG0(1, CE_WARN, "gptwo_cpu (CPU/MC Functions) " 1281c42de6dSgd78059 "has been loaded.\n"); 1291c42de6dSgd78059 } 1301c42de6dSgd78059 return (err); 1311c42de6dSgd78059 } 1321c42de6dSgd78059 1331c42de6dSgd78059 int 1341c42de6dSgd78059 _fini(void) 1351c42de6dSgd78059 { 1361c42de6dSgd78059 /* cleanup/freeup structs with configurator */ 1371c42de6dSgd78059 gptwocfg_unregister_ops(SAFPTYPE_CPU); 1381c42de6dSgd78059 return (mod_remove(&modlinkage)); 1391c42de6dSgd78059 } 1401c42de6dSgd78059 1411c42de6dSgd78059 int 1421c42de6dSgd78059 _info(struct modinfo *modinfop) 1431c42de6dSgd78059 { 1441c42de6dSgd78059 return (mod_info(&modlinkage, modinfop)); 1451c42de6dSgd78059 } 1461c42de6dSgd78059 1471c42de6dSgd78059 gptwo_new_nodes_t * 1481c42de6dSgd78059 gptwocfg_configure_cpu(dev_info_t *ap, spcd_t *pcd, uint_t portid) 1491c42de6dSgd78059 { 1501c42de6dSgd78059 dev_info_t *cpu_node[AGENTS_PER_PORT], *mc_node[AGENTS_PER_PORT]; 1511c42de6dSgd78059 dev_info_t *cmp_node = NULL; 1521c42de6dSgd78059 gptwo_new_nodes_t *new_nodes; 1531c42de6dSgd78059 int nodes = 0; 1541c42de6dSgd78059 int i, j = 0; 1551c42de6dSgd78059 uint_t implementation; 1561c42de6dSgd78059 1571c42de6dSgd78059 GPTWO_DEBUG2(1, CE_CONT, "gptwocfg_configure_cpu: portid=%x pcd=%lx\n", 1581c42de6dSgd78059 portid, pcd); 1591c42de6dSgd78059 1601c42de6dSgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) { 1611c42de6dSgd78059 cpu_node[i] = NULL; 1621c42de6dSgd78059 mc_node[i] = NULL; 1631c42de6dSgd78059 } 1641c42de6dSgd78059 1651c42de6dSgd78059 implementation = (pcd->spcd_ver_reg >> 32) & 0x000000000000ffff; 1661c42de6dSgd78059 1671c42de6dSgd78059 switch (implementation) { 1681c42de6dSgd78059 case CHEETAH_IMPL: 1691c42de6dSgd78059 case CHEETAH_PLUS_IMPL: 1701c42de6dSgd78059 case JAGUAR_IMPL: 1711c42de6dSgd78059 case PANTHER_IMPL: 1721c42de6dSgd78059 break; 1731c42de6dSgd78059 default: 1741c42de6dSgd78059 cmn_err(CE_WARN, "Unsupported cpu implementation=0x%x : " 1751c42de6dSgd78059 "skipping configure of portid=0x%x", implementation, 1761c42de6dSgd78059 portid); 1771c42de6dSgd78059 ASSERT(0); 1781c42de6dSgd78059 return (NULL); 1791c42de6dSgd78059 } 1801c42de6dSgd78059 1811c42de6dSgd78059 if (CPU_IMPL_IS_CMP(implementation)) { 1821c42de6dSgd78059 if (cmp_node = gptwocfg_create_cmp_node(ap, pcd, portid)) 1831c42de6dSgd78059 nodes++; 1841c42de6dSgd78059 else 1851c42de6dSgd78059 return (NULL); 1861c42de6dSgd78059 } 1871c42de6dSgd78059 1881c42de6dSgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) { 1891c42de6dSgd78059 if (pcd->spcd_agent[i] != SPCD_RSV_PASS) 1901c42de6dSgd78059 continue; 1911c42de6dSgd78059 1921c42de6dSgd78059 if (cpu_node[i] = gptwocfg_create_cpu_node(cmp_node ? 1931c42de6dSgd78059 cmp_node : ap, pcd, portid, pcd->spcd_cpuid[i], i, 1941c42de6dSgd78059 implementation)) { 1951c42de6dSgd78059 /* 1961c42de6dSgd78059 * If the CPU is a CMP, the entire branch is 1971c42de6dSgd78059 * manipulated using just the top node. Thus, 1981c42de6dSgd78059 * the dips of the individual cores do not need 1991c42de6dSgd78059 * to be held or stored in the new node list. 2001c42de6dSgd78059 */ 2011c42de6dSgd78059 if (cmp_node) { 2021c42de6dSgd78059 e_ddi_branch_rele(cpu_node[i]); 2031c42de6dSgd78059 } else { 2041c42de6dSgd78059 nodes++; 2051c42de6dSgd78059 } 2061c42de6dSgd78059 } 2071c42de6dSgd78059 } 2081c42de6dSgd78059 2091c42de6dSgd78059 /* current implementations have 1 MC node per Safari port */ 2101c42de6dSgd78059 if (pcd->spcd_prsv == SPCD_RSV_PASS && 2111c42de6dSgd78059 (mc_node[0] = gptwocfg_create_mc_node(ap, pcd, portid))) 2121c42de6dSgd78059 nodes++; 2131c42de6dSgd78059 2141c42de6dSgd78059 new_nodes = gptwocfg_allocate_node_list(nodes); 2151c42de6dSgd78059 2161c42de6dSgd78059 j = 0; 2171c42de6dSgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) { 2181c42de6dSgd78059 if ((cpu_node[i] != NULL) && (!CPU_IMPL_IS_CMP(implementation))) 2191c42de6dSgd78059 new_nodes->gptwo_nodes[j++] = cpu_node[i]; 2201c42de6dSgd78059 if (mc_node[i] != NULL) 2211c42de6dSgd78059 new_nodes->gptwo_nodes[j++] = mc_node[i]; 2221c42de6dSgd78059 } 2231c42de6dSgd78059 2241c42de6dSgd78059 if (cmp_node) 2251c42de6dSgd78059 new_nodes->gptwo_nodes[j++] = cmp_node; 2261c42de6dSgd78059 2271c42de6dSgd78059 return (new_nodes); 2281c42de6dSgd78059 } 2291c42de6dSgd78059 2301c42de6dSgd78059 2311c42de6dSgd78059 static dev_info_t * 2321c42de6dSgd78059 gptwocfg_create_cmp_node(dev_info_t *ap, spcd_t *pcd, uint_t portid) 2331c42de6dSgd78059 { 2341c42de6dSgd78059 struct bca arg; 2351c42de6dSgd78059 devi_branch_t b; 2361c42de6dSgd78059 2371c42de6dSgd78059 arg.pcd = pcd; 2381c42de6dSgd78059 arg.portid = portid; 2391c42de6dSgd78059 arg.cpuid = 0; 2401c42de6dSgd78059 arg.coreid = 0; 2411c42de6dSgd78059 arg.new_child = NULL; 2421c42de6dSgd78059 2431c42de6dSgd78059 b.arg = &arg; 2441c42de6dSgd78059 b.type = DEVI_BRANCH_SID; 2451c42de6dSgd78059 b.create.sid_branch_create = set_cmp_props; 2461c42de6dSgd78059 b.devi_branch_callback = get_new_child; 2471c42de6dSgd78059 2481c42de6dSgd78059 if (e_ddi_branch_create(ap, &b, NULL, 0)) 2491c42de6dSgd78059 return (NULL); 2501c42de6dSgd78059 2511c42de6dSgd78059 return (arg.new_child); 2521c42de6dSgd78059 } 2531c42de6dSgd78059 2541c42de6dSgd78059 /*ARGSUSED*/ 2551c42de6dSgd78059 static int 2561c42de6dSgd78059 set_cmp_props(dev_info_t *new_child, void *arg, uint_t flags) 2571c42de6dSgd78059 { 2581c42de6dSgd78059 struct bca *bap = (struct bca *)arg; 2591c42de6dSgd78059 gptwo_regspec_t reg; 2601c42de6dSgd78059 spcd_t *pcd; 2611c42de6dSgd78059 uint_t portid; 2621c42de6dSgd78059 2631c42de6dSgd78059 pcd = bap->pcd; 2641c42de6dSgd78059 portid = bap->portid; 2651c42de6dSgd78059 2661c42de6dSgd78059 GPTWO_DEBUG2(1, CE_CONT, "set_cmp_props: portid=%x pcd=%lx\n", 2671c42de6dSgd78059 portid, pcd); 2681c42de6dSgd78059 2691c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 2701c42de6dSgd78059 "name", "cmp") != DDI_SUCCESS) { 2711c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cmp_props: failed to " 2721c42de6dSgd78059 "create name property\n"); 2731c42de6dSgd78059 return (DDI_WALK_ERROR); 2741c42de6dSgd78059 } 2751c42de6dSgd78059 2761c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 2771c42de6dSgd78059 "portid", portid) != DDI_SUCCESS) { 2781c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cmp_props: failed to " 2791c42de6dSgd78059 "create portid property\n"); 2801c42de6dSgd78059 return (DDI_WALK_ERROR); 2811c42de6dSgd78059 } 2821c42de6dSgd78059 2831c42de6dSgd78059 reg.gptwo_phys_hi = 0x400 | (portid >> 9); 2841c42de6dSgd78059 reg.gptwo_phys_low = (portid << 23); 2851c42de6dSgd78059 reg.gptwo_size_hi = 0; 2861c42de6dSgd78059 reg.gptwo_size_low = 0x10000; 2871c42de6dSgd78059 2881c42de6dSgd78059 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, 2891c42de6dSgd78059 new_child, "reg", (int *)®, 2901c42de6dSgd78059 sizeof (gptwo_regspec_t) / sizeof (int)) != DDI_SUCCESS) { 2911c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cmp_props: failed to " 2921c42de6dSgd78059 "create reg property\n"); 2931c42de6dSgd78059 return (DDI_WALK_ERROR); 2941c42de6dSgd78059 } 2951c42de6dSgd78059 2961c42de6dSgd78059 return (DDI_WALK_TERMINATE); 2971c42de6dSgd78059 } 2981c42de6dSgd78059 2991c42de6dSgd78059 static dev_info_t * 3001c42de6dSgd78059 gptwocfg_create_cpu_node(dev_info_t *ap, spcd_t *pcd, uint_t portid, 3011c42de6dSgd78059 uint_t cpuid, uint_t coreid, uint_t impl) 3021c42de6dSgd78059 { 3031c42de6dSgd78059 struct bca arg; 3041c42de6dSgd78059 devi_branch_t b = {0}; 3051c42de6dSgd78059 3061c42de6dSgd78059 arg.pcd = pcd; 3071c42de6dSgd78059 arg.portid = portid; 3081c42de6dSgd78059 arg.cpuid = cpuid; 3091c42de6dSgd78059 arg.coreid = coreid; 3101c42de6dSgd78059 arg.impl = impl; 3111c42de6dSgd78059 arg.new_child = NULL; 3121c42de6dSgd78059 3131c42de6dSgd78059 b.arg = &arg; 3141c42de6dSgd78059 b.type = DEVI_BRANCH_SID; 3151c42de6dSgd78059 b.create.sid_branch_create = set_cpu_props; 3161c42de6dSgd78059 b.devi_branch_callback = get_new_child; 3171c42de6dSgd78059 3181c42de6dSgd78059 if (e_ddi_branch_create(ap, &b, NULL, 0)) 3191c42de6dSgd78059 return (NULL); 3201c42de6dSgd78059 3211c42de6dSgd78059 return (arg.new_child); 3221c42de6dSgd78059 } 3231c42de6dSgd78059 3241c42de6dSgd78059 /*ARGSUSED*/ 3251c42de6dSgd78059 static int 3261c42de6dSgd78059 set_cpu_props(dev_info_t *new_child, void *arg, uint_t flags) 3271c42de6dSgd78059 { 3281c42de6dSgd78059 struct bca *bcp = arg; 3291c42de6dSgd78059 uint_t impl = bcp->impl; 3301c42de6dSgd78059 int rc; 3311c42de6dSgd78059 3321c42de6dSgd78059 if (set_cpu_common_props(new_child, bcp) != DDI_WALK_CONTINUE) 3331c42de6dSgd78059 return (DDI_WALK_ERROR); 3341c42de6dSgd78059 3351c42de6dSgd78059 switch (impl) { 3361c42de6dSgd78059 case CHEETAH_IMPL: 3371c42de6dSgd78059 case CHEETAH_PLUS_IMPL: 3381c42de6dSgd78059 rc = set_cpu_us3_props(new_child, bcp); 3391c42de6dSgd78059 break; 3401c42de6dSgd78059 case JAGUAR_IMPL: 3411c42de6dSgd78059 case PANTHER_IMPL: 3421c42de6dSgd78059 rc = set_cpu_us4_props(new_child, bcp); 3431c42de6dSgd78059 break; 3441c42de6dSgd78059 default: 3451c42de6dSgd78059 ASSERT(0); 3461c42de6dSgd78059 return (DDI_WALK_ERROR); 3471c42de6dSgd78059 } 3481c42de6dSgd78059 3491c42de6dSgd78059 return (rc); 3501c42de6dSgd78059 } 3511c42de6dSgd78059 3521c42de6dSgd78059 /* 3531c42de6dSgd78059 * Set properties common to cpu (non-CMP) and core (CMP) nodes. 3541c42de6dSgd78059 * 3551c42de6dSgd78059 * cpuid 3561c42de6dSgd78059 * device_type 3571c42de6dSgd78059 * manufacturer# 3581c42de6dSgd78059 * implementation# 3591c42de6dSgd78059 * mask# 3601c42de6dSgd78059 * sparc-version 3611c42de6dSgd78059 * clock-frequency 3621c42de6dSgd78059 * #dtlb-entries 3631c42de6dSgd78059 * #itlb-entries 3641c42de6dSgd78059 */ 3651c42de6dSgd78059 static int 3661c42de6dSgd78059 set_cpu_common_props(dev_info_t *new_child, struct bca *bcp) 3671c42de6dSgd78059 { 3681c42de6dSgd78059 uint_t cpuid, impl; 3691c42de6dSgd78059 spcd_t *pcd; 3701c42de6dSgd78059 int mask, manufacturer; 3711c42de6dSgd78059 3721c42de6dSgd78059 cpuid = bcp->cpuid; 3731c42de6dSgd78059 pcd = bcp->pcd; 3741c42de6dSgd78059 impl = bcp->impl; 3751c42de6dSgd78059 3761c42de6dSgd78059 mask = (pcd->spcd_ver_reg >> 24) & 0x00000000000000ff; 3771c42de6dSgd78059 manufacturer = (pcd->spcd_ver_reg >> 48) & 0x000000000000ffff; 3781c42de6dSgd78059 3791c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 3801c42de6dSgd78059 "cpuid", cpuid) != DDI_SUCCESS) { 3811c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 3821c42de6dSgd78059 "to create cpuid property\n"); 3831c42de6dSgd78059 return (DDI_WALK_ERROR); 3841c42de6dSgd78059 } 3851c42de6dSgd78059 3861c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 3871c42de6dSgd78059 "device_type", "cpu") != DDI_SUCCESS) { 3881c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 3891c42de6dSgd78059 "to create device_type property\n"); 3901c42de6dSgd78059 return (DDI_WALK_ERROR); 3911c42de6dSgd78059 } 3921c42de6dSgd78059 3931c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, "manufacturer#", 3941c42de6dSgd78059 manufacturer) != DDI_SUCCESS) { 3951c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 3961c42de6dSgd78059 "to create manufacturer# property\n"); 3971c42de6dSgd78059 return (DDI_WALK_ERROR); 3981c42de6dSgd78059 } 3991c42de6dSgd78059 4001c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, "implementation#", 4011c42de6dSgd78059 impl) != DDI_SUCCESS) { 4021c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 4031c42de6dSgd78059 "to create implementation# property\n"); 4041c42de6dSgd78059 return (DDI_WALK_ERROR); 4051c42de6dSgd78059 } 4061c42de6dSgd78059 4071c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, "mask#", 4081c42de6dSgd78059 mask) != DDI_SUCCESS) { 4091c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 4101c42de6dSgd78059 "to create mask# property\n"); 4111c42de6dSgd78059 return (DDI_WALK_ERROR); 4121c42de6dSgd78059 } 4131c42de6dSgd78059 4141c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 4151c42de6dSgd78059 "sparc-version", 9) != DDI_SUCCESS) { 4161c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 4171c42de6dSgd78059 "to create sparc-version property\n"); 4181c42de6dSgd78059 return (DDI_WALK_ERROR); 4191c42de6dSgd78059 } 4201c42de6dSgd78059 4211c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 4221c42de6dSgd78059 "clock-frequency", (pcd->spcd_afreq * 1000000)) != DDI_SUCCESS) { 4231c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 4241c42de6dSgd78059 "to create clock-frequency property\n"); 4251c42de6dSgd78059 return (DDI_WALK_ERROR); 4261c42de6dSgd78059 } 4271c42de6dSgd78059 4281c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 4291c42de6dSgd78059 "#dtlb-entries", 0x10) != DDI_SUCCESS) { 4301c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 4311c42de6dSgd78059 "to create #dtlb-entries property\n"); 4321c42de6dSgd78059 return (DDI_WALK_ERROR); 4331c42de6dSgd78059 } 4341c42de6dSgd78059 4351c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 4361c42de6dSgd78059 "#itlb-entries", 0x10) != DDI_SUCCESS) { 4371c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed " 4381c42de6dSgd78059 "to create #itlb-entries property\n"); 4391c42de6dSgd78059 return (DDI_WALK_ERROR); 4401c42de6dSgd78059 } 4411c42de6dSgd78059 4421c42de6dSgd78059 return (DDI_WALK_CONTINUE); 4431c42de6dSgd78059 } 4441c42de6dSgd78059 4451c42de6dSgd78059 /* 4461c42de6dSgd78059 * Set cpu node properties for Cheetah and Cheetah+. 4471c42de6dSgd78059 * 4481c42de6dSgd78059 * name 4491c42de6dSgd78059 * portid 4501c42de6dSgd78059 * reg 4511c42de6dSgd78059 * icache-size 4521c42de6dSgd78059 * icache-line-size 4531c42de6dSgd78059 * icache-associativity 4541c42de6dSgd78059 * dcache-size 4551c42de6dSgd78059 * dcache-line-size 4561c42de6dSgd78059 * dcache-associativity 4571c42de6dSgd78059 * ecache-size 4581c42de6dSgd78059 * ecache-line-size 4591c42de6dSgd78059 * ecache-associativity 4601c42de6dSgd78059 */ 4611c42de6dSgd78059 static int 4621c42de6dSgd78059 set_cpu_us3_props(dev_info_t *new_child, struct bca *bcp) 4631c42de6dSgd78059 { 4641c42de6dSgd78059 char *node_name; 4651c42de6dSgd78059 gptwo_regspec_t reg; 4661c42de6dSgd78059 int ecache_size, ecache_line_size; 4671c42de6dSgd78059 int dimms, ecache_assoc; 4681c42de6dSgd78059 spcd_t *pcd; 4691c42de6dSgd78059 uint_t portid, impl; 4701c42de6dSgd78059 4711c42de6dSgd78059 pcd = bcp->pcd; 4721c42de6dSgd78059 portid = bcp->portid; 4731c42de6dSgd78059 impl = bcp->impl; 4741c42de6dSgd78059 4751c42de6dSgd78059 ASSERT(IS_CHEETAH(impl) || IS_CHEETAH_PLUS(impl)); 4761c42de6dSgd78059 4771c42de6dSgd78059 switch (impl) { 4781c42de6dSgd78059 case CHEETAH_IMPL: 4791c42de6dSgd78059 ecache_assoc = CH_ECACHE_NWAY; 4801c42de6dSgd78059 node_name = "SUNW,UltraSPARC-III"; 4811c42de6dSgd78059 break; 4821c42de6dSgd78059 case CHEETAH_PLUS_IMPL: 4831c42de6dSgd78059 /* 4841c42de6dSgd78059 * Hard coding the ecache-associativity to 2 for Cheetah+. 4851c42de6dSgd78059 * We probably should add this to the PCD. 4861c42de6dSgd78059 */ 4871c42de6dSgd78059 ecache_assoc = CHP_ECACHE_NWAY; 4881c42de6dSgd78059 node_name = "SUNW,UltraSPARC-III+"; 4891c42de6dSgd78059 break; 4901c42de6dSgd78059 default: 4911c42de6dSgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us3_props: invalid " 4921c42de6dSgd78059 "implementation=0x%x\n", impl); 4931c42de6dSgd78059 return (DDI_WALK_ERROR); 4941c42de6dSgd78059 } 4951c42de6dSgd78059 4961c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 4971c42de6dSgd78059 "name", node_name) != DDI_SUCCESS) { 4981c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 4991c42de6dSgd78059 "to create name property\n"); 5001c42de6dSgd78059 return (DDI_WALK_ERROR); 5011c42de6dSgd78059 } 5021c42de6dSgd78059 5031c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5041c42de6dSgd78059 "portid", portid) != DDI_SUCCESS) { 5051c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5061c42de6dSgd78059 "to create portid property\n"); 5071c42de6dSgd78059 return (DDI_WALK_ERROR); 5081c42de6dSgd78059 } 5091c42de6dSgd78059 5101c42de6dSgd78059 reg.gptwo_phys_hi = 0x400 | (portid >> 9); 5111c42de6dSgd78059 reg.gptwo_phys_low = (portid << 23); 5121c42de6dSgd78059 reg.gptwo_size_hi = 0; 5131c42de6dSgd78059 reg.gptwo_size_low = 0x10000; 5141c42de6dSgd78059 5151c42de6dSgd78059 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, 5161c42de6dSgd78059 new_child, "reg", (int *)®, 5171c42de6dSgd78059 sizeof (gptwo_regspec_t) / sizeof (int)) != DDI_SUCCESS) { 5181c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5191c42de6dSgd78059 "to create reg property\n"); 5201c42de6dSgd78059 return (DDI_WALK_ERROR); 5211c42de6dSgd78059 } 5221c42de6dSgd78059 5231c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5241c42de6dSgd78059 "icache-size", CH_ICACHE_SIZE) != DDI_SUCCESS) { 5251c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5261c42de6dSgd78059 "to create icache-size property\n"); 5271c42de6dSgd78059 return (DDI_WALK_ERROR); 5281c42de6dSgd78059 } 5291c42de6dSgd78059 5301c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5311c42de6dSgd78059 "icache-line-size", CH_ICACHE_LSIZE) != DDI_SUCCESS) { 5321c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5331c42de6dSgd78059 "to create icache-line-size property\n"); 5341c42de6dSgd78059 return (DDI_WALK_ERROR); 5351c42de6dSgd78059 } 5361c42de6dSgd78059 5371c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5381c42de6dSgd78059 "icache-associativity", CH_ICACHE_NWAY) != DDI_SUCCESS) { 5391c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5401c42de6dSgd78059 "to create icache-associativity property\n"); 5411c42de6dSgd78059 return (DDI_WALK_ERROR); 5421c42de6dSgd78059 } 5431c42de6dSgd78059 5441c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5451c42de6dSgd78059 "dcache-size", CH_DCACHE_SIZE) != DDI_SUCCESS) { 5461c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5471c42de6dSgd78059 "to create dcache-size property\n"); 5481c42de6dSgd78059 return (DDI_WALK_ERROR); 5491c42de6dSgd78059 } 5501c42de6dSgd78059 5511c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5521c42de6dSgd78059 "dcache-line-size", CH_DCACHE_LSIZE) != DDI_SUCCESS) { 5531c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5541c42de6dSgd78059 "to create dcache-line-size property\n"); 5551c42de6dSgd78059 return (DDI_WALK_ERROR); 5561c42de6dSgd78059 } 5571c42de6dSgd78059 5581c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5591c42de6dSgd78059 "dcache-associativity", CH_DCACHE_NWAY) != DDI_SUCCESS) { 5601c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5611c42de6dSgd78059 "to create dcache-associativity property\n"); 5621c42de6dSgd78059 return (DDI_WALK_ERROR); 5631c42de6dSgd78059 } 5641c42de6dSgd78059 5651c42de6dSgd78059 /* 5661c42de6dSgd78059 * Get the External Cache Size from the Common PCD. 5671c42de6dSgd78059 */ 5681c42de6dSgd78059 ecache_size = pcd->spcd_cache * 0x100000; 5691c42de6dSgd78059 5701c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5711c42de6dSgd78059 "ecache-size", ecache_size) != DDI_SUCCESS) { 5721c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5731c42de6dSgd78059 "to create ecache-line-size property\n"); 5741c42de6dSgd78059 return (DDI_WALK_ERROR); 5751c42de6dSgd78059 } 5761c42de6dSgd78059 5771c42de6dSgd78059 switch (ecache_size) { 5781c42de6dSgd78059 case CH_ECACHE_1M_SIZE: 5791c42de6dSgd78059 ecache_line_size = 64; 5801c42de6dSgd78059 break; 5811c42de6dSgd78059 case CH_ECACHE_4M_SIZE: 5821c42de6dSgd78059 ecache_line_size = 256; 5831c42de6dSgd78059 break; 5841c42de6dSgd78059 case CH_ECACHE_8M_SIZE: 5851c42de6dSgd78059 ecache_line_size = 512; 5861c42de6dSgd78059 break; 5871c42de6dSgd78059 default: 5881c42de6dSgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us3_props: invalid " 5891c42de6dSgd78059 "ecache-size 0x%x\b", ecache_size); 5901c42de6dSgd78059 return (DDI_WALK_ERROR); 5911c42de6dSgd78059 } 5921c42de6dSgd78059 5931c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 5941c42de6dSgd78059 "ecache-line-size", ecache_line_size) != DDI_SUCCESS) { 5951c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 5961c42de6dSgd78059 "to create ecache-line-size property\n"); 5971c42de6dSgd78059 return (DDI_WALK_ERROR); 5981c42de6dSgd78059 } 5991c42de6dSgd78059 6001c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 6011c42de6dSgd78059 "ecache-associativity", ecache_assoc) != DDI_SUCCESS) { 6021c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed " 6031c42de6dSgd78059 "to create ecache-associativity property\n"); 6041c42de6dSgd78059 return (DDI_WALK_ERROR); 6051c42de6dSgd78059 } 6061c42de6dSgd78059 6071c42de6dSgd78059 /* 6081c42de6dSgd78059 * Create the ecache-dimm-label property. 6091c42de6dSgd78059 */ 6101c42de6dSgd78059 dimms = 0; 6111c42de6dSgd78059 6121c42de6dSgd78059 while ((pcd->sprd_ecache_dimm_label[dimms] != NULL) && 6131c42de6dSgd78059 (dimms < MAX_DIMMS_PER_PORT)) 6141c42de6dSgd78059 dimms++; 6151c42de6dSgd78059 6161c42de6dSgd78059 if (dimms) { 6171c42de6dSgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child, 6181c42de6dSgd78059 "ecache-dimm-label", (char **)pcd->sprd_ecache_dimm_label, 6191c42de6dSgd78059 dimms); 6201c42de6dSgd78059 } 6211c42de6dSgd78059 6221c42de6dSgd78059 return (DDI_WALK_TERMINATE); 6231c42de6dSgd78059 } 6241c42de6dSgd78059 6251c42de6dSgd78059 /* 6261c42de6dSgd78059 * Set cmp core node properties for Jaguar and Panther. 6271c42de6dSgd78059 * 6281c42de6dSgd78059 * name 6291c42de6dSgd78059 * compatible 6301c42de6dSgd78059 * reg 6311c42de6dSgd78059 * l1-icache-size 6321c42de6dSgd78059 * l1-icache-line-size 6331c42de6dSgd78059 * l1-icache-associativity 6341c42de6dSgd78059 * l1-dcache-size 6351c42de6dSgd78059 * l1-dcache-line-size 6361c42de6dSgd78059 * l1-dcache-associativity 6371c42de6dSgd78059 * l2-cache-size 6381c42de6dSgd78059 * l2-cache-line-size 6391c42de6dSgd78059 * l2-cache-associativity 6401c42de6dSgd78059 * l2-cache-sharing 6411c42de6dSgd78059 * l3-cache-size 6421c42de6dSgd78059 * l3-cache-line-size 6431c42de6dSgd78059 * l3-cache-associativity 6441c42de6dSgd78059 * l3-cache-sharing 6451c42de6dSgd78059 */ 6461c42de6dSgd78059 static int 6471c42de6dSgd78059 set_cpu_us4_props(dev_info_t *new_child, struct bca *bcp) 6481c42de6dSgd78059 { 6491c42de6dSgd78059 uint_t l1_icache_size, l1_icache_line_size; 6501c42de6dSgd78059 uint_t l2_cache_size, l2_cache_line_size, l2_cache_assoc; 6511c42de6dSgd78059 uint_t l2_cache_share; 6521c42de6dSgd78059 uint_t pcd_cache_size; 6531c42de6dSgd78059 uint_t coreid, impl; 6541c42de6dSgd78059 spcd_t *pcd; 6551c42de6dSgd78059 char *compatible; 6561c42de6dSgd78059 int dimms; 6571c42de6dSgd78059 int i; 6581c42de6dSgd78059 6591c42de6dSgd78059 pcd = bcp->pcd; 6601c42de6dSgd78059 coreid = bcp->coreid; 6611c42de6dSgd78059 impl = bcp->impl; 6621c42de6dSgd78059 6631c42de6dSgd78059 ASSERT(IS_JAGUAR(impl) || IS_PANTHER(impl)); 6641c42de6dSgd78059 6651c42de6dSgd78059 /* 6661c42de6dSgd78059 * Get the External Cache Size from the Common PCD. 6671c42de6dSgd78059 */ 6681c42de6dSgd78059 pcd_cache_size = pcd->spcd_cache * 0x100000; 6691c42de6dSgd78059 6701c42de6dSgd78059 switch (impl) { 6711c42de6dSgd78059 case JAGUAR_IMPL: 6721c42de6dSgd78059 compatible = "SUNW,UltraSPARC-IV"; 6731c42de6dSgd78059 l1_icache_size = CH_ICACHE_SIZE; 6741c42de6dSgd78059 l1_icache_line_size = CH_ICACHE_LSIZE; 6751c42de6dSgd78059 l2_cache_assoc = CHP_ECACHE_NWAY; 6761c42de6dSgd78059 6771c42de6dSgd78059 /* 6781c42de6dSgd78059 * Jaguar has no logical sharing of L2 cache, so the sharing 6791c42de6dSgd78059 * bit-map will represent this core only. 6801c42de6dSgd78059 */ 6811c42de6dSgd78059 l2_cache_share = coreid ? 0x2 : 0x1; 6821c42de6dSgd78059 6831c42de6dSgd78059 /* 6841c42de6dSgd78059 * Jaguar has a split ecache, so the total ecache must be 6851c42de6dSgd78059 * divided in half to get the ecache for the individual core. 6861c42de6dSgd78059 */ 6871c42de6dSgd78059 l2_cache_size = pcd_cache_size / 2; 6881c42de6dSgd78059 6891c42de6dSgd78059 switch (l2_cache_size) { 6901c42de6dSgd78059 case JG_ECACHE_4M_SIZE: 6911c42de6dSgd78059 l2_cache_line_size = 64; 6921c42de6dSgd78059 break; 6931c42de6dSgd78059 case JG_ECACHE_8M_SIZE: 6941c42de6dSgd78059 l2_cache_line_size = 128; 6951c42de6dSgd78059 break; 6961c42de6dSgd78059 default: 6971c42de6dSgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us4_props: " 6981c42de6dSgd78059 "invalid l2_cache-size 0x%x\n", l2_cache_size); 6991c42de6dSgd78059 return (DDI_WALK_ERROR); 7001c42de6dSgd78059 } 7011c42de6dSgd78059 break; 7021c42de6dSgd78059 case PANTHER_IMPL: 7031c42de6dSgd78059 ASSERT(pcd_cache_size == PN_L3_SIZE); 7041c42de6dSgd78059 compatible = "SUNW,UltraSPARC-IV+"; 7051c42de6dSgd78059 l1_icache_size = PN_ICACHE_SIZE; 7061c42de6dSgd78059 l1_icache_line_size = PN_ICACHE_LSIZE; 7071c42de6dSgd78059 l2_cache_size = PN_L2_SIZE; 7081c42de6dSgd78059 l2_cache_line_size = PN_L2_LINESIZE; 7091c42de6dSgd78059 l2_cache_assoc = PN_ECACHE_NWAY; 7101c42de6dSgd78059 7111c42de6dSgd78059 /* 7121c42de6dSgd78059 * For Panther, the L2 and L3 caches are logically shared by 7131c42de6dSgd78059 * all enabled cores, so the sharing bit-map will represent 7141c42de6dSgd78059 * all enabled cores. Panther split-mode is still considered 7151c42de6dSgd78059 * shared. 7161c42de6dSgd78059 * 7171c42de6dSgd78059 * Check the PCD status to determine enabled cores. 7181c42de6dSgd78059 */ 7191c42de6dSgd78059 ASSERT(pcd->spcd_ptype == SAFPTYPE_CPU); 7201c42de6dSgd78059 l2_cache_share = 0; 7211c42de6dSgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) { 7221c42de6dSgd78059 if (pcd->spcd_agent[i] == SPCD_RSV_PASS) { 7231c42de6dSgd78059 l2_cache_share |= (1 << i); 7241c42de6dSgd78059 } 7251c42de6dSgd78059 } 7261c42de6dSgd78059 7271c42de6dSgd78059 break; 7281c42de6dSgd78059 default: 7291c42de6dSgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us4_props: invalid " 7301c42de6dSgd78059 "implementation=0x%x\n", impl); 7311c42de6dSgd78059 return (DDI_WALK_ERROR); 7321c42de6dSgd78059 } 7331c42de6dSgd78059 7341c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 7351c42de6dSgd78059 "name", "cpu") != DDI_SUCCESS) { 7361c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7371c42de6dSgd78059 "to create name property\n"); 7381c42de6dSgd78059 return (DDI_WALK_ERROR); 7391c42de6dSgd78059 } 7401c42de6dSgd78059 7411c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 7421c42de6dSgd78059 "compatible", compatible) != DDI_SUCCESS) { 7431c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7441c42de6dSgd78059 "to create compatible property\n"); 7451c42de6dSgd78059 return (DDI_WALK_ERROR); 7461c42de6dSgd78059 } 7471c42de6dSgd78059 7481c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7491c42de6dSgd78059 "reg", coreid) != DDI_SUCCESS) { 7501c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7511c42de6dSgd78059 "to create reg property\n"); 7521c42de6dSgd78059 return (DDI_WALK_ERROR); 7531c42de6dSgd78059 } 7541c42de6dSgd78059 7551c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7561c42de6dSgd78059 "l1-icache-size", l1_icache_size) != DDI_SUCCESS) { 7571c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7581c42de6dSgd78059 "to create l1-icache-size property\n"); 7591c42de6dSgd78059 return (DDI_WALK_ERROR); 7601c42de6dSgd78059 } 7611c42de6dSgd78059 7621c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7631c42de6dSgd78059 "l1-icache-line-size", l1_icache_line_size) != DDI_SUCCESS) { 7641c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7651c42de6dSgd78059 "to create icache-line-size property\n"); 7661c42de6dSgd78059 return (DDI_WALK_ERROR); 7671c42de6dSgd78059 } 7681c42de6dSgd78059 7691c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7701c42de6dSgd78059 "l1-icache-associativity", CH_ICACHE_NWAY) != DDI_SUCCESS) { 7711c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7721c42de6dSgd78059 "to create l1-icache-associativity property\n"); 7731c42de6dSgd78059 return (DDI_WALK_ERROR); 7741c42de6dSgd78059 } 7751c42de6dSgd78059 7761c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7771c42de6dSgd78059 "l1-dcache-size", CH_DCACHE_SIZE) != DDI_SUCCESS) { 7781c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7791c42de6dSgd78059 "to create l1-dcache-size property\n"); 7801c42de6dSgd78059 return (DDI_WALK_ERROR); 7811c42de6dSgd78059 } 7821c42de6dSgd78059 7831c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7841c42de6dSgd78059 "l1-dcache-line-size", CH_DCACHE_LSIZE) != DDI_SUCCESS) { 7851c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7861c42de6dSgd78059 "to create dcache-line-size property\n"); 7871c42de6dSgd78059 return (DDI_WALK_ERROR); 7881c42de6dSgd78059 } 7891c42de6dSgd78059 7901c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7911c42de6dSgd78059 "l1-dcache-associativity", CH_DCACHE_NWAY) != DDI_SUCCESS) { 7921c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 7931c42de6dSgd78059 "to create l1-dcache-associativity property\n"); 7941c42de6dSgd78059 return (DDI_WALK_ERROR); 7951c42de6dSgd78059 } 7961c42de6dSgd78059 7971c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 7981c42de6dSgd78059 "l2-cache-size", l2_cache_size) != DDI_SUCCESS) { 7991c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 8001c42de6dSgd78059 "to create l2-cache-size property\n"); 8011c42de6dSgd78059 return (DDI_WALK_ERROR); 8021c42de6dSgd78059 } 8031c42de6dSgd78059 8041c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 8051c42de6dSgd78059 "l2-cache-line-size", l2_cache_line_size) != DDI_SUCCESS) { 8061c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 8071c42de6dSgd78059 "to create l2_cache-line-size property\n"); 8081c42de6dSgd78059 return (DDI_WALK_ERROR); 8091c42de6dSgd78059 } 8101c42de6dSgd78059 8111c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 8121c42de6dSgd78059 "l2-cache-associativity", l2_cache_assoc) != DDI_SUCCESS) { 8131c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 8141c42de6dSgd78059 "to create l2-cache-associativity property\n"); 8151c42de6dSgd78059 return (DDI_WALK_ERROR); 8161c42de6dSgd78059 } 8171c42de6dSgd78059 8181c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 8191c42de6dSgd78059 "l2-cache-sharing", l2_cache_share) != DDI_SUCCESS) { 8201c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed " 8211c42de6dSgd78059 "to create l2-cache-sharing property\n"); 8221c42de6dSgd78059 return (DDI_WALK_ERROR); 8231c42de6dSgd78059 } 8241c42de6dSgd78059 8251c42de6dSgd78059 /* 8261c42de6dSgd78059 * Create the ecache-dimm-label property. 8271c42de6dSgd78059 */ 8281c42de6dSgd78059 dimms = 0; 8291c42de6dSgd78059 8301c42de6dSgd78059 while ((pcd->sprd_ecache_dimm_label[dimms] != NULL) && 8311c42de6dSgd78059 (dimms < MAX_DIMMS_PER_PORT)) 8321c42de6dSgd78059 dimms++; 8331c42de6dSgd78059 8341c42de6dSgd78059 if (dimms) { 8351c42de6dSgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child, 8361c42de6dSgd78059 "ecache-dimm-label", (char **)pcd->sprd_ecache_dimm_label, 8371c42de6dSgd78059 dimms); 8381c42de6dSgd78059 } 8391c42de6dSgd78059 8401c42de6dSgd78059 if (IS_PANTHER(impl)) { 8411c42de6dSgd78059 int l3_cache_share = l2_cache_share; 8421c42de6dSgd78059 8431c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 8441c42de6dSgd78059 "l3-cache-size", PN_L3_SIZE) != DDI_SUCCESS) { 8451c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: " 8461c42de6dSgd78059 "failed to create l3-cache-size property\n"); 8471c42de6dSgd78059 return (DDI_WALK_ERROR); 8481c42de6dSgd78059 } 8491c42de6dSgd78059 8501c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 8511c42de6dSgd78059 "l3-cache-line-size", PN_L3_LINESIZE) != DDI_SUCCESS) { 8521c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: " 8531c42de6dSgd78059 "failed to create l3-cache-line-size property\n"); 8541c42de6dSgd78059 return (DDI_WALK_ERROR); 8551c42de6dSgd78059 } 8561c42de6dSgd78059 8571c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 8581c42de6dSgd78059 "l3-cache-associativity", PN_ECACHE_NWAY) != DDI_SUCCESS) { 8591c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: " 8601c42de6dSgd78059 "failed to create l3-cache-associativity " 8611c42de6dSgd78059 "property\n"); 8621c42de6dSgd78059 return (DDI_WALK_ERROR); 8631c42de6dSgd78059 } 8641c42de6dSgd78059 8651c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 8661c42de6dSgd78059 "l3-cache-sharing", l3_cache_share) != DDI_SUCCESS) { 8671c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: " 8681c42de6dSgd78059 "failed to create l3-cache-sharing property\n"); 8691c42de6dSgd78059 return (DDI_WALK_ERROR); 8701c42de6dSgd78059 } 8711c42de6dSgd78059 } 8721c42de6dSgd78059 8731c42de6dSgd78059 return (DDI_WALK_TERMINATE); 8741c42de6dSgd78059 } 8751c42de6dSgd78059 8761c42de6dSgd78059 static dev_info_t * 8771c42de6dSgd78059 gptwocfg_create_mc_node(dev_info_t *ap, spcd_t *pcd, uint_t portid) 8781c42de6dSgd78059 { 8791c42de6dSgd78059 struct bca arg; 8801c42de6dSgd78059 devi_branch_t b = {0}; 8811c42de6dSgd78059 8821c42de6dSgd78059 arg.pcd = pcd; 8831c42de6dSgd78059 arg.portid = portid; 8841c42de6dSgd78059 arg.cpuid = portid; 8851c42de6dSgd78059 arg.new_child = NULL; 8861c42de6dSgd78059 8871c42de6dSgd78059 b.arg = &arg; 8881c42de6dSgd78059 b.type = DEVI_BRANCH_SID; 8891c42de6dSgd78059 b.create.sid_branch_create = set_mc_props; 8901c42de6dSgd78059 b.devi_branch_callback = get_new_child; 8911c42de6dSgd78059 8921c42de6dSgd78059 if (e_ddi_branch_create(ap, &b, NULL, 0)) 8931c42de6dSgd78059 return (NULL); 8941c42de6dSgd78059 8951c42de6dSgd78059 return (arg.new_child); 8961c42de6dSgd78059 } 8971c42de6dSgd78059 8981c42de6dSgd78059 /*ARGSUSED*/ 8991c42de6dSgd78059 static int 9001c42de6dSgd78059 set_mc_props(dev_info_t *new_child, void *arg, uint_t flags) 9011c42de6dSgd78059 { 9021c42de6dSgd78059 struct bca *bcp = arg; 9031c42de6dSgd78059 gptwo_regspec_t reg; 9041c42de6dSgd78059 int banks, dimms; 9051c42de6dSgd78059 spcd_t *pcd = bcp->pcd; 9061c42de6dSgd78059 uint_t portid = bcp->portid; 9071c42de6dSgd78059 uint_t cpuid = bcp->cpuid; 9081c42de6dSgd78059 9091c42de6dSgd78059 GPTWO_DEBUG3(1, CE_CONT, "set_mc_props: ap=0x%lx portid=0x%x " 9101c42de6dSgd78059 "cpuid=0x%x\n", ddi_get_parent(new_child), portid, cpuid); 9111c42de6dSgd78059 9121c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 9131c42de6dSgd78059 "name", "memory-controller") != DDI_SUCCESS) { 9141c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed " 9151c42de6dSgd78059 "to create name property\n"); 9161c42de6dSgd78059 return (DDI_WALK_ERROR); 9171c42de6dSgd78059 } 9181c42de6dSgd78059 9191c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 9201c42de6dSgd78059 "compatible", "SUNW,UltraSPARC-III,mc") != DDI_SUCCESS) { 9211c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed " 9221c42de6dSgd78059 "to create compatible property\n"); 9231c42de6dSgd78059 return (DDI_WALK_ERROR); 9241c42de6dSgd78059 } 9251c42de6dSgd78059 9261c42de6dSgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child, 9271c42de6dSgd78059 "device_type", "memory-controller") != DDI_SUCCESS) { 9281c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed " 9291c42de6dSgd78059 "to create device_type property\n"); 9301c42de6dSgd78059 return (DDI_WALK_ERROR); 9311c42de6dSgd78059 } 9321c42de6dSgd78059 9331c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 9341c42de6dSgd78059 "portid", portid) != DDI_SUCCESS) { 9351c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed " 9361c42de6dSgd78059 "to create portid property\n"); 9371c42de6dSgd78059 return (DDI_WALK_ERROR); 9381c42de6dSgd78059 } 9391c42de6dSgd78059 9401c42de6dSgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, 9411c42de6dSgd78059 "cpuid", cpuid) != DDI_SUCCESS) { 9421c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed " 9431c42de6dSgd78059 "to create cpuid property\n"); 9441c42de6dSgd78059 return (DDI_WALK_ERROR); 9451c42de6dSgd78059 } 9461c42de6dSgd78059 9471c42de6dSgd78059 reg.gptwo_phys_hi = 0x400 | (portid >> 9); 9481c42de6dSgd78059 reg.gptwo_phys_low = (portid << 23) | 0x400000; 9491c42de6dSgd78059 reg.gptwo_size_hi = 0; 9501c42de6dSgd78059 reg.gptwo_size_low = 0x48; 9511c42de6dSgd78059 9521c42de6dSgd78059 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, 9531c42de6dSgd78059 new_child, "reg", (int *)®, 9541c42de6dSgd78059 sizeof (gptwo_regspec_t) / sizeof (int)) != DDI_SUCCESS) { 9551c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed " 9561c42de6dSgd78059 "to create reg property\n"); 9571c42de6dSgd78059 return (DDI_WALK_ERROR); 9581c42de6dSgd78059 } 9591c42de6dSgd78059 9601c42de6dSgd78059 if (pcd->memory_layout) { 9611c42de6dSgd78059 if (ndi_prop_update_byte_array(DDI_DEV_T_NONE, 9621c42de6dSgd78059 new_child, "memory-layout", (uchar_t *)pcd->memory_layout, 9631c42de6dSgd78059 pcd->memory_layout_size) != DDI_SUCCESS) { 9641c42de6dSgd78059 9651c42de6dSgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed " 9661c42de6dSgd78059 "to create memory-layout property\n"); 9671c42de6dSgd78059 9681c42de6dSgd78059 return (DDI_WALK_ERROR); 9691c42de6dSgd78059 } 9701c42de6dSgd78059 } 9711c42de6dSgd78059 9721c42de6dSgd78059 /* 9731c42de6dSgd78059 * Create the bank-status property. 9741c42de6dSgd78059 */ 9751c42de6dSgd78059 banks = 0; 9761c42de6dSgd78059 9771c42de6dSgd78059 while ((pcd->sprd_bank_rsv[banks] != NULL) && 9781c42de6dSgd78059 (banks < MAX_BANKS_PER_PORT)) 9791c42de6dSgd78059 banks++; 9801c42de6dSgd78059 9811c42de6dSgd78059 if (banks) { 9821c42de6dSgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child, 9831c42de6dSgd78059 "bank-status", (char **)pcd->sprd_bank_rsv, banks); 9841c42de6dSgd78059 } 9851c42de6dSgd78059 9861c42de6dSgd78059 /* 9871c42de6dSgd78059 * Create the dimm-status property. 9881c42de6dSgd78059 */ 9891c42de6dSgd78059 dimms = 0; 9901c42de6dSgd78059 9911c42de6dSgd78059 while ((pcd->sprd_dimm[dimms] != NULL) && 9921c42de6dSgd78059 (dimms < MAX_DIMMS_PER_PORT)) 9931c42de6dSgd78059 dimms++; 9941c42de6dSgd78059 9951c42de6dSgd78059 if (dimms) { 9961c42de6dSgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child, 9971c42de6dSgd78059 "dimm-status", (char **)pcd->sprd_dimm, dimms); 9981c42de6dSgd78059 } 9991c42de6dSgd78059 10001c42de6dSgd78059 10011c42de6dSgd78059 return (DDI_WALK_TERMINATE); 10021c42de6dSgd78059 } 10031c42de6dSgd78059 10041c42de6dSgd78059 /*ARGSUSED*/ 10051c42de6dSgd78059 static void 10061c42de6dSgd78059 get_new_child(dev_info_t *rdip, void *arg, uint_t flags) 10071c42de6dSgd78059 { 10081c42de6dSgd78059 struct bca *bcp = arg; 10091c42de6dSgd78059 10101c42de6dSgd78059 bcp->new_child = rdip; 10111c42de6dSgd78059 10121c42de6dSgd78059 } 10131c42de6dSgd78059 10141c42de6dSgd78059 #ifdef DEBUG 10151c42de6dSgd78059 static void 10161c42de6dSgd78059 debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3, 10171c42de6dSgd78059 uintptr_t a4, uintptr_t a5) 10181c42de6dSgd78059 { 10191c42de6dSgd78059 cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5); 10201c42de6dSgd78059 } 10211c42de6dSgd78059 #endif 1022