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