xref: /onnv-gate/usr/src/uts/i86pc/os/mp_implfuncs.c (revision 12004:93f274d4a367)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53446Smrj  * Common Development and Distribution License (the "License").
63446Smrj  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
226356Smrj  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
25*12004Sjiang.liu@intel.com #define	PSMI_1_7
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include <sys/vmem.h>
280Sstevel@tonic-gate #include <vm/hat.h>
290Sstevel@tonic-gate #include <sys/modctl.h>
300Sstevel@tonic-gate #include <vm/seg_kmem.h>
310Sstevel@tonic-gate #include <sys/psm.h>
320Sstevel@tonic-gate #include <sys/psm_modctl.h>
330Sstevel@tonic-gate #include <sys/smp_impldefs.h>
340Sstevel@tonic-gate #include <sys/reboot.h>
355084Sjohnlev #if defined(__xpv)
365084Sjohnlev #include <sys/hypervisor.h>
375084Sjohnlev #include <vm/kboot_mmu.h>
385084Sjohnlev #include <vm/hat_pte.h>
395084Sjohnlev #endif
400Sstevel@tonic-gate 
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate  *	External reference functions
430Sstevel@tonic-gate  */
440Sstevel@tonic-gate extern void *get_next_mach(void *, char *);
450Sstevel@tonic-gate extern void close_mach_list(void);
460Sstevel@tonic-gate extern void open_mach_list(void);
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /*
490Sstevel@tonic-gate  * from startup.c - kernel VA range allocator for device mappings
500Sstevel@tonic-gate  */
510Sstevel@tonic-gate extern void *device_arena_alloc(size_t size, int vm_flag);
520Sstevel@tonic-gate extern void device_arena_free(void * vaddr, size_t size);
530Sstevel@tonic-gate 
540Sstevel@tonic-gate void psm_modloadonly(void);
550Sstevel@tonic-gate void psm_install(void);
560Sstevel@tonic-gate 
570Sstevel@tonic-gate /*
580Sstevel@tonic-gate  * Local Function Prototypes
590Sstevel@tonic-gate  */
600Sstevel@tonic-gate static struct modlinkage *psm_modlinkage_alloc(struct psm_info *infop);
610Sstevel@tonic-gate static void psm_modlinkage_free(struct modlinkage *mlinkp);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate static char *psm_get_impl_module(int first);
640Sstevel@tonic-gate 
650Sstevel@tonic-gate static int mod_installpsm(struct modlpsm *modl, struct modlinkage *modlp);
660Sstevel@tonic-gate static int mod_removepsm(struct modlpsm *modl, struct modlinkage *modlp);
670Sstevel@tonic-gate static int mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0);
680Sstevel@tonic-gate struct mod_ops mod_psmops = {
690Sstevel@tonic-gate 	mod_installpsm, mod_removepsm, mod_infopsm
700Sstevel@tonic-gate };
710Sstevel@tonic-gate 
720Sstevel@tonic-gate static struct psm_sw psm_swtab = {
730Sstevel@tonic-gate 	&psm_swtab, &psm_swtab, NULL, NULL
740Sstevel@tonic-gate };
750Sstevel@tonic-gate 
760Sstevel@tonic-gate kmutex_t psmsw_lock;			/* lock accesses to psmsw 	*/
770Sstevel@tonic-gate struct psm_sw *psmsw = &psm_swtab; 	/* start of all psm_sw		*/
780Sstevel@tonic-gate 
790Sstevel@tonic-gate static struct modlinkage *
psm_modlinkage_alloc(struct psm_info * infop)800Sstevel@tonic-gate psm_modlinkage_alloc(struct psm_info *infop)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate 	int	memsz;
830Sstevel@tonic-gate 	struct modlinkage *mlinkp;
840Sstevel@tonic-gate 	struct modlpsm *mlpsmp;
850Sstevel@tonic-gate 	struct psm_sw *swp;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	memsz = sizeof (struct modlinkage) + sizeof (struct modlpsm) +
885084Sjohnlev 	    sizeof (struct psm_sw);
890Sstevel@tonic-gate 	mlinkp = (struct modlinkage *)kmem_zalloc(memsz, KM_NOSLEEP);
900Sstevel@tonic-gate 	if (!mlinkp) {
910Sstevel@tonic-gate 		cmn_err(CE_WARN, "!psm_mod_init: Cannot install %s",
925084Sjohnlev 		    infop->p_mach_idstring);
930Sstevel@tonic-gate 		return (NULL);
940Sstevel@tonic-gate 	}
950Sstevel@tonic-gate 	mlpsmp = (struct modlpsm *)(mlinkp + 1);
960Sstevel@tonic-gate 	swp = (struct psm_sw *)(mlpsmp + 1);
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	mlinkp->ml_rev = MODREV_1;
990Sstevel@tonic-gate 	mlinkp->ml_linkage[0] = (void *)mlpsmp;
1000Sstevel@tonic-gate 	mlinkp->ml_linkage[1] = (void *)NULL;
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	mlpsmp->psm_modops = &mod_psmops;
1030Sstevel@tonic-gate 	mlpsmp->psm_linkinfo = infop->p_mach_desc;
1040Sstevel@tonic-gate 	mlpsmp->psm_swp = swp;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	swp->psw_infop = infop;
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	return (mlinkp);
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate static void
psm_modlinkage_free(struct modlinkage * mlinkp)1120Sstevel@tonic-gate psm_modlinkage_free(struct modlinkage *mlinkp)
1130Sstevel@tonic-gate {
1140Sstevel@tonic-gate 	if (!mlinkp)
1150Sstevel@tonic-gate 		return;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	(void) kmem_free(mlinkp, (sizeof (struct modlinkage) +
1185084Sjohnlev 	    sizeof (struct modlpsm) + sizeof (struct psm_sw)));
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate int
psm_mod_init(void ** handlepp,struct psm_info * infop)1220Sstevel@tonic-gate psm_mod_init(void **handlepp, struct psm_info *infop)
1230Sstevel@tonic-gate {
1240Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
1250Sstevel@tonic-gate 	int	status;
1260Sstevel@tonic-gate 	struct modlinkage *mlinkp;
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate 	if (!*modlpp) {
1290Sstevel@tonic-gate 		mlinkp = psm_modlinkage_alloc(infop);
1300Sstevel@tonic-gate 		if (!mlinkp)
1310Sstevel@tonic-gate 			return (ENOSPC);
1320Sstevel@tonic-gate 	} else
1330Sstevel@tonic-gate 		mlinkp = *modlpp;
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	status = mod_install(mlinkp);
1360Sstevel@tonic-gate 	if (status) {
1370Sstevel@tonic-gate 		psm_modlinkage_free(mlinkp);
1380Sstevel@tonic-gate 		*modlpp = NULL;
1390Sstevel@tonic-gate 	} else
1400Sstevel@tonic-gate 		*modlpp = mlinkp;
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 	return (status);
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate /*ARGSUSED1*/
1460Sstevel@tonic-gate int
psm_mod_fini(void ** handlepp,struct psm_info * infop)1470Sstevel@tonic-gate psm_mod_fini(void **handlepp, struct psm_info *infop)
1480Sstevel@tonic-gate {
1490Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
1500Sstevel@tonic-gate 	int	status;
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 	status = mod_remove(*modlpp);
1530Sstevel@tonic-gate 	if (status == 0) {
1540Sstevel@tonic-gate 		psm_modlinkage_free(*modlpp);
1550Sstevel@tonic-gate 		*modlpp = NULL;
1560Sstevel@tonic-gate 	}
1570Sstevel@tonic-gate 	return (status);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate int
psm_mod_info(void ** handlepp,struct psm_info * infop,struct modinfo * modinfop)1610Sstevel@tonic-gate psm_mod_info(void **handlepp, struct psm_info *infop, struct modinfo *modinfop)
1620Sstevel@tonic-gate {
1630Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
1640Sstevel@tonic-gate 	int status;
1650Sstevel@tonic-gate 	struct modlinkage *mlinkp;
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 	if (!*modlpp) {
1680Sstevel@tonic-gate 		mlinkp = psm_modlinkage_alloc(infop);
1690Sstevel@tonic-gate 		if (!mlinkp)
1700Sstevel@tonic-gate 			return ((int)NULL);
1710Sstevel@tonic-gate 	} else
1720Sstevel@tonic-gate 		mlinkp = *modlpp;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	status =  mod_info(mlinkp, modinfop);
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	if (!status) {
1770Sstevel@tonic-gate 		psm_modlinkage_free(mlinkp);
1780Sstevel@tonic-gate 		*modlpp = NULL;
1790Sstevel@tonic-gate 	} else
1800Sstevel@tonic-gate 		*modlpp = mlinkp;
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate 	return (status);
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate int
psm_add_intr(int lvl,avfunc xxintr,char * name,int vect,caddr_t arg)1860Sstevel@tonic-gate psm_add_intr(int lvl, avfunc xxintr, char *name, int vect, caddr_t arg)
1870Sstevel@tonic-gate {
1880Sstevel@tonic-gate 	return (add_avintr((void *)NULL, lvl, xxintr, name, vect,
189916Sschwartz 	    arg, NULL, NULL, NULL));
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate int
psm_add_nmintr(int lvl,avfunc xxintr,char * name,caddr_t arg)1930Sstevel@tonic-gate psm_add_nmintr(int lvl, avfunc xxintr, char *name, caddr_t arg)
1940Sstevel@tonic-gate {
1950Sstevel@tonic-gate 	return (add_nmintr(lvl, xxintr, name, arg));
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate processorid_t
psm_get_cpu_id(void)1990Sstevel@tonic-gate psm_get_cpu_id(void)
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate 	return (CPU->cpu_id);
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate caddr_t
psm_map_phys_new(paddr_t addr,size_t len,int prot)2050Sstevel@tonic-gate psm_map_phys_new(paddr_t addr, size_t len, int prot)
2060Sstevel@tonic-gate {
2070Sstevel@tonic-gate 	uint_t pgoffset;
2080Sstevel@tonic-gate 	paddr_t base;
2090Sstevel@tonic-gate 	pgcnt_t npages;
2100Sstevel@tonic-gate 	caddr_t cvaddr;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 	if (len == 0)
2130Sstevel@tonic-gate 		return (0);
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 	pgoffset = addr & MMU_PAGEOFFSET;
2165084Sjohnlev #ifdef __xpv
2175084Sjohnlev 	/*
2185084Sjohnlev 	 * If we're dom0, we're starting from a MA. translate that to a PA
2195084Sjohnlev 	 * XXPV - what about driver domains???
2205084Sjohnlev 	 */
2215084Sjohnlev 	if (DOMAIN_IS_INITDOMAIN(xen_info)) {
2225084Sjohnlev 		base = pfn_to_pa(xen_assign_pfn(mmu_btop(addr))) |
2235084Sjohnlev 		    (addr & MMU_PAGEOFFSET);
2245084Sjohnlev 	} else {
2255084Sjohnlev 		base = addr;
2265084Sjohnlev 	}
2275084Sjohnlev #else
2283446Smrj 	base = addr;
2295084Sjohnlev #endif
2300Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
2310Sstevel@tonic-gate 	cvaddr = device_arena_alloc(ptob(npages), VM_NOSLEEP);
2320Sstevel@tonic-gate 	if (cvaddr == NULL)
2330Sstevel@tonic-gate 		return (0);
2340Sstevel@tonic-gate 	hat_devload(kas.a_hat, cvaddr, mmu_ptob(npages), mmu_btop(base),
2350Sstevel@tonic-gate 	    prot, HAT_LOAD_LOCK);
2360Sstevel@tonic-gate 	return (cvaddr + pgoffset);
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate void
psm_unmap_phys(caddr_t addr,size_t len)2400Sstevel@tonic-gate psm_unmap_phys(caddr_t addr, size_t len)
2410Sstevel@tonic-gate {
2420Sstevel@tonic-gate 	uint_t pgoffset;
2430Sstevel@tonic-gate 	caddr_t base;
2440Sstevel@tonic-gate 	pgcnt_t npages;
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate 	if (len == 0)
2470Sstevel@tonic-gate 		return;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
2500Sstevel@tonic-gate 	base = addr - pgoffset;
2510Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
2520Sstevel@tonic-gate 	hat_unload(kas.a_hat, base, ptob(npages), HAT_UNLOAD_UNLOCK);
2530Sstevel@tonic-gate 	device_arena_free(base, ptob(npages));
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate caddr_t
psm_map_new(paddr_t addr,size_t len,int prot)2570Sstevel@tonic-gate psm_map_new(paddr_t addr, size_t len, int prot)
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate 	int phys_prot = PROT_READ;
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 	ASSERT(prot == (prot & (PSM_PROT_WRITE | PSM_PROT_READ)));
2620Sstevel@tonic-gate 	if (prot & PSM_PROT_WRITE)
2630Sstevel@tonic-gate 		phys_prot |= PROT_WRITE;
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	return (psm_map_phys(addr, len, phys_prot));
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate #undef psm_map_phys
2690Sstevel@tonic-gate #undef psm_map
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate caddr_t
psm_map_phys(uint32_t addr,size_t len,int prot)2720Sstevel@tonic-gate psm_map_phys(uint32_t addr, size_t len, int prot)
2730Sstevel@tonic-gate {
2740Sstevel@tonic-gate 	return (psm_map_phys_new((paddr_t)(addr & 0xffffffff), len, prot));
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate caddr_t
psm_map(uint32_t addr,size_t len,int prot)2780Sstevel@tonic-gate psm_map(uint32_t addr, size_t len, int prot)
2790Sstevel@tonic-gate {
2800Sstevel@tonic-gate 	return (psm_map_new((paddr_t)(addr & 0xffffffff), len, prot));
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate void
psm_unmap(caddr_t addr,size_t len)2840Sstevel@tonic-gate psm_unmap(caddr_t addr, size_t len)
2850Sstevel@tonic-gate {
2860Sstevel@tonic-gate 	uint_t pgoffset;
2870Sstevel@tonic-gate 	caddr_t base;
2880Sstevel@tonic-gate 	pgcnt_t npages;
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate 	if (len == 0)
2910Sstevel@tonic-gate 		return;
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 	pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
2940Sstevel@tonic-gate 	base = addr - pgoffset;
2950Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
2960Sstevel@tonic-gate 	hat_unload(kas.a_hat, base, ptob(npages), HAT_UNLOAD_UNLOCK);
2970Sstevel@tonic-gate 	device_arena_free(base, ptob(npages));
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate /*ARGSUSED1*/
3010Sstevel@tonic-gate static int
mod_installpsm(struct modlpsm * modl,struct modlinkage * modlp)3020Sstevel@tonic-gate mod_installpsm(struct modlpsm *modl, struct modlinkage *modlp)
3030Sstevel@tonic-gate {
3040Sstevel@tonic-gate 	struct psm_sw *swp;
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	swp = modl->psm_swp;
3070Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
3080Sstevel@tonic-gate 	psmsw->psw_back->psw_forw = swp;
3090Sstevel@tonic-gate 	swp->psw_back = psmsw->psw_back;
3100Sstevel@tonic-gate 	swp->psw_forw = psmsw;
3110Sstevel@tonic-gate 	psmsw->psw_back = swp;
3120Sstevel@tonic-gate 	swp->psw_flag |= PSM_MOD_INSTALL;
3130Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
3140Sstevel@tonic-gate 	return (0);
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate /*ARGSUSED1*/
3180Sstevel@tonic-gate static int
mod_removepsm(struct modlpsm * modl,struct modlinkage * modlp)3190Sstevel@tonic-gate mod_removepsm(struct modlpsm *modl, struct modlinkage *modlp)
3200Sstevel@tonic-gate {
3210Sstevel@tonic-gate 	struct psm_sw *swp;
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate 	swp = modl->psm_swp;
3240Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
3250Sstevel@tonic-gate 	if (swp->psw_flag & PSM_MOD_IDENTIFY) {
3260Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
3270Sstevel@tonic-gate 		return (EBUSY);
3280Sstevel@tonic-gate 	}
3290Sstevel@tonic-gate 	if (!(swp->psw_flag & PSM_MOD_INSTALL)) {
3300Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
3310Sstevel@tonic-gate 		return (0);
3320Sstevel@tonic-gate 	}
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 	swp->psw_back->psw_forw = swp->psw_forw;
3350Sstevel@tonic-gate 	swp->psw_forw->psw_back = swp->psw_back;
3360Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
3370Sstevel@tonic-gate 	return (0);
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate /*ARGSUSED1*/
3410Sstevel@tonic-gate static int
mod_infopsm(struct modlpsm * modl,struct modlinkage * modlp,int * p0)3420Sstevel@tonic-gate mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate 	*p0 = (int)modl->psm_swp->psw_infop->p_owner;
3450Sstevel@tonic-gate 	return (0);
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate 
3485084Sjohnlev #if defined(__xpv)
3496356Smrj #define	DEFAULT_PSM_MODULE	"xpv_uppc"
3505084Sjohnlev #else
3513446Smrj #define	DEFAULT_PSM_MODULE	"uppc"
3525084Sjohnlev #endif
3533446Smrj 
3540Sstevel@tonic-gate static char *
psm_get_impl_module(int first)3550Sstevel@tonic-gate psm_get_impl_module(int first)
3560Sstevel@tonic-gate {
3570Sstevel@tonic-gate 	static char **pnamep;
3580Sstevel@tonic-gate 	static char *psm_impl_module_list[] = {
3593446Smrj 		DEFAULT_PSM_MODULE,
3600Sstevel@tonic-gate 		(char *)0
3610Sstevel@tonic-gate 	};
3620Sstevel@tonic-gate 	static void *mhdl = NULL;
3630Sstevel@tonic-gate 	static char machname[MAXNAMELEN];
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 	if (first)
3660Sstevel@tonic-gate 		pnamep = psm_impl_module_list;
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	if (*pnamep != (char *)0)
3690Sstevel@tonic-gate 		return (*pnamep++);
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 	mhdl = get_next_mach(mhdl, machname);
3720Sstevel@tonic-gate 	if (mhdl)
3730Sstevel@tonic-gate 		return (machname);
3740Sstevel@tonic-gate 	return ((char *)0);
3750Sstevel@tonic-gate }
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate void
psm_modload(void)3780Sstevel@tonic-gate psm_modload(void)
3790Sstevel@tonic-gate {
3800Sstevel@tonic-gate 	char *this;
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 	mutex_init(&psmsw_lock, NULL, MUTEX_DEFAULT, NULL);
3830Sstevel@tonic-gate 	open_mach_list();
3840Sstevel@tonic-gate 
3855084Sjohnlev 	for (this = psm_get_impl_module(1); this != (char *)NULL;
3865084Sjohnlev 	    this = psm_get_impl_module(0)) {
3870Sstevel@tonic-gate 		if (modload("mach", this) == -1)
3887772SMark.Johnson@Sun.COM 			cmn_err(CE_CONT, "!Skipping psm: %s\n", this);
3890Sstevel@tonic-gate 	}
3900Sstevel@tonic-gate 	close_mach_list();
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate 
3935529Ssmaybe #if defined(__xpv)
3945529Ssmaybe #define	NOTSUP_MSG "This version of Solaris xVM does not support this hardware"
3955529Ssmaybe #else
3965529Ssmaybe #define	NOTSUP_MSG "This version of Solaris does not support this hardware"
3975529Ssmaybe #endif	/* __xpv */
3985529Ssmaybe 
3990Sstevel@tonic-gate void
psm_install(void)4000Sstevel@tonic-gate psm_install(void)
4010Sstevel@tonic-gate {
4020Sstevel@tonic-gate 	struct psm_sw *swp, *cswp;
4030Sstevel@tonic-gate 	struct psm_ops *opsp;
4040Sstevel@tonic-gate 	char machstring[15];
4055529Ssmaybe 	int err, psmcnt = 0;
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
4080Sstevel@tonic-gate 	for (swp = psmsw->psw_forw; swp != psmsw; ) {
4090Sstevel@tonic-gate 		opsp = swp->psw_infop->p_ops;
4100Sstevel@tonic-gate 		if (opsp->psm_probe) {
4110Sstevel@tonic-gate 			if ((*opsp->psm_probe)() == PSM_SUCCESS) {
4125529Ssmaybe 				psmcnt++;
4130Sstevel@tonic-gate 				swp->psw_flag |= PSM_MOD_IDENTIFY;
4140Sstevel@tonic-gate 				swp = swp->psw_forw;
4150Sstevel@tonic-gate 				continue;
4160Sstevel@tonic-gate 			}
4170Sstevel@tonic-gate 		}
4180Sstevel@tonic-gate 		/* remove the unsuccessful psm modules */
4190Sstevel@tonic-gate 		cswp = swp;
4200Sstevel@tonic-gate 		swp = swp->psw_forw;
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
4230Sstevel@tonic-gate 		(void) strcpy(&machstring[0], cswp->psw_infop->p_mach_idstring);
4240Sstevel@tonic-gate 		err = mod_remove_by_name(cswp->psw_infop->p_mach_idstring);
4250Sstevel@tonic-gate 		if (err)
4268198SVikram.Hegde@Sun.COM 			cmn_err(CE_WARN, "!%s: mod_remove_by_name failed %d",
4275084Sjohnlev 			    &machstring[0], err);
4280Sstevel@tonic-gate 		mutex_enter(&psmsw_lock);
4290Sstevel@tonic-gate 	}
4300Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
4315529Ssmaybe 	if (psmcnt == 0)
4325529Ssmaybe 		halt(NOTSUP_MSG);
4330Sstevel@tonic-gate 	(*psminitf)();
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate /*
4370Sstevel@tonic-gate  * Return 1 if kernel debugger is present, and 0 if not.
4380Sstevel@tonic-gate  */
4390Sstevel@tonic-gate int
psm_debugger(void)4400Sstevel@tonic-gate psm_debugger(void)
4410Sstevel@tonic-gate {
4420Sstevel@tonic-gate 	return ((boothowto & RB_DEBUG) != 0);
4430Sstevel@tonic-gate }
444