xref: /onnv-gate/usr/src/uts/i86pc/os/mp_implfuncs.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <sys/psm.h>
30*0Sstevel@tonic-gate #include <sys/vmem.h>
31*0Sstevel@tonic-gate #include <vm/hat.h>
32*0Sstevel@tonic-gate #include <sys/modctl.h>
33*0Sstevel@tonic-gate #include <vm/seg_kmem.h>
34*0Sstevel@tonic-gate #define	PSMI_1_5
35*0Sstevel@tonic-gate #include <sys/psm.h>
36*0Sstevel@tonic-gate #include <sys/psm_modctl.h>
37*0Sstevel@tonic-gate #include <sys/smp_impldefs.h>
38*0Sstevel@tonic-gate #include <sys/reboot.h>
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate /*
41*0Sstevel@tonic-gate  *	External reference functions
42*0Sstevel@tonic-gate  */
43*0Sstevel@tonic-gate extern void *get_next_mach(void *, char *);
44*0Sstevel@tonic-gate extern void close_mach_list(void);
45*0Sstevel@tonic-gate extern void open_mach_list(void);
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate /*
48*0Sstevel@tonic-gate  * from startup.c - kernel VA range allocator for device mappings
49*0Sstevel@tonic-gate  */
50*0Sstevel@tonic-gate extern void *device_arena_alloc(size_t size, int vm_flag);
51*0Sstevel@tonic-gate extern void device_arena_free(void * vaddr, size_t size);
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate void psm_modloadonly(void);
54*0Sstevel@tonic-gate void psm_install(void);
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate /*
57*0Sstevel@tonic-gate  * Local Function Prototypes
58*0Sstevel@tonic-gate  */
59*0Sstevel@tonic-gate static struct modlinkage *psm_modlinkage_alloc(struct psm_info *infop);
60*0Sstevel@tonic-gate static void psm_modlinkage_free(struct modlinkage *mlinkp);
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate static char *psm_get_impl_module(int first);
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate static int mod_installpsm(struct modlpsm *modl, struct modlinkage *modlp);
65*0Sstevel@tonic-gate static int mod_removepsm(struct modlpsm *modl, struct modlinkage *modlp);
66*0Sstevel@tonic-gate static int mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0);
67*0Sstevel@tonic-gate struct mod_ops mod_psmops = {
68*0Sstevel@tonic-gate 	mod_installpsm, mod_removepsm, mod_infopsm
69*0Sstevel@tonic-gate };
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate static struct psm_sw psm_swtab = {
72*0Sstevel@tonic-gate 	&psm_swtab, &psm_swtab, NULL, NULL
73*0Sstevel@tonic-gate };
74*0Sstevel@tonic-gate 
75*0Sstevel@tonic-gate kmutex_t psmsw_lock;			/* lock accesses to psmsw 	*/
76*0Sstevel@tonic-gate struct psm_sw *psmsw = &psm_swtab; 	/* start of all psm_sw		*/
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate static struct modlinkage *
79*0Sstevel@tonic-gate psm_modlinkage_alloc(struct psm_info *infop)
80*0Sstevel@tonic-gate {
81*0Sstevel@tonic-gate 	int	memsz;
82*0Sstevel@tonic-gate 	struct modlinkage *mlinkp;
83*0Sstevel@tonic-gate 	struct modlpsm *mlpsmp;
84*0Sstevel@tonic-gate 	struct psm_sw *swp;
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 	memsz = sizeof (struct modlinkage) + sizeof (struct modlpsm) +
87*0Sstevel@tonic-gate 		sizeof (struct psm_sw);
88*0Sstevel@tonic-gate 	mlinkp = (struct modlinkage *)kmem_zalloc(memsz, KM_NOSLEEP);
89*0Sstevel@tonic-gate 	if (!mlinkp) {
90*0Sstevel@tonic-gate 		cmn_err(CE_WARN, "!psm_mod_init: Cannot install %s",
91*0Sstevel@tonic-gate 			infop->p_mach_idstring);
92*0Sstevel@tonic-gate 		return (NULL);
93*0Sstevel@tonic-gate 	}
94*0Sstevel@tonic-gate 	mlpsmp = (struct modlpsm *)(mlinkp + 1);
95*0Sstevel@tonic-gate 	swp = (struct psm_sw *)(mlpsmp + 1);
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate 	mlinkp->ml_rev = MODREV_1;
98*0Sstevel@tonic-gate 	mlinkp->ml_linkage[0] = (void *)mlpsmp;
99*0Sstevel@tonic-gate 	mlinkp->ml_linkage[1] = (void *)NULL;
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	mlpsmp->psm_modops = &mod_psmops;
102*0Sstevel@tonic-gate 	mlpsmp->psm_linkinfo = infop->p_mach_desc;
103*0Sstevel@tonic-gate 	mlpsmp->psm_swp = swp;
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	swp->psw_infop = infop;
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate 	return (mlinkp);
108*0Sstevel@tonic-gate }
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate static void
111*0Sstevel@tonic-gate psm_modlinkage_free(struct modlinkage *mlinkp)
112*0Sstevel@tonic-gate {
113*0Sstevel@tonic-gate 	if (!mlinkp)
114*0Sstevel@tonic-gate 		return;
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 	(void) kmem_free(mlinkp, (sizeof (struct modlinkage) +
117*0Sstevel@tonic-gate 		sizeof (struct modlpsm) + sizeof (struct psm_sw)));
118*0Sstevel@tonic-gate }
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate int
121*0Sstevel@tonic-gate psm_mod_init(void **handlepp, struct psm_info *infop)
122*0Sstevel@tonic-gate {
123*0Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
124*0Sstevel@tonic-gate 	int	status;
125*0Sstevel@tonic-gate 	struct modlinkage *mlinkp;
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 	if (!*modlpp) {
128*0Sstevel@tonic-gate 		mlinkp = psm_modlinkage_alloc(infop);
129*0Sstevel@tonic-gate 		if (!mlinkp)
130*0Sstevel@tonic-gate 			return (ENOSPC);
131*0Sstevel@tonic-gate 	} else
132*0Sstevel@tonic-gate 		mlinkp = *modlpp;
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 	status = mod_install(mlinkp);
135*0Sstevel@tonic-gate 	if (status) {
136*0Sstevel@tonic-gate 		psm_modlinkage_free(mlinkp);
137*0Sstevel@tonic-gate 		*modlpp = NULL;
138*0Sstevel@tonic-gate 	} else
139*0Sstevel@tonic-gate 		*modlpp = mlinkp;
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate 	return (status);
142*0Sstevel@tonic-gate }
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate /*ARGSUSED1*/
145*0Sstevel@tonic-gate int
146*0Sstevel@tonic-gate psm_mod_fini(void **handlepp, struct psm_info *infop)
147*0Sstevel@tonic-gate {
148*0Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
149*0Sstevel@tonic-gate 	int	status;
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 	status = mod_remove(*modlpp);
152*0Sstevel@tonic-gate 	if (status == 0) {
153*0Sstevel@tonic-gate 		psm_modlinkage_free(*modlpp);
154*0Sstevel@tonic-gate 		*modlpp = NULL;
155*0Sstevel@tonic-gate 	}
156*0Sstevel@tonic-gate 	return (status);
157*0Sstevel@tonic-gate }
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate int
160*0Sstevel@tonic-gate psm_mod_info(void **handlepp, struct psm_info *infop, struct modinfo *modinfop)
161*0Sstevel@tonic-gate {
162*0Sstevel@tonic-gate 	struct modlinkage **modlpp = (struct modlinkage **)handlepp;
163*0Sstevel@tonic-gate 	int status;
164*0Sstevel@tonic-gate 	struct modlinkage *mlinkp;
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate 	if (!*modlpp) {
167*0Sstevel@tonic-gate 		mlinkp = psm_modlinkage_alloc(infop);
168*0Sstevel@tonic-gate 		if (!mlinkp)
169*0Sstevel@tonic-gate 			return ((int)NULL);
170*0Sstevel@tonic-gate 	} else
171*0Sstevel@tonic-gate 		mlinkp = *modlpp;
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate 	status =  mod_info(mlinkp, modinfop);
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	if (!status) {
176*0Sstevel@tonic-gate 		psm_modlinkage_free(mlinkp);
177*0Sstevel@tonic-gate 		*modlpp = NULL;
178*0Sstevel@tonic-gate 	} else
179*0Sstevel@tonic-gate 		*modlpp = mlinkp;
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	return (status);
182*0Sstevel@tonic-gate }
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate int
185*0Sstevel@tonic-gate psm_add_intr(int lvl, avfunc xxintr, char *name, int vect, caddr_t arg)
186*0Sstevel@tonic-gate {
187*0Sstevel@tonic-gate 	return (add_avintr((void *)NULL, lvl, xxintr, name, vect,
188*0Sstevel@tonic-gate 	    arg, NULL, NULL));
189*0Sstevel@tonic-gate }
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate int
192*0Sstevel@tonic-gate psm_add_nmintr(int lvl, avfunc xxintr, char *name, caddr_t arg)
193*0Sstevel@tonic-gate {
194*0Sstevel@tonic-gate 	return (add_nmintr(lvl, xxintr, name, arg));
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate processorid_t
198*0Sstevel@tonic-gate psm_get_cpu_id(void)
199*0Sstevel@tonic-gate {
200*0Sstevel@tonic-gate 	return (CPU->cpu_id);
201*0Sstevel@tonic-gate }
202*0Sstevel@tonic-gate 
203*0Sstevel@tonic-gate caddr_t
204*0Sstevel@tonic-gate psm_map_phys_new(paddr_t addr, size_t len, int prot)
205*0Sstevel@tonic-gate {
206*0Sstevel@tonic-gate 	uint_t pgoffset;
207*0Sstevel@tonic-gate 	paddr_t base;
208*0Sstevel@tonic-gate 	pgcnt_t npages;
209*0Sstevel@tonic-gate 	caddr_t cvaddr;
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate 	if (len == 0)
212*0Sstevel@tonic-gate 		return (0);
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate 	pgoffset = addr & MMU_PAGEOFFSET;
215*0Sstevel@tonic-gate 	base = addr - pgoffset;
216*0Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
217*0Sstevel@tonic-gate 	cvaddr = device_arena_alloc(ptob(npages), VM_NOSLEEP);
218*0Sstevel@tonic-gate 	if (cvaddr == NULL)
219*0Sstevel@tonic-gate 		return (0);
220*0Sstevel@tonic-gate 	hat_devload(kas.a_hat, cvaddr, mmu_ptob(npages), mmu_btop(base),
221*0Sstevel@tonic-gate 	    prot, HAT_LOAD_LOCK);
222*0Sstevel@tonic-gate 	return (cvaddr + pgoffset);
223*0Sstevel@tonic-gate }
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate void
226*0Sstevel@tonic-gate psm_unmap_phys(caddr_t addr, size_t len)
227*0Sstevel@tonic-gate {
228*0Sstevel@tonic-gate 	uint_t pgoffset;
229*0Sstevel@tonic-gate 	caddr_t base;
230*0Sstevel@tonic-gate 	pgcnt_t npages;
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	if (len == 0)
233*0Sstevel@tonic-gate 		return;
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate 	pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
236*0Sstevel@tonic-gate 	base = addr - pgoffset;
237*0Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
238*0Sstevel@tonic-gate 	hat_unload(kas.a_hat, base, ptob(npages), HAT_UNLOAD_UNLOCK);
239*0Sstevel@tonic-gate 	device_arena_free(base, ptob(npages));
240*0Sstevel@tonic-gate }
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate caddr_t
243*0Sstevel@tonic-gate psm_map_new(paddr_t addr, size_t len, int prot)
244*0Sstevel@tonic-gate {
245*0Sstevel@tonic-gate 	int phys_prot = PROT_READ;
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate 	ASSERT(prot == (prot & (PSM_PROT_WRITE | PSM_PROT_READ)));
248*0Sstevel@tonic-gate 	if (prot & PSM_PROT_WRITE)
249*0Sstevel@tonic-gate 		phys_prot |= PROT_WRITE;
250*0Sstevel@tonic-gate 
251*0Sstevel@tonic-gate 	return (psm_map_phys(addr, len, phys_prot));
252*0Sstevel@tonic-gate }
253*0Sstevel@tonic-gate 
254*0Sstevel@tonic-gate #undef psm_map_phys
255*0Sstevel@tonic-gate #undef psm_map
256*0Sstevel@tonic-gate 
257*0Sstevel@tonic-gate caddr_t
258*0Sstevel@tonic-gate psm_map_phys(uint32_t addr, size_t len, int prot)
259*0Sstevel@tonic-gate {
260*0Sstevel@tonic-gate 	return (psm_map_phys_new((paddr_t)(addr & 0xffffffff), len, prot));
261*0Sstevel@tonic-gate }
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate caddr_t
264*0Sstevel@tonic-gate psm_map(uint32_t addr, size_t len, int prot)
265*0Sstevel@tonic-gate {
266*0Sstevel@tonic-gate 	return (psm_map_new((paddr_t)(addr & 0xffffffff), len, prot));
267*0Sstevel@tonic-gate }
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate void
270*0Sstevel@tonic-gate psm_unmap(caddr_t addr, size_t len)
271*0Sstevel@tonic-gate {
272*0Sstevel@tonic-gate 	uint_t pgoffset;
273*0Sstevel@tonic-gate 	caddr_t base;
274*0Sstevel@tonic-gate 	pgcnt_t npages;
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate 	if (len == 0)
277*0Sstevel@tonic-gate 		return;
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate 	pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
280*0Sstevel@tonic-gate 	base = addr - pgoffset;
281*0Sstevel@tonic-gate 	npages = mmu_btopr(len + pgoffset);
282*0Sstevel@tonic-gate 	hat_unload(kas.a_hat, base, ptob(npages), HAT_UNLOAD_UNLOCK);
283*0Sstevel@tonic-gate 	device_arena_free(base, ptob(npages));
284*0Sstevel@tonic-gate }
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate /*ARGSUSED1*/
287*0Sstevel@tonic-gate static int
288*0Sstevel@tonic-gate mod_installpsm(struct modlpsm *modl, struct modlinkage *modlp)
289*0Sstevel@tonic-gate {
290*0Sstevel@tonic-gate 	struct psm_sw *swp;
291*0Sstevel@tonic-gate 
292*0Sstevel@tonic-gate 	swp = modl->psm_swp;
293*0Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
294*0Sstevel@tonic-gate 	psmsw->psw_back->psw_forw = swp;
295*0Sstevel@tonic-gate 	swp->psw_back = psmsw->psw_back;
296*0Sstevel@tonic-gate 	swp->psw_forw = psmsw;
297*0Sstevel@tonic-gate 	psmsw->psw_back = swp;
298*0Sstevel@tonic-gate 	swp->psw_flag |= PSM_MOD_INSTALL;
299*0Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
300*0Sstevel@tonic-gate 	return (0);
301*0Sstevel@tonic-gate }
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate /*ARGSUSED1*/
304*0Sstevel@tonic-gate static int
305*0Sstevel@tonic-gate mod_removepsm(struct modlpsm *modl, struct modlinkage *modlp)
306*0Sstevel@tonic-gate {
307*0Sstevel@tonic-gate 	struct psm_sw *swp;
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate 	swp = modl->psm_swp;
310*0Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
311*0Sstevel@tonic-gate 	if (swp->psw_flag & PSM_MOD_IDENTIFY) {
312*0Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
313*0Sstevel@tonic-gate 		return (EBUSY);
314*0Sstevel@tonic-gate 	}
315*0Sstevel@tonic-gate 	if (!(swp->psw_flag & PSM_MOD_INSTALL)) {
316*0Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
317*0Sstevel@tonic-gate 		return (0);
318*0Sstevel@tonic-gate 	}
319*0Sstevel@tonic-gate 
320*0Sstevel@tonic-gate 	swp->psw_back->psw_forw = swp->psw_forw;
321*0Sstevel@tonic-gate 	swp->psw_forw->psw_back = swp->psw_back;
322*0Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
323*0Sstevel@tonic-gate 	return (0);
324*0Sstevel@tonic-gate }
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate /*ARGSUSED1*/
327*0Sstevel@tonic-gate static int
328*0Sstevel@tonic-gate mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0)
329*0Sstevel@tonic-gate {
330*0Sstevel@tonic-gate 	*p0 = (int)modl->psm_swp->psw_infop->p_owner;
331*0Sstevel@tonic-gate 	return (0);
332*0Sstevel@tonic-gate }
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate static char *
335*0Sstevel@tonic-gate psm_get_impl_module(int first)
336*0Sstevel@tonic-gate {
337*0Sstevel@tonic-gate 	static char **pnamep;
338*0Sstevel@tonic-gate 	static char *psm_impl_module_list[] = {
339*0Sstevel@tonic-gate 		"uppc",
340*0Sstevel@tonic-gate 		(char *)0
341*0Sstevel@tonic-gate 	};
342*0Sstevel@tonic-gate 	static void *mhdl = NULL;
343*0Sstevel@tonic-gate 	static char machname[MAXNAMELEN];
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 	if (first)
346*0Sstevel@tonic-gate 		pnamep = psm_impl_module_list;
347*0Sstevel@tonic-gate 
348*0Sstevel@tonic-gate 	if (*pnamep != (char *)0)
349*0Sstevel@tonic-gate 		return (*pnamep++);
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 	mhdl = get_next_mach(mhdl, machname);
352*0Sstevel@tonic-gate 	if (mhdl)
353*0Sstevel@tonic-gate 		return (machname);
354*0Sstevel@tonic-gate 	return ((char *)0);
355*0Sstevel@tonic-gate }
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate void
358*0Sstevel@tonic-gate psm_modload(void)
359*0Sstevel@tonic-gate {
360*0Sstevel@tonic-gate 	char *this;
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate 	mutex_init(&psmsw_lock, NULL, MUTEX_DEFAULT, NULL);
363*0Sstevel@tonic-gate 	open_mach_list();
364*0Sstevel@tonic-gate 
365*0Sstevel@tonic-gate 	for (this = psm_get_impl_module(1);
366*0Sstevel@tonic-gate 		this != (char *)NULL;
367*0Sstevel@tonic-gate 		this = psm_get_impl_module(0)) {
368*0Sstevel@tonic-gate 		if (modload("mach", this) == -1)
369*0Sstevel@tonic-gate 			cmn_err(CE_WARN, "!Cannot load psm %s", this);
370*0Sstevel@tonic-gate 	}
371*0Sstevel@tonic-gate 	close_mach_list();
372*0Sstevel@tonic-gate }
373*0Sstevel@tonic-gate 
374*0Sstevel@tonic-gate void
375*0Sstevel@tonic-gate psm_install(void)
376*0Sstevel@tonic-gate {
377*0Sstevel@tonic-gate 	struct psm_sw *swp, *cswp;
378*0Sstevel@tonic-gate 	struct psm_ops *opsp;
379*0Sstevel@tonic-gate 	char machstring[15];
380*0Sstevel@tonic-gate 	int err;
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate 	mutex_enter(&psmsw_lock);
383*0Sstevel@tonic-gate 	for (swp = psmsw->psw_forw; swp != psmsw; ) {
384*0Sstevel@tonic-gate 		opsp = swp->psw_infop->p_ops;
385*0Sstevel@tonic-gate 		if (opsp->psm_probe) {
386*0Sstevel@tonic-gate 			if ((*opsp->psm_probe)() == PSM_SUCCESS) {
387*0Sstevel@tonic-gate 				swp->psw_flag |= PSM_MOD_IDENTIFY;
388*0Sstevel@tonic-gate 				swp = swp->psw_forw;
389*0Sstevel@tonic-gate 				continue;
390*0Sstevel@tonic-gate 			}
391*0Sstevel@tonic-gate 		}
392*0Sstevel@tonic-gate 		/* remove the unsuccessful psm modules */
393*0Sstevel@tonic-gate 		cswp = swp;
394*0Sstevel@tonic-gate 		swp = swp->psw_forw;
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate 		mutex_exit(&psmsw_lock);
397*0Sstevel@tonic-gate 		(void) strcpy(&machstring[0], cswp->psw_infop->p_mach_idstring);
398*0Sstevel@tonic-gate 		err = mod_remove_by_name(cswp->psw_infop->p_mach_idstring);
399*0Sstevel@tonic-gate 		if (err)
400*0Sstevel@tonic-gate 			cmn_err(CE_WARN, "%s: mod_remove_by_name failed %d",
401*0Sstevel@tonic-gate 				&machstring[0], err);
402*0Sstevel@tonic-gate 		mutex_enter(&psmsw_lock);
403*0Sstevel@tonic-gate 	}
404*0Sstevel@tonic-gate 	mutex_exit(&psmsw_lock);
405*0Sstevel@tonic-gate 	(*psminitf)();
406*0Sstevel@tonic-gate }
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate /*
409*0Sstevel@tonic-gate  * Return 1 if kernel debugger is present, and 0 if not.
410*0Sstevel@tonic-gate  */
411*0Sstevel@tonic-gate int
412*0Sstevel@tonic-gate psm_debugger(void)
413*0Sstevel@tonic-gate {
414*0Sstevel@tonic-gate 	return ((boothowto & RB_DEBUG) != 0);
415*0Sstevel@tonic-gate }
416