11708Sstevel /*
21708Sstevel * CDDL HEADER START
31708Sstevel *
41708Sstevel * The contents of this file are subject to the terms of the
51708Sstevel * Common Development and Distribution License (the "License").
61708Sstevel * You may not use this file except in compliance with the License.
71708Sstevel *
81708Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91708Sstevel * or http://www.opensolaris.org/os/licensing.
101708Sstevel * See the License for the specific language governing permissions
111708Sstevel * and limitations under the License.
121708Sstevel *
131708Sstevel * When distributing Covered Code, include this CDDL HEADER in each
141708Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151708Sstevel * If applicable, add the following below this CDDL HEADER, with the
161708Sstevel * fields enclosed by brackets "[]" replaced with your own identifying
171708Sstevel * information: Portions Copyright [yyyy] [name of copyright owner]
181708Sstevel *
191708Sstevel * CDDL HEADER END
201708Sstevel */
211708Sstevel
221708Sstevel /*
23*11311SSurya.Prakki@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
241708Sstevel * Use is subject to license terms.
251708Sstevel */
261708Sstevel
271708Sstevel /*
281708Sstevel * Starcat Specific Glue for Safari Configurator
291708Sstevel */
301708Sstevel
311708Sstevel #include <sys/isa_defs.h>
321708Sstevel #include <sys/conf.h>
331708Sstevel #include <sys/kmem.h>
341708Sstevel #include <sys/debug.h>
351708Sstevel #include <sys/modctl.h>
361708Sstevel #include <sys/autoconf.h>
371708Sstevel #include <sys/hwconf.h>
381708Sstevel #include <sys/ddi_impldefs.h>
391708Sstevel #include <sys/ddi.h>
401708Sstevel #include <sys/sunddi.h>
411708Sstevel #include <sys/sunndi.h>
421708Sstevel #include <sys/ndi_impldefs.h>
431708Sstevel #include <sys/safari_pcd.h>
441708Sstevel #include <sys/gp2cfg.h>
451708Sstevel #include <sys/gptwo_cpu.h>
461708Sstevel #include <sys/gptwo_pci.h>
471708Sstevel #include <sys/sc_gptwocfg.h>
481708Sstevel #include <post/scat_dcd.h>
491708Sstevel #include <sys/machsystm.h>
501708Sstevel
511708Sstevel int sc_gptwocfg_debug = 0;
521708Sstevel
531708Sstevel #define SC_DEBUG(level, args) if (sc_gptwocfg_debug >= level) cmn_err args
541708Sstevel
551708Sstevel typedef struct sc_gptwocfg_config {
561708Sstevel int board;
571708Sstevel struct gptwocfg_config *port_cookie;
581708Sstevel gptwo_aid_t portid;
591708Sstevel struct sc_gptwocfg_config *link;
601708Sstevel struct sc_gptwocfg_config *next;
611708Sstevel } sc_gptwocfg_config_t;
621708Sstevel
631708Sstevel static kmutex_t sc_gptwo_config_list_lock;
641708Sstevel static sc_gptwocfg_config_t *sc_gptwo_config_list;
651708Sstevel static dev_info_t *sc_find_axq_node(uint_t);
661708Sstevel static sc_gptwocfg_cookie_t sc_configure(uint_t, int);
671708Sstevel static spcd_t *sc_get_common_pcd(uint_t, uint_t);
681708Sstevel static void sc_free_common_pcd(spcd_t *);
691708Sstevel static gptwo_new_nodes_t *sc_gptwocfg_configure_axq(dev_info_t *, uint_t, int);
701708Sstevel static gptwocfg_config_t *sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *);
711708Sstevel static void dump_config(sc_gptwocfg_config_t *);
721708Sstevel static void dump_pcd(spcd_t *);
731708Sstevel static uint_t sc_get_agent_id(spcd_t *, uint_t, uint_t, uint_t);
741708Sstevel static char *rsv_string(prdrsv_t);
751708Sstevel
761708Sstevel extern gptwo_new_nodes_t *gptwocfg_allocate_node_list(int);
771708Sstevel extern void gptwocfg_free_node_list(gptwo_new_nodes_t *);
781708Sstevel
791708Sstevel static uint8_t *get_memlayout(uint32_t, uint32_t *);
801708Sstevel
811708Sstevel #ifdef NO_IOSRAM
821708Sstevel int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t);
831708Sstevel #else
841708Sstevel extern int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t);
851708Sstevel #endif
861708Sstevel extern void gptwocfg_devi_attach_to_parent(dev_info_t *);
871708Sstevel
881708Sstevel /*
891708Sstevel * Module control operations
901708Sstevel */
911708Sstevel
921708Sstevel extern struct mod_ops mod_miscops;
931708Sstevel
941708Sstevel static struct modlmisc modlmisc = {
951708Sstevel &mod_miscops, /* Type of module */
967799SRichard.Bean@Sun.COM "Sun Fire 15000 gptwocfg"
971708Sstevel };
981708Sstevel
991708Sstevel static struct modlinkage modlinkage = {
1001708Sstevel MODREV_1, (void *)&modlmisc, NULL
1011708Sstevel };
1021708Sstevel
1031708Sstevel int
_init()1041708Sstevel _init()
1051708Sstevel {
1061708Sstevel int err = 0;
1071708Sstevel
1081708Sstevel mutex_init(&sc_gptwo_config_list_lock, NULL, MUTEX_DRIVER, NULL);
1091708Sstevel sc_gptwo_config_list = NULL;
1101708Sstevel
1111708Sstevel /*
1121708Sstevel * CPU/PCI devices are already registered by their respective modules,
1131708Sstevel * so all we need to do now is install.
1141708Sstevel */
1151708Sstevel if ((err = mod_install(&modlinkage)) != 0) {
1161708Sstevel SC_DEBUG(1, (CE_WARN, "sc_gptwocfg failed to load, error=%d\n",
1177799SRichard.Bean@Sun.COM err));
1181708Sstevel mutex_destroy(&sc_gptwo_config_list_lock);
1191708Sstevel } else {
1201708Sstevel SC_DEBUG(1, (CE_WARN, "sc_gptwocfg has been loaded.\n"));
1211708Sstevel }
1221708Sstevel return (err);
1231708Sstevel }
1241708Sstevel
1251708Sstevel int
_fini(void)1261708Sstevel _fini(void)
1271708Sstevel {
1281708Sstevel mutex_destroy(&sc_gptwo_config_list_lock);
1291708Sstevel return (mod_remove(&modlinkage));
1301708Sstevel }
1311708Sstevel
1321708Sstevel int
_info(modinfop)1331708Sstevel _info(modinfop)
1341708Sstevel struct modinfo *modinfop;
1351708Sstevel {
1361708Sstevel return (mod_info(&modlinkage, modinfop));
1371708Sstevel }
1381708Sstevel
1391708Sstevel static spcd_t *
sc_get_common_pcd(uint_t expander,uint_t prd_slot)1401708Sstevel sc_get_common_pcd(uint_t expander, uint_t prd_slot)
1411708Sstevel {
1421708Sstevel spcd_t *pcd;
1431708Sstevel gdcd_t *gdcd;
1441708Sstevel int portid;
1451708Sstevel int i, j, slot;
1461708Sstevel int dimm;
1471708Sstevel char *label1, *label2;
1481708Sstevel
1491708Sstevel SC_DEBUG(1, (CE_WARN, "sc_get_common_pcd() expander=%d prd_slot=%d\n",
1501708Sstevel expander, prd_slot));
1511708Sstevel
1521708Sstevel gdcd = (gdcd_t *)kmem_zalloc(sizeof (gdcd_t), KM_SLEEP);
1531708Sstevel
1541708Sstevel /*
1551708Sstevel * Get the Starcat Specific Global DCD Structure from the golden
1561708Sstevel * IOSRAM.
1571708Sstevel */
1581708Sstevel if (iosram_rd(GDCD_MAGIC, 0, sizeof (gdcd_t), (caddr_t)gdcd)) {
1591708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: Unable To Read GDCD "
1601708Sstevel "From IOSRAM\n");
1611708Sstevel kmem_free(gdcd, sizeof (gdcd_t));
1621708Sstevel return (NULL);
1631708Sstevel }
1641708Sstevel
1651708Sstevel if (gdcd->h.dcd_magic != GDCD_MAGIC) {
1661708Sstevel
1671708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Magic 0x%x\n",
1681708Sstevel gdcd->h.dcd_magic);
1691708Sstevel
1701708Sstevel kmem_free(gdcd, sizeof (gdcd_t));
1711708Sstevel return (NULL);
1721708Sstevel }
1731708Sstevel
1741708Sstevel if (gdcd->h.dcd_version != DCD_VERSION) {
1751708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Version: "
1761708Sstevel "GDCD Version 0x%x Expecting 0x%x\n",
1771708Sstevel gdcd->h.dcd_version, DCD_VERSION);
1781708Sstevel
1791708Sstevel kmem_free(gdcd, sizeof (gdcd_t));
1801708Sstevel return (NULL);
1811708Sstevel }
1821708Sstevel
1831708Sstevel pcd = (spcd_t *)kmem_zalloc(sizeof (spcd_t), KM_SLEEP);
1841708Sstevel
1851708Sstevel /*
1861708Sstevel * Copy various information from the platform specific Port
1871708Sstevel * Resource Descriptor (PRD) To the platform independent
1881708Sstevel * Port Configuration Descriptor.
1891708Sstevel */
1901708Sstevel pcd->spcd_magic = PCD_MAGIC;
1911708Sstevel pcd->spcd_version = PCD_VERSION;
1921708Sstevel pcd->spcd_ptype = gdcd->dcd_prd[expander][prd_slot].prd_ptype;
1931708Sstevel pcd->spcd_ver_reg = gdcd->dcd_prd[expander][prd_slot].prd_ver_reg;
1941708Sstevel
1951708Sstevel if (pcd->spcd_ptype == SAFPTYPE_CPU) {
1961708Sstevel /*
1971708Sstevel * This will calculate the cpu speed based on the
1981708Sstevel * the actual frequency ratio * interconnect frequency
1991708Sstevel * converted to Mhz.
2001708Sstevel */
2011708Sstevel pcd->spcd_afreq = gdcd->dcd_prd[expander][prd_slot].
2021708Sstevel prd_afreq_ratio *
2031708Sstevel (uint16_t)((gdcd->dcd_intercon_freq + 500000) / 1000000);
2041708Sstevel } else {
2051708Sstevel /*
2061708Sstevel * For non-cpu devices, just pass through the frequency
2071708Sstevel * unchanged.
2081708Sstevel */
2091708Sstevel pcd->spcd_afreq =
2101708Sstevel gdcd->dcd_prd[expander][prd_slot].prd_afreq_ratio;
2111708Sstevel }
2121708Sstevel
2131708Sstevel pcd->spcd_cache = gdcd->dcd_prd[expander][prd_slot].prd_cache;
2141708Sstevel
2151708Sstevel SC_DEBUG(1, (CE_WARN, "Safari Device Status status=0x%x\n",
2161708Sstevel gdcd->dcd_prd[expander][prd_slot].prd_prsv));
2171708Sstevel
2181708Sstevel /*
2191708Sstevel * Fill in the entire port status.
2201708Sstevel */
2211708Sstevel if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot].prd_prsv)) {
2221708Sstevel pcd->spcd_prsv = SPCD_RSV_PASS;
2231708Sstevel } else {
2241708Sstevel pcd->spcd_prsv = SPCD_RSV_FAIL;
2251708Sstevel }
2261708Sstevel
2271708Sstevel /*
2281708Sstevel * Fill in the per agent status.
2291708Sstevel */
2301708Sstevel if (gdcd->dcd_prd[expander][prd_slot].prd_agent[1] == RSV_UNKNOWN) {
2311708Sstevel pcd->spcd_agent[0] = pcd->spcd_prsv;
2321708Sstevel pcd->spcd_agent[1] = SPCD_RSV_FAIL;
2331708Sstevel } else {
2341708Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) {
2351708Sstevel
2361708Sstevel if (RSV_GOOD(
2371708Sstevel gdcd->dcd_prd[expander][prd_slot].prd_agent[i]))
2381708Sstevel pcd->spcd_agent[i] = SPCD_RSV_PASS;
2391708Sstevel else
2401708Sstevel pcd->spcd_agent[i] = SPCD_RSV_FAIL;
2411708Sstevel }
2421708Sstevel }
2431708Sstevel
2441708Sstevel /*
2451708Sstevel * If this is a CPU device calculate the cpuid for it. For Starcat
2461708Sstevel * the cpuid is in the following format.
2471708Sstevel *
2481708Sstevel * EEEEEPPAPP
2491708Sstevel *
2501708Sstevel * where: EEEEE is the expander
2511708Sstevel * PP_PP is the portid
2521708Sstevel * __A__ is the sub-agent identifier.
2531708Sstevel */
2541708Sstevel if (pcd->spcd_ptype == SAFPTYPE_CPU) {
2551708Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) {
2561708Sstevel switch (prd_slot) {
2571708Sstevel case 0:
2581708Sstevel case 1:
2591708Sstevel case 2:
2601708Sstevel case 3:
2611708Sstevel portid = (expander << 5) | prd_slot;
2621708Sstevel break;
2631708Sstevel case 4: /* Maxcat */
2641708Sstevel portid = (expander << 5) | 8;
2651708Sstevel break;
2661708Sstevel case 5: /* Maxcat */
2671708Sstevel portid = (expander << 5) | 9;
2681708Sstevel break;
2691708Sstevel default:
2701708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: invalid "
2711708Sstevel "prd_slot=%d\n", prd_slot);
2721708Sstevel }
2731708Sstevel pcd->spcd_cpuid[i] = (i << 2) | portid;
2741708Sstevel }
2751708Sstevel }
2761708Sstevel
2771708Sstevel /*
2781708Sstevel * Starcat does not have ports with UPA devices so
2791708Sstevel * spcd_upadev structure will not be filled in.
2801708Sstevel */
2811708Sstevel
2821708Sstevel /*
2831708Sstevel * Fill in IO Bus Status
2841708Sstevel */
2851708Sstevel for (i = 0; i < IOBUS_PER_PORT; i++) {
2861708Sstevel
2871708Sstevel SC_DEBUG(1, (CE_WARN, " IO Bus Status "
2881708Sstevel "bus=%d status=0x%x\n", i,
2891708Sstevel gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i]));
2901708Sstevel
2911708Sstevel if (RSV_GOOD(
2921708Sstevel gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i])) {
2931708Sstevel pcd->spcd_iobus_rsv[i] = SPCD_RSV_PASS;
2941708Sstevel } else {
2951708Sstevel pcd->spcd_iobus_rsv[i] = SPCD_RSV_FAIL;
2961708Sstevel }
2971708Sstevel
2981708Sstevel for (j = 0; j < IOCARD_PER_BUS; j++)
2991708Sstevel pcd->spcd_iocard_rsv[i][j] = SPCD_RSV_FAIL;
3001708Sstevel
3011708Sstevel /*
3021708Sstevel * Fill in IO Card Status
3031708Sstevel */
3041708Sstevel for (j = 0; j < IOCARD_PER_BUS; j++) {
3051708Sstevel
3061708Sstevel SC_DEBUG(1, (CE_WARN, " Card Status bus=%d "
3071708Sstevel "slot=%d status=0x%x\n", i, j,
3081708Sstevel gdcd->dcd_prd[expander][prd_slot].
3091708Sstevel prd_iocard_rsv[i][j]));
3101708Sstevel
3111708Sstevel if (j == 1)
3121708Sstevel continue;
3131708Sstevel
3141708Sstevel if (j == 0)
3151708Sstevel slot = 1;
3161708Sstevel else
3171708Sstevel slot = j;
3181708Sstevel
3191708Sstevel /*
3201708Sstevel * If POST marked the card as GOOD or if the slot
3211708Sstevel * is empty, we want to probe for the device.
3221708Sstevel */
3231708Sstevel if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot].
3241708Sstevel prd_iocard_rsv[i][j]) ||
3251708Sstevel (gdcd->dcd_prd[expander][prd_slot].
3261708Sstevel prd_iocard_rsv[i][j] == RSV_MISS) ||
3271708Sstevel (gdcd->dcd_prd[expander][prd_slot].
3281708Sstevel prd_iocard_rsv[i][j] == RSV_EMPTY_CASSETTE))
3291708Sstevel pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_PASS;
3301708Sstevel else
3311708Sstevel pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_FAIL;
3321708Sstevel }
3331708Sstevel }
3341708Sstevel
3351708Sstevel /*
3361708Sstevel * Fill in WIC Link Status
3371708Sstevel */
3381708Sstevel for (i = 0; i < LINKS_PER_PORT; i++) {
3391708Sstevel if (RSV_GOOD(
3401708Sstevel gdcd->dcd_prd[expander][prd_slot].prd_wic_links[i])) {
3411708Sstevel pcd->spcd_wic_links[i] = SPCD_RSV_PASS;
3421708Sstevel
3431708Sstevel } else {
3441708Sstevel pcd->spcd_wic_links[i] = SPCD_RSV_FAIL;
3451708Sstevel }
3461708Sstevel }
3471708Sstevel
3481708Sstevel /*
3491708Sstevel * Get data for the "bank-status" property.
3501708Sstevel */
3511708Sstevel pcd->sprd_bank_rsv[0] =
3521708Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][0]);
3531708Sstevel pcd->sprd_bank_rsv[1] =
3541708Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][0]);
3551708Sstevel pcd->sprd_bank_rsv[2] =
3561708Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][1]);
3571708Sstevel pcd->sprd_bank_rsv[3] =
3581708Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][1]);
3591708Sstevel
3601708Sstevel dimm = 0;
3611708Sstevel for (i = 0; i < PMBANKS_PER_PORT; i++) {
3621708Sstevel for (j = 0; j < DIMMS_PER_PMBANK; j++) {
3631708Sstevel if (dimm < MAX_DIMMS_PER_PORT) {
3641708Sstevel pcd->sprd_dimm[dimm] = rsv_string(
3651708Sstevel gdcd->dcd_prd[expander][prd_slot].
3661708Sstevel prd_dimm[i][j]);
3671708Sstevel dimm++;
3681708Sstevel }
3691708Sstevel }
3701708Sstevel }
3711708Sstevel
3721708Sstevel /*
3731708Sstevel * Get data for the "ecache-dimm-label" property.
3741708Sstevel *
3751708Sstevel * Right now it is hardcoded, but we should eventually get this
3761708Sstevel * from the SC.
3771708Sstevel */
3781708Sstevel label1 = NULL;
3791708Sstevel label2 = NULL;
3801708Sstevel
3811708Sstevel switch (prd_slot) {
3821708Sstevel case 0:
3831708Sstevel label1 = "4400";
3841708Sstevel label2 = "4300";
3851708Sstevel break;
3861708Sstevel case 1:
3871708Sstevel label1 = "5400";
3881708Sstevel label2 = "5300";
3891708Sstevel break;
3901708Sstevel case 2:
3911708Sstevel label1 = "6400";
3921708Sstevel label2 = "6300";
3931708Sstevel break;
3941708Sstevel case 3:
3951708Sstevel label1 = "7400";
3961708Sstevel label2 = "7300";
3971708Sstevel break;
3981708Sstevel
3991708Sstevel /*
4001708Sstevel * Maxcat labels.
4011708Sstevel */
4021708Sstevel case 4:
4031708Sstevel label1 = "6400";
4041708Sstevel label2 = "6300";
4051708Sstevel break;
4061708Sstevel case 5:
4071708Sstevel label1 = "7400";
4081708Sstevel label2 = "7300";
4091708Sstevel break;
4101708Sstevel }
4111708Sstevel
4121708Sstevel i = 0;
4131708Sstevel if (label1) {
4141708Sstevel pcd->sprd_ecache_dimm_label[i] =
4151708Sstevel kmem_alloc(strlen(label1) + 1, KM_SLEEP);
4161708Sstevel
4171708Sstevel (void) strcpy(pcd->sprd_ecache_dimm_label[i], label1);
4181708Sstevel
4191708Sstevel i++;
4201708Sstevel }
4211708Sstevel if (label2) {
4221708Sstevel pcd->sprd_ecache_dimm_label[i] =
4231708Sstevel kmem_alloc(strlen(label2) + 1, KM_SLEEP);
4241708Sstevel
4251708Sstevel (void) strcpy(pcd->sprd_ecache_dimm_label[i], label2);
4261708Sstevel
4271708Sstevel i++;
4281708Sstevel
4291708Sstevel }
4301708Sstevel
4311708Sstevel kmem_free(gdcd, sizeof (gdcd_t));
4321708Sstevel
4331708Sstevel #ifdef DEBUG
4341708Sstevel dump_pcd(pcd);
4351708Sstevel #endif
4361708Sstevel
4371708Sstevel return (pcd);
4381708Sstevel }
4391708Sstevel
4401708Sstevel void
sc_free_common_pcd(spcd_t * pcd)4411708Sstevel sc_free_common_pcd(spcd_t *pcd)
4421708Sstevel {
4431708Sstevel int i;
4441708Sstevel
445*11311SSurya.Prakki@Sun.COM SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd pcd=%p\n", (void *)pcd));
4461708Sstevel
4471708Sstevel if (pcd->memory_layout && pcd->memory_layout_size) {
4481708Sstevel SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd: memory_layout %p "
449*11311SSurya.Prakki@Sun.COM "size=%x", (void *)pcd->memory_layout,
450*11311SSurya.Prakki@Sun.COM pcd->memory_layout_size));
4511708Sstevel kmem_free(pcd->memory_layout, pcd->memory_layout_size);
4521708Sstevel }
4531708Sstevel
4541708Sstevel for (i = 0; i < MAX_BANKS_PER_PORT; i++) {
4551708Sstevel if (pcd->sprd_bank_rsv[i]) {
4561708Sstevel kmem_free(pcd->sprd_bank_rsv[i],
4571708Sstevel strlen(pcd->sprd_bank_rsv[i]) + 1);
4581708Sstevel
4591708Sstevel pcd->sprd_bank_rsv[i] = NULL;
4601708Sstevel }
4611708Sstevel }
4621708Sstevel
4631708Sstevel for (i = 0; i < MAX_DIMMS_PER_PORT; i++) {
4641708Sstevel if (pcd->sprd_dimm[i]) {
4651708Sstevel kmem_free(pcd->sprd_dimm[i],
4661708Sstevel strlen(pcd->sprd_dimm[i]) + 1);
4671708Sstevel
4681708Sstevel pcd->sprd_dimm[i] = NULL;
4691708Sstevel }
4701708Sstevel if (pcd->sprd_ecache_dimm_label[i]) {
4711708Sstevel kmem_free(pcd->sprd_ecache_dimm_label[i],
4721708Sstevel strlen(pcd->sprd_ecache_dimm_label[i]) + 1);
4731708Sstevel
4741708Sstevel pcd->sprd_ecache_dimm_label[i] = NULL;
4751708Sstevel }
4761708Sstevel }
4771708Sstevel
4781708Sstevel kmem_free(pcd, sizeof (spcd_t));
4791708Sstevel }
4801708Sstevel
4811708Sstevel sc_gptwocfg_cookie_t
sc_probe_board(uint_t board)4821708Sstevel sc_probe_board(uint_t board)
4831708Sstevel {
4841708Sstevel return (sc_configure(board, 1));
4851708Sstevel }
4861708Sstevel
4871708Sstevel static sc_gptwocfg_cookie_t
sc_configure(uint_t board,int create_nodes)4881708Sstevel sc_configure(uint_t board, int create_nodes)
4891708Sstevel {
4901708Sstevel spcd_t *pcd;
4911708Sstevel dev_info_t *ap, *axq_dip;
4921708Sstevel uint_t agent_id;
4931708Sstevel uint_t prd_slot, prd_slot_start, prd_slot_end;
4941708Sstevel uint_t expander, slot;
4951708Sstevel gptwo_new_nodes_t *new_nodes;
4961708Sstevel gptwocfg_config_t *port_cookie;
4971708Sstevel struct sc_gptwocfg_config *board_config, *last, *new;
4981708Sstevel int created_node = 0;
4991708Sstevel uint32_t size;
5001708Sstevel
5011708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: board=%d, create_nodes=%d\n",
5027799SRichard.Bean@Sun.COM board, create_nodes));
5031708Sstevel
5041708Sstevel if (board > 35) {
5051708Sstevel SC_DEBUG(1, (CE_WARN, "sc_gptwocfg - probe_board - "
5061708Sstevel "invalid board 0x%x\n", board));
5071708Sstevel return (NULL);
5081708Sstevel }
5091708Sstevel
5101708Sstevel slot = board & 1; /* Extract Slot Number */
5111708Sstevel expander = board >> 1; /* Extract Expander Number */
5121708Sstevel
5131708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: exp=0x%x slot=0x%x\n",
5141708Sstevel expander, slot));
5151708Sstevel
5161708Sstevel /*
5171708Sstevel * Get the Attachment Point. For Starcat the parent of all
5181708Sstevel * Safari children is root node.
5191708Sstevel */
5201708Sstevel ap = ddi_root_node();
5211708Sstevel
5221708Sstevel /*
5231708Sstevel * Get the agent id of the AXQ.
5241708Sstevel */
5251708Sstevel agent_id = (expander << 5) | 0x1e | slot;
5261708Sstevel
5271708Sstevel /*
5281708Sstevel * Look to see if the board is already configured by searching for
5291708Sstevel * its AXQ.
5301708Sstevel */
5311708Sstevel if (create_nodes && (axq_dip = sc_find_axq_node(agent_id))) {
5321708Sstevel ddi_release_devi(axq_dip);
5331708Sstevel cmn_err(CE_WARN, "Board %d AXQ is already configured\n",
5341708Sstevel board);
5351708Sstevel return (NULL);
5361708Sstevel }
5371708Sstevel
5381708Sstevel /*
5391708Sstevel * Probe AXQ first
5401708Sstevel */
5411708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Probing AXQ exp=0x%x brd=0x%x\n",
5421708Sstevel expander, slot));
5431708Sstevel
5441708Sstevel /*
5451708Sstevel * The generic gptwocfg does not support the AXQ, so we need
5461708Sstevel * to configure it. The AXQ branch is returned held.
5471708Sstevel */
5481708Sstevel new_nodes = sc_gptwocfg_configure_axq(ap, agent_id, create_nodes);
5491708Sstevel
5501708Sstevel if (new_nodes == NULL) {
5511708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Can not probe AXQ\n"));
5521708Sstevel return (NULL);
5531708Sstevel }
5541708Sstevel
5551708Sstevel port_cookie = kmem_zalloc(sizeof (gptwocfg_config_t), KM_SLEEP);
5561708Sstevel
5571708Sstevel /*
5581708Sstevel * Build a cookie for the AXQ.
5591708Sstevel */
5601708Sstevel port_cookie->gptwo_ap = ap;
5611708Sstevel port_cookie->gptwo_portid = agent_id;
5621708Sstevel port_cookie->gptwo_nodes = new_nodes;
5631708Sstevel
5641708Sstevel board_config = kmem_zalloc(sizeof (sc_gptwocfg_config_t), KM_SLEEP);
5651708Sstevel
5661708Sstevel board_config->port_cookie = port_cookie;
5671708Sstevel board_config->board = board;
5681708Sstevel board_config->portid = agent_id;
5691708Sstevel board_config->link = NULL;
5701708Sstevel last = board_config;
5711708Sstevel
5721708Sstevel mutex_enter(&sc_gptwo_config_list_lock);
5731708Sstevel board_config->next = sc_gptwo_config_list;
5741708Sstevel sc_gptwo_config_list = board_config;
5751708Sstevel mutex_exit(&sc_gptwo_config_list_lock);
5761708Sstevel
5771708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: AXQ Probing Complete. "
5781708Sstevel "%d nodes added\n", new_nodes->gptwo_number_of_nodes));
5791708Sstevel
5801708Sstevel /*
5811708Sstevel * Determine the starting ending slots of the PRD array.
5821708Sstevel */
5831708Sstevel switch (slot) {
5841708Sstevel case 0: /* Full Bandwidth Slot */
5851708Sstevel prd_slot_start = 0;
5861708Sstevel prd_slot_end = 3;
5871708Sstevel break;
5881708Sstevel case 1: /* Half Bandwidth Slot */
5891708Sstevel prd_slot_start = 4;
5901708Sstevel prd_slot_end = 5;
5911708Sstevel break;
5921708Sstevel default:
5931708Sstevel SC_DEBUG(1, (CE_WARN, "Unknown Board Address - "
5941708Sstevel "Can not probe\n"));
5951708Sstevel return (board_config);
5961708Sstevel }
5971708Sstevel
5981708Sstevel /*
5991708Sstevel * For each valid PRD entry, determine the agent id which is based
6001708Sstevel * on what type of device is described by the slot, and then
6011708Sstevel * call the safari configurator.
6021708Sstevel */
6031708Sstevel for (prd_slot = prd_slot_start; prd_slot <= prd_slot_end; prd_slot++) {
6041708Sstevel
6051708Sstevel pcd = sc_get_common_pcd(expander, prd_slot);
6061708Sstevel
6071708Sstevel if (pcd == NULL) {
6081708Sstevel
6091708Sstevel /*
6101708Sstevel * We can not get a PCD for this port so skip it.
6111708Sstevel */
6121708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: Can not get PCD "
6131708Sstevel "expander 0x%x prd slot 0x%x\n",
6141708Sstevel expander, prd_slot);
6151708Sstevel
6161708Sstevel return (board_config);
6171708Sstevel }
6181708Sstevel
6191708Sstevel /*
6201708Sstevel * Only configure good devices.
6211708Sstevel */
6221708Sstevel if (pcd->spcd_prsv == SPCD_RSV_PASS) {
6231708Sstevel /*
6241708Sstevel * Determine the agent id.
6251708Sstevel */
6261708Sstevel agent_id = sc_get_agent_id(
6271708Sstevel pcd, expander, slot, prd_slot);
6281708Sstevel
6291708Sstevel pcd->memory_layout = get_memlayout(agent_id, &size);
6301708Sstevel pcd->memory_layout_size = size;
6311708Sstevel
6321708Sstevel /*
6331708Sstevel * Call Platform Independent gptwo configurator to
6341708Sstevel * create node and properties.
6351708Sstevel */
6361708Sstevel if (create_nodes) {
6371708Sstevel port_cookie =
6381708Sstevel gptwocfg_configure(ap, pcd, agent_id);
6391708Sstevel if (port_cookie)
6401708Sstevel created_node++;
6411708Sstevel }
6421708Sstevel
6431708Sstevel new = kmem_zalloc
6441708Sstevel (sizeof (sc_gptwocfg_config_t), KM_SLEEP);
6451708Sstevel
6461708Sstevel /*
6471708Sstevel * XXX Shouldn't port_cookie be NULL if
6481708Sstevel * !create_nodes ?
6491708Sstevel */
6501708Sstevel new->port_cookie = port_cookie;
6511708Sstevel new->portid = agent_id;
6521708Sstevel new->link = NULL;
6531708Sstevel last->link = new;
6541708Sstevel last = new;
6551708Sstevel } else {
6561708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Bad Agent "
6571708Sstevel "Exp=0x%x PRD Slot=0x%x prsv Status=0x%x\n",
6581708Sstevel expander, prd_slot, pcd->spcd_prsv));
6591708Sstevel }
6601708Sstevel
6611708Sstevel sc_free_common_pcd(pcd);
6621708Sstevel
6631708Sstevel } /* for loop */
6641708Sstevel
6651708Sstevel dump_config(board_config);
6661708Sstevel
6671708Sstevel if (create_nodes && !created_node) {
6681708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: GPTWO Devices failed "
6691708Sstevel "to configure - unprobing board %d\n", board));
6701708Sstevel board_config = sc_unprobe_board(board);
6711708Sstevel }
6721708Sstevel
6731708Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Returning 0x%p\n",
674*11311SSurya.Prakki@Sun.COM (void *)board_config));
6751708Sstevel
6761708Sstevel return (board_config);
6771708Sstevel }
6781708Sstevel
6791708Sstevel sc_gptwocfg_cookie_t
sc_unprobe_board(uint_t board)6801708Sstevel sc_unprobe_board(uint_t board)
6811708Sstevel {
6821708Sstevel sc_gptwocfg_config_t *board_config, *axq_config, *prior_config;
6831708Sstevel gptwocfg_cookie_t port_cookie;
6841708Sstevel
6851708Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: board=%d\n", board));
6861708Sstevel
6871708Sstevel if (board > 35) {
6881708Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: "
6891708Sstevel "invalid board 0x%x\n", board));
6901708Sstevel return (NULL);
6911708Sstevel }
6921708Sstevel mutex_enter(&sc_gptwo_config_list_lock);
6931708Sstevel board_config = sc_gptwo_config_list;
6941708Sstevel while (board_config != NULL) {
6951708Sstevel if (board_config->board == board) {
6961708Sstevel break;
6971708Sstevel }
6981708Sstevel board_config = board_config->next;
6991708Sstevel }
7001708Sstevel mutex_exit(&sc_gptwo_config_list_lock);
7011708Sstevel
7021708Sstevel if (board_config == NULL) {
7031708Sstevel
7041708Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: No "
7051708Sstevel "config structure board=0x%x\n", board));
7061708Sstevel
7071708Sstevel /*
7081708Sstevel * Configure the board without creating nodes.
7091708Sstevel */
7101708Sstevel board_config = sc_configure(board, 0);
7111708Sstevel
7121708Sstevel if (board_config == NULL) {
7131708Sstevel
7141708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: sc_unprobe_board: "
7151708Sstevel "Unable to unconfigure board %d - board is not "
7161708Sstevel "configured\n", board);
7171708Sstevel
7181708Sstevel return (NULL);
7191708Sstevel }
7201708Sstevel }
7211708Sstevel
7221708Sstevel axq_config = board_config;
7231708Sstevel
7241708Sstevel /*
7251708Sstevel * Walk the link of ports on this board and unconfigure them.
7261708Sstevel * Save the AXQ for last.
7271708Sstevel */
7281708Sstevel while (board_config->link != NULL) {
7291708Sstevel prior_config = board_config;
7301708Sstevel board_config = board_config->link;
7311708Sstevel
7321708Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: "
7331708Sstevel "calling gptwocfg_unconfigure(ap=0x%p portid=0x%x)\n",
734*11311SSurya.Prakki@Sun.COM (void *)ddi_root_node(), board_config->portid));
7351708Sstevel
7361708Sstevel port_cookie = gptwocfg_unconfigure(ddi_root_node(),
7371708Sstevel board_config->portid);
7381708Sstevel
7391708Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: "
7401708Sstevel "gptwocfg_unconfigure returned cookie=0x%p\n",
7411708Sstevel port_cookie));
7421708Sstevel
7431708Sstevel if (port_cookie == NULL) {
7441708Sstevel /*
7451708Sstevel * Can be removed from list.
7461708Sstevel */
7471708Sstevel prior_config->link = board_config->link;
7481708Sstevel kmem_free(board_config, sizeof (sc_gptwocfg_config_t));
7491708Sstevel board_config = prior_config;
7501708Sstevel } else {
7511708Sstevel board_config->port_cookie = port_cookie;
7521708Sstevel }
7531708Sstevel }
7541708Sstevel
7551708Sstevel if (axq_config->link == NULL) {
7561708Sstevel
7571708Sstevel /*
7581708Sstevel * If all the other Safari devices have been successfully
7591708Sstevel * unconfigured, then the AXQ can be unconfigured.
7601708Sstevel */
7611708Sstevel axq_config->port_cookie =
7621708Sstevel sc_gptwocfg_unconfigure_axq(axq_config->port_cookie);
7631708Sstevel
7641708Sstevel if (axq_config->port_cookie == NULL) {
7651708Sstevel
7661708Sstevel /*
7671708Sstevel * If the AXQ was successfully unconfigured, then
7681708Sstevel * the board is removed from the configured list.
7691708Sstevel */
7701708Sstevel mutex_enter(&sc_gptwo_config_list_lock);
7711708Sstevel if (sc_gptwo_config_list == axq_config) {
7721708Sstevel sc_gptwo_config_list = axq_config->next;
7731708Sstevel } else {
7741708Sstevel board_config = sc_gptwo_config_list;
7751708Sstevel while (board_config->next != axq_config) {
7761708Sstevel board_config = board_config->next;
7771708Sstevel }
7781708Sstevel board_config->next = axq_config->next;
7791708Sstevel }
7801708Sstevel mutex_exit(&sc_gptwo_config_list_lock);
7811708Sstevel kmem_free(axq_config, sizeof (sc_gptwocfg_config_t));
7821708Sstevel axq_config = NULL;
7831708Sstevel }
7841708Sstevel }
7851708Sstevel dump_config(axq_config);
7861708Sstevel return (axq_config);
7871708Sstevel }
7881708Sstevel
7891708Sstevel int
sc_next_node(sc_gptwocfg_cookie_t c,dev_info_t * previous,dev_info_t ** next)7901708Sstevel sc_next_node(sc_gptwocfg_cookie_t c, dev_info_t *previous, dev_info_t **next)
7911708Sstevel {
7921708Sstevel dev_info_t *dip;
7931708Sstevel sc_gptwocfg_config_t *cookie;
7941708Sstevel
7951708Sstevel SC_DEBUG(1, (CE_WARN, "sccfg: sccfg_next_node"
796*11311SSurya.Prakki@Sun.COM "(c=0x%p, previous=0x%p, next=0x%p)\n", (void *)c,
797*11311SSurya.Prakki@Sun.COM (void *)previous, (void *)next));
7981708Sstevel
7991708Sstevel cookie = (sc_gptwocfg_config_t *)c;
8001708Sstevel
8011708Sstevel if (cookie == NULL) {
8021708Sstevel cmn_err(CE_WARN, "sccfg: sccfg_next_node - "
8031708Sstevel "Invalid Cookie\n");
8041708Sstevel return (0);
8051708Sstevel }
8061708Sstevel if (previous == NULL) {
8071708Sstevel /*
8081708Sstevel * Start with the AXQ node.
8091708Sstevel */
8101708Sstevel if (gptwocfg_next_node(cookie->port_cookie, NULL, &dip)) {
8111708Sstevel *next = dip;
8121708Sstevel return (1);
8131708Sstevel } else {
8141708Sstevel return (0);
8151708Sstevel }
8161708Sstevel }
8171708Sstevel
8181708Sstevel while (cookie != NULL) {
8191708Sstevel if (gptwocfg_next_node(cookie->port_cookie, previous, &dip)) {
8201708Sstevel if ((dip == NULL) && (cookie->link == NULL)) {
8211708Sstevel *next = NULL;
8221708Sstevel return (1);
8231708Sstevel }
8241708Sstevel if (dip != NULL) {
8251708Sstevel *next = dip;
8261708Sstevel return (1);
8271708Sstevel }
8281708Sstevel
8291708Sstevel /* dip == NULL */
8301708Sstevel
8311708Sstevel previous = NULL;
8321708Sstevel }
8331708Sstevel cookie = cookie->link;
8341708Sstevel }
8351708Sstevel
8361708Sstevel return (0);
8371708Sstevel }
8381708Sstevel
8391708Sstevel static dev_info_t *
sc_find_axq_node(uint_t axq_id)8401708Sstevel sc_find_axq_node(uint_t axq_id)
8411708Sstevel {
8421708Sstevel char *name;
8431708Sstevel int size;
8441708Sstevel gptwo_regspec_t *reg;
8451708Sstevel dev_info_t *dip;
8461708Sstevel uint_t id;
8471708Sstevel int circ;
8481708Sstevel
8491708Sstevel SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: id=0x%x\n", axq_id));
8501708Sstevel
8511708Sstevel /*
8521708Sstevel * Hold root node busy to walk its child list
8531708Sstevel */
8541708Sstevel ndi_devi_enter(ddi_root_node(), &circ);
8551708Sstevel
8561708Sstevel dip = ddi_get_child(ddi_root_node());
8571708Sstevel
8581708Sstevel while (dip != NULL) {
8591708Sstevel
8601708Sstevel SC_DEBUG(1, (CE_CONT, "Searching dip=0x%p for our AXQ\n",
861*11311SSurya.Prakki@Sun.COM (void *)dip));
8621708Sstevel
8631708Sstevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
8641708Sstevel DDI_PROP_DONTPASS, "name", (caddr_t)&name, &size)
8651708Sstevel != DDI_PROP_SUCCESS) {
8661708Sstevel
8671708Sstevel /*
8681708Sstevel * This node does not have a name property.
8691708Sstevel */
8701708Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p does not have a "
871*11311SSurya.Prakki@Sun.COM "'name' property\n", (void *)dip));
8721708Sstevel
8731708Sstevel dip = ddi_get_next_sibling(dip);
8741708Sstevel continue;
8751708Sstevel }
8761708Sstevel
877*11311SSurya.Prakki@Sun.COM SC_DEBUG(1, (CE_CONT, "dip=0x%p name=%s\n", (void *)dip, name));
8781708Sstevel
8791708Sstevel if (strcmp(name, "address-extender-queue")) {
8801708Sstevel
8811708Sstevel /*
8821708Sstevel * This node is not a AXQ node.
8831708Sstevel */
8841708Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p is not an AXQ "
885*11311SSurya.Prakki@Sun.COM "node\n", (void *)dip));
8861708Sstevel kmem_free(name, size);
8871708Sstevel dip = ddi_get_next_sibling(dip);
8881708Sstevel continue;
8891708Sstevel }
8901708Sstevel kmem_free(name, size);
8911708Sstevel
8921708Sstevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
8931708Sstevel DDI_PROP_DONTPASS, "reg", (caddr_t)®, &size)
8941708Sstevel != DDI_PROP_SUCCESS) {
8951708Sstevel
8961708Sstevel /*
8971708Sstevel * This AXQ node does not have a reg property.
8981708Sstevel */
8991708Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p (AXQ Node) does "
900*11311SSurya.Prakki@Sun.COM "have a 'reg' property\n", (void *)dip));
9011708Sstevel dip = ddi_get_next_sibling(dip);
9021708Sstevel continue;
9031708Sstevel }
9041708Sstevel
9051708Sstevel id = ((reg[0].gptwo_phys_hi & 1) << 9) |
9061708Sstevel ((reg[0].gptwo_phys_low & 0xff800000) >> 23);
9071708Sstevel
9081708Sstevel kmem_free(reg, size);
9091708Sstevel
9101708Sstevel if (axq_id != id) {
9111708Sstevel
9121708Sstevel /*
9131708Sstevel * This is the wrong AXQ node.
9141708Sstevel */
9151708Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p Wrong node id=0x%x\n",
916*11311SSurya.Prakki@Sun.COM (void *)dip, id));
9171708Sstevel
9181708Sstevel dip = ddi_get_next_sibling(dip);
9191708Sstevel continue;
9201708Sstevel
9211708Sstevel }
9221708Sstevel
9231708Sstevel /*
9241708Sstevel * The correct AXQ node was found.
9251708Sstevel */
926*11311SSurya.Prakki@Sun.COM SC_DEBUG(1, (CE_CONT, "dip=0x%p Found AXQ Node\n",
927*11311SSurya.Prakki@Sun.COM (void *)dip));
9281708Sstevel ndi_hold_devi(dip);
9291708Sstevel break;
9301708Sstevel }
9311708Sstevel ndi_devi_exit(ddi_root_node(), circ);
9321708Sstevel
933*11311SSurya.Prakki@Sun.COM SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: Returning 0x%p\n",
934*11311SSurya.Prakki@Sun.COM (void *)dip));
9351708Sstevel
9361708Sstevel return (dip);
9371708Sstevel }
9381708Sstevel
9391708Sstevel struct axq_arg {
9401708Sstevel uint_t id;
9411708Sstevel dev_info_t *axq_dip;
9421708Sstevel };
9431708Sstevel
9441708Sstevel /*ARGSUSED*/
9451708Sstevel static int
axq_set_prop(dev_info_t * axq_dip,void * arg,uint_t flags)9461708Sstevel axq_set_prop(dev_info_t *axq_dip, void *arg, uint_t flags)
9471708Sstevel {
9481708Sstevel struct axq_arg *aqp = (struct axq_arg *)arg;
9491708Sstevel gptwo_regspec_t reg[2];
9501708Sstevel uint_t id;
9511708Sstevel
9521708Sstevel ASSERT(aqp);
9531708Sstevel
9541708Sstevel id = aqp->id;
9551708Sstevel
9561708Sstevel if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip,
9571708Sstevel "name", "address-extender-queue") != DDI_SUCCESS) {
9581708Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
9591708Sstevel "to create name property\n"));
9601708Sstevel return (DDI_WALK_ERROR);
9611708Sstevel }
9621708Sstevel
9631708Sstevel if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip,
9641708Sstevel "device_type", "address-extender-queue") != DDI_SUCCESS) {
9651708Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
9661708Sstevel "to create device_type property\n"));
9671708Sstevel return (DDI_WALK_ERROR);
9681708Sstevel }
9691708Sstevel
9701708Sstevel if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip,
9711708Sstevel "compatible", "SUNW,axq") != DDI_SUCCESS) {
9721708Sstevel SC_DEBUG(1, (CE_CONT, "sc_gptwocfg: failed "
9731708Sstevel "to create compatible property\n"));
9741708Sstevel return (DDI_WALK_ERROR);
9751708Sstevel }
9761708Sstevel
9771708Sstevel if (ndi_prop_update_int(DDI_DEV_T_NONE, axq_dip,
9781708Sstevel "portid", id) != DDI_SUCCESS) {
9791708Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
9801708Sstevel "to create portid property\n"));
9811708Sstevel return (DDI_WALK_ERROR);
9821708Sstevel }
9831708Sstevel
9841708Sstevel reg[0].gptwo_phys_hi = 0x400 | (id >> 9);
9851708Sstevel reg[0].gptwo_phys_low = (id << 23);
9861708Sstevel reg[0].gptwo_size_hi = 0;
9871708Sstevel reg[0].gptwo_size_low = 0x520;
9881708Sstevel
9891708Sstevel reg[1].gptwo_phys_hi = 0x401;
9901708Sstevel reg[1].gptwo_phys_low = 0xf0000000;
9911708Sstevel reg[1].gptwo_size_hi = 0;
9921708Sstevel reg[1].gptwo_size_low = 0x520;
9931708Sstevel
9941708Sstevel if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
9951708Sstevel axq_dip, "reg", (int *)®,
9961708Sstevel (sizeof (gptwo_regspec_t) * 2)/sizeof (int)) != DDI_SUCCESS) {
9971708Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
9981708Sstevel "to create reg property\n"));
9991708Sstevel return (DDI_WALK_ERROR);
10001708Sstevel }
10011708Sstevel
10021708Sstevel return (DDI_WALK_TERMINATE);
10031708Sstevel }
10041708Sstevel
10051708Sstevel /*ARGSUSED*/
10061708Sstevel static void
get_axq_dip(dev_info_t * rdip,void * arg,uint_t flags)10071708Sstevel get_axq_dip(dev_info_t *rdip, void *arg, uint_t flags)
10081708Sstevel {
10091708Sstevel struct axq_arg *aqp = (struct axq_arg *)arg;
10101708Sstevel
10111708Sstevel ASSERT(aqp);
10121708Sstevel
10131708Sstevel aqp->axq_dip = rdip;
10141708Sstevel }
10151708Sstevel
10161708Sstevel static gptwo_new_nodes_t *
sc_gptwocfg_configure_axq(dev_info_t * ap,uint_t id,int create_nodes)10171708Sstevel sc_gptwocfg_configure_axq(dev_info_t *ap, uint_t id, int create_nodes)
10181708Sstevel {
10191708Sstevel struct axq_arg arg = {0};
10201708Sstevel devi_branch_t b = {0};
10211708Sstevel dev_info_t *axq_dip, *fdip = NULL;
10221708Sstevel gptwo_new_nodes_t *new_nodes = NULL;
10231708Sstevel int rv;
10241708Sstevel
10251708Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: id=0x%x "
10261708Sstevel "create_nodes=%d\n", id, create_nodes));
10271708Sstevel
10281708Sstevel if (!create_nodes) {
10291708Sstevel axq_dip = sc_find_axq_node(id);
10301708Sstevel
10311708Sstevel if (axq_dip) {
10321708Sstevel new_nodes = gptwocfg_allocate_node_list(1);
10331708Sstevel new_nodes->gptwo_nodes[0] = axq_dip;
10341708Sstevel ASSERT(!e_ddi_branch_held(axq_dip));
10351708Sstevel e_ddi_branch_hold(axq_dip);
10361708Sstevel /*
10371708Sstevel * Release hold from sc_find_axq_node()
10381708Sstevel */
10391708Sstevel ddi_release_devi(axq_dip);
10401708Sstevel }
10411708Sstevel
10421708Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: "
1043*11311SSurya.Prakki@Sun.COM "Returning 0x%p\n", (void *)new_nodes));
10441708Sstevel
10451708Sstevel return (new_nodes);
10461708Sstevel }
10471708Sstevel
10481708Sstevel arg.id = id;
10491708Sstevel arg.axq_dip = NULL;
10501708Sstevel
10511708Sstevel b.arg = &arg;
10521708Sstevel b.type = DEVI_BRANCH_SID;
10531708Sstevel b.create.sid_branch_create = axq_set_prop;
10541708Sstevel b.devi_branch_callback = get_axq_dip;
10551708Sstevel
10561708Sstevel rv = e_ddi_branch_create(ap, &b, &fdip, DEVI_BRANCH_CONFIGURE);
10571708Sstevel if (rv != 0) {
10581708Sstevel char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
10591708Sstevel
10601708Sstevel /*
10611708Sstevel * If non-NULL, fdip is held and must be released.
10621708Sstevel */
10631708Sstevel if (fdip != NULL) {
10641708Sstevel (void) ddi_pathname(fdip, path);
10651708Sstevel ddi_release_devi(fdip);
10661708Sstevel } else {
10671708Sstevel (void) ddi_pathname(ap, path);
10681708Sstevel }
10691708Sstevel
10701708Sstevel SC_DEBUG(1, (CE_WARN, "e_ddi_branch_create failed: "
10711708Sstevel "path=%s, dip=%p, rv=%d", path, fdip ? (void *)fdip :
10721708Sstevel (void *)ap, rv));
10731708Sstevel
10741708Sstevel kmem_free(path, MAXPATHLEN);
10751708Sstevel
10761708Sstevel return (NULL);
10771708Sstevel }
10781708Sstevel
10791708Sstevel axq_dip = arg.axq_dip;
10801708Sstevel
10811708Sstevel new_nodes = gptwocfg_allocate_node_list(1);
10821708Sstevel new_nodes->gptwo_nodes[0] = axq_dip;
10831708Sstevel
10841708Sstevel return (new_nodes);
10851708Sstevel }
10861708Sstevel
10871708Sstevel static gptwocfg_config_t *
sc_gptwocfg_unconfigure_axq(gptwocfg_config_t * config)10881708Sstevel sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *config)
10891708Sstevel {
10901708Sstevel int i;
10911708Sstevel int failure = 0;
10921708Sstevel dev_info_t *saf_dip;
10931708Sstevel
10941708Sstevel if (config == NULL) {
10951708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: sc_gptwocfg_unconfigure_axq: "
10961708Sstevel "Invalid AXQ\n");
10971708Sstevel return (NULL);
10981708Sstevel }
10991708Sstevel for (i = 0; i < config->gptwo_nodes->gptwo_number_of_nodes; i++) {
11001708Sstevel int rv;
11011708Sstevel dev_info_t *fdip = NULL;
11021708Sstevel
11031708Sstevel saf_dip = config->gptwo_nodes->gptwo_nodes[i];
11041708Sstevel ASSERT(e_ddi_branch_held(saf_dip));
11051708Sstevel rv = e_ddi_branch_destroy(saf_dip, &fdip, 0);
11061708Sstevel if (rv != 0) {
11071708Sstevel char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
11081708Sstevel
11091708Sstevel /*
11101708Sstevel * If non-NULL, fdip is held and must be released.
11111708Sstevel */
11121708Sstevel if (fdip != NULL) {
11131708Sstevel (void) ddi_pathname(fdip, path);
11141708Sstevel ddi_release_devi(fdip);
11151708Sstevel } else {
11161708Sstevel (void) ddi_pathname(saf_dip, path);
11171708Sstevel }
11181708Sstevel
11191708Sstevel cmn_err(CE_CONT, "AXQ node removal failed: "
11201708Sstevel "path=%s, dip=%p, rv=%d\n", path,
11211708Sstevel fdip ? (void *)fdip : (void *)saf_dip, rv);
11221708Sstevel
11231708Sstevel kmem_free(path, MAXPATHLEN);
11241708Sstevel failure = 1;
11251708Sstevel } else {
11261708Sstevel config->gptwo_nodes->gptwo_nodes[i] = NULL;
11271708Sstevel }
11281708Sstevel }
11291708Sstevel if (!failure) {
11301708Sstevel gptwocfg_free_node_list(config->gptwo_nodes);
11311708Sstevel
11321708Sstevel kmem_free(config, sizeof (gptwocfg_config_t));
11331708Sstevel config = NULL;
11341708Sstevel }
11351708Sstevel return (config);
11361708Sstevel }
11371708Sstevel
11381708Sstevel static uint_t
sc_get_agent_id(spcd_t * pcd,uint_t expander,uint_t slot,uint_t prd_slot)11391708Sstevel sc_get_agent_id(spcd_t *pcd, uint_t expander, uint_t slot, uint_t prd_slot)
11401708Sstevel {
11411708Sstevel uint_t agent_id;
11421708Sstevel
11431708Sstevel switch (pcd->spcd_ptype) {
11441708Sstevel case SAFPTYPE_CPU:
11451708Sstevel if (slot == 0) {
11461708Sstevel agent_id = prd_slot;
11471708Sstevel } else {
11481708Sstevel if (prd_slot == 4) {
11491708Sstevel agent_id = 8;
11501708Sstevel } else {
11511708Sstevel agent_id = 9;
11521708Sstevel }
11531708Sstevel }
11541708Sstevel break;
11551708Sstevel
11561708Sstevel case SAFPTYPE_sPCI:
11571708Sstevel case SAFPTYPE_cPCI:
11581708Sstevel case SAFPTYPE_PCIX:
11591708Sstevel if (prd_slot == 4) {
11601708Sstevel agent_id = 0x1c;
11611708Sstevel } else {
11621708Sstevel agent_id = 0x1d;
11631708Sstevel }
11641708Sstevel break;
11651708Sstevel case SAFPTYPE_WCI:
11661708Sstevel agent_id = 0x1d;
11671708Sstevel break;
11681708Sstevel default:
11691708Sstevel cmn_err(CE_WARN, "sc_gptwocfg: Invalid Safari Port "
11701708Sstevel "Type 0x%x Slot 0x%x\n",
11711708Sstevel pcd->spcd_ptype, prd_slot);
11721708Sstevel } /* switch */
11731708Sstevel
11741708Sstevel agent_id |= (expander << 5);
11751708Sstevel
11761708Sstevel SC_DEBUG(1, (CE_CONT, "sc_get_agent_id(pcd=0x%p, expander=0x%x, "
1177*11311SSurya.Prakki@Sun.COM "prd_slot=0x%x) Returning agent_id=0x%x\n", (void *)pcd, expander,
11781708Sstevel prd_slot, agent_id));
11791708Sstevel
11801708Sstevel return (agent_id);
11811708Sstevel }
11821708Sstevel
11831708Sstevel static void
dump_config(sc_gptwocfg_config_t * board_config)11841708Sstevel dump_config(sc_gptwocfg_config_t *board_config)
11851708Sstevel {
11861708Sstevel gptwocfg_config_t *port;
11871708Sstevel
1188*11311SSurya.Prakki@Sun.COM SC_DEBUG(1, (CE_CONT, "dump_config 0x%p", (void *)board_config));
11891708Sstevel while (board_config != NULL) {
11901708Sstevel SC_DEBUG(1, (CE_CONT, "************* 0x%p ************\n",
1191*11311SSurya.Prakki@Sun.COM (void *)board_config));
11921708Sstevel SC_DEBUG(1, (CE_CONT, "port_cookie - 0x%p\n",
1193*11311SSurya.Prakki@Sun.COM (void *)board_config->port_cookie));
11941708Sstevel
11951708Sstevel port = board_config->port_cookie;
11961708Sstevel if (port) {
11971708Sstevel SC_DEBUG(1, (CE_CONT, " ap - 0x%p\n",
1198*11311SSurya.Prakki@Sun.COM (void *)port->gptwo_ap));
11991708Sstevel SC_DEBUG(1, (CE_CONT, " portid - 0x%x\n",
12001708Sstevel port->gptwo_portid));
12011708Sstevel }
12021708Sstevel SC_DEBUG(1, (CE_CONT, "portid - 0x%x\n",
12031708Sstevel board_config->portid));
12041708Sstevel SC_DEBUG(1, (CE_CONT, "board - 0x%x\n",
12051708Sstevel board_config->board));
12061708Sstevel SC_DEBUG(1, (CE_CONT, "link - 0x%p\n",
1207*11311SSurya.Prakki@Sun.COM (void *)board_config->link));
12081708Sstevel SC_DEBUG(1, (CE_CONT, "next - 0x%p\n",
1209*11311SSurya.Prakki@Sun.COM (void *)board_config->next));
12101708Sstevel board_config = board_config->link;
12111708Sstevel }
12121708Sstevel }
12131708Sstevel
12141708Sstevel static void
dump_pcd(spcd_t * pcd)12151708Sstevel dump_pcd(spcd_t *pcd)
12161708Sstevel {
12171708Sstevel int i;
12181708Sstevel
1219*11311SSurya.Prakki@Sun.COM SC_DEBUG(1, (CE_CONT, "dump_pcd 0x%p", (void *)pcd));
12201708Sstevel SC_DEBUG(1, (CE_CONT, " magic - 0x%x\n", pcd->spcd_magic));
12211708Sstevel SC_DEBUG(1, (CE_CONT, " version - 0x%x\n", pcd->spcd_version));
12221708Sstevel SC_DEBUG(1, (CE_CONT, " ver.reg - 0x%lx\n", pcd->spcd_ver_reg));
12231708Sstevel SC_DEBUG(1, (CE_CONT, " afreq - %d\n", pcd->spcd_afreq));
12241708Sstevel switch (pcd->spcd_ptype) {
12251708Sstevel case SAFPTYPE_CPU:
12261708Sstevel SC_DEBUG(1, (CE_CONT, " ptype - CPU\n"));
12271708Sstevel break;
12281708Sstevel case SAFPTYPE_sPCI:
12291708Sstevel SC_DEBUG(1, (CE_CONT, " ptype - sPCI\n"));
12301708Sstevel break;
12311708Sstevel case SAFPTYPE_cPCI:
12321708Sstevel SC_DEBUG(1, (CE_CONT, " ptype - cPCI\n"));
12331708Sstevel break;
12341708Sstevel case SAFPTYPE_PCIX:
12351708Sstevel SC_DEBUG(1, (CE_CONT, " ptype - sPCI+\n"));
12361708Sstevel break;
12371708Sstevel case SAFPTYPE_WCI:
12381708Sstevel SC_DEBUG(1, (CE_CONT, " ptype - WIC\n"));
12391708Sstevel break;
12401708Sstevel default:
12411708Sstevel SC_DEBUG(1, (CE_CONT, " ptype - 0x%x\n",
12421708Sstevel pcd->spcd_ptype));
12431708Sstevel break;
12441708Sstevel }
12451708Sstevel SC_DEBUG(1, (CE_CONT, " cache - %d\n", pcd->spcd_cache));
12461708Sstevel
12471708Sstevel if (pcd->spcd_prsv == SPCD_RSV_PASS) {
12481708Sstevel SC_DEBUG(1, (CE_CONT, " prsv - SPCD_RSV_PASS\n"));
12491708Sstevel } else {
12501708Sstevel SC_DEBUG(1, (CE_CONT, " prsv - 0x%x (FAIL)\n",
12511708Sstevel pcd->spcd_prsv));
12521708Sstevel }
12531708Sstevel
12541708Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) {
12551708Sstevel if (pcd->spcd_agent[i] == SPCD_RSV_PASS) {
12561708Sstevel SC_DEBUG(1, (CE_CONT, " agent[%d] "
12571708Sstevel "- SPCD_RSV_PASS\n", i));
12581708Sstevel } else {
12591708Sstevel SC_DEBUG(1, (CE_CONT, " agent[%d] "
12601708Sstevel "- 0x%x (FAIL)\n", i, pcd->spcd_agent[i]));
12611708Sstevel }
12621708Sstevel }
12631708Sstevel
12641708Sstevel if (pcd->spcd_ptype == SAFPTYPE_CPU) {
12651708Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) {
12661708Sstevel SC_DEBUG(1, (CE_CONT, " cpuid[%d] - 0x%x\n",
12671708Sstevel i, pcd->spcd_cpuid[i]));
12681708Sstevel }
12691708Sstevel }
12701708Sstevel
12711708Sstevel SC_DEBUG(1, (CE_CONT, " Banks\n"));
12721708Sstevel for (i = 0; i < MAX_BANKS_PER_PORT; i++) {
12731708Sstevel if (pcd->sprd_bank_rsv[i]) {
12741708Sstevel SC_DEBUG(1, (CE_CONT, " %d %s\n", i,
12751708Sstevel pcd->sprd_bank_rsv[i]));
12761708Sstevel }
12771708Sstevel }
12781708Sstevel
12791708Sstevel SC_DEBUG(1, (CE_CONT, " Dimms\n"));
12801708Sstevel for (i = 0; i < MAX_DIMMS_PER_PORT; i++) {
12811708Sstevel if (pcd->sprd_dimm[i]) {
12821708Sstevel SC_DEBUG(1, (CE_CONT, " %d %s\n", i,
12831708Sstevel pcd->sprd_dimm[i]));
12841708Sstevel }
12851708Sstevel }
12861708Sstevel SC_DEBUG(1, (CE_CONT, " Ecache Dimm Labels\n"));
12871708Sstevel for (i = 0; i < MAX_DIMMS_PER_PORT; i++) {
12881708Sstevel if (pcd->sprd_ecache_dimm_label[i]) {
12891708Sstevel SC_DEBUG(1, (CE_CONT, " %d %s\n", i,
12901708Sstevel pcd->sprd_ecache_dimm_label[i]));
12911708Sstevel }
12921708Sstevel }
12931708Sstevel }
12941708Sstevel
12951708Sstevel
12961708Sstevel typedef struct {
12971708Sstevel char Jnumber[8][8];
12981708Sstevel uint8_t sym_flag;
12991708Sstevel uint8_t d_dimmtable[144];
13001708Sstevel uint8_t d_pintable[576];
13011708Sstevel }m_layout;
13021708Sstevel
13031708Sstevel /*
13041708Sstevel * Use 2 bits to represent each bit at a cache line. The table
13051708Sstevel * is in big endian order, i.e.
13061708Sstevel * dimmtable[0], ... , dimmtable[143]
13071708Sstevel * Q0:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0]
13081708Sstevel * .
13091708Sstevel * .
13101708Sstevel * Q3:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0]
13111708Sstevel */
13121708Sstevel uint8_t J_dimm_pinTable[] = {
13131708Sstevel /* Jnumber */
13141708Sstevel /* 0 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x30, 0x00, 0x00,
13151708Sstevel /* 1 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x30, 0x00, 0x00,
13161708Sstevel /* 2 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x30, 0x00, 0x00,
13171708Sstevel /* 3 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x30, 0x00, 0x00,
13181708Sstevel /* 4 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x31, 0x00, 0x00,
13191708Sstevel /* 5 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x31, 0x00, 0x00,
13201708Sstevel /* 6 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x31, 0x00, 0x00,
13211708Sstevel /* 7 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x31, 0x00, 0x00,
13221708Sstevel /* flag */ 0x01,
13231708Sstevel /* -- Q0 -- */
13241708Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
13251708Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
13261708Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
13271708Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
13281708Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
13291708Sstevel /* -- Q1 -- */
13301708Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
13311708Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
13321708Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
13331708Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
13341708Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
13351708Sstevel /* -- Q2 -- */
13361708Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
13371708Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
13381708Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
13391708Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
13401708Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
13411708Sstevel /* -- Q3 -- */
13421708Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
13431708Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
13441708Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
13451708Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
13461708Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
13471708Sstevel /*
13481708Sstevel * In the following order
13491708Sstevel * pintable[0], ..., pintable[575]
13501708Sstevel * Quadword3, Quadword2, Quadword1, Quadword0
13511708Sstevel * MtagEcc, Mtag, Ecc, Data
13521708Sstevel */
13531708Sstevel /* -- Q3 -- */
13541708Sstevel /* 0 */ 227, 227, 227, 227, 111, 111, 111, 22,
13551708Sstevel /* 1 */ 22, 32, 138, 222, 81, 117, 117, 117,
13561708Sstevel /* 2 */ 111, 222, 106, 222, 222, 106, 106, 106,
13571708Sstevel /* 3 */ 217, 101, 212, 96, 217, 101, 212, 96,
13581708Sstevel /* 4 */ 217, 101, 212, 96, 217, 101, 212, 96,
13591708Sstevel /* 5 */ 207, 91, 202, 86, 187, 71, 158, 42,
13601708Sstevel /* 6 */ 187, 71, 158, 42, 153, 37, 148, 32,
13611708Sstevel /* 7 */ 153, 37, 148, 32, 153, 37, 148, 32,
13621708Sstevel /* 8 */ 153, 37, 148, 143, 27, 138, 143, 27,
13631708Sstevel /* 9 */ 143, 27, 138, 22, 207, 91, 202, 86,
13641708Sstevel /* 10 */ 207, 91, 202, 86, 207, 91, 202, 86,
13651708Sstevel /* 11 */ 192, 76, 81, 192, 76, 81, 192, 76,
13661708Sstevel /* 12 */ 197, 81, 192, 76, 187, 71, 158, 42,
13671708Sstevel /* 13 */ 187, 71, 158, 42, 143, 27, 138, 22,
13681708Sstevel /* 14 */ 133, 17, 128, 12, 133, 17, 128, 12,
13691708Sstevel /* 15 */ 133, 17, 128, 12, 133, 17, 128, 12,
13701708Sstevel /* 16 */ 123, 07, 118, 2, 123, 07, 118, 2,
13711708Sstevel /* 17 */ 123, 07, 118, 2, 123, 07, 118, 2,
13721708Sstevel /* -- Q2 -- */
13731708Sstevel /* 0 */ 228, 228, 228, 228, 112, 112, 112, 23,
13741708Sstevel /* 1 */ 23, 33, 139, 223, 82, 118, 118, 118,
13751708Sstevel /* 2 */ 112, 223, 107, 223, 223, 107, 107, 107,
13761708Sstevel /* 3 */ 218, 102, 213, 97, 218, 102, 213, 97,
13771708Sstevel /* 4 */ 218, 102, 213, 97, 218, 102, 213, 97,
13781708Sstevel /* 5 */ 208, 92, 203, 87, 188, 72, 159, 43,
13791708Sstevel /* 6 */ 188, 72, 159, 43, 154, 38, 149, 33,
13801708Sstevel /* 7 */ 154, 38, 149, 33, 154, 38, 149, 33,
13811708Sstevel /* 8 */ 154, 38, 149, 144, 28, 139, 144, 28,
13821708Sstevel /* 9 */ 144, 28, 139, 23, 208, 92, 203, 87,
13831708Sstevel /* 10 */ 208, 92, 203, 87, 208, 92, 203, 87,
13841708Sstevel /* 11 */ 193, 77, 82, 193, 77, 82, 193, 77,
13851708Sstevel /* 12 */ 198, 82, 193, 77, 188, 72, 159, 43,
13861708Sstevel /* 13 */ 188, 72, 159, 43, 144, 28, 139, 23,
13871708Sstevel /* 14 */ 134, 18, 129, 13, 134, 18, 129, 13,
13881708Sstevel /* 15 */ 134, 18, 129, 13, 134, 18, 129, 13,
13891708Sstevel /* 16 */ 124, 8, 119, 3, 124, 8, 119, 3,
13901708Sstevel /* 17 */ 124, 8, 119, 3, 124, 8, 119, 3,
13911708Sstevel /* -- Q1 -- */
13921708Sstevel /* 0 */ 229, 229, 229, 229, 113, 113, 113, 24,
13931708Sstevel /* 1 */ 24, 34, 140, 224, 83, 119, 119, 119,
13941708Sstevel /* 2 */ 113, 224, 108, 224, 224, 108, 108, 108,
13951708Sstevel /* 3 */ 219, 103, 214, 98, 219, 103, 214, 98,
13961708Sstevel /* 4 */ 219, 103, 214, 98, 219, 103, 214, 98,
13971708Sstevel /* 5 */ 209, 93, 204, 88, 189, 73, 160, 44,
13981708Sstevel /* 6 */ 189, 73, 160, 44, 155, 39, 150, 34,
13991708Sstevel /* 7 */ 155, 39, 150, 34, 155, 39, 150, 34,
14001708Sstevel /* 8 */ 155, 39, 150, 145, 29, 140, 145, 29,
14011708Sstevel /* 9 */ 145, 29, 140, 24, 209, 93, 204, 88,
14021708Sstevel /* 10 */ 209, 93, 204, 88, 209, 93, 204, 88,
14031708Sstevel /* 11 */ 194, 78, 83, 194, 78, 83, 194, 78,
14041708Sstevel /* 12 */ 199, 83, 194, 78, 189, 73, 160, 44,
14051708Sstevel /* 13 */ 189, 73, 160, 44, 145, 29, 140, 24,
14061708Sstevel /* 14 */ 135, 19, 130, 14, 135, 19, 130, 14,
14071708Sstevel /* 15 */ 135, 19, 130, 14, 135, 19, 130, 14,
14081708Sstevel /* 16 */ 125, 9, 120, 4, 125, 9, 120, 4,
14091708Sstevel /* 17 */ 125, 9, 120, 4, 125, 9, 120, 4,
14101708Sstevel /* -- Q0 -- */
14111708Sstevel /* 0 */ 230, 230, 230, 230, 114, 114, 114, 25,
14121708Sstevel /* 1 */ 25, 35, 141, 225, 84, 200, 200, 200,
14131708Sstevel /* 2 */ 114, 225, 109, 225, 225, 109, 109, 109,
14141708Sstevel /* 3 */ 220, 104, 215, 99, 220, 104, 215, 99,
14151708Sstevel /* 4 */ 220, 104, 215, 99, 220, 104, 215, 99,
14161708Sstevel /* 5 */ 210, 94, 205, 89, 190, 74, 161, 45,
14171708Sstevel /* 6 */ 190, 74, 161, 45, 156, 40, 151, 35,
14181708Sstevel /* 7 */ 156, 40, 151, 35, 156, 40, 151, 35,
14191708Sstevel /* 8 */ 156, 40, 151, 146, 30, 141, 146, 30,
14201708Sstevel /* 9 */ 146, 30, 141, 25, 210, 94, 205, 89,
14211708Sstevel /* 10 */ 210, 94, 205, 89, 210, 94, 205, 89,
14221708Sstevel /* 11 */ 195, 79, 84, 195, 79, 84, 195, 79,
14231708Sstevel /* 12 */ 200, 84, 195, 79, 190, 74, 161, 45,
14241708Sstevel /* 13 */ 190, 74, 161, 45, 146, 30, 141, 25,
14251708Sstevel /* 14 */ 136, 20, 131, 15, 136, 20, 131, 15,
14261708Sstevel /* 15 */ 136, 20, 131, 15, 136, 20, 131, 15,
14271708Sstevel /* 16 */ 126, 10, 121, 5, 126, 10, 121, 5,
14281708Sstevel /* 17 */ 126, 10, 121, 5, 126, 10, 121, 5
14291708Sstevel };
14301708Sstevel
14311708Sstevel /*
14321708Sstevel * This table is for internal reference
14331708Sstevel *
14341708Sstevel * pintable_internal[]= {
14351708Sstevel * -- Q0 --
14361708Sstevel * 0 143,143,143,143,139,139,139,35
14371708Sstevel * 1 35,51,39,135,91,95,95,95
14381708Sstevel * 2 139,135,131,135,135,131,131,131
14391708Sstevel * 3 127,123,119,115,127,123,119,115
14401708Sstevel * 4 127,123,119,115,127,123,119,115
14411708Sstevel * 5 111,107,103,99,79,75,71,67
14421708Sstevel * 6 79,75,71,67,63,59,55,51
14431708Sstevel * 7 63,59,55,51,63,59,55,51
14441708Sstevel * 8 63,59,55,47,43,39,47,43
14451708Sstevel * 9 47,43,39,35,111,107,103,99
14461708Sstevel * 10 111,107,103,99,111,107,103,99
14471708Sstevel * 11 87,83,91,87,83,91,87,83
14481708Sstevel * 12 95,91,87,83,79,75,71,67
14491708Sstevel * 13 79,75,71,67,47,43,39,35
14501708Sstevel * 14 31,27,23,19,31,27,23,19
14511708Sstevel * 15 31,27,23,19,31,27,23,19
14521708Sstevel * 16 15,11,7,3,15,11,7,3
14531708Sstevel * 17 15,11,7,3,15,11,7,3
14541708Sstevel * }
14551708Sstevel */
14561708Sstevel
14571708Sstevel char *dimm_Jno[] = {
14581708Sstevel /* P0 */ "J13300", "J13400", "J13500", "J13600",
14591708Sstevel "J13301", "J13401", "J13501", "J13601",
14601708Sstevel /* P1 */ "J14300", "J14400", "J14500", "J14600",
14611708Sstevel "J14301", "J14401", "J14501", "J14601",
14621708Sstevel /* P2 */ "J15300", "J15400", "J15500", "J15600",
14631708Sstevel "J15301", "J15401", "J15501", "J15601",
14641708Sstevel /* P3 */ "J16300", "J16400", "J16500", "J16600",
14651708Sstevel "J16301", "J16401", "J16501", "J16601",
14661708Sstevel NULL
14671708Sstevel };
14681708Sstevel
14691708Sstevel
14701708Sstevel static uint8_t *
get_memlayout(uint32_t cpuid,uint32_t * len)14711708Sstevel get_memlayout(uint32_t cpuid, uint32_t *len)
14721708Sstevel {
14731708Sstevel m_layout *LayoutBuf;
14741708Sstevel
14751708Sstevel if ((LayoutBuf = (m_layout *)kmem_zalloc(sizeof (m_layout),
14761708Sstevel KM_SLEEP)) == NULL) {
14771708Sstevel *len = 0;
14781708Sstevel return (NULL);
14791708Sstevel }
14801708Sstevel
14811708Sstevel bcopy(J_dimm_pinTable, LayoutBuf, sizeof (m_layout));
14821708Sstevel
14831708Sstevel *len = sizeof (m_layout);
14841708Sstevel cpuid &= 0x03; /* last 2 bits of a 10 bit number */
14851708Sstevel
14861708Sstevel bcopy(dimm_Jno[cpuid << 3], LayoutBuf->Jnumber[0], 64);
14871708Sstevel
14881708Sstevel return ((uint8_t *)LayoutBuf);
14891708Sstevel }
14901708Sstevel
14911708Sstevel static char *
rsv_string(prdrsv_t rsv)14921708Sstevel rsv_string(prdrsv_t rsv)
14931708Sstevel {
14941708Sstevel char *buffer;
14951708Sstevel char *status;
14961708Sstevel
14971708Sstevel switch (rsv) {
14981708Sstevel case RSV_UNKNOWN:
14991708Sstevel buffer = "unknown";
15001708Sstevel break;
15011708Sstevel case RSV_PRESENT:
15021708Sstevel buffer = "okay";
15031708Sstevel break;
15041708Sstevel case RSV_CRUNCH:
15051708Sstevel buffer = "disabled";
15061708Sstevel break;
15071708Sstevel case RSV_UNDEFINED:
15081708Sstevel buffer = "undefined";
15091708Sstevel break;
15101708Sstevel case RSV_MISS:
15111708Sstevel buffer = "missing";
15121708Sstevel break;
15131708Sstevel case RSV_EMPTY_CASSETTE:
15141708Sstevel buffer = "disabled";
15151708Sstevel break;
15161708Sstevel case RSV_MISCONFIG:
15171708Sstevel buffer = "misconfigured";
15181708Sstevel break;
15191708Sstevel case RSV_FAIL_OBP:
15201708Sstevel buffer = "fail-obp";
15211708Sstevel break;
15221708Sstevel case RSV_BLACK:
15231708Sstevel buffer = "blacklisted";
15241708Sstevel break;
15251708Sstevel case RSV_RED:
15261708Sstevel buffer = "redlisted";
15271708Sstevel break;
15281708Sstevel case RSV_EXCLUDED:
15291708Sstevel buffer = "disabled";
15301708Sstevel break;
15311708Sstevel case RSV_UNCONFIG:
15321708Sstevel buffer = "disabled";
15331708Sstevel break;
15341708Sstevel case RSV_PASS:
15351708Sstevel buffer = "okay";
15361708Sstevel break;
15371708Sstevel case RSV_FAIL:
15381708Sstevel default:
15391708Sstevel buffer = "fail";
15401708Sstevel break;
15411708Sstevel }
15421708Sstevel
15431708Sstevel status = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
15441708Sstevel (void) strcpy(status, buffer);
15451708Sstevel
15461708Sstevel return (status);
15471708Sstevel }
1548