14135Sgd78059 /*
24135Sgd78059 * CDDL HEADER START
34135Sgd78059 *
44135Sgd78059 * The contents of this file are subject to the terms of the
54135Sgd78059 * Common Development and Distribution License (the "License").
64135Sgd78059 * You may not use this file except in compliance with the License.
74135Sgd78059 *
84135Sgd78059 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94135Sgd78059 * or http://www.opensolaris.org/os/licensing.
104135Sgd78059 * See the License for the specific language governing permissions
114135Sgd78059 * and limitations under the License.
124135Sgd78059 *
134135Sgd78059 * When distributing Covered Code, include this CDDL HEADER in each
144135Sgd78059 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154135Sgd78059 * If applicable, add the following below this CDDL HEADER, with the
164135Sgd78059 * fields enclosed by brackets "[]" replaced with your own identifying
174135Sgd78059 * information: Portions Copyright [yyyy] [name of copyright owner]
184135Sgd78059 *
194135Sgd78059 * CDDL HEADER END
204135Sgd78059 */
214135Sgd78059 /*
22*7696SRichard.Bean@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
234135Sgd78059 * Use is subject to license terms.
244135Sgd78059 */
254135Sgd78059
264135Sgd78059 /*
274135Sgd78059 * CPU functions to the Safari Configurator (gptwo_cpu)
284135Sgd78059 */
294135Sgd78059
304135Sgd78059 #include <sys/types.h>
314135Sgd78059 #include <sys/cred.h>
324135Sgd78059 #include <sys/mman.h>
334135Sgd78059 #include <sys/kmem.h>
344135Sgd78059 #include <sys/conf.h>
354135Sgd78059 #include <sys/ddi.h>
364135Sgd78059 #include <sys/sunddi.h>
374135Sgd78059 #include <sys/sunndi.h>
384135Sgd78059 #include <sys/modctl.h>
394135Sgd78059 #include <sys/stat.h>
404135Sgd78059 #include <sys/param.h>
414135Sgd78059 #include <sys/autoconf.h>
424135Sgd78059 #include <sys/ksynch.h>
434135Sgd78059 #include <sys/promif.h>
444135Sgd78059 #include <sys/ndi_impldefs.h>
454135Sgd78059 #include <sys/ddi_impldefs.h>
464135Sgd78059 #include <sys/machsystm.h>
474135Sgd78059 #include <sys/gp2cfg.h>
484135Sgd78059 #include <sys/gptwo_cpu.h>
494135Sgd78059 #include <sys/cheetahregs.h>
504135Sgd78059
514135Sgd78059 #ifdef DEBUG
524135Sgd78059 int gptwo_cpu_debug = 0;
534135Sgd78059
544135Sgd78059 static void debug(char *, uintptr_t, uintptr_t,
554135Sgd78059 uintptr_t, uintptr_t, uintptr_t);
564135Sgd78059
574135Sgd78059 #define GPTWO_DEBUG0(level, flag, s) if (gptwo_cpu_debug >= level) \
584135Sgd78059 cmn_err(flag, s)
594135Sgd78059 #define GPTWO_DEBUG1(level, flag, fmt, a1) if (gptwo_cpu_debug >= level) \
604135Sgd78059 debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
614135Sgd78059 #define GPTWO_DEBUG2(level, flag, fmt, a1, a2) if (gptwo_cpu_debug >= level) \
624135Sgd78059 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
634135Sgd78059 #define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3) \
644135Sgd78059 if (gptwo_cpu_debug >= level) \
654135Sgd78059 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), (uintptr_t)(a3), 0, 0);
664135Sgd78059 #else
674135Sgd78059 #define GPTWO_DEBUG0(level, flag, s)
684135Sgd78059 #define GPTWO_DEBUG1(level, flag, fmt, a1)
694135Sgd78059 #define GPTWO_DEBUG2(level, flag, fmt, a1, a2)
704135Sgd78059 #define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3)
714135Sgd78059 #endif
724135Sgd78059
734135Sgd78059 /*
744135Sgd78059 * Devinfo branch create arg
754135Sgd78059 */
764135Sgd78059 struct bca {
774135Sgd78059 spcd_t *pcd;
784135Sgd78059 uint_t portid;
794135Sgd78059 uint_t cpuid;
804135Sgd78059 uint_t coreid;
814135Sgd78059 uint_t impl;
824135Sgd78059 dev_info_t *new_child;
834135Sgd78059 };
844135Sgd78059
854135Sgd78059 static dev_info_t *gptwocfg_create_cpu_node(dev_info_t *, spcd_t *,
864135Sgd78059 uint_t, uint_t, uint_t, uint_t);
874135Sgd78059 static dev_info_t *gptwocfg_create_mc_node(dev_info_t *, spcd_t *, uint_t);
884135Sgd78059 static dev_info_t *gptwocfg_create_cmp_node(dev_info_t *, spcd_t *, uint_t);
894135Sgd78059 static int gptwocfg_create_core_node(dev_info_t *, spcd_t *, uint_t, uint_t);
904135Sgd78059 static int set_mc_props(dev_info_t *new_child, void *arg, uint_t flags);
914135Sgd78059 static int set_cmp_props(dev_info_t *new_child, void *arg, uint_t flags);
924135Sgd78059 static int set_cpu_props(dev_info_t *new_child, void *arg, uint_t flags);
934135Sgd78059 static int set_cpu_common_props(dev_info_t *new_child, struct bca *bcp);
944135Sgd78059 static int set_cpu_us3_props(dev_info_t *new_child, struct bca *bcp);
954135Sgd78059 static int set_cpu_us4_props(dev_info_t *new_child, struct bca *bcp);
964135Sgd78059 static void get_new_child(dev_info_t *rdip, void *arg, uint_t flags);
974135Sgd78059
984135Sgd78059
994135Sgd78059 /*
1004135Sgd78059 * Module linkage information for the kernel.
1014135Sgd78059 */
1024135Sgd78059
1034135Sgd78059 extern struct mod_ops mod_miscops;
1044135Sgd78059
1054135Sgd78059 static struct modlmisc modlmisc = {
1064135Sgd78059 &mod_miscops, /* Type of module */
107*7696SRichard.Bean@Sun.COM "gptwo->cpu configurator",
1084135Sgd78059 };
1094135Sgd78059
1104135Sgd78059 static struct modlinkage modlinkage = {
1114135Sgd78059 MODREV_1, (void *)&modlmisc, NULL
1124135Sgd78059 };
1134135Sgd78059
1144135Sgd78059 int
_init(void)1154135Sgd78059 _init(void)
1164135Sgd78059 {
1174135Sgd78059 int err = 0;
1184135Sgd78059
1194135Sgd78059 /* register device with the configurator */
1204135Sgd78059 gptwocfg_register_ops(SAFPTYPE_CPU, gptwocfg_configure_cpu, NULL);
1214135Sgd78059
1224135Sgd78059 if ((err = mod_install(&modlinkage)) != 0) {
1234135Sgd78059 GPTWO_DEBUG1(1, CE_WARN, "gptwo_cpu (CPU/MC Functions) "
1244135Sgd78059 "failed to load, error=%d\n", err);
1254135Sgd78059 gptwocfg_unregister_ops(SAFPTYPE_CPU);
1264135Sgd78059 } else {
1274135Sgd78059 GPTWO_DEBUG0(1, CE_WARN, "gptwo_cpu (CPU/MC Functions) "
1284135Sgd78059 "has been loaded.\n");
1294135Sgd78059 }
1304135Sgd78059 return (err);
1314135Sgd78059 }
1324135Sgd78059
1334135Sgd78059 int
_fini(void)1344135Sgd78059 _fini(void)
1354135Sgd78059 {
1364135Sgd78059 /* cleanup/freeup structs with configurator */
1374135Sgd78059 gptwocfg_unregister_ops(SAFPTYPE_CPU);
1384135Sgd78059 return (mod_remove(&modlinkage));
1394135Sgd78059 }
1404135Sgd78059
1414135Sgd78059 int
_info(struct modinfo * modinfop)1424135Sgd78059 _info(struct modinfo *modinfop)
1434135Sgd78059 {
1444135Sgd78059 return (mod_info(&modlinkage, modinfop));
1454135Sgd78059 }
1464135Sgd78059
1474135Sgd78059 gptwo_new_nodes_t *
gptwocfg_configure_cpu(dev_info_t * ap,spcd_t * pcd,uint_t portid)1484135Sgd78059 gptwocfg_configure_cpu(dev_info_t *ap, spcd_t *pcd, uint_t portid)
1494135Sgd78059 {
1504135Sgd78059 dev_info_t *cpu_node[AGENTS_PER_PORT], *mc_node[AGENTS_PER_PORT];
1514135Sgd78059 dev_info_t *cmp_node = NULL;
1524135Sgd78059 gptwo_new_nodes_t *new_nodes;
1534135Sgd78059 int nodes = 0;
1544135Sgd78059 int i, j = 0;
1554135Sgd78059 uint_t implementation;
1564135Sgd78059
1574135Sgd78059 GPTWO_DEBUG2(1, CE_CONT, "gptwocfg_configure_cpu: portid=%x pcd=%lx\n",
1584135Sgd78059 portid, pcd);
1594135Sgd78059
1604135Sgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) {
1614135Sgd78059 cpu_node[i] = NULL;
1624135Sgd78059 mc_node[i] = NULL;
1634135Sgd78059 }
1644135Sgd78059
1654135Sgd78059 implementation = (pcd->spcd_ver_reg >> 32) & 0x000000000000ffff;
1664135Sgd78059
1674135Sgd78059 switch (implementation) {
1684135Sgd78059 case CHEETAH_IMPL:
1694135Sgd78059 case CHEETAH_PLUS_IMPL:
1704135Sgd78059 case JAGUAR_IMPL:
1714135Sgd78059 case PANTHER_IMPL:
1724135Sgd78059 break;
1734135Sgd78059 default:
1744135Sgd78059 cmn_err(CE_WARN, "Unsupported cpu implementation=0x%x : "
1754135Sgd78059 "skipping configure of portid=0x%x", implementation,
1764135Sgd78059 portid);
1774135Sgd78059 ASSERT(0);
1784135Sgd78059 return (NULL);
1794135Sgd78059 }
1804135Sgd78059
1814135Sgd78059 if (CPU_IMPL_IS_CMP(implementation)) {
1824135Sgd78059 if (cmp_node = gptwocfg_create_cmp_node(ap, pcd, portid))
1834135Sgd78059 nodes++;
1844135Sgd78059 else
1854135Sgd78059 return (NULL);
1864135Sgd78059 }
1874135Sgd78059
1884135Sgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) {
1894135Sgd78059 if (pcd->spcd_agent[i] != SPCD_RSV_PASS)
1904135Sgd78059 continue;
1914135Sgd78059
1924135Sgd78059 if (cpu_node[i] = gptwocfg_create_cpu_node(cmp_node ?
1934135Sgd78059 cmp_node : ap, pcd, portid, pcd->spcd_cpuid[i], i,
1944135Sgd78059 implementation)) {
1954135Sgd78059 /*
1964135Sgd78059 * If the CPU is a CMP, the entire branch is
1974135Sgd78059 * manipulated using just the top node. Thus,
1984135Sgd78059 * the dips of the individual cores do not need
1994135Sgd78059 * to be held or stored in the new node list.
2004135Sgd78059 */
2014135Sgd78059 if (cmp_node) {
2024135Sgd78059 e_ddi_branch_rele(cpu_node[i]);
2034135Sgd78059 } else {
2044135Sgd78059 nodes++;
2054135Sgd78059 }
2064135Sgd78059 }
2074135Sgd78059 }
2084135Sgd78059
2094135Sgd78059 /* current implementations have 1 MC node per Safari port */
2104135Sgd78059 if (pcd->spcd_prsv == SPCD_RSV_PASS &&
2114135Sgd78059 (mc_node[0] = gptwocfg_create_mc_node(ap, pcd, portid)))
2124135Sgd78059 nodes++;
2134135Sgd78059
2144135Sgd78059 new_nodes = gptwocfg_allocate_node_list(nodes);
2154135Sgd78059
2164135Sgd78059 j = 0;
2174135Sgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) {
2184135Sgd78059 if ((cpu_node[i] != NULL) && (!CPU_IMPL_IS_CMP(implementation)))
2194135Sgd78059 new_nodes->gptwo_nodes[j++] = cpu_node[i];
2204135Sgd78059 if (mc_node[i] != NULL)
2214135Sgd78059 new_nodes->gptwo_nodes[j++] = mc_node[i];
2224135Sgd78059 }
2234135Sgd78059
2244135Sgd78059 if (cmp_node)
2254135Sgd78059 new_nodes->gptwo_nodes[j++] = cmp_node;
2264135Sgd78059
2274135Sgd78059 return (new_nodes);
2284135Sgd78059 }
2294135Sgd78059
2304135Sgd78059
2314135Sgd78059 static dev_info_t *
gptwocfg_create_cmp_node(dev_info_t * ap,spcd_t * pcd,uint_t portid)2324135Sgd78059 gptwocfg_create_cmp_node(dev_info_t *ap, spcd_t *pcd, uint_t portid)
2334135Sgd78059 {
2344135Sgd78059 struct bca arg;
2354135Sgd78059 devi_branch_t b;
2364135Sgd78059
2374135Sgd78059 arg.pcd = pcd;
2384135Sgd78059 arg.portid = portid;
2394135Sgd78059 arg.cpuid = 0;
2404135Sgd78059 arg.coreid = 0;
2414135Sgd78059 arg.new_child = NULL;
2424135Sgd78059
2434135Sgd78059 b.arg = &arg;
2444135Sgd78059 b.type = DEVI_BRANCH_SID;
2454135Sgd78059 b.create.sid_branch_create = set_cmp_props;
2464135Sgd78059 b.devi_branch_callback = get_new_child;
2474135Sgd78059
2484135Sgd78059 if (e_ddi_branch_create(ap, &b, NULL, 0))
2494135Sgd78059 return (NULL);
2504135Sgd78059
2514135Sgd78059 return (arg.new_child);
2524135Sgd78059 }
2534135Sgd78059
2544135Sgd78059 /*ARGSUSED*/
2554135Sgd78059 static int
set_cmp_props(dev_info_t * new_child,void * arg,uint_t flags)2564135Sgd78059 set_cmp_props(dev_info_t *new_child, void *arg, uint_t flags)
2574135Sgd78059 {
2584135Sgd78059 struct bca *bap = (struct bca *)arg;
2594135Sgd78059 gptwo_regspec_t reg;
2604135Sgd78059 spcd_t *pcd;
2614135Sgd78059 uint_t portid;
2624135Sgd78059
2634135Sgd78059 pcd = bap->pcd;
2644135Sgd78059 portid = bap->portid;
2654135Sgd78059
2664135Sgd78059 GPTWO_DEBUG2(1, CE_CONT, "set_cmp_props: portid=%x pcd=%lx\n",
2674135Sgd78059 portid, pcd);
2684135Sgd78059
2694135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
2704135Sgd78059 "name", "cmp") != DDI_SUCCESS) {
2714135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cmp_props: failed to "
2724135Sgd78059 "create name property\n");
2734135Sgd78059 return (DDI_WALK_ERROR);
2744135Sgd78059 }
2754135Sgd78059
2764135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
2774135Sgd78059 "portid", portid) != DDI_SUCCESS) {
2784135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cmp_props: failed to "
2794135Sgd78059 "create portid property\n");
2804135Sgd78059 return (DDI_WALK_ERROR);
2814135Sgd78059 }
2824135Sgd78059
2834135Sgd78059 reg.gptwo_phys_hi = 0x400 | (portid >> 9);
2844135Sgd78059 reg.gptwo_phys_low = (portid << 23);
2854135Sgd78059 reg.gptwo_size_hi = 0;
2864135Sgd78059 reg.gptwo_size_low = 0x10000;
2874135Sgd78059
2884135Sgd78059 if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
2894135Sgd78059 new_child, "reg", (int *)®,
2904135Sgd78059 sizeof (gptwo_regspec_t) / sizeof (int)) != DDI_SUCCESS) {
2914135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cmp_props: failed to "
2924135Sgd78059 "create reg property\n");
2934135Sgd78059 return (DDI_WALK_ERROR);
2944135Sgd78059 }
2954135Sgd78059
2964135Sgd78059 return (DDI_WALK_TERMINATE);
2974135Sgd78059 }
2984135Sgd78059
2994135Sgd78059 static dev_info_t *
gptwocfg_create_cpu_node(dev_info_t * ap,spcd_t * pcd,uint_t portid,uint_t cpuid,uint_t coreid,uint_t impl)3004135Sgd78059 gptwocfg_create_cpu_node(dev_info_t *ap, spcd_t *pcd, uint_t portid,
3014135Sgd78059 uint_t cpuid, uint_t coreid, uint_t impl)
3024135Sgd78059 {
3034135Sgd78059 struct bca arg;
3044135Sgd78059 devi_branch_t b = {0};
3054135Sgd78059
3064135Sgd78059 arg.pcd = pcd;
3074135Sgd78059 arg.portid = portid;
3084135Sgd78059 arg.cpuid = cpuid;
3094135Sgd78059 arg.coreid = coreid;
3104135Sgd78059 arg.impl = impl;
3114135Sgd78059 arg.new_child = NULL;
3124135Sgd78059
3134135Sgd78059 b.arg = &arg;
3144135Sgd78059 b.type = DEVI_BRANCH_SID;
3154135Sgd78059 b.create.sid_branch_create = set_cpu_props;
3164135Sgd78059 b.devi_branch_callback = get_new_child;
3174135Sgd78059
3184135Sgd78059 if (e_ddi_branch_create(ap, &b, NULL, 0))
3194135Sgd78059 return (NULL);
3204135Sgd78059
3214135Sgd78059 return (arg.new_child);
3224135Sgd78059 }
3234135Sgd78059
3244135Sgd78059 /*ARGSUSED*/
3254135Sgd78059 static int
set_cpu_props(dev_info_t * new_child,void * arg,uint_t flags)3264135Sgd78059 set_cpu_props(dev_info_t *new_child, void *arg, uint_t flags)
3274135Sgd78059 {
3284135Sgd78059 struct bca *bcp = arg;
3294135Sgd78059 uint_t impl = bcp->impl;
3304135Sgd78059 int rc;
3314135Sgd78059
3324135Sgd78059 if (set_cpu_common_props(new_child, bcp) != DDI_WALK_CONTINUE)
3334135Sgd78059 return (DDI_WALK_ERROR);
3344135Sgd78059
3354135Sgd78059 switch (impl) {
3364135Sgd78059 case CHEETAH_IMPL:
3374135Sgd78059 case CHEETAH_PLUS_IMPL:
3384135Sgd78059 rc = set_cpu_us3_props(new_child, bcp);
3394135Sgd78059 break;
3404135Sgd78059 case JAGUAR_IMPL:
3414135Sgd78059 case PANTHER_IMPL:
3424135Sgd78059 rc = set_cpu_us4_props(new_child, bcp);
3434135Sgd78059 break;
3444135Sgd78059 default:
3454135Sgd78059 ASSERT(0);
3464135Sgd78059 return (DDI_WALK_ERROR);
3474135Sgd78059 }
3484135Sgd78059
3494135Sgd78059 return (rc);
3504135Sgd78059 }
3514135Sgd78059
3524135Sgd78059 /*
3534135Sgd78059 * Set properties common to cpu (non-CMP) and core (CMP) nodes.
3544135Sgd78059 *
3554135Sgd78059 * cpuid
3564135Sgd78059 * device_type
3574135Sgd78059 * manufacturer#
3584135Sgd78059 * implementation#
3594135Sgd78059 * mask#
3604135Sgd78059 * sparc-version
3614135Sgd78059 * clock-frequency
3624135Sgd78059 * #dtlb-entries
3634135Sgd78059 * #itlb-entries
3644135Sgd78059 */
3654135Sgd78059 static int
set_cpu_common_props(dev_info_t * new_child,struct bca * bcp)3664135Sgd78059 set_cpu_common_props(dev_info_t *new_child, struct bca *bcp)
3674135Sgd78059 {
3684135Sgd78059 uint_t cpuid, impl;
3694135Sgd78059 spcd_t *pcd;
3704135Sgd78059 int mask, manufacturer;
3714135Sgd78059
3724135Sgd78059 cpuid = bcp->cpuid;
3734135Sgd78059 pcd = bcp->pcd;
3744135Sgd78059 impl = bcp->impl;
3754135Sgd78059
3764135Sgd78059 mask = (pcd->spcd_ver_reg >> 24) & 0x00000000000000ff;
3774135Sgd78059 manufacturer = (pcd->spcd_ver_reg >> 48) & 0x000000000000ffff;
3784135Sgd78059
3794135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
3804135Sgd78059 "cpuid", cpuid) != DDI_SUCCESS) {
3814135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
3824135Sgd78059 "to create cpuid property\n");
3834135Sgd78059 return (DDI_WALK_ERROR);
3844135Sgd78059 }
3854135Sgd78059
3864135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
3874135Sgd78059 "device_type", "cpu") != DDI_SUCCESS) {
3884135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
3894135Sgd78059 "to create device_type property\n");
3904135Sgd78059 return (DDI_WALK_ERROR);
3914135Sgd78059 }
3924135Sgd78059
3934135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, "manufacturer#",
3944135Sgd78059 manufacturer) != DDI_SUCCESS) {
3954135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
3964135Sgd78059 "to create manufacturer# property\n");
3974135Sgd78059 return (DDI_WALK_ERROR);
3984135Sgd78059 }
3994135Sgd78059
4004135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, "implementation#",
4014135Sgd78059 impl) != DDI_SUCCESS) {
4024135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
4034135Sgd78059 "to create implementation# property\n");
4044135Sgd78059 return (DDI_WALK_ERROR);
4054135Sgd78059 }
4064135Sgd78059
4074135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child, "mask#",
4084135Sgd78059 mask) != DDI_SUCCESS) {
4094135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
4104135Sgd78059 "to create mask# property\n");
4114135Sgd78059 return (DDI_WALK_ERROR);
4124135Sgd78059 }
4134135Sgd78059
4144135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
4154135Sgd78059 "sparc-version", 9) != DDI_SUCCESS) {
4164135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
4174135Sgd78059 "to create sparc-version property\n");
4184135Sgd78059 return (DDI_WALK_ERROR);
4194135Sgd78059 }
4204135Sgd78059
4214135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
4224135Sgd78059 "clock-frequency", (pcd->spcd_afreq * 1000000)) != DDI_SUCCESS) {
4234135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
4244135Sgd78059 "to create clock-frequency property\n");
4254135Sgd78059 return (DDI_WALK_ERROR);
4264135Sgd78059 }
4274135Sgd78059
4284135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
4294135Sgd78059 "#dtlb-entries", 0x10) != DDI_SUCCESS) {
4304135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
4314135Sgd78059 "to create #dtlb-entries property\n");
4324135Sgd78059 return (DDI_WALK_ERROR);
4334135Sgd78059 }
4344135Sgd78059
4354135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
4364135Sgd78059 "#itlb-entries", 0x10) != DDI_SUCCESS) {
4374135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_common_props: failed "
4384135Sgd78059 "to create #itlb-entries property\n");
4394135Sgd78059 return (DDI_WALK_ERROR);
4404135Sgd78059 }
4414135Sgd78059
4424135Sgd78059 return (DDI_WALK_CONTINUE);
4434135Sgd78059 }
4444135Sgd78059
4454135Sgd78059 /*
4464135Sgd78059 * Set cpu node properties for Cheetah and Cheetah+.
4474135Sgd78059 *
4484135Sgd78059 * name
4494135Sgd78059 * portid
4504135Sgd78059 * reg
4514135Sgd78059 * icache-size
4524135Sgd78059 * icache-line-size
4534135Sgd78059 * icache-associativity
4544135Sgd78059 * dcache-size
4554135Sgd78059 * dcache-line-size
4564135Sgd78059 * dcache-associativity
4574135Sgd78059 * ecache-size
4584135Sgd78059 * ecache-line-size
4594135Sgd78059 * ecache-associativity
4604135Sgd78059 */
4614135Sgd78059 static int
set_cpu_us3_props(dev_info_t * new_child,struct bca * bcp)4624135Sgd78059 set_cpu_us3_props(dev_info_t *new_child, struct bca *bcp)
4634135Sgd78059 {
4644135Sgd78059 char *node_name;
4654135Sgd78059 gptwo_regspec_t reg;
4664135Sgd78059 int ecache_size, ecache_line_size;
4674135Sgd78059 int dimms, ecache_assoc;
4684135Sgd78059 spcd_t *pcd;
4694135Sgd78059 uint_t portid, impl;
4704135Sgd78059
4714135Sgd78059 pcd = bcp->pcd;
4724135Sgd78059 portid = bcp->portid;
4734135Sgd78059 impl = bcp->impl;
4744135Sgd78059
4754135Sgd78059 ASSERT(IS_CHEETAH(impl) || IS_CHEETAH_PLUS(impl));
4764135Sgd78059
4774135Sgd78059 switch (impl) {
4784135Sgd78059 case CHEETAH_IMPL:
4794135Sgd78059 ecache_assoc = CH_ECACHE_NWAY;
4804135Sgd78059 node_name = "SUNW,UltraSPARC-III";
4814135Sgd78059 break;
4824135Sgd78059 case CHEETAH_PLUS_IMPL:
4834135Sgd78059 /*
4844135Sgd78059 * Hard coding the ecache-associativity to 2 for Cheetah+.
4854135Sgd78059 * We probably should add this to the PCD.
4864135Sgd78059 */
4874135Sgd78059 ecache_assoc = CHP_ECACHE_NWAY;
4884135Sgd78059 node_name = "SUNW,UltraSPARC-III+";
4894135Sgd78059 break;
4904135Sgd78059 default:
4914135Sgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us3_props: invalid "
4924135Sgd78059 "implementation=0x%x\n", impl);
4934135Sgd78059 return (DDI_WALK_ERROR);
4944135Sgd78059 }
4954135Sgd78059
4964135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
4974135Sgd78059 "name", node_name) != DDI_SUCCESS) {
4984135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
4994135Sgd78059 "to create name property\n");
5004135Sgd78059 return (DDI_WALK_ERROR);
5014135Sgd78059 }
5024135Sgd78059
5034135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5044135Sgd78059 "portid", portid) != DDI_SUCCESS) {
5054135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5064135Sgd78059 "to create portid property\n");
5074135Sgd78059 return (DDI_WALK_ERROR);
5084135Sgd78059 }
5094135Sgd78059
5104135Sgd78059 reg.gptwo_phys_hi = 0x400 | (portid >> 9);
5114135Sgd78059 reg.gptwo_phys_low = (portid << 23);
5124135Sgd78059 reg.gptwo_size_hi = 0;
5134135Sgd78059 reg.gptwo_size_low = 0x10000;
5144135Sgd78059
5154135Sgd78059 if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
5164135Sgd78059 new_child, "reg", (int *)®,
5174135Sgd78059 sizeof (gptwo_regspec_t) / sizeof (int)) != DDI_SUCCESS) {
5184135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5194135Sgd78059 "to create reg property\n");
5204135Sgd78059 return (DDI_WALK_ERROR);
5214135Sgd78059 }
5224135Sgd78059
5234135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5244135Sgd78059 "icache-size", CH_ICACHE_SIZE) != DDI_SUCCESS) {
5254135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5264135Sgd78059 "to create icache-size property\n");
5274135Sgd78059 return (DDI_WALK_ERROR);
5284135Sgd78059 }
5294135Sgd78059
5304135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5314135Sgd78059 "icache-line-size", CH_ICACHE_LSIZE) != DDI_SUCCESS) {
5324135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5334135Sgd78059 "to create icache-line-size property\n");
5344135Sgd78059 return (DDI_WALK_ERROR);
5354135Sgd78059 }
5364135Sgd78059
5374135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5384135Sgd78059 "icache-associativity", CH_ICACHE_NWAY) != DDI_SUCCESS) {
5394135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5404135Sgd78059 "to create icache-associativity property\n");
5414135Sgd78059 return (DDI_WALK_ERROR);
5424135Sgd78059 }
5434135Sgd78059
5444135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5454135Sgd78059 "dcache-size", CH_DCACHE_SIZE) != DDI_SUCCESS) {
5464135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5474135Sgd78059 "to create dcache-size property\n");
5484135Sgd78059 return (DDI_WALK_ERROR);
5494135Sgd78059 }
5504135Sgd78059
5514135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5524135Sgd78059 "dcache-line-size", CH_DCACHE_LSIZE) != DDI_SUCCESS) {
5534135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5544135Sgd78059 "to create dcache-line-size property\n");
5554135Sgd78059 return (DDI_WALK_ERROR);
5564135Sgd78059 }
5574135Sgd78059
5584135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5594135Sgd78059 "dcache-associativity", CH_DCACHE_NWAY) != DDI_SUCCESS) {
5604135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5614135Sgd78059 "to create dcache-associativity property\n");
5624135Sgd78059 return (DDI_WALK_ERROR);
5634135Sgd78059 }
5644135Sgd78059
5654135Sgd78059 /*
5664135Sgd78059 * Get the External Cache Size from the Common PCD.
5674135Sgd78059 */
5684135Sgd78059 ecache_size = pcd->spcd_cache * 0x100000;
5694135Sgd78059
5704135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5714135Sgd78059 "ecache-size", ecache_size) != DDI_SUCCESS) {
5724135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5734135Sgd78059 "to create ecache-line-size property\n");
5744135Sgd78059 return (DDI_WALK_ERROR);
5754135Sgd78059 }
5764135Sgd78059
5774135Sgd78059 switch (ecache_size) {
5784135Sgd78059 case CH_ECACHE_1M_SIZE:
5794135Sgd78059 ecache_line_size = 64;
5804135Sgd78059 break;
5814135Sgd78059 case CH_ECACHE_4M_SIZE:
5824135Sgd78059 ecache_line_size = 256;
5834135Sgd78059 break;
5844135Sgd78059 case CH_ECACHE_8M_SIZE:
5854135Sgd78059 ecache_line_size = 512;
5864135Sgd78059 break;
5874135Sgd78059 default:
5884135Sgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us3_props: invalid "
5894135Sgd78059 "ecache-size 0x%x\b", ecache_size);
5904135Sgd78059 return (DDI_WALK_ERROR);
5914135Sgd78059 }
5924135Sgd78059
5934135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
5944135Sgd78059 "ecache-line-size", ecache_line_size) != DDI_SUCCESS) {
5954135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
5964135Sgd78059 "to create ecache-line-size property\n");
5974135Sgd78059 return (DDI_WALK_ERROR);
5984135Sgd78059 }
5994135Sgd78059
6004135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
6014135Sgd78059 "ecache-associativity", ecache_assoc) != DDI_SUCCESS) {
6024135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us3_props: failed "
6034135Sgd78059 "to create ecache-associativity property\n");
6044135Sgd78059 return (DDI_WALK_ERROR);
6054135Sgd78059 }
6064135Sgd78059
6074135Sgd78059 /*
6084135Sgd78059 * Create the ecache-dimm-label property.
6094135Sgd78059 */
6104135Sgd78059 dimms = 0;
6114135Sgd78059
6124135Sgd78059 while ((pcd->sprd_ecache_dimm_label[dimms] != NULL) &&
6134135Sgd78059 (dimms < MAX_DIMMS_PER_PORT))
6144135Sgd78059 dimms++;
6154135Sgd78059
6164135Sgd78059 if (dimms) {
6174135Sgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child,
6184135Sgd78059 "ecache-dimm-label", (char **)pcd->sprd_ecache_dimm_label,
6194135Sgd78059 dimms);
6204135Sgd78059 }
6214135Sgd78059
6224135Sgd78059 return (DDI_WALK_TERMINATE);
6234135Sgd78059 }
6244135Sgd78059
6254135Sgd78059 /*
6264135Sgd78059 * Set cmp core node properties for Jaguar and Panther.
6274135Sgd78059 *
6284135Sgd78059 * name
6294135Sgd78059 * compatible
6304135Sgd78059 * reg
6314135Sgd78059 * l1-icache-size
6324135Sgd78059 * l1-icache-line-size
6334135Sgd78059 * l1-icache-associativity
6344135Sgd78059 * l1-dcache-size
6354135Sgd78059 * l1-dcache-line-size
6364135Sgd78059 * l1-dcache-associativity
6374135Sgd78059 * l2-cache-size
6384135Sgd78059 * l2-cache-line-size
6394135Sgd78059 * l2-cache-associativity
6404135Sgd78059 * l2-cache-sharing
6414135Sgd78059 * l3-cache-size
6424135Sgd78059 * l3-cache-line-size
6434135Sgd78059 * l3-cache-associativity
6444135Sgd78059 * l3-cache-sharing
6454135Sgd78059 */
6464135Sgd78059 static int
set_cpu_us4_props(dev_info_t * new_child,struct bca * bcp)6474135Sgd78059 set_cpu_us4_props(dev_info_t *new_child, struct bca *bcp)
6484135Sgd78059 {
6494135Sgd78059 uint_t l1_icache_size, l1_icache_line_size;
6504135Sgd78059 uint_t l2_cache_size, l2_cache_line_size, l2_cache_assoc;
6514135Sgd78059 uint_t l2_cache_share;
6524135Sgd78059 uint_t pcd_cache_size;
6534135Sgd78059 uint_t coreid, impl;
6544135Sgd78059 spcd_t *pcd;
6554135Sgd78059 char *compatible;
6564135Sgd78059 int dimms;
6574135Sgd78059 int i;
6584135Sgd78059
6594135Sgd78059 pcd = bcp->pcd;
6604135Sgd78059 coreid = bcp->coreid;
6614135Sgd78059 impl = bcp->impl;
6624135Sgd78059
6634135Sgd78059 ASSERT(IS_JAGUAR(impl) || IS_PANTHER(impl));
6644135Sgd78059
6654135Sgd78059 /*
6664135Sgd78059 * Get the External Cache Size from the Common PCD.
6674135Sgd78059 */
6684135Sgd78059 pcd_cache_size = pcd->spcd_cache * 0x100000;
6694135Sgd78059
6704135Sgd78059 switch (impl) {
6714135Sgd78059 case JAGUAR_IMPL:
6724135Sgd78059 compatible = "SUNW,UltraSPARC-IV";
6734135Sgd78059 l1_icache_size = CH_ICACHE_SIZE;
6744135Sgd78059 l1_icache_line_size = CH_ICACHE_LSIZE;
6754135Sgd78059 l2_cache_assoc = CHP_ECACHE_NWAY;
6764135Sgd78059
6774135Sgd78059 /*
6784135Sgd78059 * Jaguar has no logical sharing of L2 cache, so the sharing
6794135Sgd78059 * bit-map will represent this core only.
6804135Sgd78059 */
6814135Sgd78059 l2_cache_share = coreid ? 0x2 : 0x1;
6824135Sgd78059
6834135Sgd78059 /*
6844135Sgd78059 * Jaguar has a split ecache, so the total ecache must be
6854135Sgd78059 * divided in half to get the ecache for the individual core.
6864135Sgd78059 */
6874135Sgd78059 l2_cache_size = pcd_cache_size / 2;
6884135Sgd78059
6894135Sgd78059 switch (l2_cache_size) {
6904135Sgd78059 case JG_ECACHE_4M_SIZE:
6914135Sgd78059 l2_cache_line_size = 64;
6924135Sgd78059 break;
6934135Sgd78059 case JG_ECACHE_8M_SIZE:
6944135Sgd78059 l2_cache_line_size = 128;
6954135Sgd78059 break;
6964135Sgd78059 default:
6974135Sgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us4_props: "
6984135Sgd78059 "invalid l2_cache-size 0x%x\n", l2_cache_size);
6994135Sgd78059 return (DDI_WALK_ERROR);
7004135Sgd78059 }
7014135Sgd78059 break;
7024135Sgd78059 case PANTHER_IMPL:
7034135Sgd78059 ASSERT(pcd_cache_size == PN_L3_SIZE);
7044135Sgd78059 compatible = "SUNW,UltraSPARC-IV+";
7054135Sgd78059 l1_icache_size = PN_ICACHE_SIZE;
7064135Sgd78059 l1_icache_line_size = PN_ICACHE_LSIZE;
7074135Sgd78059 l2_cache_size = PN_L2_SIZE;
7084135Sgd78059 l2_cache_line_size = PN_L2_LINESIZE;
7094135Sgd78059 l2_cache_assoc = PN_ECACHE_NWAY;
7104135Sgd78059
7114135Sgd78059 /*
7124135Sgd78059 * For Panther, the L2 and L3 caches are logically shared by
7134135Sgd78059 * all enabled cores, so the sharing bit-map will represent
7144135Sgd78059 * all enabled cores. Panther split-mode is still considered
7154135Sgd78059 * shared.
7164135Sgd78059 *
7174135Sgd78059 * Check the PCD status to determine enabled cores.
7184135Sgd78059 */
7194135Sgd78059 ASSERT(pcd->spcd_ptype == SAFPTYPE_CPU);
7204135Sgd78059 l2_cache_share = 0;
7214135Sgd78059 for (i = 0; i < AGENTS_PER_PORT; i++) {
7224135Sgd78059 if (pcd->spcd_agent[i] == SPCD_RSV_PASS) {
7234135Sgd78059 l2_cache_share |= (1 << i);
7244135Sgd78059 }
7254135Sgd78059 }
7264135Sgd78059
7274135Sgd78059 break;
7284135Sgd78059 default:
7294135Sgd78059 GPTWO_DEBUG1(1, CE_CONT, "set_cpu_us4_props: invalid "
7304135Sgd78059 "implementation=0x%x\n", impl);
7314135Sgd78059 return (DDI_WALK_ERROR);
7324135Sgd78059 }
7334135Sgd78059
7344135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
7354135Sgd78059 "name", "cpu") != DDI_SUCCESS) {
7364135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7374135Sgd78059 "to create name property\n");
7384135Sgd78059 return (DDI_WALK_ERROR);
7394135Sgd78059 }
7404135Sgd78059
7414135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
7424135Sgd78059 "compatible", compatible) != DDI_SUCCESS) {
7434135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7444135Sgd78059 "to create compatible property\n");
7454135Sgd78059 return (DDI_WALK_ERROR);
7464135Sgd78059 }
7474135Sgd78059
7484135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7494135Sgd78059 "reg", coreid) != DDI_SUCCESS) {
7504135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7514135Sgd78059 "to create reg property\n");
7524135Sgd78059 return (DDI_WALK_ERROR);
7534135Sgd78059 }
7544135Sgd78059
7554135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7564135Sgd78059 "l1-icache-size", l1_icache_size) != DDI_SUCCESS) {
7574135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7584135Sgd78059 "to create l1-icache-size property\n");
7594135Sgd78059 return (DDI_WALK_ERROR);
7604135Sgd78059 }
7614135Sgd78059
7624135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7634135Sgd78059 "l1-icache-line-size", l1_icache_line_size) != DDI_SUCCESS) {
7644135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7654135Sgd78059 "to create icache-line-size property\n");
7664135Sgd78059 return (DDI_WALK_ERROR);
7674135Sgd78059 }
7684135Sgd78059
7694135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7704135Sgd78059 "l1-icache-associativity", CH_ICACHE_NWAY) != DDI_SUCCESS) {
7714135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7724135Sgd78059 "to create l1-icache-associativity property\n");
7734135Sgd78059 return (DDI_WALK_ERROR);
7744135Sgd78059 }
7754135Sgd78059
7764135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7774135Sgd78059 "l1-dcache-size", CH_DCACHE_SIZE) != DDI_SUCCESS) {
7784135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7794135Sgd78059 "to create l1-dcache-size property\n");
7804135Sgd78059 return (DDI_WALK_ERROR);
7814135Sgd78059 }
7824135Sgd78059
7834135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7844135Sgd78059 "l1-dcache-line-size", CH_DCACHE_LSIZE) != DDI_SUCCESS) {
7854135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7864135Sgd78059 "to create dcache-line-size property\n");
7874135Sgd78059 return (DDI_WALK_ERROR);
7884135Sgd78059 }
7894135Sgd78059
7904135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7914135Sgd78059 "l1-dcache-associativity", CH_DCACHE_NWAY) != DDI_SUCCESS) {
7924135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
7934135Sgd78059 "to create l1-dcache-associativity property\n");
7944135Sgd78059 return (DDI_WALK_ERROR);
7954135Sgd78059 }
7964135Sgd78059
7974135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
7984135Sgd78059 "l2-cache-size", l2_cache_size) != DDI_SUCCESS) {
7994135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
8004135Sgd78059 "to create l2-cache-size property\n");
8014135Sgd78059 return (DDI_WALK_ERROR);
8024135Sgd78059 }
8034135Sgd78059
8044135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
8054135Sgd78059 "l2-cache-line-size", l2_cache_line_size) != DDI_SUCCESS) {
8064135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
8074135Sgd78059 "to create l2_cache-line-size property\n");
8084135Sgd78059 return (DDI_WALK_ERROR);
8094135Sgd78059 }
8104135Sgd78059
8114135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
8124135Sgd78059 "l2-cache-associativity", l2_cache_assoc) != DDI_SUCCESS) {
8134135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
8144135Sgd78059 "to create l2-cache-associativity property\n");
8154135Sgd78059 return (DDI_WALK_ERROR);
8164135Sgd78059 }
8174135Sgd78059
8184135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
8194135Sgd78059 "l2-cache-sharing", l2_cache_share) != DDI_SUCCESS) {
8204135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: failed "
8214135Sgd78059 "to create l2-cache-sharing property\n");
8224135Sgd78059 return (DDI_WALK_ERROR);
8234135Sgd78059 }
8244135Sgd78059
8254135Sgd78059 /*
8264135Sgd78059 * Create the ecache-dimm-label property.
8274135Sgd78059 */
8284135Sgd78059 dimms = 0;
8294135Sgd78059
8304135Sgd78059 while ((pcd->sprd_ecache_dimm_label[dimms] != NULL) &&
8314135Sgd78059 (dimms < MAX_DIMMS_PER_PORT))
8324135Sgd78059 dimms++;
8334135Sgd78059
8344135Sgd78059 if (dimms) {
8354135Sgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child,
8364135Sgd78059 "ecache-dimm-label", (char **)pcd->sprd_ecache_dimm_label,
8374135Sgd78059 dimms);
8384135Sgd78059 }
8394135Sgd78059
8404135Sgd78059 if (IS_PANTHER(impl)) {
8414135Sgd78059 int l3_cache_share = l2_cache_share;
8424135Sgd78059
8434135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
8444135Sgd78059 "l3-cache-size", PN_L3_SIZE) != DDI_SUCCESS) {
8454135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: "
8464135Sgd78059 "failed to create l3-cache-size property\n");
8474135Sgd78059 return (DDI_WALK_ERROR);
8484135Sgd78059 }
8494135Sgd78059
8504135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
8514135Sgd78059 "l3-cache-line-size", PN_L3_LINESIZE) != DDI_SUCCESS) {
8524135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: "
8534135Sgd78059 "failed to create l3-cache-line-size property\n");
8544135Sgd78059 return (DDI_WALK_ERROR);
8554135Sgd78059 }
8564135Sgd78059
8574135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
8584135Sgd78059 "l3-cache-associativity", PN_ECACHE_NWAY) != DDI_SUCCESS) {
8594135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: "
8604135Sgd78059 "failed to create l3-cache-associativity "
8614135Sgd78059 "property\n");
8624135Sgd78059 return (DDI_WALK_ERROR);
8634135Sgd78059 }
8644135Sgd78059
8654135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
8664135Sgd78059 "l3-cache-sharing", l3_cache_share) != DDI_SUCCESS) {
8674135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_cpu_us4_props: "
8684135Sgd78059 "failed to create l3-cache-sharing property\n");
8694135Sgd78059 return (DDI_WALK_ERROR);
8704135Sgd78059 }
8714135Sgd78059 }
8724135Sgd78059
8734135Sgd78059 return (DDI_WALK_TERMINATE);
8744135Sgd78059 }
8754135Sgd78059
8764135Sgd78059 static dev_info_t *
gptwocfg_create_mc_node(dev_info_t * ap,spcd_t * pcd,uint_t portid)8774135Sgd78059 gptwocfg_create_mc_node(dev_info_t *ap, spcd_t *pcd, uint_t portid)
8784135Sgd78059 {
8794135Sgd78059 struct bca arg;
8804135Sgd78059 devi_branch_t b = {0};
8814135Sgd78059
8824135Sgd78059 arg.pcd = pcd;
8834135Sgd78059 arg.portid = portid;
8844135Sgd78059 arg.cpuid = portid;
8854135Sgd78059 arg.new_child = NULL;
8864135Sgd78059
8874135Sgd78059 b.arg = &arg;
8884135Sgd78059 b.type = DEVI_BRANCH_SID;
8894135Sgd78059 b.create.sid_branch_create = set_mc_props;
8904135Sgd78059 b.devi_branch_callback = get_new_child;
8914135Sgd78059
8924135Sgd78059 if (e_ddi_branch_create(ap, &b, NULL, 0))
8934135Sgd78059 return (NULL);
8944135Sgd78059
8954135Sgd78059 return (arg.new_child);
8964135Sgd78059 }
8974135Sgd78059
8984135Sgd78059 /*ARGSUSED*/
8994135Sgd78059 static int
set_mc_props(dev_info_t * new_child,void * arg,uint_t flags)9004135Sgd78059 set_mc_props(dev_info_t *new_child, void *arg, uint_t flags)
9014135Sgd78059 {
9024135Sgd78059 struct bca *bcp = arg;
9034135Sgd78059 gptwo_regspec_t reg;
9044135Sgd78059 int banks, dimms;
9054135Sgd78059 spcd_t *pcd = bcp->pcd;
9064135Sgd78059 uint_t portid = bcp->portid;
9074135Sgd78059 uint_t cpuid = bcp->cpuid;
9084135Sgd78059
9094135Sgd78059 GPTWO_DEBUG3(1, CE_CONT, "set_mc_props: ap=0x%lx portid=0x%x "
9104135Sgd78059 "cpuid=0x%x\n", ddi_get_parent(new_child), portid, cpuid);
9114135Sgd78059
9124135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
9134135Sgd78059 "name", "memory-controller") != DDI_SUCCESS) {
9144135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed "
9154135Sgd78059 "to create name property\n");
9164135Sgd78059 return (DDI_WALK_ERROR);
9174135Sgd78059 }
9184135Sgd78059
9194135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
9204135Sgd78059 "compatible", "SUNW,UltraSPARC-III,mc") != DDI_SUCCESS) {
9214135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed "
9224135Sgd78059 "to create compatible property\n");
9234135Sgd78059 return (DDI_WALK_ERROR);
9244135Sgd78059 }
9254135Sgd78059
9264135Sgd78059 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
9274135Sgd78059 "device_type", "memory-controller") != DDI_SUCCESS) {
9284135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed "
9294135Sgd78059 "to create device_type property\n");
9304135Sgd78059 return (DDI_WALK_ERROR);
9314135Sgd78059 }
9324135Sgd78059
9334135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
9344135Sgd78059 "portid", portid) != DDI_SUCCESS) {
9354135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed "
9364135Sgd78059 "to create portid property\n");
9374135Sgd78059 return (DDI_WALK_ERROR);
9384135Sgd78059 }
9394135Sgd78059
9404135Sgd78059 if (ndi_prop_update_int(DDI_DEV_T_NONE, new_child,
9414135Sgd78059 "cpuid", cpuid) != DDI_SUCCESS) {
9424135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed "
9434135Sgd78059 "to create cpuid property\n");
9444135Sgd78059 return (DDI_WALK_ERROR);
9454135Sgd78059 }
9464135Sgd78059
9474135Sgd78059 reg.gptwo_phys_hi = 0x400 | (portid >> 9);
9484135Sgd78059 reg.gptwo_phys_low = (portid << 23) | 0x400000;
9494135Sgd78059 reg.gptwo_size_hi = 0;
9504135Sgd78059 reg.gptwo_size_low = 0x48;
9514135Sgd78059
9524135Sgd78059 if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
9534135Sgd78059 new_child, "reg", (int *)®,
9544135Sgd78059 sizeof (gptwo_regspec_t) / sizeof (int)) != DDI_SUCCESS) {
9554135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed "
9564135Sgd78059 "to create reg property\n");
9574135Sgd78059 return (DDI_WALK_ERROR);
9584135Sgd78059 }
9594135Sgd78059
9604135Sgd78059 if (pcd->memory_layout) {
9614135Sgd78059 if (ndi_prop_update_byte_array(DDI_DEV_T_NONE,
9624135Sgd78059 new_child, "memory-layout", (uchar_t *)pcd->memory_layout,
9634135Sgd78059 pcd->memory_layout_size) != DDI_SUCCESS) {
9644135Sgd78059
9654135Sgd78059 GPTWO_DEBUG0(1, CE_CONT, "set_mc_props: failed "
9664135Sgd78059 "to create memory-layout property\n");
9674135Sgd78059
9684135Sgd78059 return (DDI_WALK_ERROR);
9694135Sgd78059 }
9704135Sgd78059 }
9714135Sgd78059
9724135Sgd78059 /*
9734135Sgd78059 * Create the bank-status property.
9744135Sgd78059 */
9754135Sgd78059 banks = 0;
9764135Sgd78059
9774135Sgd78059 while ((pcd->sprd_bank_rsv[banks] != NULL) &&
9784135Sgd78059 (banks < MAX_BANKS_PER_PORT))
9794135Sgd78059 banks++;
9804135Sgd78059
9814135Sgd78059 if (banks) {
9824135Sgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child,
9834135Sgd78059 "bank-status", (char **)pcd->sprd_bank_rsv, banks);
9844135Sgd78059 }
9854135Sgd78059
9864135Sgd78059 /*
9874135Sgd78059 * Create the dimm-status property.
9884135Sgd78059 */
9894135Sgd78059 dimms = 0;
9904135Sgd78059
9914135Sgd78059 while ((pcd->sprd_dimm[dimms] != NULL) &&
9924135Sgd78059 (dimms < MAX_DIMMS_PER_PORT))
9934135Sgd78059 dimms++;
9944135Sgd78059
9954135Sgd78059 if (dimms) {
9964135Sgd78059 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, new_child,
9974135Sgd78059 "dimm-status", (char **)pcd->sprd_dimm, dimms);
9984135Sgd78059 }
9994135Sgd78059
10004135Sgd78059
10014135Sgd78059 return (DDI_WALK_TERMINATE);
10024135Sgd78059 }
10034135Sgd78059
10044135Sgd78059 /*ARGSUSED*/
10054135Sgd78059 static void
get_new_child(dev_info_t * rdip,void * arg,uint_t flags)10064135Sgd78059 get_new_child(dev_info_t *rdip, void *arg, uint_t flags)
10074135Sgd78059 {
10084135Sgd78059 struct bca *bcp = arg;
10094135Sgd78059
10104135Sgd78059 bcp->new_child = rdip;
10114135Sgd78059
10124135Sgd78059 }
10134135Sgd78059
10144135Sgd78059 #ifdef DEBUG
10154135Sgd78059 static void
debug(char * fmt,uintptr_t a1,uintptr_t a2,uintptr_t a3,uintptr_t a4,uintptr_t a5)10164135Sgd78059 debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3,
10174135Sgd78059 uintptr_t a4, uintptr_t a5)
10184135Sgd78059 {
10194135Sgd78059 cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5);
10204135Sgd78059 }
10214135Sgd78059 #endif
1022