xref: /illumos-gate/usr/src/uts/sun4v/os/fillsysinfo.c (revision fedab560fb18c85777c255ea9f445ffaf6830d30)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51ae08745Sheppo  * Common Development and Distribution License (the "License").
61ae08745Sheppo  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
221ae08745Sheppo  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <sys/errno.h>
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <sys/param.h>
317c478bd9Sstevel@tonic-gate #include <sys/cpu.h>
327c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h>
337c478bd9Sstevel@tonic-gate #include <sys/clock.h>
347c478bd9Sstevel@tonic-gate #include <sys/promif.h>
357c478bd9Sstevel@tonic-gate #include <sys/promimpl.h>
367c478bd9Sstevel@tonic-gate #include <sys/systm.h>
377c478bd9Sstevel@tonic-gate #include <sys/machsystm.h>
387c478bd9Sstevel@tonic-gate #include <sys/debug.h>
397c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
407c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
417c478bd9Sstevel@tonic-gate #include <sys/cpu_module.h>
427c478bd9Sstevel@tonic-gate #include <sys/kobj.h>
437c478bd9Sstevel@tonic-gate #include <sys/cmp.h>
447c478bd9Sstevel@tonic-gate #include <sys/async.h>
457c478bd9Sstevel@tonic-gate #include <vm/page.h>
461ae08745Sheppo #include <vm/hat_sfmmu.h>
471ae08745Sheppo #include <sys/sysmacros.h>
481ae08745Sheppo #include <sys/mach_descrip.h>
491ae08745Sheppo #include <sys/mdesc.h>
501ae08745Sheppo #include <sys/archsystm.h>
511ae08745Sheppo #include <sys/error.h>
521ae08745Sheppo #include <sys/mmu.h>
531ae08745Sheppo #include <sys/bitmap.h>
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate int ncpunode;
567c478bd9Sstevel@tonic-gate struct cpu_node cpunodes[NCPU];
577c478bd9Sstevel@tonic-gate 
581ae08745Sheppo uint64_t cpu_q_entries;
591ae08745Sheppo uint64_t dev_q_entries;
601ae08745Sheppo uint64_t cpu_rq_entries;
611ae08745Sheppo uint64_t cpu_nrq_entries;
621ae08745Sheppo 
631ae08745Sheppo void fill_cpu(md_t *, mde_cookie_t);
641ae08745Sheppo 
651ae08745Sheppo static uint64_t get_mmu_ctx_bits(md_t *, mde_cookie_t);
661ae08745Sheppo static uint64_t get_cpu_pagesizes(md_t *, mde_cookie_t);
671ae08745Sheppo static char *construct_isalist(md_t *, mde_cookie_t, char **);
681ae08745Sheppo static void set_at_flags(char *, int, char **);
691ae08745Sheppo static void init_md_broken(md_t *);
701ae08745Sheppo static int get_l2_cache_info(md_t *, mde_cookie_t, uint64_t *, uint64_t *,
711ae08745Sheppo     uint64_t *);
721ae08745Sheppo static id_t get_exec_unit_mapping(md_t *, mde_cookie_t, mde_cookie_t *);
731ae08745Sheppo static int find_exec_unit_id(mde_cookie_t, mde_cookie_t *);
741ae08745Sheppo static void get_q_sizes(md_t *, mde_cookie_t);
751ae08745Sheppo static void get_va_bits(md_t *, mde_cookie_t);
761ae08745Sheppo static size_t get_ra_limit(md_t *);
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate uint64_t	system_clock_freq;
797c478bd9Sstevel@tonic-gate int		niobus = 0;
807c478bd9Sstevel@tonic-gate uint_t		niommu_tsbs = 0;
817c478bd9Sstevel@tonic-gate 
82*fedab560Sae /* prevent compilation with VAC defined */
83*fedab560Sae #ifdef VAC
84*fedab560Sae #error "The sun4v architecture does not support VAC"
85*fedab560Sae #endif
86*fedab560Sae 
87*fedab560Sae #define	S_VAC_SIZE	MMU_PAGESIZE
88*fedab560Sae #define	S_VAC_SHIFT	MMU_PAGESHIFT
89*fedab560Sae 
90*fedab560Sae int		vac_size = S_VAC_SIZE;
91*fedab560Sae uint_t		vac_mask = MMU_PAGEMASK & (S_VAC_SIZE - 1);
92*fedab560Sae int		vac_shift = S_VAC_SHIFT;
93*fedab560Sae uintptr_t	shm_alignment = S_VAC_SIZE;
94*fedab560Sae 
951ae08745Sheppo void
961ae08745Sheppo map_wellknown_devices()
971ae08745Sheppo {
981ae08745Sheppo }
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /*
1011ae08745Sheppo  * For backward compatibility we need to verify that we can handle
1021ae08745Sheppo  * running on platforms which shipped with missing MD properties.
1037c478bd9Sstevel@tonic-gate  */
1041ae08745Sheppo #define	ONTARIO_PLATNAME1	"SUNW,Sun-Fire-T200"
1051ae08745Sheppo #define	ONTARIO_PLATNAME2	"SUNW,Sun-Fire-T2000"
1061ae08745Sheppo #define	ERIE_PLATNAME1		"SUNW,Sun-Fire-T100"
1071ae08745Sheppo #define	ERIE_PLATNAME2		"SUNW,Sun-Fire-T1000"
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate void
1101ae08745Sheppo fill_cpu(md_t *mdp, mde_cookie_t cpuc)
1117c478bd9Sstevel@tonic-gate {
1121ae08745Sheppo 	struct cpu_node *cpunode;
1131ae08745Sheppo 	uint64_t cpuid;
1141ae08745Sheppo 	uint64_t clk_freq;
1151ae08745Sheppo 	char *namebuf;
1161ae08745Sheppo 	char *namebufp;
1171ae08745Sheppo 	int namelen;
1181ae08745Sheppo 	uint64_t associativity = 0, linesize = 0, size = 0;
1191ae08745Sheppo 	int status;
1201ae08745Sheppo 
1211ae08745Sheppo 	if (md_get_prop_val(mdp, cpuc, "id", &cpuid)) {
1221ae08745Sheppo 		return;
1231ae08745Sheppo 	}
1247c478bd9Sstevel@tonic-gate 
1251ae08745Sheppo 	if (cpuid >= NCPU) {
1261ae08745Sheppo 		cmn_err(CE_CONT, "fill_cpu: out of range cpuid %ld - "
1271ae08745Sheppo 		    "cpu excluded from configuration", cpuid);
1281ae08745Sheppo 
1291ae08745Sheppo 		mutex_enter(&cpu_lock);
1301ae08745Sheppo 
1311ae08745Sheppo 		/*
1321ae08745Sheppo 		 * Since the CPU cannot be used, make sure it
1331ae08745Sheppo 		 * is in a safe place. If the firmware does not
1341ae08745Sheppo 		 * support CPU stop, this is known to be true.
1351ae08745Sheppo 		 * If it fails to stop for any other reason, the
1361ae08745Sheppo 		 * system is in an inconsistent state and cannot
1371ae08745Sheppo 		 * be allowed to continue.
1381ae08745Sheppo 		 */
1391ae08745Sheppo 		status = stopcpu_bycpuid(cpuid);
1401ae08745Sheppo 
1411ae08745Sheppo 		if ((status != 0) && (status != ENOTSUP)) {
1421ae08745Sheppo 			cmn_err(CE_PANIC, "failed to stop cpu %lu (%d)",
1431ae08745Sheppo 			    cpuid, status);
1441ae08745Sheppo 		}
1451ae08745Sheppo 
1461ae08745Sheppo 		mutex_exit(&cpu_lock);
1471ae08745Sheppo 		return;
1481ae08745Sheppo 	}
1491ae08745Sheppo 
1501ae08745Sheppo 	cpunode = &cpunodes[cpuid];
1511ae08745Sheppo 	cpunode->cpuid = (int)cpuid;
1521ae08745Sheppo 	cpunode->device_id = cpuid;
1531ae08745Sheppo 
1541ae08745Sheppo 	if (sizeof (cpunode->fru_fmri) > strlen(CPU_FRU_FMRI))
1551ae08745Sheppo 		(void) strcpy(cpunode->fru_fmri, CPU_FRU_FMRI);
1561ae08745Sheppo 
1571ae08745Sheppo 	if (md_get_prop_data(mdp, cpuc,
1581ae08745Sheppo 	    "compatible", (uint8_t **)&namebuf, &namelen)) {
1591ae08745Sheppo 		cmn_err(CE_PANIC, "fill_cpu: Cannot read compatible "
1601ae08745Sheppo 		    "property");
1611ae08745Sheppo 	}
1621ae08745Sheppo 	namebufp = namebuf;
1631ae08745Sheppo 	if (strncmp(namebufp, "SUNW,", 5) == 0)
1641ae08745Sheppo 		namebufp += 5;
1651ae08745Sheppo 	if (strlen(namebufp) > sizeof (cpunode->name))
1661ae08745Sheppo 		cmn_err(CE_PANIC, "Compatible property too big to "
1671ae08745Sheppo 		    "fit into the cpunode name buffer");
1681ae08745Sheppo 	(void) strcpy(cpunode->name, namebufp);
1691ae08745Sheppo 
1701ae08745Sheppo 	if (md_get_prop_val(mdp, cpuc,
1711ae08745Sheppo 	    "clock-frequency", &clk_freq)) {
1721ae08745Sheppo 			clk_freq = 0;
1731ae08745Sheppo 	}
1741ae08745Sheppo 	cpunode->clock_freq = clk_freq;
1751ae08745Sheppo 
1761ae08745Sheppo 	ASSERT(cpunode->clock_freq != 0);
1777c478bd9Sstevel@tonic-gate 	/*
1781ae08745Sheppo 	 * Compute scaling factor based on rate of %tick. This is used
1791ae08745Sheppo 	 * to convert from ticks derived from %tick to nanoseconds. See
1801ae08745Sheppo 	 * comment in sun4u/sys/clock.h for details.
1817c478bd9Sstevel@tonic-gate 	 */
1821ae08745Sheppo 	cpunode->tick_nsec_scale = (uint_t)(((uint64_t)NANOSEC <<
1831ae08745Sheppo 	    (32 - TICK_NSEC_SHIFT)) / cpunode->clock_freq);
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	/*
1861ae08745Sheppo 	 * The nodeid is not used in sun4v at all. Setting it
1871ae08745Sheppo 	 * to positive value to make starting of slave CPUs
1881ae08745Sheppo 	 * code happy.
1897c478bd9Sstevel@tonic-gate 	 */
1901ae08745Sheppo 	cpunode->nodeid = cpuid + 1;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	/*
1931ae08745Sheppo 	 * Obtain the L2 cache information from MD.
1941ae08745Sheppo 	 * If "Cache" node exists, then set L2 cache properties
1951ae08745Sheppo 	 * as read from MD.
1961ae08745Sheppo 	 * If node does not exists, then set the L2 cache properties
1971ae08745Sheppo 	 * in individual CPU module.
1987c478bd9Sstevel@tonic-gate 	 */
1991ae08745Sheppo 	if ((!get_l2_cache_info(mdp, cpuc,
2001ae08745Sheppo 	    &associativity, &size, &linesize)) ||
2011ae08745Sheppo 	    associativity == 0 || size == 0 || linesize == 0) {
2021ae08745Sheppo 		cpu_fiximp(cpunode);
2031ae08745Sheppo 	} else {
2041ae08745Sheppo 		/*
2051ae08745Sheppo 		 * Do not expect L2 cache properties to be bigger
2061ae08745Sheppo 		 * than 32-bit quantity.
2071ae08745Sheppo 		 */
2081ae08745Sheppo 		cpunode->ecache_associativity = (int)associativity;
2091ae08745Sheppo 		cpunode->ecache_size = (int)size;
2101ae08745Sheppo 		cpunode->ecache_linesize = (int)linesize;
2117c478bd9Sstevel@tonic-gate 	}
2121ae08745Sheppo 
2131ae08745Sheppo 	cpunode->ecache_setsize =
2141ae08745Sheppo 	    cpunode->ecache_size / cpunode->ecache_associativity;
2151ae08745Sheppo 
2161ae08745Sheppo 		/*
2171ae08745Sheppo 		 * Start off by assigning the cpu id as the default
2181ae08745Sheppo 		 * mapping index.
2191ae08745Sheppo 		 */
2201ae08745Sheppo 
2211ae08745Sheppo 	cpunode->exec_unit_mapping = NO_EU_MAPPING_FOUND;
2221ae08745Sheppo 
2231ae08745Sheppo 	if (ecache_setsize == 0)
2241ae08745Sheppo 		ecache_setsize = cpunode->ecache_setsize;
2251ae08745Sheppo 	if (ecache_alignsize == 0)
2261ae08745Sheppo 		ecache_alignsize = cpunode->ecache_linesize;
2271ae08745Sheppo 
2281ae08745Sheppo 	ncpunode++;
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate 
2311ae08745Sheppo void
2321ae08745Sheppo empty_cpu(int cpuid)
2337c478bd9Sstevel@tonic-gate {
2341ae08745Sheppo 	bzero(&cpunodes[cpuid], sizeof (struct cpu_node));
2351ae08745Sheppo 	ncpunode--;
2361ae08745Sheppo }
2377c478bd9Sstevel@tonic-gate 
2381ae08745Sheppo void
2391ae08745Sheppo setup_exec_unit_mappings(md_t *mdp)
2401ae08745Sheppo {
2411ae08745Sheppo 	uint64_t num, num_eunits;
2421ae08745Sheppo 	mde_cookie_t cpus_node;
2431ae08745Sheppo 	mde_cookie_t *node, *eunit;
2441ae08745Sheppo 	int idx, i, j;
2451ae08745Sheppo 	processorid_t cpuid;
2461ae08745Sheppo 	char *eunit_name = broken_md_flag ? "exec_unit" : "exec-unit";
2477c478bd9Sstevel@tonic-gate 
2481ae08745Sheppo 	/*
2491ae08745Sheppo 	 * Find the cpu integer exec units - and
2501ae08745Sheppo 	 * setup the mappings appropriately.
2511ae08745Sheppo 	 */
2521ae08745Sheppo 	num = md_alloc_scan_dag(mdp, md_root_node(mdp), "cpus", "fwd", &node);
2531ae08745Sheppo 	if (num < 1)
2541ae08745Sheppo 		cmn_err(CE_PANIC, "No cpus node in machine desccription");
2551ae08745Sheppo 	if (num > 1)
2561ae08745Sheppo 		cmn_err(CE_PANIC, "More than 1 cpus node in machine"
2571ae08745Sheppo 		    " description");
2581ae08745Sheppo 
2591ae08745Sheppo 	cpus_node = node[0];
2601ae08745Sheppo 	md_free_scan_dag(mdp, &node);
2611ae08745Sheppo 
2621ae08745Sheppo 	num_eunits = md_alloc_scan_dag(mdp, cpus_node, eunit_name,
2631ae08745Sheppo 	    "fwd", &eunit);
2641ae08745Sheppo 	if (num_eunits > 0) {
2651ae08745Sheppo 		char *match_type = broken_md_flag ? "int" : "integer";
2661ae08745Sheppo 
2671ae08745Sheppo 		/* Spin through and find all the integer exec units */
2681ae08745Sheppo 		for (i = 0; i < num_eunits; i++) {
2691ae08745Sheppo 			char *p;
2701ae08745Sheppo 			char *val;
2711ae08745Sheppo 			int vallen;
2721ae08745Sheppo 			uint64_t lcpuid;
2731ae08745Sheppo 
2741ae08745Sheppo 				/* ignore nodes with no type */
2751ae08745Sheppo 			if (md_get_prop_data(mdp, eunit[i], "type",
2761ae08745Sheppo 				(uint8_t **)&val, &vallen)) continue;
2771ae08745Sheppo 
2781ae08745Sheppo 			for (p = val; *p != '\0'; p += strlen(p) + 1) {
2791ae08745Sheppo 				if (strcmp(p, match_type) == 0)
2801ae08745Sheppo 					goto found;
2817c478bd9Sstevel@tonic-gate 			}
2821ae08745Sheppo 
2831ae08745Sheppo 			continue;
2841ae08745Sheppo found:
2851ae08745Sheppo 			idx = NCPU + i;
2867c478bd9Sstevel@tonic-gate 			/*
2871ae08745Sheppo 			 * find the cpus attached to this EU and
2881ae08745Sheppo 			 * update their mapping indices
2897c478bd9Sstevel@tonic-gate 			 */
2901ae08745Sheppo 			num = md_alloc_scan_dag(mdp, eunit[i], "cpu",
2911ae08745Sheppo 			    "back", &node);
2921ae08745Sheppo 
2931ae08745Sheppo 			if (num < 1)
2941ae08745Sheppo 				cmn_err(CE_PANIC, "exec-unit node in MD"
2951ae08745Sheppo 				    " not attached to a cpu node");
2961ae08745Sheppo 
2971ae08745Sheppo 			for (j = 0; j < num; j++) {
2981ae08745Sheppo 				if (md_get_prop_val(mdp, node[j], "id",
2991ae08745Sheppo 				    &lcpuid))
3001ae08745Sheppo 					continue;
3011ae08745Sheppo 				if (lcpuid >= NCPU)
3021ae08745Sheppo 					continue;
3031ae08745Sheppo 				cpuid = (processorid_t)lcpuid;
3041ae08745Sheppo 				cpunodes[cpuid].exec_unit_mapping = idx;
3051ae08745Sheppo 			}
3061ae08745Sheppo 			md_free_scan_dag(mdp, &node);
3077c478bd9Sstevel@tonic-gate 		}
3087c478bd9Sstevel@tonic-gate 
3091ae08745Sheppo 
3101ae08745Sheppo 		md_free_scan_dag(mdp, &eunit);
3117c478bd9Sstevel@tonic-gate 	}
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate 
3141ae08745Sheppo /*
3151ae08745Sheppo  * All the common setup of sun4v CPU modules is done by this routine.
3161ae08745Sheppo  */
3171ae08745Sheppo void
3181ae08745Sheppo cpu_setup_common(char **cpu_module_isa_set)
3197c478bd9Sstevel@tonic-gate {
3201ae08745Sheppo 	extern int disable_delay_tlb_flush, delay_tlb_flush;
3211ae08745Sheppo 	extern int mmu_exported_pagesize_mask;
3221ae08745Sheppo 	int nocpus, i;
3231ae08745Sheppo 	size_t ra_limit;
3241ae08745Sheppo 	mde_cookie_t *cpulist;
3251ae08745Sheppo 	md_t *mdp;
3261ae08745Sheppo 
3271ae08745Sheppo 	if ((mdp = md_get_handle()) == NULL)
3281ae08745Sheppo 		cmn_err(CE_PANIC, "Unable to initialize machine description");
3291ae08745Sheppo 
3301ae08745Sheppo 	init_md_broken(mdp);
3311ae08745Sheppo 
3321ae08745Sheppo 	nocpus = md_alloc_scan_dag(mdp,
3331ae08745Sheppo 	    md_root_node(mdp), "cpu", "fwd", &cpulist);
3341ae08745Sheppo 	if (nocpus < 1) {
3351ae08745Sheppo 		cmn_err(CE_PANIC, "cpu_common_setup: cpulist allocation "
3361ae08745Sheppo 		    "failed or incorrect number of CPUs in MD");
3371ae08745Sheppo 	}
3387c478bd9Sstevel@tonic-gate 
3391ae08745Sheppo 	if (use_page_coloring) {
3401ae08745Sheppo 		do_pg_coloring = 1;
3411ae08745Sheppo 		if (use_virtual_coloring) {
3421ae08745Sheppo 			/*
3431ae08745Sheppo 			 * XXX Sun4v cpus don't have virtual caches
3441ae08745Sheppo 			 */
3451ae08745Sheppo 			do_virtual_coloring = 1;
3467c478bd9Sstevel@tonic-gate 		}
3471ae08745Sheppo 	}
3481ae08745Sheppo 
3491ae08745Sheppo 	/*
3501e2e7a75Shuah 	 * Get the valid mmu page sizes mask, Q sizes and isalist/r
3511ae08745Sheppo 	 * from the MD for the first available CPU in cpulist.
3521e2e7a75Shuah 	 *
3531e2e7a75Shuah 	 * Do not expect the MMU page sizes mask to be more than 32-bit.
3541ae08745Sheppo 	 */
3551ae08745Sheppo 	mmu_exported_pagesize_mask = (int)get_cpu_pagesizes(mdp, cpulist[0]);
3561ae08745Sheppo 
3571ae08745Sheppo 	for (i = 0; i < nocpus; i++)
3581ae08745Sheppo 		fill_cpu(mdp, cpulist[i]);
3591ae08745Sheppo 
3601ae08745Sheppo 	setup_exec_unit_mappings(mdp);
3611ae08745Sheppo 
3621ae08745Sheppo 	/*
3631ae08745Sheppo 	 * If MD is broken then append the passed ISA set,
3641ae08745Sheppo 	 * otherwise trust the MD.
3651ae08745Sheppo 	 */
3661ae08745Sheppo 
3671ae08745Sheppo 	if (broken_md_flag)
3681ae08745Sheppo 		isa_list = construct_isalist(mdp, cpulist[0],
3691ae08745Sheppo 		    cpu_module_isa_set);
3701ae08745Sheppo 	else
3711ae08745Sheppo 		isa_list = construct_isalist(mdp, cpulist[0], NULL);
3721ae08745Sheppo 
3731ae08745Sheppo 	get_q_sizes(mdp, cpulist[0]);
3741ae08745Sheppo 
3751ae08745Sheppo 	get_va_bits(mdp, cpulist[0]);
3761ae08745Sheppo 
3771ae08745Sheppo 	/*
3781ae08745Sheppo 	 * ra_limit is the highest real address in the machine.
3791ae08745Sheppo 	 */
3801ae08745Sheppo 	ra_limit = get_ra_limit(mdp);
3811ae08745Sheppo 
3821ae08745Sheppo 	md_free_scan_dag(mdp, &cpulist);
3831ae08745Sheppo 
3841ae08745Sheppo 	(void) md_fini_handle(mdp);
3851ae08745Sheppo 
3861ae08745Sheppo 	/*
3871ae08745Sheppo 	 * Block stores invalidate all pages of the d$ so pagecopy
3881ae08745Sheppo 	 * et. al. do not need virtual translations with virtual
3891ae08745Sheppo 	 * coloring taken into consideration.
3901ae08745Sheppo 	 */
3911ae08745Sheppo 	pp_consistent_coloring = 0;
3921ae08745Sheppo 
3931ae08745Sheppo 	/*
3941ae08745Sheppo 	 * The kpm mapping window.
3951ae08745Sheppo 	 * kpm_size:
3961ae08745Sheppo 	 *	The size of a single kpm range.
3971ae08745Sheppo 	 *	The overall size will be: kpm_size * vac_colors.
3981ae08745Sheppo 	 * kpm_vbase:
3991ae08745Sheppo 	 *	The virtual start address of the kpm range within the kernel
4001ae08745Sheppo 	 *	virtual address space. kpm_vbase has to be kpm_size aligned.
4011ae08745Sheppo 	 */
4021ae08745Sheppo 
4031ae08745Sheppo 	/*
4041ae08745Sheppo 	 * Make kpm_vbase, kpm_size aligned to kpm_size_shift.
4051ae08745Sheppo 	 * To do this find the nearest power of 2 size that the
4061ae08745Sheppo 	 * actual ra_limit fits within.
4071ae08745Sheppo 	 * If it is an even power of two use that, otherwise use the
4081ae08745Sheppo 	 * next power of two larger than ra_limit.
4091ae08745Sheppo 	 */
4101ae08745Sheppo 
4111ae08745Sheppo 	ASSERT(ra_limit != 0);
4121ae08745Sheppo 
4131ae08745Sheppo 	kpm_size_shift = (ra_limit & (ra_limit - 1)) != 0 ?
4141ae08745Sheppo 		highbit(ra_limit) : highbit(ra_limit) - 1;
4151ae08745Sheppo 
4161ae08745Sheppo 	/*
4171ae08745Sheppo 	 * No virtual caches on sun4v so size matches size shift
4181ae08745Sheppo 	 */
4191ae08745Sheppo 	kpm_size = 1ul << kpm_size_shift;
4201ae08745Sheppo 
4211ae08745Sheppo 	if (va_bits < VA_ADDRESS_SPACE_BITS) {
4227c478bd9Sstevel@tonic-gate 		/*
4231ae08745Sheppo 		 * In case of VA hole
4241ae08745Sheppo 		 * kpm_base = hole_end + 1TB
4251ae08745Sheppo 		 * Starting 1TB beyond where VA hole ends because on Niagara
4261ae08745Sheppo 		 * processor software must not use pages within 4GB of the
4271ae08745Sheppo 		 * VA hole as instruction pages to avoid problems with
4281ae08745Sheppo 		 * prefetching into the VA hole.
4297c478bd9Sstevel@tonic-gate 		 */
4301ae08745Sheppo 		kpm_vbase = (caddr_t)((0ull - (1ull << (va_bits - 1))) +
4311ae08745Sheppo 		    (1ull << 40));
4321ae08745Sheppo 	} else {		/* Number of VA bits 64 ... no VA hole */
4331ae08745Sheppo 		kpm_vbase = (caddr_t)0x8000000000000000ull;	/* 8 EB */
4347c478bd9Sstevel@tonic-gate 	}
4351ae08745Sheppo 
4361ae08745Sheppo 	/*
4371ae08745Sheppo 	 * The traptrace code uses either %tick or %stick for
4381ae08745Sheppo 	 * timestamping.  The sun4v require use of %stick.
4391ae08745Sheppo 	 */
4401ae08745Sheppo 	traptrace_use_stick = 1;
4411ae08745Sheppo 
4421ae08745Sheppo 	/*
4431ae08745Sheppo 	 * sun4v provides demap_all
4441ae08745Sheppo 	 */
4451ae08745Sheppo 	if (!disable_delay_tlb_flush)
4461ae08745Sheppo 		delay_tlb_flush = 1;
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate 
4491ae08745Sheppo /*
4501ae08745Sheppo  * Get the nctxs from MD. If absent panic.
4511ae08745Sheppo  */
4521ae08745Sheppo static uint64_t
4531ae08745Sheppo get_mmu_ctx_bits(md_t *mdp, mde_cookie_t cpu_node_cookie)
4547c478bd9Sstevel@tonic-gate {
4551ae08745Sheppo 	uint64_t ctx_bits;
4567c478bd9Sstevel@tonic-gate 
4571ae08745Sheppo 	if (md_get_prop_val(mdp, cpu_node_cookie, "mmu-#context-bits",
4581ae08745Sheppo 	    &ctx_bits))
4591ae08745Sheppo 		ctx_bits = 0;
4607c478bd9Sstevel@tonic-gate 
4611ae08745Sheppo 	if (ctx_bits < MIN_NCTXS_BITS || ctx_bits > MAX_NCTXS_BITS)
4621ae08745Sheppo 		cmn_err(CE_PANIC, "Incorrect %ld number of contexts bits "
4631ae08745Sheppo 		    "returned by MD", ctx_bits);
4647c478bd9Sstevel@tonic-gate 
4651ae08745Sheppo 	return (ctx_bits);
4661ae08745Sheppo }
4677c478bd9Sstevel@tonic-gate 
4681ae08745Sheppo /*
4691ae08745Sheppo  * Initalize supported page sizes information.
4701ae08745Sheppo  * Set to 0, if the page sizes mask information is absent in MD.
4711ae08745Sheppo  */
4721ae08745Sheppo static uint64_t
4731ae08745Sheppo get_cpu_pagesizes(md_t *mdp, mde_cookie_t cpu_node_cookie)
4741ae08745Sheppo {
4751ae08745Sheppo 	uint64_t mmu_page_size_list;
4767c478bd9Sstevel@tonic-gate 
4771ae08745Sheppo 	if (md_get_prop_val(mdp, cpu_node_cookie, "mmu-page-size-list",
4781ae08745Sheppo 	    &mmu_page_size_list))
4791ae08745Sheppo 		mmu_page_size_list = 0;
4801ae08745Sheppo 
4811ae08745Sheppo 	if (mmu_page_size_list == 0 || mmu_page_size_list > MAX_PAGESIZE_MASK)
4821ae08745Sheppo 		cmn_err(CE_PANIC, "Incorrect 0x%lx pagesize mask returned"
4831ae08745Sheppo 		    "by MD", mmu_page_size_list);
4841ae08745Sheppo 
4851ae08745Sheppo 	return (mmu_page_size_list);
4861ae08745Sheppo }
4871ae08745Sheppo 
4881ae08745Sheppo /*
4891ae08745Sheppo  * This routine gets the isalist information from MD and appends
4901ae08745Sheppo  * the CPU module ISA set if required.
4911ae08745Sheppo  */
4921ae08745Sheppo static char *
4931ae08745Sheppo construct_isalist(md_t *mdp, mde_cookie_t cpu_node_cookie,
4941ae08745Sheppo     char **cpu_module_isa_set)
4951ae08745Sheppo {
4961ae08745Sheppo 	extern int at_flags;
4971ae08745Sheppo 	char *md_isalist;
4981ae08745Sheppo 	int md_isalen;
4991ae08745Sheppo 	char *isabuf;
5001ae08745Sheppo 	int isalen;
5011ae08745Sheppo 	char **isa_set;
5021ae08745Sheppo 	char *p, *q;
5031ae08745Sheppo 	int cpu_module_isalen = 0, found = 0;
5041ae08745Sheppo 
5051ae08745Sheppo 	(void) md_get_prop_data(mdp, cpu_node_cookie,
5061ae08745Sheppo 	    "isalist", (uint8_t **)&isabuf, &isalen);
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	/*
5091ae08745Sheppo 	 * We support binaries for all the cpus that have shipped so far.
5101ae08745Sheppo 	 * The kernel emulates instructions that are not supported by hardware.
5117c478bd9Sstevel@tonic-gate 	 */
5121ae08745Sheppo 	at_flags = EF_SPARC_SUN_US3 | EF_SPARC_32PLUS | EF_SPARC_SUN_US1;
5137c478bd9Sstevel@tonic-gate 
5141ae08745Sheppo 	/*
5151ae08745Sheppo 	 * Construct the space separated isa_list.
5161ae08745Sheppo 	 */
5171ae08745Sheppo 	if (cpu_module_isa_set != NULL) {
5181ae08745Sheppo 		for (isa_set = cpu_module_isa_set; *isa_set != NULL;
5191ae08745Sheppo 		    isa_set++) {
5201ae08745Sheppo 			cpu_module_isalen += strlen(*isa_set);
5211ae08745Sheppo 			cpu_module_isalen++;	/* for space character */
5221ae08745Sheppo 		}
5231ae08745Sheppo 	}
5247c478bd9Sstevel@tonic-gate 
5251ae08745Sheppo 	/*
5261ae08745Sheppo 	 * Allocate the buffer of MD isa buffer length + CPU module
5271ae08745Sheppo 	 * isa buffer length.
5281ae08745Sheppo 	 */
5291ae08745Sheppo 	md_isalen = isalen + cpu_module_isalen + 2;
5301ae08745Sheppo 	md_isalist = (char *)prom_alloc((caddr_t)0, md_isalen, 0);
5311ae08745Sheppo 	if (md_isalist == NULL)
5321ae08745Sheppo 		cmn_err(CE_PANIC, "construct_isalist: Allocation failed for "
5331ae08745Sheppo 		    "md_isalist");
5341ae08745Sheppo 
5351ae08745Sheppo 	md_isalist[0] = '\0'; /* create an empty string to start */
5361ae08745Sheppo 	for (p = isabuf, q = p + isalen; p < q; p += strlen(p) + 1) {
5371ae08745Sheppo 		(void) strlcat(md_isalist, p, md_isalen);
5381ae08745Sheppo 		(void) strcat(md_isalist, " ");
5391ae08745Sheppo 	}
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 	/*
5421ae08745Sheppo 	 * Check if the isa_set is present in isalist returned by MD.
5431ae08745Sheppo 	 * If yes, then no need to append it, if no then append it to
5441ae08745Sheppo 	 * isalist returned by MD.
5457c478bd9Sstevel@tonic-gate 	 */
5461ae08745Sheppo 	if (cpu_module_isa_set != NULL) {
5471ae08745Sheppo 		for (isa_set = cpu_module_isa_set; *isa_set != NULL;
5481ae08745Sheppo 		    isa_set++) {
5491ae08745Sheppo 			found = 0;
5501ae08745Sheppo 			for (p = isabuf, q = p + isalen; p < q;
5511ae08745Sheppo 			    p += strlen(p) + 1) {
5521ae08745Sheppo 				if (strcmp(p, *isa_set) == 0) {
5531ae08745Sheppo 					found = 1;
5541ae08745Sheppo 					break;
5551ae08745Sheppo 				}
5561ae08745Sheppo 			}
5571ae08745Sheppo 			if (!found) {
5581ae08745Sheppo 				(void) strlcat(md_isalist, *isa_set, md_isalen);
5591ae08745Sheppo 				(void) strcat(md_isalist, " ");
5601ae08745Sheppo 			}
5611ae08745Sheppo 		}
5621ae08745Sheppo 	}
5631ae08745Sheppo 
5641ae08745Sheppo 	/* Get rid of any trailing white spaces */
5651ae08745Sheppo 	md_isalist[strlen(md_isalist) - 1] = '\0';
5661ae08745Sheppo 
5671ae08745Sheppo 	return (md_isalist);
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate 
5701ae08745Sheppo uint64_t
5711ae08745Sheppo get_ra_limit(md_t *mdp)
5721ae08745Sheppo {
5731ae08745Sheppo 	mde_cookie_t *mem_list;
5741ae08745Sheppo 	mde_cookie_t *mblock_list;
5751ae08745Sheppo 	int i;
5761ae08745Sheppo 	int memnodes;
5771ae08745Sheppo 	int nmblock;
5781ae08745Sheppo 	uint64_t base;
5791ae08745Sheppo 	uint64_t size;
5801ae08745Sheppo 	uint64_t ra_limit = 0, new_limit = 0;
5811ae08745Sheppo 
5821ae08745Sheppo 	memnodes = md_alloc_scan_dag(mdp,
5831ae08745Sheppo 	    md_root_node(mdp), "memory", "fwd", &mem_list);
5841ae08745Sheppo 
5851ae08745Sheppo 	ASSERT(memnodes == 1);
5861ae08745Sheppo 
5871ae08745Sheppo 	nmblock = md_alloc_scan_dag(mdp,
5881ae08745Sheppo 	    mem_list[0], "mblock", "fwd", &mblock_list);
5891ae08745Sheppo 	if (nmblock < 1)
5901ae08745Sheppo 		cmn_err(CE_PANIC, "cannot find mblock nodes in MD");
5911ae08745Sheppo 
5921ae08745Sheppo 	for (i = 0; i < nmblock; i++) {
5931ae08745Sheppo 		if (md_get_prop_val(mdp, mblock_list[i], "base", &base))
5941ae08745Sheppo 			cmn_err(CE_PANIC, "base property missing from MD"
5951ae08745Sheppo 			    " mblock node");
5961ae08745Sheppo 		if (md_get_prop_val(mdp, mblock_list[i], "size", &size))
5971ae08745Sheppo 			cmn_err(CE_PANIC, "size property missing from MD"
5981ae08745Sheppo 			    " mblock node");
5991ae08745Sheppo 
6001ae08745Sheppo 		ASSERT(size != 0);
6011ae08745Sheppo 
6021ae08745Sheppo 		new_limit = base + size;
6031ae08745Sheppo 
6041ae08745Sheppo 		if (base > new_limit)
6051ae08745Sheppo 			cmn_err(CE_PANIC, "mblock in MD wrapped around");
6061ae08745Sheppo 
6071ae08745Sheppo 		if (new_limit > ra_limit)
6081ae08745Sheppo 		    ra_limit = new_limit;
6091ae08745Sheppo 	}
6101ae08745Sheppo 
6111ae08745Sheppo 	ASSERT(ra_limit != 0);
6121ae08745Sheppo 
6131ae08745Sheppo 	if (ra_limit > MAX_REAL_ADDRESS) {
6141ae08745Sheppo 		cmn_err(CE_WARN, "Highest real address in MD too large"
6151ae08745Sheppo 		    " clipping to %llx\n", MAX_REAL_ADDRESS);
6161ae08745Sheppo 		ra_limit = MAX_REAL_ADDRESS;
6171ae08745Sheppo 	}
6181ae08745Sheppo 
6191ae08745Sheppo 	md_free_scan_dag(mdp, &mblock_list);
6201ae08745Sheppo 
6211ae08745Sheppo 	md_free_scan_dag(mdp, &mem_list);
6221ae08745Sheppo 
6231ae08745Sheppo 	return (ra_limit);
6241ae08745Sheppo }
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate /*
6271ae08745Sheppo  * This routine sets the globals for CPU and DEV mondo queue entries and
6281ae08745Sheppo  * resumable and non-resumable error queue entries.
6297c478bd9Sstevel@tonic-gate  */
6301ae08745Sheppo static uint64_t
6311ae08745Sheppo get_single_q_size(md_t *mdp, mde_cookie_t cpu_node_cookie,
6321ae08745Sheppo     char *qnamep, uint64_t default_entries)
6331ae08745Sheppo {
6341ae08745Sheppo 	uint64_t entries;
6351ae08745Sheppo 
6361ae08745Sheppo 	if (md_get_prop_val(mdp, cpu_node_cookie, qnamep, &entries)) {
6371ae08745Sheppo 		if (!broken_md_flag)
6381ae08745Sheppo 			cmn_err(CE_PANIC, "Missing %s property in MD cpu node",
6391ae08745Sheppo 				qnamep);
6401ae08745Sheppo 		entries = default_entries;
6411ae08745Sheppo 	} else {
6421ae08745Sheppo 		entries = 1 << entries;
6431ae08745Sheppo 	}
6441ae08745Sheppo 	return (entries);
6451ae08745Sheppo }
6461ae08745Sheppo 
6471ae08745Sheppo 
6487c478bd9Sstevel@tonic-gate static void
6491ae08745Sheppo get_q_sizes(md_t *mdp, mde_cookie_t cpu_node_cookie)
6507c478bd9Sstevel@tonic-gate {
6511ae08745Sheppo 	cpu_q_entries = get_single_q_size(mdp, cpu_node_cookie,
6521ae08745Sheppo 	    "q-cpu-mondo-#bits", DEFAULT_CPU_Q_ENTRIES);
6531ae08745Sheppo 
6541ae08745Sheppo 	dev_q_entries = get_single_q_size(mdp, cpu_node_cookie,
6551ae08745Sheppo 	    "q-dev-mondo-#bits", DEFAULT_DEV_Q_ENTRIES);
6561ae08745Sheppo 
6571ae08745Sheppo 	cpu_rq_entries = get_single_q_size(mdp, cpu_node_cookie,
6581ae08745Sheppo 	    "q-resumable-#bits", CPU_RQ_ENTRIES);
6591ae08745Sheppo 
6601ae08745Sheppo 	cpu_nrq_entries = get_single_q_size(mdp, cpu_node_cookie,
6611ae08745Sheppo 		"q-nonresumable-#bits", CPU_NRQ_ENTRIES);
6621ae08745Sheppo }
6631ae08745Sheppo 
6641ae08745Sheppo 
6651ae08745Sheppo static void
6661ae08745Sheppo get_va_bits(md_t *mdp, mde_cookie_t cpu_node_cookie)
6671ae08745Sheppo {
6681ae08745Sheppo 	uint64_t value = VA_ADDRESS_SPACE_BITS;
6691ae08745Sheppo 
6701ae08745Sheppo 	if (md_get_prop_val(mdp, cpu_node_cookie, "mmu-#va-bits", &value))
6711ae08745Sheppo 		cmn_err(CE_PANIC, "mmu-#va-bits property  not found in MD");
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 
6741ae08745Sheppo 	if (value == 0 || value > VA_ADDRESS_SPACE_BITS)
6751ae08745Sheppo 		cmn_err(CE_PANIC, "Incorrect number of va bits in MD");
6767c478bd9Sstevel@tonic-gate 
6771ae08745Sheppo 	/* Do not expect number of VA bits to be more than 32-bit quantity */
6787c478bd9Sstevel@tonic-gate 
6791ae08745Sheppo 	va_bits = (int)value;
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	/*
6821ae08745Sheppo 	 * Correct the value for VA bits on UltraSPARC-T1 based systems
6831ae08745Sheppo 	 * in case of broken MD.
6847c478bd9Sstevel@tonic-gate 	 */
6851ae08745Sheppo 	if (broken_md_flag)
6861ae08745Sheppo 		va_bits = DEFAULT_VA_ADDRESS_SPACE_BITS;
6877c478bd9Sstevel@tonic-gate }
6887c478bd9Sstevel@tonic-gate 
6891ae08745Sheppo /*
6901ae08745Sheppo  * This routine returns the L2 cache information such as -- associativity,
6911ae08745Sheppo  * size and linesize.
6921ae08745Sheppo  */
6931ae08745Sheppo static int
6941ae08745Sheppo get_l2_cache_info(md_t *mdp, mde_cookie_t cpu_node_cookie,
6951ae08745Sheppo 	    uint64_t *associativity, uint64_t *size, uint64_t *linesize)
6961ae08745Sheppo {
6971ae08745Sheppo 	mde_cookie_t *cachelist;
6981ae08745Sheppo 	int ncaches, i;
6991ae08745Sheppo 	uint64_t max_level;
7001ae08745Sheppo 
7011ae08745Sheppo 	ncaches = md_alloc_scan_dag(mdp, cpu_node_cookie, "cache",
7021ae08745Sheppo 	    "fwd", &cachelist);
7031ae08745Sheppo 	/*
7041ae08745Sheppo 	 * The "cache" node is optional in MD, therefore ncaches can be 0.
7051ae08745Sheppo 	 */
7061ae08745Sheppo 	if (ncaches < 1) {
7071ae08745Sheppo 		return (0);
7081ae08745Sheppo 	}
7091ae08745Sheppo 
7101ae08745Sheppo 	max_level = 0;
7111ae08745Sheppo 	for (i = 0; i < ncaches; i++) {
7121ae08745Sheppo 		uint64_t cache_level;
7131ae08745Sheppo 		uint64_t local_assoc;
7141ae08745Sheppo 		uint64_t local_size;
7151ae08745Sheppo 		uint64_t local_lsize;
7161ae08745Sheppo 
7171ae08745Sheppo 		if (md_get_prop_val(mdp, cachelist[i], "level", &cache_level))
7181ae08745Sheppo 			continue;
7191ae08745Sheppo 
7201ae08745Sheppo 		if (cache_level <= max_level) continue;
7211ae08745Sheppo 
7221ae08745Sheppo 		/* If properties are missing from this cache ignore it */
7231ae08745Sheppo 
7241ae08745Sheppo 		if ((md_get_prop_val(mdp, cachelist[i],
7251ae08745Sheppo 		    "associativity", &local_assoc))) {
7261ae08745Sheppo 			continue;
7271ae08745Sheppo 		}
7281ae08745Sheppo 
7291ae08745Sheppo 		if ((md_get_prop_val(mdp, cachelist[i],
7301ae08745Sheppo 		    "size", &local_size))) {
7311ae08745Sheppo 			continue;
7321ae08745Sheppo 		}
7331ae08745Sheppo 
7341ae08745Sheppo 		if ((md_get_prop_val(mdp, cachelist[i],
7351ae08745Sheppo 		    "line-size", &local_lsize))) {
7361ae08745Sheppo 			continue;
7371ae08745Sheppo 		}
7381ae08745Sheppo 
7391ae08745Sheppo 		max_level = cache_level;
7401ae08745Sheppo 		*associativity = local_assoc;
7411ae08745Sheppo 		*size = local_size;
7421ae08745Sheppo 		*linesize = local_lsize;
7431ae08745Sheppo 	}
7447c478bd9Sstevel@tonic-gate 
7451ae08745Sheppo 	md_free_scan_dag(mdp, &cachelist);
7461ae08745Sheppo 
7471ae08745Sheppo 	return ((max_level > 0) ? 1 : 0);
7481ae08745Sheppo }
7491ae08745Sheppo 
7501ae08745Sheppo /*
7511ae08745Sheppo  * The broken_md_flag is set to 1, if the MD doesn't have
7521ae08745Sheppo  * the domaining-enabled property in the platform node and the platforms
7531ae08745Sheppo  * are Ontario and Erie. This flag is used to workaround some of the
7541ae08745Sheppo  * incorrect MD properties.
7551ae08745Sheppo  */
7561ae08745Sheppo static void
7571ae08745Sheppo init_md_broken(md_t *mdp)
7587c478bd9Sstevel@tonic-gate {
7591ae08745Sheppo 	int nrnode;
7601ae08745Sheppo 	mde_cookie_t *platlist, rootnode;
7611ae08745Sheppo 	char *vbuf;
7621ae08745Sheppo 	uint64_t val = 0;
7631ae08745Sheppo 
7641ae08745Sheppo 	rootnode = md_root_node(mdp);
7651ae08745Sheppo 	ASSERT(rootnode != MDE_INVAL_ELEM_COOKIE);
7661ae08745Sheppo 
7671ae08745Sheppo 	nrnode = md_alloc_scan_dag(mdp, md_root_node(mdp), "platform", "fwd",
7681ae08745Sheppo 	    &platlist);
7691ae08745Sheppo 
7701ae08745Sheppo 	ASSERT(nrnode == 1);
7711ae08745Sheppo 
7721ae08745Sheppo 	if (md_get_prop_str(mdp, platlist[0], "name", &vbuf) != 0)
7731ae08745Sheppo 		panic("platform name not found in machine description");
7741ae08745Sheppo 
7757c478bd9Sstevel@tonic-gate 	/*
7761ae08745Sheppo 	 * If domaining-enable prop doesn't exist and the platform name is
7771ae08745Sheppo 	 * Ontario or Erie the md is broken.
7787c478bd9Sstevel@tonic-gate 	 */
7797c478bd9Sstevel@tonic-gate 
7801ae08745Sheppo 	if (md_get_prop_val(mdp, platlist[0], "domaining-enabled", &val) != 0 &&
7811ae08745Sheppo 	    ((strcmp(vbuf, ONTARIO_PLATNAME1) == 0) ||
7821ae08745Sheppo 	    (strcmp(vbuf, ONTARIO_PLATNAME2) == 0) ||
7831ae08745Sheppo 	    (strcmp(vbuf, ERIE_PLATNAME1) == 0) ||
7841ae08745Sheppo 	    (strcmp(vbuf, ERIE_PLATNAME2) == 0)))
7851ae08745Sheppo 		broken_md_flag = 1;
7861ae08745Sheppo 
7871ae08745Sheppo 	md_free_scan_dag(mdp, &platlist);
7887c478bd9Sstevel@tonic-gate }
789