15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 #define PSMI_1_7
26
27 #include <sys/vmem.h>
28 #include <vm/hat.h>
29 #include <sys/modctl.h>
30 #include <vm/seg_kmem.h>
31 #include <sys/psm.h>
32 #include <sys/psm_modctl.h>
33 #include <sys/smp_impldefs.h>
34 #include <sys/reboot.h>
35 #if defined(__xpv)
36 #include <sys/hypervisor.h>
37 #include <vm/kboot_mmu.h>
38 #include <vm/hat_pte.h>
39 #endif
40
41 /*
42 * External reference functions
43 */
44 extern void *get_next_mach(void *, char *);
45 extern void close_mach_list(void);
46 extern void open_mach_list(void);
47
48 /*
49 * from startup.c - kernel VA range allocator for device mappings
50 */
51 extern void *device_arena_alloc(size_t size, int vm_flag);
52 extern void device_arena_free(void * vaddr, size_t size);
53
54 void psm_modloadonly(void);
55 void psm_install(void);
56
57 /*
58 * Local Function Prototypes
59 */
196 }
197
198 processorid_t
199 psm_get_cpu_id(void)
200 {
201 return (CPU->cpu_id);
202 }
203
204 caddr_t
205 psm_map_phys_new(paddr_t addr, size_t len, int prot)
206 {
207 uint_t pgoffset;
208 paddr_t base;
209 pgcnt_t npages;
210 caddr_t cvaddr;
211
212 if (len == 0)
213 return (0);
214
215 pgoffset = addr & MMU_PAGEOFFSET;
216 #ifdef __xpv
217 /*
218 * If we're dom0, we're starting from a MA. translate that to a PA
219 * XXPV - what about driver domains???
220 */
221 if (DOMAIN_IS_INITDOMAIN(xen_info)) {
222 base = pfn_to_pa(xen_assign_pfn(mmu_btop(addr))) |
223 (addr & MMU_PAGEOFFSET);
224 } else {
225 base = addr;
226 }
227 #else
228 base = addr;
229 #endif
230 npages = mmu_btopr(len + pgoffset);
231 cvaddr = device_arena_alloc(ptob(npages), VM_NOSLEEP);
232 if (cvaddr == NULL)
233 return (0);
234 hat_devload(kas.a_hat, cvaddr, mmu_ptob(npages), mmu_btop(base),
235 prot, HAT_LOAD_LOCK);
236 return (cvaddr + pgoffset);
237 }
238
239 void
240 psm_unmap_phys(caddr_t addr, size_t len)
241 {
242 uint_t pgoffset;
243 caddr_t base;
244 pgcnt_t npages;
245
246 if (len == 0)
247 return;
248
249 pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
328 }
329 if (!(swp->psw_flag & PSM_MOD_INSTALL)) {
330 mutex_exit(&psmsw_lock);
331 return (0);
332 }
333
334 swp->psw_back->psw_forw = swp->psw_forw;
335 swp->psw_forw->psw_back = swp->psw_back;
336 mutex_exit(&psmsw_lock);
337 return (0);
338 }
339
340 /*ARGSUSED1*/
341 static int
342 mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0)
343 {
344 *p0 = (int)modl->psm_swp->psw_infop->p_owner;
345 return (0);
346 }
347
348 #if defined(__xpv)
349 #define DEFAULT_PSM_MODULE "xpv_uppc"
350 #else
351 #define DEFAULT_PSM_MODULE "uppc"
352 #endif
353
354 static char *
355 psm_get_impl_module(int first)
356 {
357 static char **pnamep;
358 static char *psm_impl_module_list[] = {
359 DEFAULT_PSM_MODULE,
360 (char *)0
361 };
362 static void *mhdl = NULL;
363 static char machname[MAXNAMELEN];
364
365 if (first)
366 pnamep = psm_impl_module_list;
367
368 if (*pnamep != (char *)0)
369 return (*pnamep++);
370
371 mhdl = get_next_mach(mhdl, machname);
372 if (mhdl)
373 return (machname);
374 return ((char *)0);
375 }
376
377 void
378 psm_modload(void)
379 {
380 char *this;
381
382 mutex_init(&psmsw_lock, NULL, MUTEX_DEFAULT, NULL);
383 open_mach_list();
384
385 for (this = psm_get_impl_module(1); this != (char *)NULL;
386 this = psm_get_impl_module(0)) {
387 if (modload("mach", this) == -1)
388 cmn_err(CE_CONT, "!Skipping psm: %s\n", this);
389 }
390 close_mach_list();
391 }
392
393 #if defined(__xpv)
394 #define NOTSUP_MSG "This version of Solaris xVM does not support this hardware"
395 #else
396 #define NOTSUP_MSG "This version of Solaris does not support this hardware"
397 #endif /* __xpv */
398
399 void
400 psm_install(void)
401 {
402 struct psm_sw *swp, *cswp;
403 struct psm_ops *opsp;
404 char machstring[15];
405 int err, psmcnt = 0;
406
407 mutex_enter(&psmsw_lock);
408 for (swp = psmsw->psw_forw; swp != psmsw; ) {
409 opsp = swp->psw_infop->p_ops;
410 if (opsp->psm_probe) {
411 if ((*opsp->psm_probe)() == PSM_SUCCESS) {
412 psmcnt++;
413 swp->psw_flag |= PSM_MOD_IDENTIFY;
414 swp = swp->psw_forw;
415 continue;
416 }
417 }
418 /* remove the unsuccessful psm modules */
419 cswp = swp;
420 swp = swp->psw_forw;
421
422 mutex_exit(&psmsw_lock);
423 (void) strcpy(&machstring[0], cswp->psw_infop->p_mach_idstring);
424 err = mod_remove_by_name(cswp->psw_infop->p_mach_idstring);
425 if (err)
426 cmn_err(CE_WARN, "!%s: mod_remove_by_name failed %d",
427 &machstring[0], err);
428 mutex_enter(&psmsw_lock);
429 }
430 mutex_exit(&psmsw_lock);
431 if (psmcnt == 0)
432 halt(NOTSUP_MSG);
433 (*psminitf)();
434 }
435
436 /*
437 * Return 1 if kernel debugger is present, and 0 if not.
438 */
439 int
440 psm_debugger(void)
441 {
442 return ((boothowto & RB_DEBUG) != 0);
443 }
|
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 #define PSMI_1_7
26
27 #include <sys/vmem.h>
28 #include <vm/hat.h>
29 #include <sys/modctl.h>
30 #include <vm/seg_kmem.h>
31 #include <sys/psm.h>
32 #include <sys/psm_modctl.h>
33 #include <sys/smp_impldefs.h>
34 #include <sys/reboot.h>
35
36 /*
37 * External reference functions
38 */
39 extern void *get_next_mach(void *, char *);
40 extern void close_mach_list(void);
41 extern void open_mach_list(void);
42
43 /*
44 * from startup.c - kernel VA range allocator for device mappings
45 */
46 extern void *device_arena_alloc(size_t size, int vm_flag);
47 extern void device_arena_free(void * vaddr, size_t size);
48
49 void psm_modloadonly(void);
50 void psm_install(void);
51
52 /*
53 * Local Function Prototypes
54 */
191 }
192
193 processorid_t
194 psm_get_cpu_id(void)
195 {
196 return (CPU->cpu_id);
197 }
198
199 caddr_t
200 psm_map_phys_new(paddr_t addr, size_t len, int prot)
201 {
202 uint_t pgoffset;
203 paddr_t base;
204 pgcnt_t npages;
205 caddr_t cvaddr;
206
207 if (len == 0)
208 return (0);
209
210 pgoffset = addr & MMU_PAGEOFFSET;
211 base = addr;
212 npages = mmu_btopr(len + pgoffset);
213 cvaddr = device_arena_alloc(ptob(npages), VM_NOSLEEP);
214 if (cvaddr == NULL)
215 return (0);
216 hat_devload(kas.a_hat, cvaddr, mmu_ptob(npages), mmu_btop(base),
217 prot, HAT_LOAD_LOCK);
218 return (cvaddr + pgoffset);
219 }
220
221 void
222 psm_unmap_phys(caddr_t addr, size_t len)
223 {
224 uint_t pgoffset;
225 caddr_t base;
226 pgcnt_t npages;
227
228 if (len == 0)
229 return;
230
231 pgoffset = (uintptr_t)addr & MMU_PAGEOFFSET;
310 }
311 if (!(swp->psw_flag & PSM_MOD_INSTALL)) {
312 mutex_exit(&psmsw_lock);
313 return (0);
314 }
315
316 swp->psw_back->psw_forw = swp->psw_forw;
317 swp->psw_forw->psw_back = swp->psw_back;
318 mutex_exit(&psmsw_lock);
319 return (0);
320 }
321
322 /*ARGSUSED1*/
323 static int
324 mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0)
325 {
326 *p0 = (int)modl->psm_swp->psw_infop->p_owner;
327 return (0);
328 }
329
330 #define DEFAULT_PSM_MODULE "uppc"
331
332 static char *
333 psm_get_impl_module(int first)
334 {
335 static char **pnamep;
336 static char *psm_impl_module_list[] = {
337 DEFAULT_PSM_MODULE,
338 (char *)0
339 };
340 static void *mhdl = NULL;
341 static char machname[MAXNAMELEN];
342
343 if (first)
344 pnamep = psm_impl_module_list;
345
346 if (*pnamep != (char *)0)
347 return (*pnamep++);
348
349 mhdl = get_next_mach(mhdl, machname);
350 if (mhdl)
351 return (machname);
352 return ((char *)0);
353 }
354
355 void
356 psm_modload(void)
357 {
358 char *this;
359
360 mutex_init(&psmsw_lock, NULL, MUTEX_DEFAULT, NULL);
361 open_mach_list();
362
363 for (this = psm_get_impl_module(1); this != (char *)NULL;
364 this = psm_get_impl_module(0)) {
365 if (modload("mach", this) == -1)
366 cmn_err(CE_CONT, "!Skipping psm: %s\n", this);
367 }
368 close_mach_list();
369 }
370
371 void
372 psm_install(void)
373 {
374 struct psm_sw *swp, *cswp;
375 struct psm_ops *opsp;
376 char machstring[15];
377 int err, psmcnt = 0;
378
379 mutex_enter(&psmsw_lock);
380 for (swp = psmsw->psw_forw; swp != psmsw; ) {
381 opsp = swp->psw_infop->p_ops;
382 if (opsp->psm_probe) {
383 if ((*opsp->psm_probe)() == PSM_SUCCESS) {
384 psmcnt++;
385 swp->psw_flag |= PSM_MOD_IDENTIFY;
386 swp = swp->psw_forw;
387 continue;
388 }
389 }
390 /* remove the unsuccessful psm modules */
391 cswp = swp;
392 swp = swp->psw_forw;
393
394 mutex_exit(&psmsw_lock);
395 (void) strcpy(&machstring[0], cswp->psw_infop->p_mach_idstring);
396 err = mod_remove_by_name(cswp->psw_infop->p_mach_idstring);
397 if (err)
398 cmn_err(CE_WARN, "!%s: mod_remove_by_name failed %d",
399 &machstring[0], err);
400 mutex_enter(&psmsw_lock);
401 }
402 mutex_exit(&psmsw_lock);
403 if (psmcnt == 0)
404 halt("This hardware is not supported by current OS version");
405 (*psminitf)();
406 }
407
408 /*
409 * Return 1 if kernel debugger is present, and 0 if not.
410 */
411 int
412 psm_debugger(void)
413 {
414 return ((boothowto & RB_DEBUG) != 0);
415 }
|