103831d35Sstevel /* 203831d35Sstevel * CDDL HEADER START 303831d35Sstevel * 403831d35Sstevel * The contents of this file are subject to the terms of the 503831d35Sstevel * Common Development and Distribution License (the "License"). 603831d35Sstevel * You may not use this file except in compliance with the License. 703831d35Sstevel * 803831d35Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 903831d35Sstevel * or http://www.opensolaris.org/os/licensing. 1003831d35Sstevel * See the License for the specific language governing permissions 1103831d35Sstevel * and limitations under the License. 1203831d35Sstevel * 1303831d35Sstevel * When distributing Covered Code, include this CDDL HEADER in each 1403831d35Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1503831d35Sstevel * If applicable, add the following below this CDDL HEADER, with the 1603831d35Sstevel * fields enclosed by brackets "[]" replaced with your own identifying 1703831d35Sstevel * information: Portions Copyright [yyyy] [name of copyright owner] 1803831d35Sstevel * 1903831d35Sstevel * CDDL HEADER END 2003831d35Sstevel */ 2103831d35Sstevel 2203831d35Sstevel /* 23*07d06da5SSurya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2403831d35Sstevel * Use is subject to license terms. 2503831d35Sstevel */ 2603831d35Sstevel 2703831d35Sstevel /* 2803831d35Sstevel * Starcat Specific Glue for Safari Configurator 2903831d35Sstevel */ 3003831d35Sstevel 3103831d35Sstevel #include <sys/isa_defs.h> 3203831d35Sstevel #include <sys/conf.h> 3303831d35Sstevel #include <sys/kmem.h> 3403831d35Sstevel #include <sys/debug.h> 3503831d35Sstevel #include <sys/modctl.h> 3603831d35Sstevel #include <sys/autoconf.h> 3703831d35Sstevel #include <sys/hwconf.h> 3803831d35Sstevel #include <sys/ddi_impldefs.h> 3903831d35Sstevel #include <sys/ddi.h> 4003831d35Sstevel #include <sys/sunddi.h> 4103831d35Sstevel #include <sys/sunndi.h> 4203831d35Sstevel #include <sys/ndi_impldefs.h> 4303831d35Sstevel #include <sys/safari_pcd.h> 4403831d35Sstevel #include <sys/gp2cfg.h> 4503831d35Sstevel #include <sys/gptwo_cpu.h> 4603831d35Sstevel #include <sys/gptwo_pci.h> 4703831d35Sstevel #include <sys/sc_gptwocfg.h> 4803831d35Sstevel #include <post/scat_dcd.h> 4903831d35Sstevel #include <sys/machsystm.h> 5003831d35Sstevel 5103831d35Sstevel int sc_gptwocfg_debug = 0; 5203831d35Sstevel 5303831d35Sstevel #define SC_DEBUG(level, args) if (sc_gptwocfg_debug >= level) cmn_err args 5403831d35Sstevel 5503831d35Sstevel typedef struct sc_gptwocfg_config { 5603831d35Sstevel int board; 5703831d35Sstevel struct gptwocfg_config *port_cookie; 5803831d35Sstevel gptwo_aid_t portid; 5903831d35Sstevel struct sc_gptwocfg_config *link; 6003831d35Sstevel struct sc_gptwocfg_config *next; 6103831d35Sstevel } sc_gptwocfg_config_t; 6203831d35Sstevel 6303831d35Sstevel static kmutex_t sc_gptwo_config_list_lock; 6403831d35Sstevel static sc_gptwocfg_config_t *sc_gptwo_config_list; 6503831d35Sstevel static dev_info_t *sc_find_axq_node(uint_t); 6603831d35Sstevel static sc_gptwocfg_cookie_t sc_configure(uint_t, int); 6703831d35Sstevel static spcd_t *sc_get_common_pcd(uint_t, uint_t); 6803831d35Sstevel static void sc_free_common_pcd(spcd_t *); 6903831d35Sstevel static gptwo_new_nodes_t *sc_gptwocfg_configure_axq(dev_info_t *, uint_t, int); 7003831d35Sstevel static gptwocfg_config_t *sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *); 7103831d35Sstevel static void dump_config(sc_gptwocfg_config_t *); 7203831d35Sstevel static void dump_pcd(spcd_t *); 7303831d35Sstevel static uint_t sc_get_agent_id(spcd_t *, uint_t, uint_t, uint_t); 7403831d35Sstevel static char *rsv_string(prdrsv_t); 7503831d35Sstevel 7603831d35Sstevel extern gptwo_new_nodes_t *gptwocfg_allocate_node_list(int); 7703831d35Sstevel extern void gptwocfg_free_node_list(gptwo_new_nodes_t *); 7803831d35Sstevel 7903831d35Sstevel static uint8_t *get_memlayout(uint32_t, uint32_t *); 8003831d35Sstevel 8103831d35Sstevel #ifdef NO_IOSRAM 8203831d35Sstevel int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t); 8303831d35Sstevel #else 8403831d35Sstevel extern int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t); 8503831d35Sstevel #endif 8603831d35Sstevel extern void gptwocfg_devi_attach_to_parent(dev_info_t *); 8703831d35Sstevel 8803831d35Sstevel /* 8903831d35Sstevel * Module control operations 9003831d35Sstevel */ 9103831d35Sstevel 9203831d35Sstevel extern struct mod_ops mod_miscops; 9303831d35Sstevel 9403831d35Sstevel static struct modlmisc modlmisc = { 9503831d35Sstevel &mod_miscops, /* Type of module */ 96f500b196SRichard Bean "Sun Fire 15000 gptwocfg" 9703831d35Sstevel }; 9803831d35Sstevel 9903831d35Sstevel static struct modlinkage modlinkage = { 10003831d35Sstevel MODREV_1, (void *)&modlmisc, NULL 10103831d35Sstevel }; 10203831d35Sstevel 10303831d35Sstevel int 10403831d35Sstevel _init() 10503831d35Sstevel { 10603831d35Sstevel int err = 0; 10703831d35Sstevel 10803831d35Sstevel mutex_init(&sc_gptwo_config_list_lock, NULL, MUTEX_DRIVER, NULL); 10903831d35Sstevel sc_gptwo_config_list = NULL; 11003831d35Sstevel 11103831d35Sstevel /* 11203831d35Sstevel * CPU/PCI devices are already registered by their respective modules, 11303831d35Sstevel * so all we need to do now is install. 11403831d35Sstevel */ 11503831d35Sstevel if ((err = mod_install(&modlinkage)) != 0) { 11603831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_gptwocfg failed to load, error=%d\n", 11703831d35Sstevel err)); 11803831d35Sstevel mutex_destroy(&sc_gptwo_config_list_lock); 11903831d35Sstevel } else { 12003831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_gptwocfg has been loaded.\n")); 12103831d35Sstevel } 12203831d35Sstevel return (err); 12303831d35Sstevel } 12403831d35Sstevel 12503831d35Sstevel int 12603831d35Sstevel _fini(void) 12703831d35Sstevel { 12803831d35Sstevel mutex_destroy(&sc_gptwo_config_list_lock); 12903831d35Sstevel return (mod_remove(&modlinkage)); 13003831d35Sstevel } 13103831d35Sstevel 13203831d35Sstevel int 13303831d35Sstevel _info(modinfop) 13403831d35Sstevel struct modinfo *modinfop; 13503831d35Sstevel { 13603831d35Sstevel return (mod_info(&modlinkage, modinfop)); 13703831d35Sstevel } 13803831d35Sstevel 13903831d35Sstevel static spcd_t * 14003831d35Sstevel sc_get_common_pcd(uint_t expander, uint_t prd_slot) 14103831d35Sstevel { 14203831d35Sstevel spcd_t *pcd; 14303831d35Sstevel gdcd_t *gdcd; 14403831d35Sstevel int portid; 14503831d35Sstevel int i, j, slot; 14603831d35Sstevel int dimm; 14703831d35Sstevel char *label1, *label2; 14803831d35Sstevel 14903831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_get_common_pcd() expander=%d prd_slot=%d\n", 15003831d35Sstevel expander, prd_slot)); 15103831d35Sstevel 15203831d35Sstevel gdcd = (gdcd_t *)kmem_zalloc(sizeof (gdcd_t), KM_SLEEP); 15303831d35Sstevel 15403831d35Sstevel /* 15503831d35Sstevel * Get the Starcat Specific Global DCD Structure from the golden 15603831d35Sstevel * IOSRAM. 15703831d35Sstevel */ 15803831d35Sstevel if (iosram_rd(GDCD_MAGIC, 0, sizeof (gdcd_t), (caddr_t)gdcd)) { 15903831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: Unable To Read GDCD " 16003831d35Sstevel "From IOSRAM\n"); 16103831d35Sstevel kmem_free(gdcd, sizeof (gdcd_t)); 16203831d35Sstevel return (NULL); 16303831d35Sstevel } 16403831d35Sstevel 16503831d35Sstevel if (gdcd->h.dcd_magic != GDCD_MAGIC) { 16603831d35Sstevel 16703831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Magic 0x%x\n", 16803831d35Sstevel gdcd->h.dcd_magic); 16903831d35Sstevel 17003831d35Sstevel kmem_free(gdcd, sizeof (gdcd_t)); 17103831d35Sstevel return (NULL); 17203831d35Sstevel } 17303831d35Sstevel 17403831d35Sstevel if (gdcd->h.dcd_version != DCD_VERSION) { 17503831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Version: " 17603831d35Sstevel "GDCD Version 0x%x Expecting 0x%x\n", 17703831d35Sstevel gdcd->h.dcd_version, DCD_VERSION); 17803831d35Sstevel 17903831d35Sstevel kmem_free(gdcd, sizeof (gdcd_t)); 18003831d35Sstevel return (NULL); 18103831d35Sstevel } 18203831d35Sstevel 18303831d35Sstevel pcd = (spcd_t *)kmem_zalloc(sizeof (spcd_t), KM_SLEEP); 18403831d35Sstevel 18503831d35Sstevel /* 18603831d35Sstevel * Copy various information from the platform specific Port 18703831d35Sstevel * Resource Descriptor (PRD) To the platform independent 18803831d35Sstevel * Port Configuration Descriptor. 18903831d35Sstevel */ 19003831d35Sstevel pcd->spcd_magic = PCD_MAGIC; 19103831d35Sstevel pcd->spcd_version = PCD_VERSION; 19203831d35Sstevel pcd->spcd_ptype = gdcd->dcd_prd[expander][prd_slot].prd_ptype; 19303831d35Sstevel pcd->spcd_ver_reg = gdcd->dcd_prd[expander][prd_slot].prd_ver_reg; 19403831d35Sstevel 19503831d35Sstevel if (pcd->spcd_ptype == SAFPTYPE_CPU) { 19603831d35Sstevel /* 19703831d35Sstevel * This will calculate the cpu speed based on the 19803831d35Sstevel * the actual frequency ratio * interconnect frequency 19903831d35Sstevel * converted to Mhz. 20003831d35Sstevel */ 20103831d35Sstevel pcd->spcd_afreq = gdcd->dcd_prd[expander][prd_slot]. 20203831d35Sstevel prd_afreq_ratio * 20303831d35Sstevel (uint16_t)((gdcd->dcd_intercon_freq + 500000) / 1000000); 20403831d35Sstevel } else { 20503831d35Sstevel /* 20603831d35Sstevel * For non-cpu devices, just pass through the frequency 20703831d35Sstevel * unchanged. 20803831d35Sstevel */ 20903831d35Sstevel pcd->spcd_afreq = 21003831d35Sstevel gdcd->dcd_prd[expander][prd_slot].prd_afreq_ratio; 21103831d35Sstevel } 21203831d35Sstevel 21303831d35Sstevel pcd->spcd_cache = gdcd->dcd_prd[expander][prd_slot].prd_cache; 21403831d35Sstevel 21503831d35Sstevel SC_DEBUG(1, (CE_WARN, "Safari Device Status status=0x%x\n", 21603831d35Sstevel gdcd->dcd_prd[expander][prd_slot].prd_prsv)); 21703831d35Sstevel 21803831d35Sstevel /* 21903831d35Sstevel * Fill in the entire port status. 22003831d35Sstevel */ 22103831d35Sstevel if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot].prd_prsv)) { 22203831d35Sstevel pcd->spcd_prsv = SPCD_RSV_PASS; 22303831d35Sstevel } else { 22403831d35Sstevel pcd->spcd_prsv = SPCD_RSV_FAIL; 22503831d35Sstevel } 22603831d35Sstevel 22703831d35Sstevel /* 22803831d35Sstevel * Fill in the per agent status. 22903831d35Sstevel */ 23003831d35Sstevel if (gdcd->dcd_prd[expander][prd_slot].prd_agent[1] == RSV_UNKNOWN) { 23103831d35Sstevel pcd->spcd_agent[0] = pcd->spcd_prsv; 23203831d35Sstevel pcd->spcd_agent[1] = SPCD_RSV_FAIL; 23303831d35Sstevel } else { 23403831d35Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) { 23503831d35Sstevel 23603831d35Sstevel if (RSV_GOOD( 23703831d35Sstevel gdcd->dcd_prd[expander][prd_slot].prd_agent[i])) 23803831d35Sstevel pcd->spcd_agent[i] = SPCD_RSV_PASS; 23903831d35Sstevel else 24003831d35Sstevel pcd->spcd_agent[i] = SPCD_RSV_FAIL; 24103831d35Sstevel } 24203831d35Sstevel } 24303831d35Sstevel 24403831d35Sstevel /* 24503831d35Sstevel * If this is a CPU device calculate the cpuid for it. For Starcat 24603831d35Sstevel * the cpuid is in the following format. 24703831d35Sstevel * 24803831d35Sstevel * EEEEEPPAPP 24903831d35Sstevel * 25003831d35Sstevel * where: EEEEE is the expander 25103831d35Sstevel * PP_PP is the portid 25203831d35Sstevel * __A__ is the sub-agent identifier. 25303831d35Sstevel */ 25403831d35Sstevel if (pcd->spcd_ptype == SAFPTYPE_CPU) { 25503831d35Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) { 25603831d35Sstevel switch (prd_slot) { 25703831d35Sstevel case 0: 25803831d35Sstevel case 1: 25903831d35Sstevel case 2: 26003831d35Sstevel case 3: 26103831d35Sstevel portid = (expander << 5) | prd_slot; 26203831d35Sstevel break; 26303831d35Sstevel case 4: /* Maxcat */ 26403831d35Sstevel portid = (expander << 5) | 8; 26503831d35Sstevel break; 26603831d35Sstevel case 5: /* Maxcat */ 26703831d35Sstevel portid = (expander << 5) | 9; 26803831d35Sstevel break; 26903831d35Sstevel default: 27003831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: invalid " 27103831d35Sstevel "prd_slot=%d\n", prd_slot); 27203831d35Sstevel } 27303831d35Sstevel pcd->spcd_cpuid[i] = (i << 2) | portid; 27403831d35Sstevel } 27503831d35Sstevel } 27603831d35Sstevel 27703831d35Sstevel /* 27803831d35Sstevel * Starcat does not have ports with UPA devices so 27903831d35Sstevel * spcd_upadev structure will not be filled in. 28003831d35Sstevel */ 28103831d35Sstevel 28203831d35Sstevel /* 28303831d35Sstevel * Fill in IO Bus Status 28403831d35Sstevel */ 28503831d35Sstevel for (i = 0; i < IOBUS_PER_PORT; i++) { 28603831d35Sstevel 28703831d35Sstevel SC_DEBUG(1, (CE_WARN, " IO Bus Status " 28803831d35Sstevel "bus=%d status=0x%x\n", i, 28903831d35Sstevel gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i])); 29003831d35Sstevel 29103831d35Sstevel if (RSV_GOOD( 29203831d35Sstevel gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i])) { 29303831d35Sstevel pcd->spcd_iobus_rsv[i] = SPCD_RSV_PASS; 29403831d35Sstevel } else { 29503831d35Sstevel pcd->spcd_iobus_rsv[i] = SPCD_RSV_FAIL; 29603831d35Sstevel } 29703831d35Sstevel 29803831d35Sstevel for (j = 0; j < IOCARD_PER_BUS; j++) 29903831d35Sstevel pcd->spcd_iocard_rsv[i][j] = SPCD_RSV_FAIL; 30003831d35Sstevel 30103831d35Sstevel /* 30203831d35Sstevel * Fill in IO Card Status 30303831d35Sstevel */ 30403831d35Sstevel for (j = 0; j < IOCARD_PER_BUS; j++) { 30503831d35Sstevel 30603831d35Sstevel SC_DEBUG(1, (CE_WARN, " Card Status bus=%d " 30703831d35Sstevel "slot=%d status=0x%x\n", i, j, 30803831d35Sstevel gdcd->dcd_prd[expander][prd_slot]. 30903831d35Sstevel prd_iocard_rsv[i][j])); 31003831d35Sstevel 31103831d35Sstevel if (j == 1) 31203831d35Sstevel continue; 31303831d35Sstevel 31403831d35Sstevel if (j == 0) 31503831d35Sstevel slot = 1; 31603831d35Sstevel else 31703831d35Sstevel slot = j; 31803831d35Sstevel 31903831d35Sstevel /* 32003831d35Sstevel * If POST marked the card as GOOD or if the slot 32103831d35Sstevel * is empty, we want to probe for the device. 32203831d35Sstevel */ 32303831d35Sstevel if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot]. 32403831d35Sstevel prd_iocard_rsv[i][j]) || 32503831d35Sstevel (gdcd->dcd_prd[expander][prd_slot]. 32603831d35Sstevel prd_iocard_rsv[i][j] == RSV_MISS) || 32703831d35Sstevel (gdcd->dcd_prd[expander][prd_slot]. 32803831d35Sstevel prd_iocard_rsv[i][j] == RSV_EMPTY_CASSETTE)) 32903831d35Sstevel pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_PASS; 33003831d35Sstevel else 33103831d35Sstevel pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_FAIL; 33203831d35Sstevel } 33303831d35Sstevel } 33403831d35Sstevel 33503831d35Sstevel /* 33603831d35Sstevel * Fill in WIC Link Status 33703831d35Sstevel */ 33803831d35Sstevel for (i = 0; i < LINKS_PER_PORT; i++) { 33903831d35Sstevel if (RSV_GOOD( 34003831d35Sstevel gdcd->dcd_prd[expander][prd_slot].prd_wic_links[i])) { 34103831d35Sstevel pcd->spcd_wic_links[i] = SPCD_RSV_PASS; 34203831d35Sstevel 34303831d35Sstevel } else { 34403831d35Sstevel pcd->spcd_wic_links[i] = SPCD_RSV_FAIL; 34503831d35Sstevel } 34603831d35Sstevel } 34703831d35Sstevel 34803831d35Sstevel /* 34903831d35Sstevel * Get data for the "bank-status" property. 35003831d35Sstevel */ 35103831d35Sstevel pcd->sprd_bank_rsv[0] = 35203831d35Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][0]); 35303831d35Sstevel pcd->sprd_bank_rsv[1] = 35403831d35Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][0]); 35503831d35Sstevel pcd->sprd_bank_rsv[2] = 35603831d35Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][1]); 35703831d35Sstevel pcd->sprd_bank_rsv[3] = 35803831d35Sstevel rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][1]); 35903831d35Sstevel 36003831d35Sstevel dimm = 0; 36103831d35Sstevel for (i = 0; i < PMBANKS_PER_PORT; i++) { 36203831d35Sstevel for (j = 0; j < DIMMS_PER_PMBANK; j++) { 36303831d35Sstevel if (dimm < MAX_DIMMS_PER_PORT) { 36403831d35Sstevel pcd->sprd_dimm[dimm] = rsv_string( 36503831d35Sstevel gdcd->dcd_prd[expander][prd_slot]. 36603831d35Sstevel prd_dimm[i][j]); 36703831d35Sstevel dimm++; 36803831d35Sstevel } 36903831d35Sstevel } 37003831d35Sstevel } 37103831d35Sstevel 37203831d35Sstevel /* 37303831d35Sstevel * Get data for the "ecache-dimm-label" property. 37403831d35Sstevel * 37503831d35Sstevel * Right now it is hardcoded, but we should eventually get this 37603831d35Sstevel * from the SC. 37703831d35Sstevel */ 37803831d35Sstevel label1 = NULL; 37903831d35Sstevel label2 = NULL; 38003831d35Sstevel 38103831d35Sstevel switch (prd_slot) { 38203831d35Sstevel case 0: 38303831d35Sstevel label1 = "4400"; 38403831d35Sstevel label2 = "4300"; 38503831d35Sstevel break; 38603831d35Sstevel case 1: 38703831d35Sstevel label1 = "5400"; 38803831d35Sstevel label2 = "5300"; 38903831d35Sstevel break; 39003831d35Sstevel case 2: 39103831d35Sstevel label1 = "6400"; 39203831d35Sstevel label2 = "6300"; 39303831d35Sstevel break; 39403831d35Sstevel case 3: 39503831d35Sstevel label1 = "7400"; 39603831d35Sstevel label2 = "7300"; 39703831d35Sstevel break; 39803831d35Sstevel 39903831d35Sstevel /* 40003831d35Sstevel * Maxcat labels. 40103831d35Sstevel */ 40203831d35Sstevel case 4: 40303831d35Sstevel label1 = "6400"; 40403831d35Sstevel label2 = "6300"; 40503831d35Sstevel break; 40603831d35Sstevel case 5: 40703831d35Sstevel label1 = "7400"; 40803831d35Sstevel label2 = "7300"; 40903831d35Sstevel break; 41003831d35Sstevel } 41103831d35Sstevel 41203831d35Sstevel i = 0; 41303831d35Sstevel if (label1) { 41403831d35Sstevel pcd->sprd_ecache_dimm_label[i] = 41503831d35Sstevel kmem_alloc(strlen(label1) + 1, KM_SLEEP); 41603831d35Sstevel 41703831d35Sstevel (void) strcpy(pcd->sprd_ecache_dimm_label[i], label1); 41803831d35Sstevel 41903831d35Sstevel i++; 42003831d35Sstevel } 42103831d35Sstevel if (label2) { 42203831d35Sstevel pcd->sprd_ecache_dimm_label[i] = 42303831d35Sstevel kmem_alloc(strlen(label2) + 1, KM_SLEEP); 42403831d35Sstevel 42503831d35Sstevel (void) strcpy(pcd->sprd_ecache_dimm_label[i], label2); 42603831d35Sstevel 42703831d35Sstevel i++; 42803831d35Sstevel 42903831d35Sstevel } 43003831d35Sstevel 43103831d35Sstevel kmem_free(gdcd, sizeof (gdcd_t)); 43203831d35Sstevel 43303831d35Sstevel #ifdef DEBUG 43403831d35Sstevel dump_pcd(pcd); 43503831d35Sstevel #endif 43603831d35Sstevel 43703831d35Sstevel return (pcd); 43803831d35Sstevel } 43903831d35Sstevel 44003831d35Sstevel void 44103831d35Sstevel sc_free_common_pcd(spcd_t *pcd) 44203831d35Sstevel { 44303831d35Sstevel int i; 44403831d35Sstevel 445*07d06da5SSurya Prakki SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd pcd=%p\n", (void *)pcd)); 44603831d35Sstevel 44703831d35Sstevel if (pcd->memory_layout && pcd->memory_layout_size) { 44803831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd: memory_layout %p " 449*07d06da5SSurya Prakki "size=%x", (void *)pcd->memory_layout, 450*07d06da5SSurya Prakki pcd->memory_layout_size)); 45103831d35Sstevel kmem_free(pcd->memory_layout, pcd->memory_layout_size); 45203831d35Sstevel } 45303831d35Sstevel 45403831d35Sstevel for (i = 0; i < MAX_BANKS_PER_PORT; i++) { 45503831d35Sstevel if (pcd->sprd_bank_rsv[i]) { 45603831d35Sstevel kmem_free(pcd->sprd_bank_rsv[i], 45703831d35Sstevel strlen(pcd->sprd_bank_rsv[i]) + 1); 45803831d35Sstevel 45903831d35Sstevel pcd->sprd_bank_rsv[i] = NULL; 46003831d35Sstevel } 46103831d35Sstevel } 46203831d35Sstevel 46303831d35Sstevel for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 46403831d35Sstevel if (pcd->sprd_dimm[i]) { 46503831d35Sstevel kmem_free(pcd->sprd_dimm[i], 46603831d35Sstevel strlen(pcd->sprd_dimm[i]) + 1); 46703831d35Sstevel 46803831d35Sstevel pcd->sprd_dimm[i] = NULL; 46903831d35Sstevel } 47003831d35Sstevel if (pcd->sprd_ecache_dimm_label[i]) { 47103831d35Sstevel kmem_free(pcd->sprd_ecache_dimm_label[i], 47203831d35Sstevel strlen(pcd->sprd_ecache_dimm_label[i]) + 1); 47303831d35Sstevel 47403831d35Sstevel pcd->sprd_ecache_dimm_label[i] = NULL; 47503831d35Sstevel } 47603831d35Sstevel } 47703831d35Sstevel 47803831d35Sstevel kmem_free(pcd, sizeof (spcd_t)); 47903831d35Sstevel } 48003831d35Sstevel 48103831d35Sstevel sc_gptwocfg_cookie_t 48203831d35Sstevel sc_probe_board(uint_t board) 48303831d35Sstevel { 48403831d35Sstevel return (sc_configure(board, 1)); 48503831d35Sstevel } 48603831d35Sstevel 48703831d35Sstevel static sc_gptwocfg_cookie_t 48803831d35Sstevel sc_configure(uint_t board, int create_nodes) 48903831d35Sstevel { 49003831d35Sstevel spcd_t *pcd; 49103831d35Sstevel dev_info_t *ap, *axq_dip; 49203831d35Sstevel uint_t agent_id; 49303831d35Sstevel uint_t prd_slot, prd_slot_start, prd_slot_end; 49403831d35Sstevel uint_t expander, slot; 49503831d35Sstevel gptwo_new_nodes_t *new_nodes; 49603831d35Sstevel gptwocfg_config_t *port_cookie; 49703831d35Sstevel struct sc_gptwocfg_config *board_config, *last, *new; 49803831d35Sstevel int created_node = 0; 49903831d35Sstevel uint32_t size; 50003831d35Sstevel 50103831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: board=%d, create_nodes=%d\n", 50203831d35Sstevel board, create_nodes)); 50303831d35Sstevel 50403831d35Sstevel if (board > 35) { 50503831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_gptwocfg - probe_board - " 50603831d35Sstevel "invalid board 0x%x\n", board)); 50703831d35Sstevel return (NULL); 50803831d35Sstevel } 50903831d35Sstevel 51003831d35Sstevel slot = board & 1; /* Extract Slot Number */ 51103831d35Sstevel expander = board >> 1; /* Extract Expander Number */ 51203831d35Sstevel 51303831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: exp=0x%x slot=0x%x\n", 51403831d35Sstevel expander, slot)); 51503831d35Sstevel 51603831d35Sstevel /* 51703831d35Sstevel * Get the Attachment Point. For Starcat the parent of all 51803831d35Sstevel * Safari children is root node. 51903831d35Sstevel */ 52003831d35Sstevel ap = ddi_root_node(); 52103831d35Sstevel 52203831d35Sstevel /* 52303831d35Sstevel * Get the agent id of the AXQ. 52403831d35Sstevel */ 52503831d35Sstevel agent_id = (expander << 5) | 0x1e | slot; 52603831d35Sstevel 52703831d35Sstevel /* 52803831d35Sstevel * Look to see if the board is already configured by searching for 52903831d35Sstevel * its AXQ. 53003831d35Sstevel */ 53103831d35Sstevel if (create_nodes && (axq_dip = sc_find_axq_node(agent_id))) { 53203831d35Sstevel ddi_release_devi(axq_dip); 53303831d35Sstevel cmn_err(CE_WARN, "Board %d AXQ is already configured\n", 53403831d35Sstevel board); 53503831d35Sstevel return (NULL); 53603831d35Sstevel } 53703831d35Sstevel 53803831d35Sstevel /* 53903831d35Sstevel * Probe AXQ first 54003831d35Sstevel */ 54103831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Probing AXQ exp=0x%x brd=0x%x\n", 54203831d35Sstevel expander, slot)); 54303831d35Sstevel 54403831d35Sstevel /* 54503831d35Sstevel * The generic gptwocfg does not support the AXQ, so we need 54603831d35Sstevel * to configure it. The AXQ branch is returned held. 54703831d35Sstevel */ 54803831d35Sstevel new_nodes = sc_gptwocfg_configure_axq(ap, agent_id, create_nodes); 54903831d35Sstevel 55003831d35Sstevel if (new_nodes == NULL) { 55103831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Can not probe AXQ\n")); 55203831d35Sstevel return (NULL); 55303831d35Sstevel } 55403831d35Sstevel 55503831d35Sstevel port_cookie = kmem_zalloc(sizeof (gptwocfg_config_t), KM_SLEEP); 55603831d35Sstevel 55703831d35Sstevel /* 55803831d35Sstevel * Build a cookie for the AXQ. 55903831d35Sstevel */ 56003831d35Sstevel port_cookie->gptwo_ap = ap; 56103831d35Sstevel port_cookie->gptwo_portid = agent_id; 56203831d35Sstevel port_cookie->gptwo_nodes = new_nodes; 56303831d35Sstevel 56403831d35Sstevel board_config = kmem_zalloc(sizeof (sc_gptwocfg_config_t), KM_SLEEP); 56503831d35Sstevel 56603831d35Sstevel board_config->port_cookie = port_cookie; 56703831d35Sstevel board_config->board = board; 56803831d35Sstevel board_config->portid = agent_id; 56903831d35Sstevel board_config->link = NULL; 57003831d35Sstevel last = board_config; 57103831d35Sstevel 57203831d35Sstevel mutex_enter(&sc_gptwo_config_list_lock); 57303831d35Sstevel board_config->next = sc_gptwo_config_list; 57403831d35Sstevel sc_gptwo_config_list = board_config; 57503831d35Sstevel mutex_exit(&sc_gptwo_config_list_lock); 57603831d35Sstevel 57703831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: AXQ Probing Complete. " 57803831d35Sstevel "%d nodes added\n", new_nodes->gptwo_number_of_nodes)); 57903831d35Sstevel 58003831d35Sstevel /* 58103831d35Sstevel * Determine the starting ending slots of the PRD array. 58203831d35Sstevel */ 58303831d35Sstevel switch (slot) { 58403831d35Sstevel case 0: /* Full Bandwidth Slot */ 58503831d35Sstevel prd_slot_start = 0; 58603831d35Sstevel prd_slot_end = 3; 58703831d35Sstevel break; 58803831d35Sstevel case 1: /* Half Bandwidth Slot */ 58903831d35Sstevel prd_slot_start = 4; 59003831d35Sstevel prd_slot_end = 5; 59103831d35Sstevel break; 59203831d35Sstevel default: 59303831d35Sstevel SC_DEBUG(1, (CE_WARN, "Unknown Board Address - " 59403831d35Sstevel "Can not probe\n")); 59503831d35Sstevel return (board_config); 59603831d35Sstevel } 59703831d35Sstevel 59803831d35Sstevel /* 59903831d35Sstevel * For each valid PRD entry, determine the agent id which is based 60003831d35Sstevel * on what type of device is described by the slot, and then 60103831d35Sstevel * call the safari configurator. 60203831d35Sstevel */ 60303831d35Sstevel for (prd_slot = prd_slot_start; prd_slot <= prd_slot_end; prd_slot++) { 60403831d35Sstevel 60503831d35Sstevel pcd = sc_get_common_pcd(expander, prd_slot); 60603831d35Sstevel 60703831d35Sstevel if (pcd == NULL) { 60803831d35Sstevel 60903831d35Sstevel /* 61003831d35Sstevel * We can not get a PCD for this port so skip it. 61103831d35Sstevel */ 61203831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: Can not get PCD " 61303831d35Sstevel "expander 0x%x prd slot 0x%x\n", 61403831d35Sstevel expander, prd_slot); 61503831d35Sstevel 61603831d35Sstevel return (board_config); 61703831d35Sstevel } 61803831d35Sstevel 61903831d35Sstevel /* 62003831d35Sstevel * Only configure good devices. 62103831d35Sstevel */ 62203831d35Sstevel if (pcd->spcd_prsv == SPCD_RSV_PASS) { 62303831d35Sstevel /* 62403831d35Sstevel * Determine the agent id. 62503831d35Sstevel */ 62603831d35Sstevel agent_id = sc_get_agent_id( 62703831d35Sstevel pcd, expander, slot, prd_slot); 62803831d35Sstevel 62903831d35Sstevel pcd->memory_layout = get_memlayout(agent_id, &size); 63003831d35Sstevel pcd->memory_layout_size = size; 63103831d35Sstevel 63203831d35Sstevel /* 63303831d35Sstevel * Call Platform Independent gptwo configurator to 63403831d35Sstevel * create node and properties. 63503831d35Sstevel */ 63603831d35Sstevel if (create_nodes) { 63703831d35Sstevel port_cookie = 63803831d35Sstevel gptwocfg_configure(ap, pcd, agent_id); 63903831d35Sstevel if (port_cookie) 64003831d35Sstevel created_node++; 64103831d35Sstevel } 64203831d35Sstevel 64303831d35Sstevel new = kmem_zalloc 64403831d35Sstevel (sizeof (sc_gptwocfg_config_t), KM_SLEEP); 64503831d35Sstevel 64603831d35Sstevel /* 64703831d35Sstevel * XXX Shouldn't port_cookie be NULL if 64803831d35Sstevel * !create_nodes ? 64903831d35Sstevel */ 65003831d35Sstevel new->port_cookie = port_cookie; 65103831d35Sstevel new->portid = agent_id; 65203831d35Sstevel new->link = NULL; 65303831d35Sstevel last->link = new; 65403831d35Sstevel last = new; 65503831d35Sstevel } else { 65603831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Bad Agent " 65703831d35Sstevel "Exp=0x%x PRD Slot=0x%x prsv Status=0x%x\n", 65803831d35Sstevel expander, prd_slot, pcd->spcd_prsv)); 65903831d35Sstevel } 66003831d35Sstevel 66103831d35Sstevel sc_free_common_pcd(pcd); 66203831d35Sstevel 66303831d35Sstevel } /* for loop */ 66403831d35Sstevel 66503831d35Sstevel dump_config(board_config); 66603831d35Sstevel 66703831d35Sstevel if (create_nodes && !created_node) { 66803831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: GPTWO Devices failed " 66903831d35Sstevel "to configure - unprobing board %d\n", board)); 67003831d35Sstevel board_config = sc_unprobe_board(board); 67103831d35Sstevel } 67203831d35Sstevel 67303831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_configure: Returning 0x%p\n", 674*07d06da5SSurya Prakki (void *)board_config)); 67503831d35Sstevel 67603831d35Sstevel return (board_config); 67703831d35Sstevel } 67803831d35Sstevel 67903831d35Sstevel sc_gptwocfg_cookie_t 68003831d35Sstevel sc_unprobe_board(uint_t board) 68103831d35Sstevel { 68203831d35Sstevel sc_gptwocfg_config_t *board_config, *axq_config, *prior_config; 68303831d35Sstevel gptwocfg_cookie_t port_cookie; 68403831d35Sstevel 68503831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: board=%d\n", board)); 68603831d35Sstevel 68703831d35Sstevel if (board > 35) { 68803831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 68903831d35Sstevel "invalid board 0x%x\n", board)); 69003831d35Sstevel return (NULL); 69103831d35Sstevel } 69203831d35Sstevel mutex_enter(&sc_gptwo_config_list_lock); 69303831d35Sstevel board_config = sc_gptwo_config_list; 69403831d35Sstevel while (board_config != NULL) { 69503831d35Sstevel if (board_config->board == board) { 69603831d35Sstevel break; 69703831d35Sstevel } 69803831d35Sstevel board_config = board_config->next; 69903831d35Sstevel } 70003831d35Sstevel mutex_exit(&sc_gptwo_config_list_lock); 70103831d35Sstevel 70203831d35Sstevel if (board_config == NULL) { 70303831d35Sstevel 70403831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: No " 70503831d35Sstevel "config structure board=0x%x\n", board)); 70603831d35Sstevel 70703831d35Sstevel /* 70803831d35Sstevel * Configure the board without creating nodes. 70903831d35Sstevel */ 71003831d35Sstevel board_config = sc_configure(board, 0); 71103831d35Sstevel 71203831d35Sstevel if (board_config == NULL) { 71303831d35Sstevel 71403831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: sc_unprobe_board: " 71503831d35Sstevel "Unable to unconfigure board %d - board is not " 71603831d35Sstevel "configured\n", board); 71703831d35Sstevel 71803831d35Sstevel return (NULL); 71903831d35Sstevel } 72003831d35Sstevel } 72103831d35Sstevel 72203831d35Sstevel axq_config = board_config; 72303831d35Sstevel 72403831d35Sstevel /* 72503831d35Sstevel * Walk the link of ports on this board and unconfigure them. 72603831d35Sstevel * Save the AXQ for last. 72703831d35Sstevel */ 72803831d35Sstevel while (board_config->link != NULL) { 72903831d35Sstevel prior_config = board_config; 73003831d35Sstevel board_config = board_config->link; 73103831d35Sstevel 73203831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 73303831d35Sstevel "calling gptwocfg_unconfigure(ap=0x%p portid=0x%x)\n", 734*07d06da5SSurya Prakki (void *)ddi_root_node(), board_config->portid)); 73503831d35Sstevel 73603831d35Sstevel port_cookie = gptwocfg_unconfigure(ddi_root_node(), 73703831d35Sstevel board_config->portid); 73803831d35Sstevel 73903831d35Sstevel SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 74003831d35Sstevel "gptwocfg_unconfigure returned cookie=0x%p\n", 74103831d35Sstevel port_cookie)); 74203831d35Sstevel 74303831d35Sstevel if (port_cookie == NULL) { 74403831d35Sstevel /* 74503831d35Sstevel * Can be removed from list. 74603831d35Sstevel */ 74703831d35Sstevel prior_config->link = board_config->link; 74803831d35Sstevel kmem_free(board_config, sizeof (sc_gptwocfg_config_t)); 74903831d35Sstevel board_config = prior_config; 75003831d35Sstevel } else { 75103831d35Sstevel board_config->port_cookie = port_cookie; 75203831d35Sstevel } 75303831d35Sstevel } 75403831d35Sstevel 75503831d35Sstevel if (axq_config->link == NULL) { 75603831d35Sstevel 75703831d35Sstevel /* 75803831d35Sstevel * If all the other Safari devices have been successfully 75903831d35Sstevel * unconfigured, then the AXQ can be unconfigured. 76003831d35Sstevel */ 76103831d35Sstevel axq_config->port_cookie = 76203831d35Sstevel sc_gptwocfg_unconfigure_axq(axq_config->port_cookie); 76303831d35Sstevel 76403831d35Sstevel if (axq_config->port_cookie == NULL) { 76503831d35Sstevel 76603831d35Sstevel /* 76703831d35Sstevel * If the AXQ was successfully unconfigured, then 76803831d35Sstevel * the board is removed from the configured list. 76903831d35Sstevel */ 77003831d35Sstevel mutex_enter(&sc_gptwo_config_list_lock); 77103831d35Sstevel if (sc_gptwo_config_list == axq_config) { 77203831d35Sstevel sc_gptwo_config_list = axq_config->next; 77303831d35Sstevel } else { 77403831d35Sstevel board_config = sc_gptwo_config_list; 77503831d35Sstevel while (board_config->next != axq_config) { 77603831d35Sstevel board_config = board_config->next; 77703831d35Sstevel } 77803831d35Sstevel board_config->next = axq_config->next; 77903831d35Sstevel } 78003831d35Sstevel mutex_exit(&sc_gptwo_config_list_lock); 78103831d35Sstevel kmem_free(axq_config, sizeof (sc_gptwocfg_config_t)); 78203831d35Sstevel axq_config = NULL; 78303831d35Sstevel } 78403831d35Sstevel } 78503831d35Sstevel dump_config(axq_config); 78603831d35Sstevel return (axq_config); 78703831d35Sstevel } 78803831d35Sstevel 78903831d35Sstevel int 79003831d35Sstevel sc_next_node(sc_gptwocfg_cookie_t c, dev_info_t *previous, dev_info_t **next) 79103831d35Sstevel { 79203831d35Sstevel dev_info_t *dip; 79303831d35Sstevel sc_gptwocfg_config_t *cookie; 79403831d35Sstevel 79503831d35Sstevel SC_DEBUG(1, (CE_WARN, "sccfg: sccfg_next_node" 796*07d06da5SSurya Prakki "(c=0x%p, previous=0x%p, next=0x%p)\n", (void *)c, 797*07d06da5SSurya Prakki (void *)previous, (void *)next)); 79803831d35Sstevel 79903831d35Sstevel cookie = (sc_gptwocfg_config_t *)c; 80003831d35Sstevel 80103831d35Sstevel if (cookie == NULL) { 80203831d35Sstevel cmn_err(CE_WARN, "sccfg: sccfg_next_node - " 80303831d35Sstevel "Invalid Cookie\n"); 80403831d35Sstevel return (0); 80503831d35Sstevel } 80603831d35Sstevel if (previous == NULL) { 80703831d35Sstevel /* 80803831d35Sstevel * Start with the AXQ node. 80903831d35Sstevel */ 81003831d35Sstevel if (gptwocfg_next_node(cookie->port_cookie, NULL, &dip)) { 81103831d35Sstevel *next = dip; 81203831d35Sstevel return (1); 81303831d35Sstevel } else { 81403831d35Sstevel return (0); 81503831d35Sstevel } 81603831d35Sstevel } 81703831d35Sstevel 81803831d35Sstevel while (cookie != NULL) { 81903831d35Sstevel if (gptwocfg_next_node(cookie->port_cookie, previous, &dip)) { 82003831d35Sstevel if ((dip == NULL) && (cookie->link == NULL)) { 82103831d35Sstevel *next = NULL; 82203831d35Sstevel return (1); 82303831d35Sstevel } 82403831d35Sstevel if (dip != NULL) { 82503831d35Sstevel *next = dip; 82603831d35Sstevel return (1); 82703831d35Sstevel } 82803831d35Sstevel 82903831d35Sstevel /* dip == NULL */ 83003831d35Sstevel 83103831d35Sstevel previous = NULL; 83203831d35Sstevel } 83303831d35Sstevel cookie = cookie->link; 83403831d35Sstevel } 83503831d35Sstevel 83603831d35Sstevel return (0); 83703831d35Sstevel } 83803831d35Sstevel 83903831d35Sstevel static dev_info_t * 84003831d35Sstevel sc_find_axq_node(uint_t axq_id) 84103831d35Sstevel { 84203831d35Sstevel char *name; 84303831d35Sstevel int size; 84403831d35Sstevel gptwo_regspec_t *reg; 84503831d35Sstevel dev_info_t *dip; 84603831d35Sstevel uint_t id; 84703831d35Sstevel int circ; 84803831d35Sstevel 84903831d35Sstevel SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: id=0x%x\n", axq_id)); 85003831d35Sstevel 85103831d35Sstevel /* 85203831d35Sstevel * Hold root node busy to walk its child list 85303831d35Sstevel */ 85403831d35Sstevel ndi_devi_enter(ddi_root_node(), &circ); 85503831d35Sstevel 85603831d35Sstevel dip = ddi_get_child(ddi_root_node()); 85703831d35Sstevel 85803831d35Sstevel while (dip != NULL) { 85903831d35Sstevel 86003831d35Sstevel SC_DEBUG(1, (CE_CONT, "Searching dip=0x%p for our AXQ\n", 861*07d06da5SSurya Prakki (void *)dip)); 86203831d35Sstevel 86303831d35Sstevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 86403831d35Sstevel DDI_PROP_DONTPASS, "name", (caddr_t)&name, &size) 86503831d35Sstevel != DDI_PROP_SUCCESS) { 86603831d35Sstevel 86703831d35Sstevel /* 86803831d35Sstevel * This node does not have a name property. 86903831d35Sstevel */ 87003831d35Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p does not have a " 871*07d06da5SSurya Prakki "'name' property\n", (void *)dip)); 87203831d35Sstevel 87303831d35Sstevel dip = ddi_get_next_sibling(dip); 87403831d35Sstevel continue; 87503831d35Sstevel } 87603831d35Sstevel 877*07d06da5SSurya Prakki SC_DEBUG(1, (CE_CONT, "dip=0x%p name=%s\n", (void *)dip, name)); 87803831d35Sstevel 87903831d35Sstevel if (strcmp(name, "address-extender-queue")) { 88003831d35Sstevel 88103831d35Sstevel /* 88203831d35Sstevel * This node is not a AXQ node. 88303831d35Sstevel */ 88403831d35Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p is not an AXQ " 885*07d06da5SSurya Prakki "node\n", (void *)dip)); 88603831d35Sstevel kmem_free(name, size); 88703831d35Sstevel dip = ddi_get_next_sibling(dip); 88803831d35Sstevel continue; 88903831d35Sstevel } 89003831d35Sstevel kmem_free(name, size); 89103831d35Sstevel 89203831d35Sstevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 89303831d35Sstevel DDI_PROP_DONTPASS, "reg", (caddr_t)®, &size) 89403831d35Sstevel != DDI_PROP_SUCCESS) { 89503831d35Sstevel 89603831d35Sstevel /* 89703831d35Sstevel * This AXQ node does not have a reg property. 89803831d35Sstevel */ 89903831d35Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p (AXQ Node) does " 900*07d06da5SSurya Prakki "have a 'reg' property\n", (void *)dip)); 90103831d35Sstevel dip = ddi_get_next_sibling(dip); 90203831d35Sstevel continue; 90303831d35Sstevel } 90403831d35Sstevel 90503831d35Sstevel id = ((reg[0].gptwo_phys_hi & 1) << 9) | 90603831d35Sstevel ((reg[0].gptwo_phys_low & 0xff800000) >> 23); 90703831d35Sstevel 90803831d35Sstevel kmem_free(reg, size); 90903831d35Sstevel 91003831d35Sstevel if (axq_id != id) { 91103831d35Sstevel 91203831d35Sstevel /* 91303831d35Sstevel * This is the wrong AXQ node. 91403831d35Sstevel */ 91503831d35Sstevel SC_DEBUG(1, (CE_CONT, "dip=0x%p Wrong node id=0x%x\n", 916*07d06da5SSurya Prakki (void *)dip, id)); 91703831d35Sstevel 91803831d35Sstevel dip = ddi_get_next_sibling(dip); 91903831d35Sstevel continue; 92003831d35Sstevel 92103831d35Sstevel } 92203831d35Sstevel 92303831d35Sstevel /* 92403831d35Sstevel * The correct AXQ node was found. 92503831d35Sstevel */ 926*07d06da5SSurya Prakki SC_DEBUG(1, (CE_CONT, "dip=0x%p Found AXQ Node\n", 927*07d06da5SSurya Prakki (void *)dip)); 92803831d35Sstevel ndi_hold_devi(dip); 92903831d35Sstevel break; 93003831d35Sstevel } 93103831d35Sstevel ndi_devi_exit(ddi_root_node(), circ); 93203831d35Sstevel 933*07d06da5SSurya Prakki SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: Returning 0x%p\n", 934*07d06da5SSurya Prakki (void *)dip)); 93503831d35Sstevel 93603831d35Sstevel return (dip); 93703831d35Sstevel } 93803831d35Sstevel 93903831d35Sstevel struct axq_arg { 94003831d35Sstevel uint_t id; 94103831d35Sstevel dev_info_t *axq_dip; 94203831d35Sstevel }; 94303831d35Sstevel 94403831d35Sstevel /*ARGSUSED*/ 94503831d35Sstevel static int 94603831d35Sstevel axq_set_prop(dev_info_t *axq_dip, void *arg, uint_t flags) 94703831d35Sstevel { 94803831d35Sstevel struct axq_arg *aqp = (struct axq_arg *)arg; 94903831d35Sstevel gptwo_regspec_t reg[2]; 95003831d35Sstevel uint_t id; 95103831d35Sstevel 95203831d35Sstevel ASSERT(aqp); 95303831d35Sstevel 95403831d35Sstevel id = aqp->id; 95503831d35Sstevel 95603831d35Sstevel if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 95703831d35Sstevel "name", "address-extender-queue") != DDI_SUCCESS) { 95803831d35Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 95903831d35Sstevel "to create name property\n")); 96003831d35Sstevel return (DDI_WALK_ERROR); 96103831d35Sstevel } 96203831d35Sstevel 96303831d35Sstevel if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 96403831d35Sstevel "device_type", "address-extender-queue") != DDI_SUCCESS) { 96503831d35Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 96603831d35Sstevel "to create device_type property\n")); 96703831d35Sstevel return (DDI_WALK_ERROR); 96803831d35Sstevel } 96903831d35Sstevel 97003831d35Sstevel if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 97103831d35Sstevel "compatible", "SUNW,axq") != DDI_SUCCESS) { 97203831d35Sstevel SC_DEBUG(1, (CE_CONT, "sc_gptwocfg: failed " 97303831d35Sstevel "to create compatible property\n")); 97403831d35Sstevel return (DDI_WALK_ERROR); 97503831d35Sstevel } 97603831d35Sstevel 97703831d35Sstevel if (ndi_prop_update_int(DDI_DEV_T_NONE, axq_dip, 97803831d35Sstevel "portid", id) != DDI_SUCCESS) { 97903831d35Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 98003831d35Sstevel "to create portid property\n")); 98103831d35Sstevel return (DDI_WALK_ERROR); 98203831d35Sstevel } 98303831d35Sstevel 98403831d35Sstevel reg[0].gptwo_phys_hi = 0x400 | (id >> 9); 98503831d35Sstevel reg[0].gptwo_phys_low = (id << 23); 98603831d35Sstevel reg[0].gptwo_size_hi = 0; 98703831d35Sstevel reg[0].gptwo_size_low = 0x520; 98803831d35Sstevel 98903831d35Sstevel reg[1].gptwo_phys_hi = 0x401; 99003831d35Sstevel reg[1].gptwo_phys_low = 0xf0000000; 99103831d35Sstevel reg[1].gptwo_size_hi = 0; 99203831d35Sstevel reg[1].gptwo_size_low = 0x520; 99303831d35Sstevel 99403831d35Sstevel if (ndi_prop_update_int_array(DDI_DEV_T_NONE, 99503831d35Sstevel axq_dip, "reg", (int *)®, 99603831d35Sstevel (sizeof (gptwo_regspec_t) * 2)/sizeof (int)) != DDI_SUCCESS) { 99703831d35Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 99803831d35Sstevel "to create reg property\n")); 99903831d35Sstevel return (DDI_WALK_ERROR); 100003831d35Sstevel } 100103831d35Sstevel 100203831d35Sstevel return (DDI_WALK_TERMINATE); 100303831d35Sstevel } 100403831d35Sstevel 100503831d35Sstevel /*ARGSUSED*/ 100603831d35Sstevel static void 100703831d35Sstevel get_axq_dip(dev_info_t *rdip, void *arg, uint_t flags) 100803831d35Sstevel { 100903831d35Sstevel struct axq_arg *aqp = (struct axq_arg *)arg; 101003831d35Sstevel 101103831d35Sstevel ASSERT(aqp); 101203831d35Sstevel 101303831d35Sstevel aqp->axq_dip = rdip; 101403831d35Sstevel } 101503831d35Sstevel 101603831d35Sstevel static gptwo_new_nodes_t * 101703831d35Sstevel sc_gptwocfg_configure_axq(dev_info_t *ap, uint_t id, int create_nodes) 101803831d35Sstevel { 101903831d35Sstevel struct axq_arg arg = {0}; 102003831d35Sstevel devi_branch_t b = {0}; 102103831d35Sstevel dev_info_t *axq_dip, *fdip = NULL; 102203831d35Sstevel gptwo_new_nodes_t *new_nodes = NULL; 102303831d35Sstevel int rv; 102403831d35Sstevel 102503831d35Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: id=0x%x " 102603831d35Sstevel "create_nodes=%d\n", id, create_nodes)); 102703831d35Sstevel 102803831d35Sstevel if (!create_nodes) { 102903831d35Sstevel axq_dip = sc_find_axq_node(id); 103003831d35Sstevel 103103831d35Sstevel if (axq_dip) { 103203831d35Sstevel new_nodes = gptwocfg_allocate_node_list(1); 103303831d35Sstevel new_nodes->gptwo_nodes[0] = axq_dip; 103403831d35Sstevel ASSERT(!e_ddi_branch_held(axq_dip)); 103503831d35Sstevel e_ddi_branch_hold(axq_dip); 103603831d35Sstevel /* 103703831d35Sstevel * Release hold from sc_find_axq_node() 103803831d35Sstevel */ 103903831d35Sstevel ddi_release_devi(axq_dip); 104003831d35Sstevel } 104103831d35Sstevel 104203831d35Sstevel SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: " 1043*07d06da5SSurya Prakki "Returning 0x%p\n", (void *)new_nodes)); 104403831d35Sstevel 104503831d35Sstevel return (new_nodes); 104603831d35Sstevel } 104703831d35Sstevel 104803831d35Sstevel arg.id = id; 104903831d35Sstevel arg.axq_dip = NULL; 105003831d35Sstevel 105103831d35Sstevel b.arg = &arg; 105203831d35Sstevel b.type = DEVI_BRANCH_SID; 105303831d35Sstevel b.create.sid_branch_create = axq_set_prop; 105403831d35Sstevel b.devi_branch_callback = get_axq_dip; 105503831d35Sstevel 105603831d35Sstevel rv = e_ddi_branch_create(ap, &b, &fdip, DEVI_BRANCH_CONFIGURE); 105703831d35Sstevel if (rv != 0) { 105803831d35Sstevel char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 105903831d35Sstevel 106003831d35Sstevel /* 106103831d35Sstevel * If non-NULL, fdip is held and must be released. 106203831d35Sstevel */ 106303831d35Sstevel if (fdip != NULL) { 106403831d35Sstevel (void) ddi_pathname(fdip, path); 106503831d35Sstevel ddi_release_devi(fdip); 106603831d35Sstevel } else { 106703831d35Sstevel (void) ddi_pathname(ap, path); 106803831d35Sstevel } 106903831d35Sstevel 107003831d35Sstevel SC_DEBUG(1, (CE_WARN, "e_ddi_branch_create failed: " 107103831d35Sstevel "path=%s, dip=%p, rv=%d", path, fdip ? (void *)fdip : 107203831d35Sstevel (void *)ap, rv)); 107303831d35Sstevel 107403831d35Sstevel kmem_free(path, MAXPATHLEN); 107503831d35Sstevel 107603831d35Sstevel return (NULL); 107703831d35Sstevel } 107803831d35Sstevel 107903831d35Sstevel axq_dip = arg.axq_dip; 108003831d35Sstevel 108103831d35Sstevel new_nodes = gptwocfg_allocate_node_list(1); 108203831d35Sstevel new_nodes->gptwo_nodes[0] = axq_dip; 108303831d35Sstevel 108403831d35Sstevel return (new_nodes); 108503831d35Sstevel } 108603831d35Sstevel 108703831d35Sstevel static gptwocfg_config_t * 108803831d35Sstevel sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *config) 108903831d35Sstevel { 109003831d35Sstevel int i; 109103831d35Sstevel int failure = 0; 109203831d35Sstevel dev_info_t *saf_dip; 109303831d35Sstevel 109403831d35Sstevel if (config == NULL) { 109503831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: sc_gptwocfg_unconfigure_axq: " 109603831d35Sstevel "Invalid AXQ\n"); 109703831d35Sstevel return (NULL); 109803831d35Sstevel } 109903831d35Sstevel for (i = 0; i < config->gptwo_nodes->gptwo_number_of_nodes; i++) { 110003831d35Sstevel int rv; 110103831d35Sstevel dev_info_t *fdip = NULL; 110203831d35Sstevel 110303831d35Sstevel saf_dip = config->gptwo_nodes->gptwo_nodes[i]; 110403831d35Sstevel ASSERT(e_ddi_branch_held(saf_dip)); 110503831d35Sstevel rv = e_ddi_branch_destroy(saf_dip, &fdip, 0); 110603831d35Sstevel if (rv != 0) { 110703831d35Sstevel char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 110803831d35Sstevel 110903831d35Sstevel /* 111003831d35Sstevel * If non-NULL, fdip is held and must be released. 111103831d35Sstevel */ 111203831d35Sstevel if (fdip != NULL) { 111303831d35Sstevel (void) ddi_pathname(fdip, path); 111403831d35Sstevel ddi_release_devi(fdip); 111503831d35Sstevel } else { 111603831d35Sstevel (void) ddi_pathname(saf_dip, path); 111703831d35Sstevel } 111803831d35Sstevel 111903831d35Sstevel cmn_err(CE_CONT, "AXQ node removal failed: " 112003831d35Sstevel "path=%s, dip=%p, rv=%d\n", path, 112103831d35Sstevel fdip ? (void *)fdip : (void *)saf_dip, rv); 112203831d35Sstevel 112303831d35Sstevel kmem_free(path, MAXPATHLEN); 112403831d35Sstevel failure = 1; 112503831d35Sstevel } else { 112603831d35Sstevel config->gptwo_nodes->gptwo_nodes[i] = NULL; 112703831d35Sstevel } 112803831d35Sstevel } 112903831d35Sstevel if (!failure) { 113003831d35Sstevel gptwocfg_free_node_list(config->gptwo_nodes); 113103831d35Sstevel 113203831d35Sstevel kmem_free(config, sizeof (gptwocfg_config_t)); 113303831d35Sstevel config = NULL; 113403831d35Sstevel } 113503831d35Sstevel return (config); 113603831d35Sstevel } 113703831d35Sstevel 113803831d35Sstevel static uint_t 113903831d35Sstevel sc_get_agent_id(spcd_t *pcd, uint_t expander, uint_t slot, uint_t prd_slot) 114003831d35Sstevel { 114103831d35Sstevel uint_t agent_id; 114203831d35Sstevel 114303831d35Sstevel switch (pcd->spcd_ptype) { 114403831d35Sstevel case SAFPTYPE_CPU: 114503831d35Sstevel if (slot == 0) { 114603831d35Sstevel agent_id = prd_slot; 114703831d35Sstevel } else { 114803831d35Sstevel if (prd_slot == 4) { 114903831d35Sstevel agent_id = 8; 115003831d35Sstevel } else { 115103831d35Sstevel agent_id = 9; 115203831d35Sstevel } 115303831d35Sstevel } 115403831d35Sstevel break; 115503831d35Sstevel 115603831d35Sstevel case SAFPTYPE_sPCI: 115703831d35Sstevel case SAFPTYPE_cPCI: 115803831d35Sstevel case SAFPTYPE_PCIX: 115903831d35Sstevel if (prd_slot == 4) { 116003831d35Sstevel agent_id = 0x1c; 116103831d35Sstevel } else { 116203831d35Sstevel agent_id = 0x1d; 116303831d35Sstevel } 116403831d35Sstevel break; 116503831d35Sstevel case SAFPTYPE_WCI: 116603831d35Sstevel agent_id = 0x1d; 116703831d35Sstevel break; 116803831d35Sstevel default: 116903831d35Sstevel cmn_err(CE_WARN, "sc_gptwocfg: Invalid Safari Port " 117003831d35Sstevel "Type 0x%x Slot 0x%x\n", 117103831d35Sstevel pcd->spcd_ptype, prd_slot); 117203831d35Sstevel } /* switch */ 117303831d35Sstevel 117403831d35Sstevel agent_id |= (expander << 5); 117503831d35Sstevel 117603831d35Sstevel SC_DEBUG(1, (CE_CONT, "sc_get_agent_id(pcd=0x%p, expander=0x%x, " 1177*07d06da5SSurya Prakki "prd_slot=0x%x) Returning agent_id=0x%x\n", (void *)pcd, expander, 117803831d35Sstevel prd_slot, agent_id)); 117903831d35Sstevel 118003831d35Sstevel return (agent_id); 118103831d35Sstevel } 118203831d35Sstevel 118303831d35Sstevel static void 118403831d35Sstevel dump_config(sc_gptwocfg_config_t *board_config) 118503831d35Sstevel { 118603831d35Sstevel gptwocfg_config_t *port; 118703831d35Sstevel 1188*07d06da5SSurya Prakki SC_DEBUG(1, (CE_CONT, "dump_config 0x%p", (void *)board_config)); 118903831d35Sstevel while (board_config != NULL) { 119003831d35Sstevel SC_DEBUG(1, (CE_CONT, "************* 0x%p ************\n", 1191*07d06da5SSurya Prakki (void *)board_config)); 119203831d35Sstevel SC_DEBUG(1, (CE_CONT, "port_cookie - 0x%p\n", 1193*07d06da5SSurya Prakki (void *)board_config->port_cookie)); 119403831d35Sstevel 119503831d35Sstevel port = board_config->port_cookie; 119603831d35Sstevel if (port) { 119703831d35Sstevel SC_DEBUG(1, (CE_CONT, " ap - 0x%p\n", 1198*07d06da5SSurya Prakki (void *)port->gptwo_ap)); 119903831d35Sstevel SC_DEBUG(1, (CE_CONT, " portid - 0x%x\n", 120003831d35Sstevel port->gptwo_portid)); 120103831d35Sstevel } 120203831d35Sstevel SC_DEBUG(1, (CE_CONT, "portid - 0x%x\n", 120303831d35Sstevel board_config->portid)); 120403831d35Sstevel SC_DEBUG(1, (CE_CONT, "board - 0x%x\n", 120503831d35Sstevel board_config->board)); 120603831d35Sstevel SC_DEBUG(1, (CE_CONT, "link - 0x%p\n", 1207*07d06da5SSurya Prakki (void *)board_config->link)); 120803831d35Sstevel SC_DEBUG(1, (CE_CONT, "next - 0x%p\n", 1209*07d06da5SSurya Prakki (void *)board_config->next)); 121003831d35Sstevel board_config = board_config->link; 121103831d35Sstevel } 121203831d35Sstevel } 121303831d35Sstevel 121403831d35Sstevel static void 121503831d35Sstevel dump_pcd(spcd_t *pcd) 121603831d35Sstevel { 121703831d35Sstevel int i; 121803831d35Sstevel 1219*07d06da5SSurya Prakki SC_DEBUG(1, (CE_CONT, "dump_pcd 0x%p", (void *)pcd)); 122003831d35Sstevel SC_DEBUG(1, (CE_CONT, " magic - 0x%x\n", pcd->spcd_magic)); 122103831d35Sstevel SC_DEBUG(1, (CE_CONT, " version - 0x%x\n", pcd->spcd_version)); 122203831d35Sstevel SC_DEBUG(1, (CE_CONT, " ver.reg - 0x%lx\n", pcd->spcd_ver_reg)); 122303831d35Sstevel SC_DEBUG(1, (CE_CONT, " afreq - %d\n", pcd->spcd_afreq)); 122403831d35Sstevel switch (pcd->spcd_ptype) { 122503831d35Sstevel case SAFPTYPE_CPU: 122603831d35Sstevel SC_DEBUG(1, (CE_CONT, " ptype - CPU\n")); 122703831d35Sstevel break; 122803831d35Sstevel case SAFPTYPE_sPCI: 122903831d35Sstevel SC_DEBUG(1, (CE_CONT, " ptype - sPCI\n")); 123003831d35Sstevel break; 123103831d35Sstevel case SAFPTYPE_cPCI: 123203831d35Sstevel SC_DEBUG(1, (CE_CONT, " ptype - cPCI\n")); 123303831d35Sstevel break; 123403831d35Sstevel case SAFPTYPE_PCIX: 123503831d35Sstevel SC_DEBUG(1, (CE_CONT, " ptype - sPCI+\n")); 123603831d35Sstevel break; 123703831d35Sstevel case SAFPTYPE_WCI: 123803831d35Sstevel SC_DEBUG(1, (CE_CONT, " ptype - WIC\n")); 123903831d35Sstevel break; 124003831d35Sstevel default: 124103831d35Sstevel SC_DEBUG(1, (CE_CONT, " ptype - 0x%x\n", 124203831d35Sstevel pcd->spcd_ptype)); 124303831d35Sstevel break; 124403831d35Sstevel } 124503831d35Sstevel SC_DEBUG(1, (CE_CONT, " cache - %d\n", pcd->spcd_cache)); 124603831d35Sstevel 124703831d35Sstevel if (pcd->spcd_prsv == SPCD_RSV_PASS) { 124803831d35Sstevel SC_DEBUG(1, (CE_CONT, " prsv - SPCD_RSV_PASS\n")); 124903831d35Sstevel } else { 125003831d35Sstevel SC_DEBUG(1, (CE_CONT, " prsv - 0x%x (FAIL)\n", 125103831d35Sstevel pcd->spcd_prsv)); 125203831d35Sstevel } 125303831d35Sstevel 125403831d35Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) { 125503831d35Sstevel if (pcd->spcd_agent[i] == SPCD_RSV_PASS) { 125603831d35Sstevel SC_DEBUG(1, (CE_CONT, " agent[%d] " 125703831d35Sstevel "- SPCD_RSV_PASS\n", i)); 125803831d35Sstevel } else { 125903831d35Sstevel SC_DEBUG(1, (CE_CONT, " agent[%d] " 126003831d35Sstevel "- 0x%x (FAIL)\n", i, pcd->spcd_agent[i])); 126103831d35Sstevel } 126203831d35Sstevel } 126303831d35Sstevel 126403831d35Sstevel if (pcd->spcd_ptype == SAFPTYPE_CPU) { 126503831d35Sstevel for (i = 0; i < AGENTS_PER_PORT; i++) { 126603831d35Sstevel SC_DEBUG(1, (CE_CONT, " cpuid[%d] - 0x%x\n", 126703831d35Sstevel i, pcd->spcd_cpuid[i])); 126803831d35Sstevel } 126903831d35Sstevel } 127003831d35Sstevel 127103831d35Sstevel SC_DEBUG(1, (CE_CONT, " Banks\n")); 127203831d35Sstevel for (i = 0; i < MAX_BANKS_PER_PORT; i++) { 127303831d35Sstevel if (pcd->sprd_bank_rsv[i]) { 127403831d35Sstevel SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 127503831d35Sstevel pcd->sprd_bank_rsv[i])); 127603831d35Sstevel } 127703831d35Sstevel } 127803831d35Sstevel 127903831d35Sstevel SC_DEBUG(1, (CE_CONT, " Dimms\n")); 128003831d35Sstevel for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 128103831d35Sstevel if (pcd->sprd_dimm[i]) { 128203831d35Sstevel SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 128303831d35Sstevel pcd->sprd_dimm[i])); 128403831d35Sstevel } 128503831d35Sstevel } 128603831d35Sstevel SC_DEBUG(1, (CE_CONT, " Ecache Dimm Labels\n")); 128703831d35Sstevel for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 128803831d35Sstevel if (pcd->sprd_ecache_dimm_label[i]) { 128903831d35Sstevel SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 129003831d35Sstevel pcd->sprd_ecache_dimm_label[i])); 129103831d35Sstevel } 129203831d35Sstevel } 129303831d35Sstevel } 129403831d35Sstevel 129503831d35Sstevel 129603831d35Sstevel typedef struct { 129703831d35Sstevel char Jnumber[8][8]; 129803831d35Sstevel uint8_t sym_flag; 129903831d35Sstevel uint8_t d_dimmtable[144]; 130003831d35Sstevel uint8_t d_pintable[576]; 130103831d35Sstevel }m_layout; 130203831d35Sstevel 130303831d35Sstevel /* 130403831d35Sstevel * Use 2 bits to represent each bit at a cache line. The table 130503831d35Sstevel * is in big endian order, i.e. 130603831d35Sstevel * dimmtable[0], ... , dimmtable[143] 130703831d35Sstevel * Q0:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0] 130803831d35Sstevel * . 130903831d35Sstevel * . 131003831d35Sstevel * Q3:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0] 131103831d35Sstevel */ 131203831d35Sstevel uint8_t J_dimm_pinTable[] = { 131303831d35Sstevel /* Jnumber */ 131403831d35Sstevel /* 0 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x30, 0x00, 0x00, 131503831d35Sstevel /* 1 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x30, 0x00, 0x00, 131603831d35Sstevel /* 2 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x30, 0x00, 0x00, 131703831d35Sstevel /* 3 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x30, 0x00, 0x00, 131803831d35Sstevel /* 4 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x31, 0x00, 0x00, 131903831d35Sstevel /* 5 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x31, 0x00, 0x00, 132003831d35Sstevel /* 6 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x31, 0x00, 0x00, 132103831d35Sstevel /* 7 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x31, 0x00, 0x00, 132203831d35Sstevel /* flag */ 0x01, 132303831d35Sstevel /* -- Q0 -- */ 132403831d35Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 132503831d35Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 132603831d35Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 132703831d35Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 132803831d35Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 132903831d35Sstevel /* -- Q1 -- */ 133003831d35Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 133103831d35Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 133203831d35Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 133303831d35Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 133403831d35Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 133503831d35Sstevel /* -- Q2 -- */ 133603831d35Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 133703831d35Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 133803831d35Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 133903831d35Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 134003831d35Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 134103831d35Sstevel /* -- Q3 -- */ 134203831d35Sstevel /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 134303831d35Sstevel /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 134403831d35Sstevel /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 134503831d35Sstevel /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 134603831d35Sstevel /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 134703831d35Sstevel /* 134803831d35Sstevel * In the following order 134903831d35Sstevel * pintable[0], ..., pintable[575] 135003831d35Sstevel * Quadword3, Quadword2, Quadword1, Quadword0 135103831d35Sstevel * MtagEcc, Mtag, Ecc, Data 135203831d35Sstevel */ 135303831d35Sstevel /* -- Q3 -- */ 135403831d35Sstevel /* 0 */ 227, 227, 227, 227, 111, 111, 111, 22, 135503831d35Sstevel /* 1 */ 22, 32, 138, 222, 81, 117, 117, 117, 135603831d35Sstevel /* 2 */ 111, 222, 106, 222, 222, 106, 106, 106, 135703831d35Sstevel /* 3 */ 217, 101, 212, 96, 217, 101, 212, 96, 135803831d35Sstevel /* 4 */ 217, 101, 212, 96, 217, 101, 212, 96, 135903831d35Sstevel /* 5 */ 207, 91, 202, 86, 187, 71, 158, 42, 136003831d35Sstevel /* 6 */ 187, 71, 158, 42, 153, 37, 148, 32, 136103831d35Sstevel /* 7 */ 153, 37, 148, 32, 153, 37, 148, 32, 136203831d35Sstevel /* 8 */ 153, 37, 148, 143, 27, 138, 143, 27, 136303831d35Sstevel /* 9 */ 143, 27, 138, 22, 207, 91, 202, 86, 136403831d35Sstevel /* 10 */ 207, 91, 202, 86, 207, 91, 202, 86, 136503831d35Sstevel /* 11 */ 192, 76, 81, 192, 76, 81, 192, 76, 136603831d35Sstevel /* 12 */ 197, 81, 192, 76, 187, 71, 158, 42, 136703831d35Sstevel /* 13 */ 187, 71, 158, 42, 143, 27, 138, 22, 136803831d35Sstevel /* 14 */ 133, 17, 128, 12, 133, 17, 128, 12, 136903831d35Sstevel /* 15 */ 133, 17, 128, 12, 133, 17, 128, 12, 137003831d35Sstevel /* 16 */ 123, 07, 118, 2, 123, 07, 118, 2, 137103831d35Sstevel /* 17 */ 123, 07, 118, 2, 123, 07, 118, 2, 137203831d35Sstevel /* -- Q2 -- */ 137303831d35Sstevel /* 0 */ 228, 228, 228, 228, 112, 112, 112, 23, 137403831d35Sstevel /* 1 */ 23, 33, 139, 223, 82, 118, 118, 118, 137503831d35Sstevel /* 2 */ 112, 223, 107, 223, 223, 107, 107, 107, 137603831d35Sstevel /* 3 */ 218, 102, 213, 97, 218, 102, 213, 97, 137703831d35Sstevel /* 4 */ 218, 102, 213, 97, 218, 102, 213, 97, 137803831d35Sstevel /* 5 */ 208, 92, 203, 87, 188, 72, 159, 43, 137903831d35Sstevel /* 6 */ 188, 72, 159, 43, 154, 38, 149, 33, 138003831d35Sstevel /* 7 */ 154, 38, 149, 33, 154, 38, 149, 33, 138103831d35Sstevel /* 8 */ 154, 38, 149, 144, 28, 139, 144, 28, 138203831d35Sstevel /* 9 */ 144, 28, 139, 23, 208, 92, 203, 87, 138303831d35Sstevel /* 10 */ 208, 92, 203, 87, 208, 92, 203, 87, 138403831d35Sstevel /* 11 */ 193, 77, 82, 193, 77, 82, 193, 77, 138503831d35Sstevel /* 12 */ 198, 82, 193, 77, 188, 72, 159, 43, 138603831d35Sstevel /* 13 */ 188, 72, 159, 43, 144, 28, 139, 23, 138703831d35Sstevel /* 14 */ 134, 18, 129, 13, 134, 18, 129, 13, 138803831d35Sstevel /* 15 */ 134, 18, 129, 13, 134, 18, 129, 13, 138903831d35Sstevel /* 16 */ 124, 8, 119, 3, 124, 8, 119, 3, 139003831d35Sstevel /* 17 */ 124, 8, 119, 3, 124, 8, 119, 3, 139103831d35Sstevel /* -- Q1 -- */ 139203831d35Sstevel /* 0 */ 229, 229, 229, 229, 113, 113, 113, 24, 139303831d35Sstevel /* 1 */ 24, 34, 140, 224, 83, 119, 119, 119, 139403831d35Sstevel /* 2 */ 113, 224, 108, 224, 224, 108, 108, 108, 139503831d35Sstevel /* 3 */ 219, 103, 214, 98, 219, 103, 214, 98, 139603831d35Sstevel /* 4 */ 219, 103, 214, 98, 219, 103, 214, 98, 139703831d35Sstevel /* 5 */ 209, 93, 204, 88, 189, 73, 160, 44, 139803831d35Sstevel /* 6 */ 189, 73, 160, 44, 155, 39, 150, 34, 139903831d35Sstevel /* 7 */ 155, 39, 150, 34, 155, 39, 150, 34, 140003831d35Sstevel /* 8 */ 155, 39, 150, 145, 29, 140, 145, 29, 140103831d35Sstevel /* 9 */ 145, 29, 140, 24, 209, 93, 204, 88, 140203831d35Sstevel /* 10 */ 209, 93, 204, 88, 209, 93, 204, 88, 140303831d35Sstevel /* 11 */ 194, 78, 83, 194, 78, 83, 194, 78, 140403831d35Sstevel /* 12 */ 199, 83, 194, 78, 189, 73, 160, 44, 140503831d35Sstevel /* 13 */ 189, 73, 160, 44, 145, 29, 140, 24, 140603831d35Sstevel /* 14 */ 135, 19, 130, 14, 135, 19, 130, 14, 140703831d35Sstevel /* 15 */ 135, 19, 130, 14, 135, 19, 130, 14, 140803831d35Sstevel /* 16 */ 125, 9, 120, 4, 125, 9, 120, 4, 140903831d35Sstevel /* 17 */ 125, 9, 120, 4, 125, 9, 120, 4, 141003831d35Sstevel /* -- Q0 -- */ 141103831d35Sstevel /* 0 */ 230, 230, 230, 230, 114, 114, 114, 25, 141203831d35Sstevel /* 1 */ 25, 35, 141, 225, 84, 200, 200, 200, 141303831d35Sstevel /* 2 */ 114, 225, 109, 225, 225, 109, 109, 109, 141403831d35Sstevel /* 3 */ 220, 104, 215, 99, 220, 104, 215, 99, 141503831d35Sstevel /* 4 */ 220, 104, 215, 99, 220, 104, 215, 99, 141603831d35Sstevel /* 5 */ 210, 94, 205, 89, 190, 74, 161, 45, 141703831d35Sstevel /* 6 */ 190, 74, 161, 45, 156, 40, 151, 35, 141803831d35Sstevel /* 7 */ 156, 40, 151, 35, 156, 40, 151, 35, 141903831d35Sstevel /* 8 */ 156, 40, 151, 146, 30, 141, 146, 30, 142003831d35Sstevel /* 9 */ 146, 30, 141, 25, 210, 94, 205, 89, 142103831d35Sstevel /* 10 */ 210, 94, 205, 89, 210, 94, 205, 89, 142203831d35Sstevel /* 11 */ 195, 79, 84, 195, 79, 84, 195, 79, 142303831d35Sstevel /* 12 */ 200, 84, 195, 79, 190, 74, 161, 45, 142403831d35Sstevel /* 13 */ 190, 74, 161, 45, 146, 30, 141, 25, 142503831d35Sstevel /* 14 */ 136, 20, 131, 15, 136, 20, 131, 15, 142603831d35Sstevel /* 15 */ 136, 20, 131, 15, 136, 20, 131, 15, 142703831d35Sstevel /* 16 */ 126, 10, 121, 5, 126, 10, 121, 5, 142803831d35Sstevel /* 17 */ 126, 10, 121, 5, 126, 10, 121, 5 142903831d35Sstevel }; 143003831d35Sstevel 143103831d35Sstevel /* 143203831d35Sstevel * This table is for internal reference 143303831d35Sstevel * 143403831d35Sstevel * pintable_internal[]= { 143503831d35Sstevel * -- Q0 -- 143603831d35Sstevel * 0 143,143,143,143,139,139,139,35 143703831d35Sstevel * 1 35,51,39,135,91,95,95,95 143803831d35Sstevel * 2 139,135,131,135,135,131,131,131 143903831d35Sstevel * 3 127,123,119,115,127,123,119,115 144003831d35Sstevel * 4 127,123,119,115,127,123,119,115 144103831d35Sstevel * 5 111,107,103,99,79,75,71,67 144203831d35Sstevel * 6 79,75,71,67,63,59,55,51 144303831d35Sstevel * 7 63,59,55,51,63,59,55,51 144403831d35Sstevel * 8 63,59,55,47,43,39,47,43 144503831d35Sstevel * 9 47,43,39,35,111,107,103,99 144603831d35Sstevel * 10 111,107,103,99,111,107,103,99 144703831d35Sstevel * 11 87,83,91,87,83,91,87,83 144803831d35Sstevel * 12 95,91,87,83,79,75,71,67 144903831d35Sstevel * 13 79,75,71,67,47,43,39,35 145003831d35Sstevel * 14 31,27,23,19,31,27,23,19 145103831d35Sstevel * 15 31,27,23,19,31,27,23,19 145203831d35Sstevel * 16 15,11,7,3,15,11,7,3 145303831d35Sstevel * 17 15,11,7,3,15,11,7,3 145403831d35Sstevel * } 145503831d35Sstevel */ 145603831d35Sstevel 145703831d35Sstevel char *dimm_Jno[] = { 145803831d35Sstevel /* P0 */ "J13300", "J13400", "J13500", "J13600", 145903831d35Sstevel "J13301", "J13401", "J13501", "J13601", 146003831d35Sstevel /* P1 */ "J14300", "J14400", "J14500", "J14600", 146103831d35Sstevel "J14301", "J14401", "J14501", "J14601", 146203831d35Sstevel /* P2 */ "J15300", "J15400", "J15500", "J15600", 146303831d35Sstevel "J15301", "J15401", "J15501", "J15601", 146403831d35Sstevel /* P3 */ "J16300", "J16400", "J16500", "J16600", 146503831d35Sstevel "J16301", "J16401", "J16501", "J16601", 146603831d35Sstevel NULL 146703831d35Sstevel }; 146803831d35Sstevel 146903831d35Sstevel 147003831d35Sstevel static uint8_t * 147103831d35Sstevel get_memlayout(uint32_t cpuid, uint32_t *len) 147203831d35Sstevel { 147303831d35Sstevel m_layout *LayoutBuf; 147403831d35Sstevel 147503831d35Sstevel if ((LayoutBuf = (m_layout *)kmem_zalloc(sizeof (m_layout), 147603831d35Sstevel KM_SLEEP)) == NULL) { 147703831d35Sstevel *len = 0; 147803831d35Sstevel return (NULL); 147903831d35Sstevel } 148003831d35Sstevel 148103831d35Sstevel bcopy(J_dimm_pinTable, LayoutBuf, sizeof (m_layout)); 148203831d35Sstevel 148303831d35Sstevel *len = sizeof (m_layout); 148403831d35Sstevel cpuid &= 0x03; /* last 2 bits of a 10 bit number */ 148503831d35Sstevel 148603831d35Sstevel bcopy(dimm_Jno[cpuid << 3], LayoutBuf->Jnumber[0], 64); 148703831d35Sstevel 148803831d35Sstevel return ((uint8_t *)LayoutBuf); 148903831d35Sstevel } 149003831d35Sstevel 149103831d35Sstevel static char * 149203831d35Sstevel rsv_string(prdrsv_t rsv) 149303831d35Sstevel { 149403831d35Sstevel char *buffer; 149503831d35Sstevel char *status; 149603831d35Sstevel 149703831d35Sstevel switch (rsv) { 149803831d35Sstevel case RSV_UNKNOWN: 149903831d35Sstevel buffer = "unknown"; 150003831d35Sstevel break; 150103831d35Sstevel case RSV_PRESENT: 150203831d35Sstevel buffer = "okay"; 150303831d35Sstevel break; 150403831d35Sstevel case RSV_CRUNCH: 150503831d35Sstevel buffer = "disabled"; 150603831d35Sstevel break; 150703831d35Sstevel case RSV_UNDEFINED: 150803831d35Sstevel buffer = "undefined"; 150903831d35Sstevel break; 151003831d35Sstevel case RSV_MISS: 151103831d35Sstevel buffer = "missing"; 151203831d35Sstevel break; 151303831d35Sstevel case RSV_EMPTY_CASSETTE: 151403831d35Sstevel buffer = "disabled"; 151503831d35Sstevel break; 151603831d35Sstevel case RSV_MISCONFIG: 151703831d35Sstevel buffer = "misconfigured"; 151803831d35Sstevel break; 151903831d35Sstevel case RSV_FAIL_OBP: 152003831d35Sstevel buffer = "fail-obp"; 152103831d35Sstevel break; 152203831d35Sstevel case RSV_BLACK: 152303831d35Sstevel buffer = "blacklisted"; 152403831d35Sstevel break; 152503831d35Sstevel case RSV_RED: 152603831d35Sstevel buffer = "redlisted"; 152703831d35Sstevel break; 152803831d35Sstevel case RSV_EXCLUDED: 152903831d35Sstevel buffer = "disabled"; 153003831d35Sstevel break; 153103831d35Sstevel case RSV_UNCONFIG: 153203831d35Sstevel buffer = "disabled"; 153303831d35Sstevel break; 153403831d35Sstevel case RSV_PASS: 153503831d35Sstevel buffer = "okay"; 153603831d35Sstevel break; 153703831d35Sstevel case RSV_FAIL: 153803831d35Sstevel default: 153903831d35Sstevel buffer = "fail"; 154003831d35Sstevel break; 154103831d35Sstevel } 154203831d35Sstevel 154303831d35Sstevel status = kmem_alloc(strlen(buffer) + 1, KM_SLEEP); 154403831d35Sstevel (void) strcpy(status, buffer); 154503831d35Sstevel 154603831d35Sstevel return (status); 154703831d35Sstevel } 1548