xref: /onnv-gate/usr/src/uts/i86pc/os/mp_implfuncs.c (revision 3446:5903aece022d)
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
5*3446Smrj  * Common Development and Distribution License (the "License").
6*3446Smrj  * 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 /*
22*3446Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <sys/psm.h>
290Sstevel@tonic-gate #include <sys/vmem.h>
300Sstevel@tonic-gate #include <vm/hat.h>
310Sstevel@tonic-gate #include <sys/modctl.h>
320Sstevel@tonic-gate #include <vm/seg_kmem.h>
330Sstevel@tonic-gate #define	PSMI_1_5
340Sstevel@tonic-gate #include <sys/psm.h>
350Sstevel@tonic-gate #include <sys/psm_modctl.h>
360Sstevel@tonic-gate #include <sys/smp_impldefs.h>
370Sstevel@tonic-gate #include <sys/reboot.h>
380Sstevel@tonic-gate 
390Sstevel@tonic-gate /*
400Sstevel@tonic-gate  *	External reference functions
410Sstevel@tonic-gate  */
420Sstevel@tonic-gate extern void *get_next_mach(void *, char *);
430Sstevel@tonic-gate extern void close_mach_list(void);
440Sstevel@tonic-gate extern void open_mach_list(void);
450Sstevel@tonic-gate 
460Sstevel@tonic-gate /*
470Sstevel@tonic-gate  * from startup.c - kernel VA range allocator for device mappings
480Sstevel@tonic-gate  */
490Sstevel@tonic-gate extern void *device_arena_alloc(size_t size, int vm_flag);
500Sstevel@tonic-gate extern void device_arena_free(void * vaddr, size_t size);
510Sstevel@tonic-gate 
520Sstevel@tonic-gate void psm_modloadonly(void);
530Sstevel@tonic-gate void psm_install(void);
540Sstevel@tonic-gate 
550Sstevel@tonic-gate /*
560Sstevel@tonic-gate  * Local Function Prototypes
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate static struct modlinkage *psm_modlinkage_alloc(struct psm_info *infop);
590Sstevel@tonic-gate static void psm_modlinkage_free(struct modlinkage *mlinkp);
600Sstevel@tonic-gate 
610Sstevel@tonic-gate static char *psm_get_impl_module(int first);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate static int mod_installpsm(struct modlpsm *modl, struct modlinkage *modlp);
640Sstevel@tonic-gate static int mod_removepsm(struct modlpsm *modl, struct modlinkage *modlp);
650Sstevel@tonic-gate static int mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0);
660Sstevel@tonic-gate struct mod_ops mod_psmops = {
670Sstevel@tonic-gate 	mod_installpsm, mod_removepsm, mod_infopsm
680Sstevel@tonic-gate };
690Sstevel@tonic-gate 
700Sstevel@tonic-gate static struct psm_sw psm_swtab = {
710Sstevel@tonic-gate 	&psm_swtab, &psm_swtab, NULL, NULL
720Sstevel@tonic-gate };
730Sstevel@tonic-gate 
740Sstevel@tonic-gate kmutex_t psmsw_lock;			/* lock accesses to psmsw 	*/
750Sstevel@tonic-gate struct psm_sw *psmsw = &psm_swtab; 	/* start of all psm_sw		*/
760Sstevel@tonic-gate 
770Sstevel@tonic-gate static struct modlinkage *
780Sstevel@tonic-gate psm_modlinkage_alloc(struct psm_info *infop)
790Sstevel@tonic-gate {
800Sstevel@tonic-gate 	int	memsz;
810Sstevel@tonic-gate 	struct modlinkage *mlinkp;
820Sstevel@tonic-gate 	struct modlpsm *mlpsmp;
830Sstevel@tonic-gate 	struct psm_sw *swp;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	memsz = sizeof (struct modlinkage) + sizeof (struct modlpsm) +
860Sstevel@tonic-gate 		sizeof (struct psm_sw);
870Sstevel@tonic-gate 	mlinkp = (struct modlinkage *)kmem_zalloc(memsz, KM_NOSLEEP);
880Sstevel@tonic-gate 	if (!mlinkp) {
890Sstevel@tonic-gate 		cmn_err(CE_WARN, "!psm_mod_init: Cannot install %s",
900Sstevel@tonic-gate 			infop->p_mach_idstring);
910Sstevel@tonic-gate 		return (NULL);
920Sstevel@tonic-gate 	}
930Sstevel@tonic-gate 	mlpsmp = (struct modlpsm *)(mlinkp + 1);
940Sstevel@tonic-gate 	swp = (struct psm_sw *)(mlpsmp + 1);
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	mlinkp->ml_rev = MODREV_1;
970Sstevel@tonic-gate 	mlinkp->ml_linkage[0] = (void *)mlpsmp;
980Sstevel@tonic-gate 	mlinkp->ml_linkage[1] = (void *)NULL;
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	mlpsmp->psm_modops = &mod_psmops;
1010Sstevel@tonic-gate 	mlpsmp->psm_linkinfo = infop->p_mach_desc;
1020Sstevel@tonic-gate 	mlpsmp->psm_swp = swp;
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	swp->psw_infop = infop;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	return (mlinkp);
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate static void
1100Sstevel@tonic-gate psm_modlinkage_free(struct modlinkage *mlinkp)
1110Sstevel@tonic-gate {
1120Sstevel@tonic-gate 	if (!mlinkp)
1130Sstevel@tonic-gate 		return;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	(void) kmem_free(mlinkp, (sizeof (struct modlinkage) +
1160Sstevel@tonic-gate 		sizeof (struct modlpsm) + sizeof (struct psm_sw)));
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate int
1200Sstevel@tonic-gate psm_mod_init(void **handlepp, struct psm_info *infop)
1210Sstevel@tonic-gate {
1220Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
1230Sstevel@tonic-gate 	int	status;
1240Sstevel@tonic-gate 	struct modlinkage *mlinkp;
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 	if (!*modlpp) {
1270Sstevel@tonic-gate 		mlinkp = psm_modlinkage_alloc(infop);
1280Sstevel@tonic-gate 		if (!mlinkp)
1290Sstevel@tonic-gate 			return (ENOSPC);
1300Sstevel@tonic-gate 	} else
1310Sstevel@tonic-gate 		mlinkp = *modlpp;
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 	status = mod_install(mlinkp);
1340Sstevel@tonic-gate 	if (status) {
1350Sstevel@tonic-gate 		psm_modlinkage_free(mlinkp);
1360Sstevel@tonic-gate 		*modlpp = NULL;
1370Sstevel@tonic-gate 	} else
1380Sstevel@tonic-gate 		*modlpp = mlinkp;
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	return (status);
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate /*ARGSUSED1*/
1440Sstevel@tonic-gate int
1450Sstevel@tonic-gate psm_mod_fini(void **handlepp, struct psm_info *infop)
1460Sstevel@tonic-gate {
1470Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
1480Sstevel@tonic-gate 	int	status;
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	status = mod_remove(*modlpp);
1510Sstevel@tonic-gate 	if (status == 0) {
1520Sstevel@tonic-gate 		psm_modlinkage_free(*modlpp);
1530Sstevel@tonic-gate 		*modlpp = NULL;
1540Sstevel@tonic-gate 	}
1550Sstevel@tonic-gate 	return (status);
1560Sstevel@tonic-gate }
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate int
1590Sstevel@tonic-gate psm_mod_info(void **handlepp, struct psm_info *infop, struct modinfo *modinfop)
1600Sstevel@tonic-gate {
1610Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
1620Sstevel@tonic-gate 	int status;
1630Sstevel@tonic-gate 	struct modlinkage *mlinkp;
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	if (!*modlpp) {
1660Sstevel@tonic-gate 		mlinkp = psm_modlinkage_alloc(infop);
1670Sstevel@tonic-gate 		if (!mlinkp)
1680Sstevel@tonic-gate 			return ((int)NULL);
1690Sstevel@tonic-gate 	} else
1700Sstevel@tonic-gate 		mlinkp = *modlpp;
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	status =  mod_info(mlinkp, modinfop);
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	if (!status) {
1750Sstevel@tonic-gate 		psm_modlinkage_free(mlinkp);
1760Sstevel@tonic-gate 		*modlpp = NULL;
1770Sstevel@tonic-gate 	} else
1780Sstevel@tonic-gate 		*modlpp = mlinkp;
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 	return (status);
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate int
1840Sstevel@tonic-gate psm_add_intr(int lvl, avfunc xxintr, char *name, int vect, caddr_t arg)
1850Sstevel@tonic-gate {
1860Sstevel@tonic-gate 	return (add_avintr((void *)NULL, lvl, xxintr, name, vect,
187916Sschwartz 	    arg, NULL, NULL, NULL));
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate int
1910Sstevel@tonic-gate psm_add_nmintr(int lvl, avfunc xxintr, char *name, caddr_t arg)
1920Sstevel@tonic-gate {
1930Sstevel@tonic-gate 	return (add_nmintr(lvl, xxintr, name, arg));
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate processorid_t
1970Sstevel@tonic-gate psm_get_cpu_id(void)
1980Sstevel@tonic-gate {
1990Sstevel@tonic-gate 	return (CPU->cpu_id);
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate caddr_t
2030Sstevel@tonic-gate psm_map_phys_new(paddr_t addr, size_t len, int prot)
2040Sstevel@tonic-gate {
2050Sstevel@tonic-gate 	uint_t pgoffset;
2060Sstevel@tonic-gate 	paddr_t base;
2070Sstevel@tonic-gate 	pgcnt_t npages;
2080Sstevel@tonic-gate 	caddr_t cvaddr;
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	if (len == 0)
2110Sstevel@tonic-gate 		return (0);
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	pgoffset = addr & MMU_PAGEOFFSET;
214*3446Smrj 	base = addr;
2150Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
2160Sstevel@tonic-gate 	cvaddr = device_arena_alloc(ptob(npages), VM_NOSLEEP);
2170Sstevel@tonic-gate 	if (cvaddr == NULL)
2180Sstevel@tonic-gate 		return (0);
2190Sstevel@tonic-gate 	hat_devload(kas.a_hat, cvaddr, mmu_ptob(npages), mmu_btop(base),
2200Sstevel@tonic-gate 	    prot, HAT_LOAD_LOCK);
2210Sstevel@tonic-gate 	return (cvaddr + pgoffset);
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate void
2250Sstevel@tonic-gate psm_unmap_phys(caddr_t addr, size_t len)
2260Sstevel@tonic-gate {
2270Sstevel@tonic-gate 	uint_t pgoffset;
2280Sstevel@tonic-gate 	caddr_t base;
2290Sstevel@tonic-gate 	pgcnt_t npages;
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 	if (len == 0)
2320Sstevel@tonic-gate 		return;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
2350Sstevel@tonic-gate 	base = addr - pgoffset;
2360Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
2370Sstevel@tonic-gate 	hat_unload(kas.a_hat, base, ptob(npages), HAT_UNLOAD_UNLOCK);
2380Sstevel@tonic-gate 	device_arena_free(base, ptob(npages));
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate caddr_t
2420Sstevel@tonic-gate psm_map_new(paddr_t addr, size_t len, int prot)
2430Sstevel@tonic-gate {
2440Sstevel@tonic-gate 	int phys_prot = PROT_READ;
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate 	ASSERT(prot == (prot & (PSM_PROT_WRITE | PSM_PROT_READ)));
2470Sstevel@tonic-gate 	if (prot & PSM_PROT_WRITE)
2480Sstevel@tonic-gate 		phys_prot |= PROT_WRITE;
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 	return (psm_map_phys(addr, len, phys_prot));
2510Sstevel@tonic-gate }
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate #undef psm_map_phys
2540Sstevel@tonic-gate #undef psm_map
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate caddr_t
2570Sstevel@tonic-gate psm_map_phys(uint32_t addr, size_t len, int prot)
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate 	return (psm_map_phys_new((paddr_t)(addr & 0xffffffff), len, prot));
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate caddr_t
2630Sstevel@tonic-gate psm_map(uint32_t addr, size_t len, int prot)
2640Sstevel@tonic-gate {
2650Sstevel@tonic-gate 	return (psm_map_new((paddr_t)(addr & 0xffffffff), len, prot));
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate void
2690Sstevel@tonic-gate psm_unmap(caddr_t addr, size_t len)
2700Sstevel@tonic-gate {
2710Sstevel@tonic-gate 	uint_t pgoffset;
2720Sstevel@tonic-gate 	caddr_t base;
2730Sstevel@tonic-gate 	pgcnt_t npages;
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate 	if (len == 0)
2760Sstevel@tonic-gate 		return;
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate 	pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
2790Sstevel@tonic-gate 	base = addr - pgoffset;
2800Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
2810Sstevel@tonic-gate 	hat_unload(kas.a_hat, base, ptob(npages), HAT_UNLOAD_UNLOCK);
2820Sstevel@tonic-gate 	device_arena_free(base, ptob(npages));
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate /*ARGSUSED1*/
2860Sstevel@tonic-gate static int
2870Sstevel@tonic-gate mod_installpsm(struct modlpsm *modl, struct modlinkage *modlp)
2880Sstevel@tonic-gate {
2890Sstevel@tonic-gate 	struct psm_sw *swp;
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate 	swp = modl->psm_swp;
2920Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
2930Sstevel@tonic-gate 	psmsw->psw_back->psw_forw = swp;
2940Sstevel@tonic-gate 	swp->psw_back = psmsw->psw_back;
2950Sstevel@tonic-gate 	swp->psw_forw = psmsw;
2960Sstevel@tonic-gate 	psmsw->psw_back = swp;
2970Sstevel@tonic-gate 	swp->psw_flag |= PSM_MOD_INSTALL;
2980Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
2990Sstevel@tonic-gate 	return (0);
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate /*ARGSUSED1*/
3030Sstevel@tonic-gate static int
3040Sstevel@tonic-gate mod_removepsm(struct modlpsm *modl, struct modlinkage *modlp)
3050Sstevel@tonic-gate {
3060Sstevel@tonic-gate 	struct psm_sw *swp;
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	swp = modl->psm_swp;
3090Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
3100Sstevel@tonic-gate 	if (swp->psw_flag & PSM_MOD_IDENTIFY) {
3110Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
3120Sstevel@tonic-gate 		return (EBUSY);
3130Sstevel@tonic-gate 	}
3140Sstevel@tonic-gate 	if (!(swp->psw_flag & PSM_MOD_INSTALL)) {
3150Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
3160Sstevel@tonic-gate 		return (0);
3170Sstevel@tonic-gate 	}
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	swp->psw_back->psw_forw = swp->psw_forw;
3200Sstevel@tonic-gate 	swp->psw_forw->psw_back = swp->psw_back;
3210Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
3220Sstevel@tonic-gate 	return (0);
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate /*ARGSUSED1*/
3260Sstevel@tonic-gate static int
3270Sstevel@tonic-gate mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0)
3280Sstevel@tonic-gate {
3290Sstevel@tonic-gate 	*p0 = (int)modl->psm_swp->psw_infop->p_owner;
3300Sstevel@tonic-gate 	return (0);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate 
333*3446Smrj #define	DEFAULT_PSM_MODULE	"uppc"
334*3446Smrj 
3350Sstevel@tonic-gate static char *
3360Sstevel@tonic-gate psm_get_impl_module(int first)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate 	static char **pnamep;
3390Sstevel@tonic-gate 	static char *psm_impl_module_list[] = {
340*3446Smrj 		DEFAULT_PSM_MODULE,
3410Sstevel@tonic-gate 		(char *)0
3420Sstevel@tonic-gate 	};
3430Sstevel@tonic-gate 	static void *mhdl = NULL;
3440Sstevel@tonic-gate 	static char machname[MAXNAMELEN];
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate 	if (first)
3470Sstevel@tonic-gate 		pnamep = psm_impl_module_list;
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 	if (*pnamep != (char *)0)
3500Sstevel@tonic-gate 		return (*pnamep++);
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	mhdl = get_next_mach(mhdl, machname);
3530Sstevel@tonic-gate 	if (mhdl)
3540Sstevel@tonic-gate 		return (machname);
3550Sstevel@tonic-gate 	return ((char *)0);
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate void
3590Sstevel@tonic-gate psm_modload(void)
3600Sstevel@tonic-gate {
3610Sstevel@tonic-gate 	char *this;
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate 	mutex_init(&psmsw_lock, NULL, MUTEX_DEFAULT, NULL);
3640Sstevel@tonic-gate 	open_mach_list();
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 	for (this = psm_get_impl_module(1);
3670Sstevel@tonic-gate 		this != (char *)NULL;
3680Sstevel@tonic-gate 		this = psm_get_impl_module(0)) {
3690Sstevel@tonic-gate 		if (modload("mach", this) == -1)
3700Sstevel@tonic-gate 			cmn_err(CE_WARN, "!Cannot load psm %s", this);
3710Sstevel@tonic-gate 	}
3720Sstevel@tonic-gate 	close_mach_list();
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate void
3760Sstevel@tonic-gate psm_install(void)
3770Sstevel@tonic-gate {
3780Sstevel@tonic-gate 	struct psm_sw *swp, *cswp;
3790Sstevel@tonic-gate 	struct psm_ops *opsp;
3800Sstevel@tonic-gate 	char machstring[15];
3810Sstevel@tonic-gate 	int err;
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
3840Sstevel@tonic-gate 	for (swp = psmsw->psw_forw; swp != psmsw; ) {
3850Sstevel@tonic-gate 		opsp = swp->psw_infop->p_ops;
3860Sstevel@tonic-gate 		if (opsp->psm_probe) {
3870Sstevel@tonic-gate 			if ((*opsp->psm_probe)() == PSM_SUCCESS) {
3880Sstevel@tonic-gate 				swp->psw_flag |= PSM_MOD_IDENTIFY;
3890Sstevel@tonic-gate 				swp = swp->psw_forw;
3900Sstevel@tonic-gate 				continue;
3910Sstevel@tonic-gate 			}
3920Sstevel@tonic-gate 		}
3930Sstevel@tonic-gate 		/* remove the unsuccessful psm modules */
3940Sstevel@tonic-gate 		cswp = swp;
3950Sstevel@tonic-gate 		swp = swp->psw_forw;
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
3980Sstevel@tonic-gate 		(void) strcpy(&machstring[0], cswp->psw_infop->p_mach_idstring);
3990Sstevel@tonic-gate 		err = mod_remove_by_name(cswp->psw_infop->p_mach_idstring);
4000Sstevel@tonic-gate 		if (err)
4010Sstevel@tonic-gate 			cmn_err(CE_WARN, "%s: mod_remove_by_name failed %d",
4020Sstevel@tonic-gate 				&machstring[0], err);
4030Sstevel@tonic-gate 		mutex_enter(&psmsw_lock);
4040Sstevel@tonic-gate 	}
4050Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
4060Sstevel@tonic-gate 	(*psminitf)();
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate /*
4100Sstevel@tonic-gate  * Return 1 if kernel debugger is present, and 0 if not.
4110Sstevel@tonic-gate  */
4120Sstevel@tonic-gate int
4130Sstevel@tonic-gate psm_debugger(void)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate 	return ((boothowto & RB_DEBUG) != 0);
4160Sstevel@tonic-gate }
417