xref: /onnv-gate/usr/src/uts/sun4u/io/gptwo_cpu.c (revision 7696:21f5c73c0c15)
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 *)&reg,
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 *)&reg,
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 *)&reg,
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