1 /* $NetBSD: machdep.c,v 1.344 2026/04/08 04:06:41 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1992, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * This software was developed by the Computer Systems Engineering group 38 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 39 * contributed to Berkeley. 40 * 41 * All advertising materials mentioning features or use of this software 42 * must display the following acknowledgement: 43 * This product includes software developed by the University of 44 * California, Lawrence Berkeley Laboratory. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)machdep.c 8.6 (Berkeley) 1/14/94 71 */ 72 73 #include <sys/cdefs.h> 74 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.344 2026/04/08 04:06:41 thorpej Exp $"); 75 76 #include "opt_compat_netbsd.h" 77 #include "opt_compat_sunos.h" 78 #include "opt_sparc_arch.h" 79 #include "opt_modular.h" 80 #include "opt_multiprocessor.h" 81 82 #include <sys/param.h> 83 #include <sys/signal.h> 84 #include <sys/signalvar.h> 85 #include <sys/proc.h> 86 #include <sys/vmem.h> 87 #include <sys/cpu.h> 88 #include <sys/buf.h> 89 #include <sys/device.h> 90 #include <sys/reboot.h> 91 #include <sys/systm.h> 92 #include <sys/kernel.h> 93 #include <sys/conf.h> 94 #include <sys/file.h> 95 #include <sys/kmem.h> 96 #include <sys/mbuf.h> 97 #include <sys/mount.h> 98 #include <sys/msgbuf.h> 99 #include <sys/syscallargs.h> 100 #include <sys/exec.h> 101 #include <sys/exec_aout.h> 102 #include <sys/ucontext.h> 103 #include <sys/module.h> 104 #include <sys/mutex.h> 105 #include <sys/ras.h> 106 107 #include <dev/mm.h> 108 109 #include <uvm/uvm.h> /* we use uvm.kernel_object */ 110 111 #include <sys/sysctl.h> 112 113 #ifdef COMPAT_13 114 #include <compat/sys/signal.h> 115 #include <compat/sys/signalvar.h> 116 #endif 117 118 #define _SPARC_BUS_DMA_PRIVATE 119 #include <machine/autoconf.h> 120 #include <sys/bus.h> 121 #include <machine/frame.h> 122 #include <machine/cpu.h> 123 #include <machine/pcb.h> 124 #include <machine/pmap.h> 125 #include <machine/oldmon.h> 126 #include <machine/bsd_openprom.h> 127 #include <machine/bootinfo.h> 128 #include <machine/eeprom.h> 129 130 #include <sparc/sparc/asm.h> 131 #include <sparc/sparc/cache.h> 132 #include <sparc/sparc/vaddrs.h> 133 #include <sparc/sparc/cpuvar.h> 134 135 #include "fb.h" 136 #include "power.h" 137 138 #if NPOWER > 0 139 #include <sparc/dev/power.h> 140 #endif 141 142 kmutex_t fpu_mtx; 143 144 /* 145 * dvmamap24 is used to manage DVMA memory for devices that have the upper 146 * eight address bits wired to all-ones (e.g. `le' and `ie') 147 */ 148 vmem_t *dvmamap24; 149 150 void dumpsys(void); 151 void stackdump(void); 152 153 /* 154 * Machine-dependent startup code 155 */ 156 void 157 cpu_startup(void) 158 { 159 #ifdef DEBUG 160 extern int pmapdebug; 161 int opmapdebug = pmapdebug; 162 #endif 163 struct pcb *pcb; 164 vsize_t size; 165 paddr_t pa; 166 char pbuf[9]; 167 168 #ifdef DEBUG 169 pmapdebug = 0; 170 #endif 171 172 /* XXX */ 173 pcb = lwp_getpcb(&lwp0); 174 if (pcb && pcb->pcb_psr == 0) 175 pcb->pcb_psr = getpsr(); 176 177 /* 178 * Re-map the message buffer from its temporary address 179 * at KERNBASE to MSGBUF_VA. 180 */ 181 #if !defined(MSGBUFSIZE) || MSGBUFSIZE <= 8192 182 /* 183 * We use the free page(s) in front of the kernel load address. 184 */ 185 size = 8192; 186 187 /* Get physical address of the message buffer */ 188 pmap_extract(pmap_kernel(), (vaddr_t)KERNBASE, &pa); 189 190 /* Invalidate the current mapping at KERNBASE. */ 191 pmap_kremove((vaddr_t)KERNBASE, size); 192 pmap_update(pmap_kernel()); 193 194 /* Enter the new mapping */ 195 pmap_map(MSGBUF_VA, pa, pa + size, VM_PROT_READ|VM_PROT_WRITE); 196 197 /* 198 * Re-initialize the message buffer. 199 */ 200 initmsgbuf((void *)MSGBUF_VA, size); 201 #else /* MSGBUFSIZE */ 202 { 203 struct pglist mlist; 204 struct vm_page *m; 205 vaddr_t va0, va; 206 207 /* 208 * We use the free page(s) in front of the kernel load address, 209 * and then allocate some more. 210 */ 211 size = round_page(MSGBUFSIZE); 212 213 /* Get physical address of first 8192 chunk of the message buffer */ 214 pmap_extract(pmap_kernel(), (vaddr_t)KERNBASE, &pa); 215 216 /* Allocate additional physical pages */ 217 if (uvm_pglistalloc(size - 8192, 218 vm_first_phys, vm_first_phys+vm_num_phys, 219 0, 0, &mlist, 1, 0) != 0) 220 panic("cpu_start: no memory for message buffer"); 221 222 /* Invalidate the current mapping at KERNBASE. */ 223 pmap_kremove((vaddr_t)KERNBASE, 8192); 224 pmap_update(pmap_kernel()); 225 226 /* Allocate virtual memory space */ 227 va0 = va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY); 228 if (va == 0) 229 panic("cpu_start: no virtual memory for message buffer"); 230 231 /* Map first 8192 */ 232 while (va < va0 + 8192) { 233 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0); 234 pa += PAGE_SIZE; 235 va += PAGE_SIZE; 236 } 237 pmap_update(pmap_kernel()); 238 239 /* Map the rest of the pages */ 240 TAILQ_FOREACH(m, &mlist ,pageq.queue) { 241 if (va >= va0 + size) 242 panic("cpu_start: memory buffer size botch"); 243 pa = VM_PAGE_TO_PHYS(m); 244 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0); 245 va += PAGE_SIZE; 246 } 247 pmap_update(pmap_kernel()); 248 249 /* 250 * Re-initialize the message buffer. 251 */ 252 initmsgbuf((void *)va0, size); 253 } 254 #endif /* MSGBUFSIZE */ 255 256 /* 257 * Good {morning,afternoon,evening,night}. 258 */ 259 printf("%s%s", copyright, version); 260 /*identifycpu();*/ 261 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 262 printf("total memory = %s\n", pbuf); 263 264 /* 265 * Tune buffer cache variables based on the capabilities of the MMU 266 * to cut down on VM space allocated for the buffer caches that 267 * would lead to MMU resource shortage. 268 */ 269 if (CPU_ISSUN4 || CPU_ISSUN4C) { 270 /* Clip UBC windows */ 271 if (cpuinfo.mmu_nsegment <= 128) { 272 /* 273 * ubc_nwins and ubc_winshift control the amount 274 * of VM used by the UBC. Normally, this VM is 275 * not wired in the kernel map, hence non-locked 276 * `PMEGs' (see pmap.c) are used for this space. 277 * We still limit possible fragmentation to prevent 278 * the occasional wired UBC mappings from tying up 279 * too many PMEGs. 280 * 281 * Set the upper limit to 9 segments (default 282 * winshift = 13). 283 */ 284 ubc_nwins = 512; 285 286 /* 287 * buf_setvalimit() allocates a submap for buffer 288 * allocation. We use it to limit the number of locked 289 * `PMEGs' (see pmap.c) dedicated to the buffer cache. 290 * 291 * Set the upper limit to 12 segments (3MB), which 292 * corresponds approximately to the size of the 293 * traditional 5% rule (assuming a maximum 64MB of 294 * memory in small sun4c machines). 295 */ 296 buf_setvalimit(12 * 256*1024); 297 } 298 299 /* Clip max data & stack to avoid running into the MMU hole */ 300 #if MAXDSIZ > 256*1024*1024 301 maxdmap = 256*1024*1024; 302 #endif 303 #if MAXSSIZ > 256*1024*1024 304 maxsmap = 256*1024*1024; 305 #endif 306 } 307 308 if (CPU_ISSUN4 || CPU_ISSUN4C) { 309 /* 310 * Allocate DMA map for 24-bit devices (le, ie) 311 * [dvma_base - dvma_end] is for VME devices.. 312 */ 313 dvmamap24 = vmem_create("dvmamap24", 314 D24_DVMA_BASE, 315 D24_DVMA_END - D24_DVMA_BASE, 316 PAGE_SIZE, /* quantum */ 317 NULL, /* importfn */ 318 NULL, /* releasefn */ 319 NULL, /* source */ 320 0, /* qcache_max */ 321 VM_SLEEP, 322 IPL_VM); 323 if (dvmamap24 == NULL) 324 panic("unable to allocate DVMA map"); 325 } 326 327 #ifdef DEBUG 328 pmapdebug = opmapdebug; 329 #endif 330 format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false))); 331 printf("avail memory = %s\n", pbuf); 332 333 pmap_redzone(); 334 335 mutex_init(&fpu_mtx, MUTEX_DEFAULT, IPL_SCHED); 336 } 337 338 /* 339 * Set up registers on exec. 340 * 341 * XXX this entire mess must be fixed 342 */ 343 /* ARGSUSED */ 344 void 345 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 346 { 347 struct trapframe *tf = l->l_md.md_tf; 348 struct fpstate *fs; 349 int psr; 350 351 /* Don't allow unaligned data references by default */ 352 l->l_proc->p_md.md_flags &= ~MDP_FIXALIGN; 353 354 /* 355 * Set the registers to 0 except for: 356 * %o6: stack pointer, built in exec()) 357 * %psr: (retain CWP and PSR_S bits) 358 * %g1: p->p_psstrp (used by crt0) 359 * %pc,%npc: entry point of program 360 */ 361 psr = tf->tf_psr & (PSR_S | PSR_CWP); 362 if ((fs = l->l_md.md_fpstate) != NULL) { 363 struct cpu_info *cpi; 364 int s; 365 /* 366 * We hold an FPU state. If we own *some* FPU chip state 367 * we must get rid of it, and the only way to do that is 368 * to save it. In any case, get rid of our FPU state. 369 */ 370 FPU_LOCK(s); 371 if ((cpi = l->l_md.md_fpu) != NULL) { 372 if (cpi->fplwp != l) 373 panic("FPU(%d): fplwp %p", 374 cpi->ci_cpuid, cpi->fplwp); 375 if (l == cpuinfo.fplwp) 376 savefpstate(fs); 377 #if defined(MULTIPROCESSOR) 378 else 379 XCALL1(ipi_savefpstate, fs, 1 << cpi->ci_cpuid); 380 #endif 381 cpi->fplwp = NULL; 382 } 383 l->l_md.md_fpu = NULL; 384 FPU_UNLOCK(s); 385 kmem_free(fs, sizeof(struct fpstate)); 386 l->l_md.md_fpstate = NULL; 387 } 388 memset((void *)tf, 0, sizeof *tf); 389 tf->tf_psr = psr; 390 tf->tf_global[1] = l->l_proc->p_psstrp; 391 tf->tf_pc = pack->ep_entry & ~3; 392 tf->tf_npc = tf->tf_pc + 4; 393 stack -= sizeof(struct rwindow); 394 tf->tf_out[6] = stack; 395 } 396 397 #ifdef DEBUG 398 int sigdebug = 0; 399 int sigpid = 0; 400 #define SDB_FOLLOW 0x01 401 #define SDB_KSTACK 0x02 402 #define SDB_FPSTATE 0x04 403 #endif 404 405 /* 406 * machine dependent system variables. 407 */ 408 static int 409 sysctl_machdep_boot(SYSCTLFN_ARGS) 410 { 411 struct sysctlnode node = *rnode; 412 struct btinfo_kernelfile *bi_file; 413 const char *cp; 414 415 416 switch (node.sysctl_num) { 417 case CPU_BOOTED_KERNEL: 418 if ((bi_file = lookup_bootinfo(BTINFO_KERNELFILE)) != NULL) 419 cp = bi_file->name; 420 else 421 cp = prom_getbootfile(); 422 if (cp != NULL && cp[0] == '\0') 423 cp = "netbsd"; 424 break; 425 case CPU_BOOTED_DEVICE: 426 cp = prom_getbootpath(); 427 break; 428 case CPU_BOOT_ARGS: 429 cp = prom_getbootargs(); 430 break; 431 default: 432 return (EINVAL); 433 } 434 435 if (cp == NULL || cp[0] == '\0') 436 return (ENOENT); 437 438 node.sysctl_data = __UNCONST(cp); 439 node.sysctl_size = strlen(cp) + 1; 440 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 441 } 442 443 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 444 { 445 446 sysctl_createv(clog, 0, NULL, NULL, 447 CTLFLAG_PERMANENT, 448 CTLTYPE_NODE, "machdep", NULL, 449 NULL, 0, NULL, 0, 450 CTL_MACHDEP, CTL_EOL); 451 452 sysctl_createv(clog, 0, NULL, NULL, 453 CTLFLAG_PERMANENT, 454 CTLTYPE_STRING, "booted_kernel", NULL, 455 sysctl_machdep_boot, 0, NULL, 0, 456 CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL); 457 sysctl_createv(clog, 0, NULL, NULL, 458 CTLFLAG_PERMANENT, 459 CTLTYPE_STRING, "booted_device", NULL, 460 sysctl_machdep_boot, 0, NULL, 0, 461 CTL_MACHDEP, CPU_BOOTED_DEVICE, CTL_EOL); 462 sysctl_createv(clog, 0, NULL, NULL, 463 CTLFLAG_PERMANENT, 464 CTLTYPE_STRING, "boot_args", NULL, 465 sysctl_machdep_boot, 0, NULL, 0, 466 CTL_MACHDEP, CPU_BOOT_ARGS, CTL_EOL); 467 sysctl_createv(clog, 0, NULL, NULL, 468 CTLFLAG_PERMANENT, 469 CTLTYPE_INT, "cpu_arch", NULL, 470 NULL, 0, &cpu_arch, 0, 471 CTL_MACHDEP, CPU_ARCH, CTL_EOL); 472 } 473 474 /* 475 * Send an interrupt to process. 476 */ 477 struct sigframe { 478 siginfo_t sf_si; 479 ucontext_t sf_uc; 480 }; 481 482 void 483 sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) 484 { 485 struct lwp *l = curlwp; 486 struct proc *p = l->l_proc; 487 struct sigacts *ps = p->p_sigacts; 488 struct trapframe *tf; 489 ucontext_t uc; 490 struct sigframe *fp; 491 u_int onstack, oldsp, newsp; 492 u_int catcher; 493 int sig, error; 494 size_t ucsz; 495 496 sig = ksi->ksi_signo; 497 catcher = (u_int)SIGACTION(p, sig).sa_handler; 498 499 tf = l->l_md.md_tf; 500 oldsp = tf->tf_out[6]; 501 502 /* 503 * Compute new user stack addresses, subtract off 504 * one signal frame, and align. 505 */ 506 onstack = 507 (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 508 (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; 509 510 if (onstack) 511 fp = (struct sigframe *) 512 ((char *)l->l_sigstk.ss_sp + 513 l->l_sigstk.ss_size); 514 else 515 fp = (struct sigframe *)oldsp; 516 517 fp = (struct sigframe *)((int)(fp - 1) & ~STACK_ALIGNBYTES); 518 519 #ifdef DEBUG 520 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 521 printf("sendsig: %s[%d] sig %d newusp %p si %p uc %p\n", 522 p->p_comm, p->p_pid, sig, fp, &fp->sf_si, &fp->sf_uc); 523 #endif 524 525 /* 526 * Build the signal context to be used by sigreturn. 527 */ 528 uc.uc_flags = _UC_SIGMASK | 529 ((l->l_sigstk.ss_flags & SS_ONSTACK) 530 ? _UC_SETSTACK : _UC_CLRSTACK); 531 uc.uc_sigmask = *mask; 532 uc.uc_link = l->l_ctxlink; 533 memset(&uc.uc_stack, 0, sizeof(uc.uc_stack)); 534 535 /* 536 * Now copy the stack contents out to user space. 537 * We need to make sure that when we start the signal handler, 538 * its %i6 (%fp), which is loaded from the newly allocated stack area, 539 * joins seamlessly with the frame it was in when the signal occurred, 540 * so that the debugger and _longjmp code can back up through it. 541 * Since we're calling the handler directly, allocate a full size 542 * C stack frame. 543 */ 544 sendsig_reset(l, sig); 545 mutex_exit(p->p_lock); 546 newsp = (int)fp - sizeof(struct frame); 547 cpu_getmcontext(l, &uc.uc_mcontext, &uc.uc_flags); 548 ucsz = (int)&uc.__uc_pad - (int)&uc; 549 error = (copyout(&ksi->ksi_info, &fp->sf_si, sizeof ksi->ksi_info) || 550 copyout(&uc, &fp->sf_uc, ucsz) || 551 ustore_int((u_int *)&((struct rwindow *)newsp)->rw_in[6], oldsp)); 552 mutex_enter(p->p_lock); 553 554 if (error) { 555 /* 556 * Process has trashed its stack; give it an illegal 557 * instruction to halt it in its tracks. 558 */ 559 #ifdef DEBUG 560 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 561 printf("sendsig: window save or copyout error\n"); 562 #endif 563 sigexit(l, SIGILL); 564 /* NOTREACHED */ 565 } 566 567 switch (ps->sa_sigdesc[sig].sd_vers) { 568 default: 569 /* Unsupported trampoline version; kill the process. */ 570 sigexit(l, SIGILL); 571 case __SIGTRAMP_SIGINFO_VERSION: 572 /* 573 * Arrange to continue execution at the user's handler. 574 * It needs a new stack pointer, a return address and 575 * three arguments: (signo, siginfo *, ucontext *). 576 */ 577 578 tf->tf_pc = catcher; 579 tf->tf_npc = catcher + 4; 580 tf->tf_out[0] = sig; 581 tf->tf_out[1] = (int)&fp->sf_si; 582 tf->tf_out[2] = (int)&fp->sf_uc; 583 tf->tf_out[6] = newsp; 584 tf->tf_out[7] = (int)ps->sa_sigdesc[sig].sd_tramp - 8; 585 break; 586 } 587 588 /* Remember that we're now on the signal stack. */ 589 if (onstack) 590 l->l_sigstk.ss_flags |= SS_ONSTACK; 591 592 #ifdef DEBUG 593 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 594 printf("sendsig: about to return to catcher\n"); 595 #endif 596 } 597 598 void 599 cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags) 600 { 601 struct trapframe *tf = (struct trapframe *)l->l_md.md_tf; 602 __greg_t *r = mcp->__gregs; 603 __greg_t ras_pc; 604 #ifdef FPU_CONTEXT 605 __fpregset_t *f = &mcp->__fpregs; 606 struct fpstate *fps = l->l_md.md_fpstate; 607 #endif 608 609 /* 610 * Put the stack in a consistent state before we whack away 611 * at it. Note that write_user_windows may just dump the 612 * registers into the pcb; we need them in the process's memory. 613 */ 614 write_user_windows(); 615 if (rwindow_save(l)) { 616 mutex_enter(l->l_proc->p_lock); 617 sigexit(l, SIGILL); 618 } 619 620 /* 621 * Get the general purpose registers 622 */ 623 r[_REG_PSR] = tf->tf_psr; 624 r[_REG_PC] = tf->tf_pc; 625 r[_REG_nPC] = tf->tf_npc; 626 r[_REG_Y] = tf->tf_y; 627 r[_REG_G1] = tf->tf_global[1]; 628 r[_REG_G2] = tf->tf_global[2]; 629 r[_REG_G3] = tf->tf_global[3]; 630 r[_REG_G4] = tf->tf_global[4]; 631 r[_REG_G5] = tf->tf_global[5]; 632 r[_REG_G6] = tf->tf_global[6]; 633 r[_REG_G7] = tf->tf_global[7]; 634 r[_REG_O0] = tf->tf_out[0]; 635 r[_REG_O1] = tf->tf_out[1]; 636 r[_REG_O2] = tf->tf_out[2]; 637 r[_REG_O3] = tf->tf_out[3]; 638 r[_REG_O4] = tf->tf_out[4]; 639 r[_REG_O5] = tf->tf_out[5]; 640 r[_REG_O6] = tf->tf_out[6]; 641 r[_REG_O7] = tf->tf_out[7]; 642 643 if ((ras_pc = (__greg_t)ras_lookup(l->l_proc, 644 (void *) r[_REG_PC])) != -1) { 645 r[_REG_PC] = ras_pc; 646 r[_REG_nPC] = ras_pc + 4; 647 } 648 649 *flags |= (_UC_CPU|_UC_TLSBASE); 650 651 #ifdef FPU_CONTEXT 652 /* 653 * Get the floating point registers 654 */ 655 memcpy(f->__fpu_regs, fps->fs_regs, sizeof(fps->fs_regs)); 656 f->__fp_nqsize = sizeof(struct fp_qentry); 657 f->__fp_nqel = fps->fs_qsize; 658 f->__fp_fsr = fps->fs_fsr; 659 if (f->__fp_q != NULL) { 660 size_t sz = f->__fp_nqel * f->__fp_nqsize; 661 if (sz > sizeof(fps->fs_queue)) { 662 #ifdef DIAGNOSTIC 663 printf("getcontext: fp_queue too large\n"); 664 #endif 665 return; 666 } 667 if (copyout(fps->fs_queue, f->__fp_q, sz) != 0) { 668 #ifdef DIAGNOSTIC 669 printf("getcontext: copy of fp_queue failed %d\n", 670 error); 671 #endif 672 return; 673 } 674 } 675 f->fp_busy = 0; /* XXX: How do we determine that? */ 676 *flags |= _UC_FPU; 677 #endif 678 679 return; 680 } 681 682 int 683 cpu_mcontext_validate(struct lwp *l, const mcontext_t *mc) 684 { 685 const __greg_t *gr = mc->__gregs; 686 687 /* 688 * Only the icc bits in the psr are used, so it need not be 689 * verified. pc and npc must be multiples of 4. This is all 690 * that is required; if it holds, just do it. 691 */ 692 if (((gr[_REG_PC] | gr[_REG_nPC]) & 3) != 0 || 693 gr[_REG_PC] == 0 || gr[_REG_nPC] == 0) 694 return EINVAL; 695 696 return 0; 697 } 698 699 /* 700 * Set to mcontext specified. 701 * Return to previous pc and psl as specified by 702 * context left by sendsig. Check carefully to 703 * make sure that the user has not modified the 704 * psl to gain improper privileges or to cause 705 * a machine fault. 706 * This is almost like sigreturn() and it shows. 707 */ 708 int 709 cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags) 710 { 711 struct trapframe *tf; 712 const __greg_t *r = mcp->__gregs; 713 struct proc *p = l->l_proc; 714 int error; 715 #ifdef FPU_CONTEXT 716 __fpregset_t *f = &mcp->__fpregs; 717 struct fpstate *fps = l->l_md.md_fpstate; 718 #endif 719 720 write_user_windows(); 721 if (rwindow_save(l)) { 722 mutex_enter(p->p_lock); 723 sigexit(l, SIGILL); 724 } 725 726 #ifdef DEBUG 727 if (sigdebug & SDB_FOLLOW) 728 printf("__setmcontext: %s[%d], __mcontext %p\n", 729 l->l_proc->p_comm, l->l_proc->p_pid, mcp); 730 #endif 731 732 if (flags & _UC_CPU) { 733 /* Validate */ 734 error = cpu_mcontext_validate(l, mcp); 735 if (error) 736 return error; 737 738 /* Restore register context. */ 739 tf = (struct trapframe *)l->l_md.md_tf; 740 741 /* take only psr ICC field */ 742 tf->tf_psr = (tf->tf_psr & ~PSR_ICC) | 743 (r[_REG_PSR] & PSR_ICC); 744 tf->tf_pc = r[_REG_PC]; 745 tf->tf_npc = r[_REG_nPC]; 746 tf->tf_y = r[_REG_Y]; 747 748 /* Restore everything */ 749 tf->tf_global[1] = r[_REG_G1]; 750 tf->tf_global[2] = r[_REG_G2]; 751 tf->tf_global[3] = r[_REG_G3]; 752 tf->tf_global[4] = r[_REG_G4]; 753 tf->tf_global[5] = r[_REG_G5]; 754 tf->tf_global[6] = r[_REG_G6]; 755 /* done in lwp_setprivate */ 756 /* tf->tf_global[7] = r[_REG_G7]; */ 757 758 tf->tf_out[0] = r[_REG_O0]; 759 tf->tf_out[1] = r[_REG_O1]; 760 tf->tf_out[2] = r[_REG_O2]; 761 tf->tf_out[3] = r[_REG_O3]; 762 tf->tf_out[4] = r[_REG_O4]; 763 tf->tf_out[5] = r[_REG_O5]; 764 tf->tf_out[6] = r[_REG_O6]; 765 tf->tf_out[7] = r[_REG_O7]; 766 767 if (flags & _UC_TLSBASE) 768 lwp_setprivate(l, (void *)(uintptr_t)r[_REG_G7]); 769 } 770 771 #ifdef FPU_CONTEXT 772 if (flags & _UC_FPU) { 773 /* 774 * Set the floating point registers 775 */ 776 int error; 777 size_t sz = f->__fp_nqel * f->__fp_nqsize; 778 if (sz > sizeof(fps->fs_queue)) { 779 #ifdef DIAGNOSTIC 780 printf("setmcontext: fp_queue too large\n"); 781 #endif 782 return (EINVAL); 783 } 784 memcpy(fps->fs_regs, f->__fpu_regs, sizeof(fps->fs_regs)); 785 fps->fs_qsize = f->__fp_nqel; 786 fps->fs_fsr = f->__fp_fsr; 787 if (f->__fp_q != NULL) { 788 if ((error = copyin(f->__fp_q, fps->fs_queue, sz)) != 0) { 789 #ifdef DIAGNOSTIC 790 printf("setmcontext: fp_queue copy failed\n"); 791 #endif 792 return (error); 793 } 794 } 795 } 796 #endif 797 798 mutex_enter(p->p_lock); 799 if (flags & _UC_SETSTACK) 800 l->l_sigstk.ss_flags |= SS_ONSTACK; 801 if (flags & _UC_CLRSTACK) 802 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 803 mutex_exit(p->p_lock); 804 805 return (0); 806 } 807 808 int waittime = -1; 809 810 void 811 cpu_reboot(int howto, char *user_boot_string) 812 { 813 int i; 814 char opts[4]; 815 static char str[128]; 816 817 /* If system is cold, just halt. */ 818 if (cold) { 819 howto |= RB_HALT; 820 goto haltsys; 821 } 822 823 #if NFB > 0 824 fb_unblank(); 825 #endif 826 boothowto = howto; 827 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 828 829 /* XXX protect against curlwp->p_stats.foo refs in sync() */ 830 if (curlwp == NULL) 831 curlwp = &lwp0; 832 waittime = 0; 833 vfs_shutdown(); 834 } 835 836 /* Disable interrupts. But still allow IPI on MP systems */ 837 if (sparc_ncpus > 1) 838 (void)splsched(); 839 else 840 (void)splhigh(); 841 842 #if defined(MULTIPROCESSOR) 843 /* Direct system interrupts to this CPU, since dump uses polled I/O */ 844 if (CPU_ISSUN4M) 845 *((u_int *)ICR_ITR) = cpuinfo.mid - 8; 846 #endif 847 848 /* If rebooting and a dump is requested, do it. */ 849 #if 0 850 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 851 #else 852 if (howto & RB_DUMP) 853 #endif 854 dumpsys(); 855 856 haltsys: 857 858 /* Run any shutdown hooks. */ 859 doshutdownhooks(); 860 861 pmf_system_shutdown(boothowto); 862 863 /* If powerdown was requested, do it. */ 864 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 865 prom_interpret("power-off"); 866 #if NPOWER > 0 867 /* Fall back on `power' device if the PROM can't do it */ 868 powerdown(); 869 #endif 870 printf("WARNING: powerdown not supported\n"); 871 /* 872 * RB_POWERDOWN implies RB_HALT... fall into it... 873 */ 874 } 875 876 if (howto & RB_HALT) { 877 #if defined(MULTIPROCESSOR) 878 mp_halt_cpus(); 879 printf("cpu%d halted\n\n", cpu_number()); 880 #else 881 printf("halted\n\n"); 882 #endif 883 prom_halt(); 884 } 885 886 printf("rebooting\n\n"); 887 888 i = 1; 889 if (howto & RB_SINGLE) 890 opts[i++] = 's'; 891 if (howto & RB_KDB) 892 opts[i++] = 'd'; 893 opts[i] = '\0'; 894 opts[0] = (i > 1) ? '-' : '\0'; 895 896 if (user_boot_string && *user_boot_string) { 897 i = strlen(user_boot_string); 898 if (i > sizeof(str) - sizeof(opts) - 1) 899 prom_boot(user_boot_string); /* XXX */ 900 memcpy(str, user_boot_string, i); 901 if (opts[0] != '\0') 902 str[i] = ' '; 903 } 904 strcat(str, opts); 905 prom_boot(str); 906 /*NOTREACHED*/ 907 } 908 909 uint32_t dumpmag = 0x8fca0101; /* magic number for savecore */ 910 int dumpsize = 0; /* also for savecore */ 911 long dumplo = 0; 912 913 void 914 cpu_dumpconf(void) 915 { 916 int nblks, dumpblks; 917 918 if (dumpdev == NODEV) 919 return; 920 nblks = bdev_size(dumpdev); 921 922 dumpblks = ctod(physmem) + pmap_dumpsize(); 923 if (dumpblks > (nblks - ctod(1))) 924 /* 925 * dump size is too big for the partition. 926 * Note, we safeguard a click at the front for a 927 * possible disk label. 928 */ 929 return; 930 931 /* Put the dump at the end of the partition */ 932 dumplo = nblks - dumpblks; 933 934 /* 935 * savecore(8) expects dumpsize to be the number of pages 936 * of actual core dumped (i.e. excluding the MMU stuff). 937 */ 938 dumpsize = physmem; 939 } 940 941 #define BYTES_PER_DUMP (32 * 1024) /* must be a multiple of pagesize */ 942 static vaddr_t dumpspace; 943 struct pcb dumppcb; 944 945 void * 946 reserve_dumppages(void *p) 947 { 948 949 dumpspace = (vaddr_t)p; 950 return ((char *)p + BYTES_PER_DUMP); 951 } 952 953 /* 954 * Write a crash dump. 955 */ 956 void 957 dumpsys(void) 958 { 959 const struct bdevsw *bdev; 960 int psize; 961 daddr_t blkno; 962 int (*dump)(dev_t, daddr_t, void *, size_t); 963 int error = 0; 964 struct memarr *mp; 965 int nmem; 966 967 /* copy registers to memory */ 968 snapshot(cpuinfo.curpcb); 969 memcpy(&dumppcb, cpuinfo.curpcb, sizeof dumppcb); 970 stackdump(); 971 972 if (dumpdev == NODEV) 973 return; 974 bdev = bdevsw_lookup(dumpdev); 975 if (bdev == NULL || bdev->d_psize == NULL) 976 return; 977 978 /* 979 * For dumps during autoconfiguration, 980 * if dump device has already configured... 981 */ 982 if (dumpsize == 0) 983 cpu_dumpconf(); 984 if (dumplo <= 0) { 985 printf("\ndump to dev %u,%u not possible\n", 986 major(dumpdev), minor(dumpdev)); 987 return; 988 } 989 printf("\ndumping to dev %u,%u offset %ld\n", 990 major(dumpdev), minor(dumpdev), dumplo); 991 992 psize = bdev_size(dumpdev); 993 printf("dump "); 994 if (psize == -1) { 995 printf("area unavailable\n"); 996 return; 997 } 998 blkno = dumplo; 999 dump = bdev->d_dump; 1000 1001 error = pmap_dumpmmu(dump, blkno); 1002 blkno += pmap_dumpsize(); 1003 1004 for (mp = pmemarr, nmem = npmemarr; --nmem >= 0 && error == 0; mp++) { 1005 unsigned i = 0, n; 1006 int maddr = mp->addr; 1007 1008 if (maddr == 0) { 1009 /* Skip first page at physical address 0 */ 1010 maddr += PAGE_SIZE; 1011 i += PAGE_SIZE; 1012 blkno += btodb(PAGE_SIZE); 1013 } 1014 1015 for (; i < mp->len; i += n) { 1016 n = mp->len - i; 1017 if (n > BYTES_PER_DUMP) 1018 n = BYTES_PER_DUMP; 1019 1020 /* print out how many MBs we have dumped */ 1021 if (i && (i % (1024*1024)) == 0) 1022 printf_nolog("%d ", i / (1024*1024)); 1023 1024 (void) pmap_map(dumpspace, maddr, maddr + n, 1025 VM_PROT_READ); 1026 error = (*dump)(dumpdev, blkno, 1027 (void *)dumpspace, (int)n); 1028 pmap_kremove(dumpspace, n); 1029 pmap_update(pmap_kernel()); 1030 if (error) 1031 break; 1032 maddr += n; 1033 blkno += btodb(n); 1034 } 1035 } 1036 1037 switch (error) { 1038 1039 case ENXIO: 1040 printf("device bad\n"); 1041 break; 1042 1043 case EFAULT: 1044 printf("device not ready\n"); 1045 break; 1046 1047 case EINVAL: 1048 printf("area improper\n"); 1049 break; 1050 1051 case EIO: 1052 printf("i/o error\n"); 1053 break; 1054 1055 case 0: 1056 printf("succeeded\n"); 1057 break; 1058 1059 default: 1060 printf("error %d\n", error); 1061 break; 1062 } 1063 } 1064 1065 /* 1066 * get the fp and dump the stack as best we can. don't leave the 1067 * current stack page 1068 */ 1069 void 1070 stackdump(void) 1071 { 1072 struct frame *fp = getfp(), *sfp; 1073 1074 sfp = fp; 1075 printf("Frame pointer is at %p\n", fp); 1076 printf("Call traceback:\n"); 1077 while (fp && ((u_long)fp >> PGSHIFT) == ((u_long)sfp >> PGSHIFT)) { 1078 printf(" pc = 0x%x args = (0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) fp = %p\n", 1079 fp->fr_pc, fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], 1080 fp->fr_arg[3], fp->fr_arg[4], fp->fr_arg[5], fp->fr_fp); 1081 fp = fp->fr_fp; 1082 } 1083 } 1084 1085 int 1086 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 1087 { 1088 1089 return (ENOEXEC); 1090 } 1091 1092 #if defined(SUN4) 1093 void 1094 oldmon_w_trace(u_long va) 1095 { 1096 struct cpu_info * const ci = curcpu(); 1097 u_long stop; 1098 struct frame *fp; 1099 1100 printf("curlwp = %p, pid %d\n", curlwp, curproc->p_pid); 1101 1102 printf("uvm: cpu%u: swtch %"PRIu64", trap %"PRIu64", sys %"PRIu64", " 1103 "intr %"PRIu64", soft %"PRIu64", faults %"PRIu64"\n", 1104 cpu_index(ci), ci->ci_data.cpu_nswtch, ci->ci_data.cpu_ntrap, 1105 ci->ci_data.cpu_nsyscall, ci->ci_data.cpu_nintr, 1106 ci->ci_data.cpu_nsoft, ci->ci_data.cpu_nfault); 1107 write_user_windows(); 1108 1109 #define round_up(x) (( (x) + (PAGE_SIZE-1) ) & (~(PAGE_SIZE-1)) ) 1110 1111 printf("\nstack trace with sp = 0x%lx\n", va); 1112 stop = round_up(va); 1113 printf("stop at 0x%lx\n", stop); 1114 fp = (struct frame *) va; 1115 while (round_up((u_long) fp) == stop) { 1116 printf(" 0x%x(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) fp %p\n", fp->fr_pc, 1117 fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3], 1118 fp->fr_arg[4], fp->fr_arg[5], fp->fr_fp); 1119 fp = fp->fr_fp; 1120 if (fp == NULL) 1121 break; 1122 } 1123 printf("end of stack trace\n"); 1124 } 1125 1126 void 1127 oldmon_w_cmd(u_long va, char *ar) 1128 { 1129 switch (*ar) { 1130 case '\0': 1131 switch (va) { 1132 case 0: 1133 panic("g0 panic"); 1134 case 4: 1135 printf("w: case 4\n"); 1136 break; 1137 default: 1138 printf("w: unknown case %ld\n", va); 1139 break; 1140 } 1141 break; 1142 case 't': 1143 oldmon_w_trace(va); 1144 break; 1145 default: 1146 printf("w: arg not allowed\n"); 1147 } 1148 } 1149 1150 int 1151 ldcontrolb(void *addr) 1152 { 1153 struct pcb *xpcb; 1154 u_long saveonfault; 1155 int res; 1156 int s; 1157 1158 if (CPU_ISSUN4M || CPU_ISSUN4D) { 1159 printf("warning: ldcontrolb called on sun4m/sun4d\n"); 1160 return 0; 1161 } 1162 1163 s = splhigh(); 1164 xpcb = lwp_getpcb(curlwp); 1165 1166 saveonfault = (u_long)xpcb->pcb_onfault; 1167 res = xldcontrolb(addr, xpcb); 1168 xpcb->pcb_onfault = (void *)saveonfault; 1169 1170 splx(s); 1171 return (res); 1172 } 1173 #endif /* SUN4 */ 1174 1175 void 1176 wzero(void *vb, u_int l) 1177 { 1178 u_char *b = vb; 1179 u_char *be = b + l; 1180 u_short *sp; 1181 1182 if (l == 0) 1183 return; 1184 1185 /* front, */ 1186 if ((u_long)b & 1) 1187 *b++ = 0; 1188 1189 /* back, */ 1190 if (b != be && ((u_long)be & 1) != 0) { 1191 be--; 1192 *be = 0; 1193 } 1194 1195 /* and middle. */ 1196 sp = (u_short *)b; 1197 while (sp != (u_short *)be) 1198 *sp++ = 0; 1199 } 1200 1201 void 1202 wcopy(const void *vb1, void *vb2, u_int l) 1203 { 1204 const u_char *b1e, *b1 = vb1; 1205 u_char *b2 = vb2; 1206 const u_short *sp; 1207 int bstore = 0; 1208 1209 if (l == 0) 1210 return; 1211 1212 /* front, */ 1213 if ((u_long)b1 & 1) { 1214 *b2++ = *b1++; 1215 l--; 1216 } 1217 1218 /* middle, */ 1219 sp = (const u_short *)b1; 1220 b1e = b1 + l; 1221 if (l & 1) 1222 b1e--; 1223 bstore = (u_long)b2 & 1; 1224 1225 while (sp < (const u_short *)b1e) { 1226 if (bstore) { 1227 b2[1] = *sp & 0xff; 1228 b2[0] = *sp >> 8; 1229 } else 1230 *((short *)b2) = *sp; 1231 sp++; 1232 b2 += 2; 1233 } 1234 1235 /* and back. */ 1236 if (l & 1) 1237 *b2 = *b1e; 1238 } 1239 1240 static size_t 1241 _bus_dmamap_mapsize(int const nsegments) 1242 { 1243 KASSERT(nsegments > 0); 1244 return sizeof(struct sparc_bus_dmamap) + 1245 (sizeof(bus_dma_segment_t) * (nsegments - 1)); 1246 } 1247 1248 /* 1249 * Common function for DMA map creation. May be called by bus-specific 1250 * DMA map creation functions. 1251 */ 1252 int 1253 _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, 1254 bus_size_t maxsegsz, bus_size_t boundary, int flags, 1255 bus_dmamap_t *dmamp) 1256 { 1257 struct sparc_bus_dmamap *map; 1258 void *mapstore; 1259 1260 /* 1261 * Allocate and initialize the DMA map. The end of the map 1262 * is a variable-sized array of segments, so we allocate enough 1263 * room for them in one shot. 1264 * 1265 * Note we don't preserve the WAITOK or NOWAIT flags. Preservation 1266 * of ALLOCNOW notifies others that we've reserved these resources, 1267 * and they are not to be freed. 1268 * 1269 * The bus_dmamap_t includes one bus_dma_segment_t, hence 1270 * the (nsegments - 1). 1271 */ 1272 if ((mapstore = kmem_zalloc(_bus_dmamap_mapsize(nsegments), 1273 (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL) 1274 return (ENOMEM); 1275 1276 map = (struct sparc_bus_dmamap *)mapstore; 1277 map->_dm_size = size; 1278 map->_dm_segcnt = nsegments; 1279 map->_dm_maxmaxsegsz = maxsegsz; 1280 map->_dm_boundary = boundary; 1281 map->_dm_align = PAGE_SIZE; 1282 map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT); 1283 map->dm_maxsegsz = maxsegsz; 1284 map->dm_mapsize = 0; /* no valid mappings */ 1285 map->dm_nsegs = 0; 1286 1287 *dmamp = map; 1288 return (0); 1289 } 1290 1291 /* 1292 * Common function for DMA map destruction. May be called by bus-specific 1293 * DMA map destruction functions. 1294 */ 1295 void 1296 _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map) 1297 { 1298 1299 kmem_free(map, _bus_dmamap_mapsize(map->_dm_segcnt)); 1300 } 1301 1302 /* 1303 * Like _bus_dmamap_load(), but for mbufs. 1304 */ 1305 int 1306 _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, 1307 struct mbuf *m, int flags) 1308 { 1309 1310 panic("_bus_dmamap_load_mbuf: not implemented"); 1311 } 1312 1313 /* 1314 * Like _bus_dmamap_load(), but for uios. 1315 */ 1316 int 1317 _bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, 1318 struct uio *uio, int flags) 1319 { 1320 1321 panic("_bus_dmamap_load_uio: not implemented"); 1322 } 1323 1324 /* 1325 * Like _bus_dmamap_load(), but for raw memory allocated with 1326 * bus_dmamem_alloc(). 1327 */ 1328 int 1329 _bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, 1330 bus_dma_segment_t *segs, int nsegs, bus_size_t size, 1331 int flags) 1332 { 1333 1334 panic("_bus_dmamap_load_raw: not implemented"); 1335 } 1336 1337 /* 1338 * Common function for DMA map synchronization. May be called 1339 * by bus-specific DMA map synchronization functions. 1340 */ 1341 void 1342 _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, 1343 bus_addr_t offset, bus_size_t len, int ops) 1344 { 1345 } 1346 1347 /* 1348 * Common function for DMA-safe memory allocation. May be called 1349 * by bus-specific DMA memory allocation functions. 1350 */ 1351 int 1352 _bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, 1353 bus_size_t alignment, bus_size_t boundary, 1354 bus_dma_segment_t *segs, int nsegs, int *rsegs, 1355 int flags) 1356 { 1357 vaddr_t low, high; 1358 struct pglist *mlist; 1359 int error; 1360 1361 /* Always round the size. */ 1362 size = round_page(size); 1363 low = vm_first_phys; 1364 high = vm_first_phys + vm_num_phys - PAGE_SIZE; 1365 1366 if ((mlist = kmem_alloc(sizeof(*mlist), 1367 (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL) 1368 return (ENOMEM); 1369 1370 /* 1371 * Allocate pages from the VM system. 1372 */ 1373 error = uvm_pglistalloc(size, low, high, 0, 0, 1374 mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0); 1375 if (error) { 1376 kmem_free(mlist, sizeof(*mlist)); 1377 return (error); 1378 } 1379 1380 /* 1381 * Simply keep a pointer around to the linked list, so 1382 * bus_dmamap_free() can return it. 1383 * 1384 * NOBODY SHOULD TOUCH THE pageq.queue FIELDS WHILE THESE PAGES 1385 * ARE IN OUR CUSTODY. 1386 */ 1387 segs[0]._ds_mlist = mlist; 1388 1389 /* 1390 * We now have physical pages, but no DVMA addresses yet. These 1391 * will be allocated in bus_dmamap_load*() routines. Hence we 1392 * save any alignment and boundary requirements in this DMA 1393 * segment. 1394 */ 1395 segs[0].ds_addr = 0; 1396 segs[0].ds_len = 0; 1397 segs[0]._ds_va = 0; 1398 *rsegs = 1; 1399 return (0); 1400 } 1401 1402 /* 1403 * Common function for freeing DMA-safe memory. May be called by 1404 * bus-specific DMA memory free functions. 1405 */ 1406 void 1407 _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs) 1408 { 1409 struct pglist *mlist = segs[0]._ds_mlist; 1410 1411 if (nsegs != 1) 1412 panic("bus_dmamem_free: nsegs = %d", nsegs); 1413 1414 /* 1415 * Return the list of pages back to the VM system. 1416 */ 1417 uvm_pglistfree(mlist); 1418 kmem_free(mlist, sizeof(*mlist)); 1419 } 1420 1421 /* 1422 * Common function for unmapping DMA-safe memory. May be called by 1423 * bus-specific DMA memory unmapping functions. 1424 */ 1425 void 1426 _bus_dmamem_unmap(bus_dma_tag_t t, void *kva, size_t size) 1427 { 1428 1429 #ifdef DIAGNOSTIC 1430 if ((u_long)kva & PAGE_MASK) 1431 panic("_bus_dmamem_unmap"); 1432 #endif 1433 1434 size = round_page(size); 1435 pmap_kremove((vaddr_t)kva, size); 1436 pmap_update(pmap_kernel()); 1437 uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY); 1438 } 1439 1440 /* 1441 * Common function for mmap(2)'ing DMA-safe memory. May be called by 1442 * bus-specific DMA mmap(2)'ing functions. 1443 */ 1444 paddr_t 1445 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, 1446 off_t off, int prot, int flags) 1447 { 1448 1449 panic("_bus_dmamem_mmap: not implemented"); 1450 } 1451 1452 /* 1453 * Utility to allocate an aligned kernel virtual address range 1454 */ 1455 vaddr_t 1456 _bus_dma_valloc_skewed(size_t size, u_long boundary, u_long align, u_long skew) 1457 { 1458 size_t oversize; 1459 vaddr_t va, sva; 1460 1461 /* 1462 * Find a region of kernel virtual addresses that is aligned 1463 * to the given address modulo the requested alignment, i.e. 1464 * 1465 * (va - skew) == 0 mod align 1466 * 1467 * The following conditions apply to the arguments: 1468 * 1469 * - `size' must be a multiple of the VM page size 1470 * - `align' must be a power of two 1471 * and greater than or equal to the VM page size 1472 * - `skew' must be smaller than `align' 1473 * - `size' must be smaller than `boundary' 1474 */ 1475 1476 #ifdef DIAGNOSTIC 1477 if ((size & PAGE_MASK) != 0) 1478 panic("_bus_dma_valloc_skewed: invalid size %lx", size); 1479 if ((align & PAGE_MASK) != 0) 1480 panic("_bus_dma_valloc_skewed: invalid alignment %lx", align); 1481 if (align < skew) 1482 panic("_bus_dma_valloc_skewed: align %lx < skew %lx", 1483 align, skew); 1484 #endif 1485 1486 /* XXX - Implement this! */ 1487 if (boundary) { 1488 printf("_bus_dma_valloc_skewed: " 1489 "boundary check not implemented"); 1490 return (0); 1491 } 1492 1493 /* 1494 * First, find a region large enough to contain any aligned chunk 1495 */ 1496 oversize = size + align - PAGE_SIZE; 1497 sva = vm_map_min(kernel_map); 1498 if (uvm_map(kernel_map, &sva, oversize, NULL, UVM_UNKNOWN_OFFSET, 1499 align, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, 1500 UVM_ADV_RANDOM, UVM_FLAG_NOWAIT))) 1501 return (0); 1502 1503 /* 1504 * Compute start of aligned region 1505 */ 1506 va = sva; 1507 va += (skew + align - va) & (align - 1); 1508 1509 /* 1510 * Return excess virtual addresses 1511 */ 1512 if (va != sva) 1513 (void)uvm_unmap(kernel_map, sva, va); 1514 if (va + size != sva + oversize) 1515 (void)uvm_unmap(kernel_map, va + size, sva + oversize); 1516 1517 return (va); 1518 } 1519 1520 /* sun4/sun4c DMA map functions */ 1521 int sun4_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, 1522 bus_size_t, struct proc *, int); 1523 int sun4_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, 1524 bus_dma_segment_t *, int, bus_size_t, int); 1525 void sun4_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 1526 int sun4_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, 1527 int, size_t, void **, int); 1528 1529 /* 1530 * sun4/sun4c: load DMA map with a linear buffer. 1531 */ 1532 int 1533 sun4_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, 1534 void *buf, bus_size_t buflen, 1535 struct proc *p, int flags) 1536 { 1537 bus_size_t sgsize; 1538 vaddr_t va = (vaddr_t)buf; 1539 int pagesz = PAGE_SIZE; 1540 vaddr_t dva; 1541 pmap_t pmap; 1542 1543 /* 1544 * Make sure that on error condition we return "no valid mappings". 1545 */ 1546 map->dm_nsegs = 0; 1547 1548 if (buflen > map->_dm_size) 1549 return (EINVAL); 1550 1551 cache_flush(buf, buflen); 1552 1553 if ((map->_dm_flags & BUS_DMA_24BIT) == 0) { 1554 /* 1555 * XXX Need to implement "don't DMA across this boundary". 1556 */ 1557 if (map->_dm_boundary != 0) { 1558 bus_addr_t baddr; 1559 1560 /* Calculate first boundary line after `buf' */ 1561 baddr = ((bus_addr_t)va + map->_dm_boundary) & 1562 -map->_dm_boundary; 1563 1564 /* 1565 * If the requested segment crosses the boundary, 1566 * we can't grant a direct map. For now, steal some 1567 * space from the `24BIT' map instead. 1568 * 1569 * (XXX - no overflow detection here) 1570 */ 1571 if (buflen > (baddr - (bus_addr_t)va)) 1572 goto no_fit; 1573 } 1574 map->dm_mapsize = buflen; 1575 map->dm_nsegs = 1; 1576 map->dm_segs[0].ds_addr = (bus_addr_t)va; 1577 map->dm_segs[0].ds_len = buflen; 1578 map->_dm_flags |= _BUS_DMA_DIRECTMAP; 1579 return (0); 1580 } 1581 1582 no_fit: 1583 sgsize = round_page(buflen + (va & (pagesz - 1))); 1584 1585 const vm_flag_t vmflags = VM_BESTFIT | 1586 ((flags & BUS_DMA_NOWAIT) ? VM_NOSLEEP : VM_SLEEP); 1587 1588 if (vmem_xalloc(dvmamap24, sgsize, 1589 0, /* alignment */ 1590 0, /* phase */ 1591 map->_dm_boundary, /* nocross */ 1592 VMEM_ADDR_MIN, /* minaddr */ 1593 VMEM_ADDR_MAX, /* maxaddr */ 1594 vmflags, 1595 &dva) != 0) { 1596 return (ENOMEM); 1597 } 1598 1599 /* 1600 * We always use just one segment. 1601 */ 1602 map->dm_mapsize = buflen; 1603 map->dm_segs[0].ds_addr = dva + (va & (pagesz - 1)); 1604 map->dm_segs[0].ds_len = buflen; 1605 map->dm_segs[0]._ds_sgsize = sgsize; 1606 1607 if (p != NULL) 1608 pmap = p->p_vmspace->vm_map.pmap; 1609 else 1610 pmap = pmap_kernel(); 1611 1612 for (; buflen > 0; ) { 1613 paddr_t pa; 1614 1615 /* 1616 * Get the physical address for this page. 1617 */ 1618 (void) pmap_extract(pmap, va, &pa); 1619 1620 /* 1621 * Compute the segment size, and adjust counts. 1622 */ 1623 sgsize = pagesz - (va & (pagesz - 1)); 1624 if (buflen < sgsize) 1625 sgsize = buflen; 1626 1627 #ifdef notyet 1628 #if defined(SUN4) 1629 if (have_iocache) 1630 pa |= PG_IOC; 1631 #endif 1632 #endif 1633 pmap_kenter_pa(dva, (pa & -pagesz) | PMAP_NC, 1634 VM_PROT_READ | VM_PROT_WRITE, 0); 1635 1636 dva += pagesz; 1637 va += sgsize; 1638 buflen -= sgsize; 1639 } 1640 pmap_update(pmap_kernel()); 1641 1642 map->dm_nsegs = 1; 1643 return (0); 1644 } 1645 1646 /* 1647 * Like _bus_dmamap_load(), but for raw memory allocated with 1648 * bus_dmamem_alloc(). 1649 */ 1650 int 1651 sun4_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, 1652 bus_dma_segment_t *segs, int nsegs, bus_size_t size, 1653 int flags) 1654 { 1655 struct vm_page *m; 1656 paddr_t pa; 1657 vaddr_t dva; 1658 bus_size_t sgsize; 1659 struct pglist *mlist; 1660 int pagesz = PAGE_SIZE; 1661 int error; 1662 1663 map->dm_nsegs = 0; 1664 sgsize = (size + pagesz - 1) & -pagesz; 1665 1666 /* Allocate DVMA addresses */ 1667 if ((map->_dm_flags & BUS_DMA_24BIT) != 0) { 1668 const vm_flag_t vmflags = VM_BESTFIT | 1669 ((flags & BUS_DMA_NOWAIT) ? VM_NOSLEEP : VM_SLEEP); 1670 1671 error = vmem_xalloc(dvmamap24, sgsize, 1672 0, /* alignment */ 1673 0, /* phase */ 1674 map->_dm_boundary, /* nocross */ 1675 VMEM_ADDR_MIN, /* minaddr */ 1676 VMEM_ADDR_MAX, /* maxaddr */ 1677 vmflags, 1678 &dva); 1679 if (error) 1680 return (error); 1681 } else { 1682 /* Any properly aligned virtual address will do */ 1683 dva = _bus_dma_valloc_skewed(sgsize, map->_dm_boundary, 1684 pagesz, 0); 1685 if (dva == 0) 1686 return (ENOMEM); 1687 } 1688 1689 map->dm_segs[0].ds_addr = dva; 1690 map->dm_segs[0].ds_len = size; 1691 map->dm_segs[0]._ds_sgsize = sgsize; 1692 1693 /* Map physical pages into IOMMU */ 1694 mlist = segs[0]._ds_mlist; 1695 for (m = TAILQ_FIRST(mlist); m != NULL; m = TAILQ_NEXT(m,pageq.queue)) { 1696 if (sgsize == 0) 1697 panic("sun4_dmamap_load_raw: size botch"); 1698 pa = VM_PAGE_TO_PHYS(m); 1699 #ifdef notyet 1700 #if defined(SUN4) 1701 if (have_iocache) 1702 pa |= PG_IOC; 1703 #endif 1704 #endif 1705 pmap_kenter_pa(dva, (pa & -pagesz) | PMAP_NC, 1706 VM_PROT_READ | VM_PROT_WRITE, 0); 1707 1708 dva += pagesz; 1709 sgsize -= pagesz; 1710 } 1711 pmap_update(pmap_kernel()); 1712 1713 map->dm_nsegs = 1; 1714 map->dm_mapsize = size; 1715 1716 return (0); 1717 } 1718 1719 /* 1720 * sun4/sun4c function for unloading a DMA map. 1721 */ 1722 void 1723 sun4_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) 1724 { 1725 bus_dma_segment_t *segs = map->dm_segs; 1726 int nsegs = map->dm_nsegs; 1727 int flags = map->_dm_flags; 1728 vaddr_t dva; 1729 bus_size_t len; 1730 int i; 1731 1732 map->dm_maxsegsz = map->_dm_maxmaxsegsz; 1733 1734 if ((flags & _BUS_DMA_DIRECTMAP) != 0) { 1735 /* Nothing to release */ 1736 map->dm_mapsize = 0; 1737 map->dm_nsegs = 0; 1738 map->_dm_flags &= ~_BUS_DMA_DIRECTMAP; 1739 return; 1740 } 1741 1742 for (i = 0; i < nsegs; i++) { 1743 dva = segs[i].ds_addr & -PAGE_SIZE; 1744 len = segs[i]._ds_sgsize; 1745 1746 pmap_kremove(dva, len); 1747 1748 if ((flags & BUS_DMA_24BIT) != 0) { 1749 vmem_xfree(dvmamap24, dva, len); 1750 } else { 1751 uvm_unmap(kernel_map, dva, dva + len); 1752 } 1753 } 1754 pmap_update(pmap_kernel()); 1755 1756 /* Mark the mappings as invalid. */ 1757 map->dm_mapsize = 0; 1758 map->dm_nsegs = 0; 1759 } 1760 1761 /* 1762 * Common function for mapping DMA-safe memory. May be called by 1763 * bus-specific DMA memory map functions. 1764 */ 1765 int 1766 sun4_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, 1767 size_t size, void **kvap, int flags) 1768 { 1769 struct vm_page *m; 1770 vaddr_t va; 1771 struct pglist *mlist; 1772 const uvm_flag_t kmflags = 1773 (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0; 1774 1775 if (nsegs != 1) 1776 panic("sun4_dmamem_map: nsegs = %d", nsegs); 1777 1778 size = round_page(size); 1779 1780 va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags); 1781 if (va == 0) 1782 return (ENOMEM); 1783 1784 segs[0]._ds_va = va; 1785 *kvap = (void *)va; 1786 1787 mlist = segs[0]._ds_mlist; 1788 TAILQ_FOREACH(m, mlist, pageq.queue) { 1789 paddr_t pa; 1790 1791 if (size == 0) 1792 panic("sun4_dmamem_map: size botch"); 1793 1794 pa = VM_PAGE_TO_PHYS(m); 1795 pmap_kenter_pa(va, pa | PMAP_NC, 1796 VM_PROT_READ | VM_PROT_WRITE, 0); 1797 1798 va += PAGE_SIZE; 1799 size -= PAGE_SIZE; 1800 } 1801 pmap_update(pmap_kernel()); 1802 1803 return (0); 1804 } 1805 1806 1807 struct sparc_bus_dma_tag mainbus_dma_tag = { 1808 NULL, 1809 _bus_dmamap_create, 1810 _bus_dmamap_destroy, 1811 sun4_dmamap_load, 1812 _bus_dmamap_load_mbuf, 1813 _bus_dmamap_load_uio, 1814 sun4_dmamap_load_raw, 1815 sun4_dmamap_unload, 1816 _bus_dmamap_sync, 1817 1818 _bus_dmamem_alloc, 1819 _bus_dmamem_free, 1820 sun4_dmamem_map, 1821 _bus_dmamem_unmap, 1822 _bus_dmamem_mmap 1823 }; 1824 1825 1826 /* 1827 * Base bus space handlers. 1828 */ 1829 static int sparc_bus_map(bus_space_tag_t, bus_addr_t, 1830 bus_size_t, int, vaddr_t, 1831 bus_space_handle_t *); 1832 static int sparc_bus_unmap(bus_space_tag_t, bus_space_handle_t, 1833 bus_size_t); 1834 static int sparc_bus_subregion(bus_space_tag_t, bus_space_handle_t, 1835 bus_size_t, bus_size_t, 1836 bus_space_handle_t *); 1837 static paddr_t sparc_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, 1838 int, int); 1839 static void *sparc_mainbus_intr_establish(bus_space_tag_t, int, int, 1840 int (*)(void *), 1841 void *, 1842 void (*)(void)); 1843 static void sparc_bus_barrier(bus_space_tag_t, bus_space_handle_t, 1844 bus_size_t, bus_size_t, int); 1845 1846 int 1847 bus_space_map( 1848 bus_space_tag_t t, 1849 bus_addr_t a, 1850 bus_size_t s, 1851 int f, 1852 bus_space_handle_t *hp) 1853 { 1854 return (*t->sparc_bus_map)(t, a, s, f, (vaddr_t)0, hp); 1855 } 1856 1857 int 1858 bus_space_map2( 1859 bus_space_tag_t t, 1860 bus_addr_t a, 1861 bus_size_t s, 1862 int f, 1863 vaddr_t v, 1864 bus_space_handle_t *hp) 1865 { 1866 return (*t->sparc_bus_map)(t, a, s, f, v, hp); 1867 } 1868 1869 void 1870 bus_space_unmap( 1871 bus_space_tag_t t, 1872 bus_space_handle_t h, 1873 bus_size_t s) 1874 { 1875 (*t->sparc_bus_unmap)(t, h, s); 1876 } 1877 1878 int 1879 bus_space_subregion( 1880 bus_space_tag_t t, 1881 bus_space_handle_t h, 1882 bus_size_t o, 1883 bus_size_t s, 1884 bus_space_handle_t *hp) 1885 { 1886 return (*t->sparc_bus_subregion)(t, h, o, s, hp); 1887 } 1888 1889 paddr_t 1890 bus_space_mmap( 1891 bus_space_tag_t t, 1892 bus_addr_t a, 1893 off_t o, 1894 int p, 1895 int f) 1896 { 1897 return (*t->sparc_bus_mmap)(t, a, o, p, f); 1898 } 1899 1900 void * 1901 bus_intr_establish( 1902 bus_space_tag_t t, 1903 int p, 1904 int l, 1905 int (*h)(void *), 1906 void *a) 1907 { 1908 return (*t->sparc_intr_establish)(t, p, l, h, a, NULL); 1909 } 1910 1911 void * 1912 bus_intr_establish2( 1913 bus_space_tag_t t, 1914 int p, 1915 int l, 1916 int (*h)(void *), 1917 void *a, 1918 void (*v)(void)) 1919 { 1920 return (*t->sparc_intr_establish)(t, p, l, h, a, v); 1921 } 1922 1923 void 1924 bus_space_barrier( 1925 bus_space_tag_t t, 1926 bus_space_handle_t h, 1927 bus_size_t o, 1928 bus_size_t s, 1929 int f) 1930 { 1931 (*t->sparc_bus_barrier)(t, h, o, s, f); 1932 } 1933 1934 void 1935 bus_space_write_multi_stream_2( 1936 bus_space_tag_t t, 1937 bus_space_handle_t h, 1938 bus_size_t o, 1939 const uint16_t *a, 1940 bus_size_t c) 1941 { 1942 while (c-- > 0) 1943 bus_space_write_2_real(t, h, o, *a++); 1944 } 1945 1946 void 1947 bus_space_write_multi_stream_4( 1948 bus_space_tag_t t, 1949 bus_space_handle_t h, 1950 bus_size_t o, 1951 const uint32_t *a, 1952 bus_size_t c) 1953 { 1954 while (c-- > 0) 1955 bus_space_write_4_real(t, h, o, *a++); 1956 } 1957 1958 void 1959 bus_space_write_multi_stream_8( 1960 bus_space_tag_t t, 1961 bus_space_handle_t h, 1962 bus_size_t o, 1963 const uint64_t *a, 1964 bus_size_t c) 1965 { 1966 while (c-- > 0) 1967 bus_space_write_8_real(t, h, o, *a++); 1968 } 1969 1970 1971 /* 1972 * void bus_space_set_multi_N(bus_space_tag_t tag, 1973 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 1974 * bus_size_t count); 1975 * 1976 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 1977 * by tag/handle/offset `count' times. 1978 */ 1979 void 1980 bus_space_set_multi_1( 1981 bus_space_tag_t t, 1982 bus_space_handle_t h, 1983 bus_size_t o, 1984 const uint8_t v, 1985 bus_size_t c) 1986 { 1987 while (c-- > 0) 1988 bus_space_write_1(t, h, o, v); 1989 } 1990 1991 void 1992 bus_space_set_multi_2( 1993 bus_space_tag_t t, 1994 bus_space_handle_t h, 1995 bus_size_t o, 1996 const uint16_t v, 1997 bus_size_t c) 1998 { 1999 while (c-- > 0) 2000 bus_space_write_2(t, h, o, v); 2001 } 2002 2003 void 2004 bus_space_set_multi_4( 2005 bus_space_tag_t t, 2006 bus_space_handle_t h, 2007 bus_size_t o, 2008 const uint32_t v, 2009 bus_size_t c) 2010 { 2011 while (c-- > 0) 2012 bus_space_write_4(t, h, o, v); 2013 } 2014 2015 void 2016 bus_space_set_multi_8( 2017 bus_space_tag_t t, 2018 bus_space_handle_t h, 2019 bus_size_t o, 2020 const uint64_t v, 2021 bus_size_t c) 2022 { 2023 while (c-- > 0) 2024 bus_space_write_8(t, h, o, v); 2025 } 2026 2027 2028 /* 2029 * void bus_space_read_region_N(bus_space_tag_t tag, 2030 * bus_space_handle_t bsh, bus_size_t off, 2031 * u_intN_t *addr, bus_size_t count); 2032 * 2033 */ 2034 void 2035 bus_space_read_region_1( 2036 bus_space_tag_t t, 2037 bus_space_handle_t h, 2038 bus_size_t o, 2039 uint8_t *a, 2040 bus_size_t c) 2041 { 2042 for (; c; a++, c--, o++) 2043 *a = bus_space_read_1(t, h, o); 2044 } 2045 2046 void 2047 bus_space_read_region_2( 2048 bus_space_tag_t t, 2049 bus_space_handle_t h, 2050 bus_size_t o, 2051 uint16_t *a, 2052 bus_size_t c) 2053 { 2054 for (; c; a++, c--, o+=2) 2055 *a = bus_space_read_2(t, h, o); 2056 } 2057 2058 void 2059 bus_space_read_region_4( 2060 bus_space_tag_t t, 2061 bus_space_handle_t h, 2062 bus_size_t o, 2063 uint32_t *a, 2064 bus_size_t c) 2065 { 2066 for (; c; a++, c--, o+=4) 2067 *a = bus_space_read_4(t, h, o); 2068 } 2069 2070 void 2071 bus_space_read_region_8( 2072 bus_space_tag_t t, 2073 bus_space_handle_t h, 2074 bus_size_t o, 2075 uint64_t *a, 2076 bus_size_t c) 2077 { 2078 for (; c; a++, c--, o+=8) 2079 *a = bus_space_read_8(t, h, o); 2080 } 2081 2082 /* 2083 * void bus_space_write_region_N(bus_space_tag_t tag, 2084 * bus_space_handle_t bsh, bus_size_t off, 2085 * u_intN_t *addr, bus_size_t count); 2086 * 2087 */ 2088 void 2089 bus_space_write_region_1( 2090 bus_space_tag_t t, 2091 bus_space_handle_t h, 2092 bus_size_t o, 2093 const uint8_t *a, 2094 bus_size_t c) 2095 { 2096 for (; c; a++, c--, o++) 2097 bus_space_write_1(t, h, o, *a); 2098 } 2099 2100 void 2101 bus_space_write_region_2( 2102 bus_space_tag_t t, 2103 bus_space_handle_t h, 2104 bus_size_t o, 2105 const uint16_t *a, 2106 bus_size_t c) 2107 { 2108 for (; c; a++, c--, o+=2) 2109 bus_space_write_2(t, h, o, *a); 2110 } 2111 2112 void 2113 bus_space_write_region_4( 2114 bus_space_tag_t t, 2115 bus_space_handle_t h, 2116 bus_size_t o, 2117 const uint32_t *a, 2118 bus_size_t c) 2119 { 2120 for (; c; a++, c--, o+=4) 2121 bus_space_write_4(t, h, o, *a); 2122 } 2123 2124 void 2125 bus_space_write_region_8( 2126 bus_space_tag_t t, 2127 bus_space_handle_t h, 2128 bus_size_t o, 2129 const uint64_t *a, 2130 bus_size_t c) 2131 { 2132 for (; c; a++, c--, o+=8) 2133 bus_space_write_8(t, h, o, *a); 2134 } 2135 2136 2137 /* 2138 * void bus_space_set_region_N(bus_space_tag_t tag, 2139 * bus_space_handle_t bsh, bus_size_t off, 2140 * u_intN_t *addr, bus_size_t count); 2141 * 2142 */ 2143 void 2144 bus_space_set_region_1( 2145 bus_space_tag_t t, 2146 bus_space_handle_t h, 2147 bus_size_t o, 2148 const uint8_t v, 2149 bus_size_t c) 2150 { 2151 for (; c; c--, o++) 2152 bus_space_write_1(t, h, o, v); 2153 } 2154 2155 void 2156 bus_space_set_region_2( 2157 bus_space_tag_t t, 2158 bus_space_handle_t h, 2159 bus_size_t o, 2160 const uint16_t v, 2161 bus_size_t c) 2162 { 2163 for (; c; c--, o+=2) 2164 bus_space_write_2(t, h, o, v); 2165 } 2166 2167 void 2168 bus_space_set_region_4( 2169 bus_space_tag_t t, 2170 bus_space_handle_t h, 2171 bus_size_t o, 2172 const uint32_t v, 2173 bus_size_t c) 2174 { 2175 for (; c; c--, o+=4) 2176 bus_space_write_4(t, h, o, v); 2177 } 2178 2179 void 2180 bus_space_set_region_8( 2181 bus_space_tag_t t, 2182 bus_space_handle_t h, 2183 bus_size_t o, 2184 const uint64_t v, 2185 bus_size_t c) 2186 { 2187 for (; c; c--, o+=8) 2188 bus_space_write_8(t, h, o, v); 2189 } 2190 2191 2192 /* 2193 * void bus_space_copy_region_N(bus_space_tag_t tag, 2194 * bus_space_handle_t bsh1, bus_size_t off1, 2195 * bus_space_handle_t bsh2, bus_size_t off2, 2196 * bus_size_t count); 2197 * 2198 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 2199 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 2200 */ 2201 void 2202 bus_space_copy_region_1( 2203 bus_space_tag_t t, 2204 bus_space_handle_t h1, 2205 bus_size_t o1, 2206 bus_space_handle_t h2, 2207 bus_size_t o2, 2208 bus_size_t c) 2209 { 2210 for (; c; c--, o1++, o2++) 2211 bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2)); 2212 } 2213 2214 void 2215 bus_space_copy_region_2( 2216 bus_space_tag_t t, 2217 bus_space_handle_t h1, 2218 bus_size_t o1, 2219 bus_space_handle_t h2, 2220 bus_size_t o2, 2221 bus_size_t c) 2222 { 2223 for (; c; c--, o1+=2, o2+=2) 2224 bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2)); 2225 } 2226 2227 void 2228 bus_space_copy_region_4( 2229 bus_space_tag_t t, 2230 bus_space_handle_t h1, 2231 bus_size_t o1, 2232 bus_space_handle_t h2, 2233 bus_size_t o2, 2234 bus_size_t c) 2235 { 2236 for (; c; c--, o1+=4, o2+=4) 2237 bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2)); 2238 } 2239 2240 void 2241 bus_space_copy_region_8( 2242 bus_space_tag_t t, 2243 bus_space_handle_t h1, 2244 bus_size_t o1, 2245 bus_space_handle_t h2, 2246 bus_size_t o2, 2247 bus_size_t c) 2248 { 2249 for (; c; c--, o1+=8, o2+=8) 2250 bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2)); 2251 } 2252 2253 /* 2254 * void bus_space_read_region_stream_N(bus_space_tag_t tag, 2255 * bus_space_handle_t bsh, bus_size_t off, 2256 * u_intN_t *addr, bus_size_t count); 2257 * 2258 */ 2259 void 2260 bus_space_read_region_stream_1( 2261 bus_space_tag_t t, 2262 bus_space_handle_t h, 2263 bus_size_t o, 2264 uint8_t *a, 2265 bus_size_t c) 2266 { 2267 for (; c; a++, c--, o++) 2268 *a = bus_space_read_stream_1(t, h, o); 2269 } 2270 void 2271 bus_space_read_region_stream_2( 2272 bus_space_tag_t t, 2273 bus_space_handle_t h, 2274 bus_size_t o, 2275 uint16_t *a, 2276 bus_size_t c) 2277 { 2278 for (; c; a++, c--, o+=2) 2279 *a = bus_space_read_stream_2(t, h, o); 2280 } 2281 void 2282 bus_space_read_region_stream_4( 2283 bus_space_tag_t t, 2284 bus_space_handle_t h, 2285 bus_size_t o, 2286 uint32_t *a, 2287 bus_size_t c) 2288 { 2289 for (; c; a++, c--, o+=4) 2290 *a = bus_space_read_stream_4(t, h, o); 2291 } 2292 void 2293 bus_space_read_region_stream_8( 2294 bus_space_tag_t t, 2295 bus_space_handle_t h, 2296 bus_size_t o, 2297 uint64_t *a, 2298 bus_size_t c) 2299 { 2300 for (; c; a++, c--, o+=8) 2301 *a = bus_space_read_stream_8(t, h, o); 2302 } 2303 2304 /* 2305 * void bus_space_write_region_stream_N(bus_space_tag_t tag, 2306 * bus_space_handle_t bsh, bus_size_t off, 2307 * u_intN_t *addr, bus_size_t count); 2308 * 2309 */ 2310 void 2311 bus_space_write_region_stream_1( 2312 bus_space_tag_t t, 2313 bus_space_handle_t h, 2314 bus_size_t o, 2315 const uint8_t *a, 2316 bus_size_t c) 2317 { 2318 for (; c; a++, c--, o++) 2319 bus_space_write_stream_1(t, h, o, *a); 2320 } 2321 2322 void 2323 bus_space_write_region_stream_2( 2324 bus_space_tag_t t, 2325 bus_space_handle_t h, 2326 bus_size_t o, 2327 const uint16_t *a, 2328 bus_size_t c) 2329 { 2330 for (; c; a++, c--, o+=2) 2331 bus_space_write_stream_2(t, h, o, *a); 2332 } 2333 2334 void 2335 bus_space_write_region_stream_4( 2336 bus_space_tag_t t, 2337 bus_space_handle_t h, 2338 bus_size_t o, 2339 const uint32_t *a, 2340 bus_size_t c) 2341 { 2342 for (; c; a++, c--, o+=4) 2343 bus_space_write_stream_4(t, h, o, *a); 2344 } 2345 2346 void 2347 bus_space_write_region_stream_8( 2348 bus_space_tag_t t, 2349 bus_space_handle_t h, 2350 bus_size_t o, 2351 const uint64_t *a, 2352 bus_size_t c) 2353 { 2354 for (; c; a++, c--, o+=8) 2355 bus_space_write_stream_8(t, h, o, *a); 2356 } 2357 2358 2359 /* 2360 * void bus_space_set_region_stream_N(bus_space_tag_t tag, 2361 * bus_space_handle_t bsh, bus_size_t off, 2362 * u_intN_t *addr, bus_size_t count); 2363 * 2364 */ 2365 void 2366 bus_space_set_region_stream_1( 2367 bus_space_tag_t t, 2368 bus_space_handle_t h, 2369 bus_size_t o, 2370 const uint8_t v, 2371 bus_size_t c) 2372 { 2373 for (; c; c--, o++) 2374 bus_space_write_stream_1(t, h, o, v); 2375 } 2376 2377 void 2378 bus_space_set_region_stream_2( 2379 bus_space_tag_t t, 2380 bus_space_handle_t h, 2381 bus_size_t o, 2382 const uint16_t v, 2383 bus_size_t c) 2384 { 2385 for (; c; c--, o+=2) 2386 bus_space_write_stream_2(t, h, o, v); 2387 } 2388 2389 void 2390 bus_space_set_region_stream_4( 2391 bus_space_tag_t t, 2392 bus_space_handle_t h, 2393 bus_size_t o, 2394 const uint32_t v, 2395 bus_size_t c) 2396 { 2397 for (; c; c--, o+=4) 2398 bus_space_write_stream_4(t, h, o, v); 2399 } 2400 2401 void 2402 bus_space_set_region_stream_8( 2403 bus_space_tag_t t, 2404 bus_space_handle_t h, 2405 bus_size_t o, 2406 const uint64_t v, 2407 bus_size_t c) 2408 { 2409 for (; c; c--, o+=8) 2410 bus_space_write_stream_8(t, h, o, v); 2411 } 2412 2413 /* 2414 * void bus_space_copy_region_stream_N(bus_space_tag_t tag, 2415 * bus_space_handle_t bsh1, bus_size_t off1, 2416 * bus_space_handle_t bsh2, bus_size_t off2, 2417 * bus_size_t count); 2418 * 2419 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 2420 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 2421 */ 2422 2423 void 2424 bus_space_copy_region_stream_1( 2425 bus_space_tag_t t, 2426 bus_space_handle_t h1, 2427 bus_size_t o1, 2428 bus_space_handle_t h2, 2429 bus_size_t o2, 2430 bus_size_t c) 2431 { 2432 for (; c; c--, o1++, o2++) 2433 bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2, o2)); 2434 } 2435 2436 void 2437 bus_space_copy_region_stream_2( 2438 bus_space_tag_t t, 2439 bus_space_handle_t h1, 2440 bus_size_t o1, 2441 bus_space_handle_t h2, 2442 bus_size_t o2, 2443 bus_size_t c) 2444 { 2445 for (; c; c--, o1+=2, o2+=2) 2446 bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2, o2)); 2447 } 2448 2449 void 2450 bus_space_copy_region_stream_4( 2451 bus_space_tag_t t, 2452 bus_space_handle_t h1, 2453 bus_size_t o1, 2454 bus_space_handle_t h2, 2455 bus_size_t o2, 2456 bus_size_t c) 2457 { 2458 for (; c; c--, o1+=4, o2+=4) 2459 bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2, o2)); 2460 } 2461 2462 void 2463 bus_space_copy_region_stream_8( 2464 bus_space_tag_t t, 2465 bus_space_handle_t h1, 2466 bus_size_t o1, 2467 bus_space_handle_t h2, 2468 bus_size_t o2, 2469 bus_size_t c) 2470 { 2471 for (; c; c--, o1+=8, o2+=8) 2472 bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2)); 2473 } 2474 2475 void 2476 bus_space_write_1( 2477 bus_space_tag_t t, 2478 bus_space_handle_t h, 2479 bus_size_t o, 2480 uint8_t v) 2481 { 2482 (*t->sparc_write_1)(t, h, o, v); 2483 } 2484 2485 void 2486 bus_space_write_2( 2487 bus_space_tag_t t, 2488 bus_space_handle_t h, 2489 bus_size_t o, 2490 uint16_t v) 2491 { 2492 (*t->sparc_write_2)(t, h, o, v); 2493 } 2494 2495 void 2496 bus_space_write_4( 2497 bus_space_tag_t t, 2498 bus_space_handle_t h, 2499 bus_size_t o, 2500 uint32_t v) 2501 { 2502 (*t->sparc_write_4)(t, h, o, v); 2503 } 2504 2505 void 2506 bus_space_write_8( 2507 bus_space_tag_t t, 2508 bus_space_handle_t h, 2509 bus_size_t o, 2510 uint64_t v) 2511 { 2512 (*t->sparc_write_8)(t, h, o, v); 2513 } 2514 2515 #if __SLIM_SPARC_BUS_SPACE 2516 2517 void 2518 bus_space_write_1( 2519 bus_space_tag_t t, 2520 bus_space_handle_t h, 2521 bus_size_t o, 2522 uint8_t v) 2523 { 2524 __insn_barrier(); 2525 bus_space_write_1_real(t, h, o, v); 2526 } 2527 2528 void 2529 bus_space_write_2( 2530 bus_space_tag_t t, 2531 bus_space_handle_t h, 2532 bus_size_t o, 2533 uint16_t v) 2534 { 2535 __insn_barrier(); 2536 bus_space_write_2_real(t, h, o, v); 2537 } 2538 2539 void 2540 bus_space_write_4( 2541 bus_space_tag_t t, 2542 bus_space_handle_t h, 2543 bus_size_t o, 2544 uint32_t v) 2545 { 2546 __insn_barrier(); 2547 bus_space_write_4_real(t, h, o, v); 2548 } 2549 2550 void 2551 bus_space_write_8( 2552 bus_space_tag_t t, 2553 bus_space_handle_t h, 2554 bus_size_t o, 2555 uint64_t v) 2556 { 2557 __insn_barrier(); 2558 bus_space_write_8_real(t, h, o, v); 2559 } 2560 2561 #endif /* __SLIM_SPARC_BUS_SPACE */ 2562 2563 uint8_t 2564 bus_space_read_1( 2565 bus_space_tag_t t, 2566 bus_space_handle_t h, 2567 bus_size_t o) 2568 { 2569 return (*t->sparc_read_1)(t, h, o); 2570 } 2571 2572 uint16_t 2573 bus_space_read_2( 2574 bus_space_tag_t t, 2575 bus_space_handle_t h, 2576 bus_size_t o) 2577 { 2578 return (*t->sparc_read_2)(t, h, o); 2579 } 2580 2581 uint32_t 2582 bus_space_read_4( 2583 bus_space_tag_t t, 2584 bus_space_handle_t h, 2585 bus_size_t o) 2586 { 2587 return (*t->sparc_read_4)(t, h, o); 2588 } 2589 2590 uint64_t 2591 bus_space_read_8( 2592 bus_space_tag_t t, 2593 bus_space_handle_t h, 2594 bus_size_t o) 2595 { 2596 return (*t->sparc_read_8)(t, h, o); 2597 } 2598 2599 #if __SLIM_SPARC_BUS_SPACE 2600 uint8_t 2601 bus_space_read_1( 2602 bus_space_tag_t t, 2603 bus_space_handle_t h, 2604 bus_size_t o) 2605 { 2606 __insn_barrier(); 2607 return bus_space_read_1_real(t, h, o); 2608 } 2609 2610 uint16_t 2611 bus_space_read_2( 2612 bus_space_tag_t t, 2613 bus_space_handle_t h, 2614 bus_size_t o) 2615 { 2616 __insn_barrier(); 2617 return bus_space_read_2_real(t, h, o); 2618 } 2619 2620 uint32_t 2621 bus_space_read_4( 2622 bus_space_tag_t t, 2623 bus_space_handle_t h, 2624 bus_size_t o) 2625 { 2626 __insn_barrier(); 2627 return bus_space_read_4_real(t, h, o); 2628 } 2629 2630 uint64_t 2631 bus_space_read_8( 2632 bus_space_tag_t t, 2633 bus_space_handle_t h, 2634 bus_size_t o) 2635 { 2636 __insn_barrier(); 2637 return bus_space_read_8_real(t, h, o); 2638 } 2639 2640 #endif /* __SLIM_SPARC_BUS_SPACE */ 2641 2642 void 2643 bus_space_read_multi_1( 2644 bus_space_tag_t t, 2645 bus_space_handle_t h, 2646 bus_size_t o, 2647 uint8_t *a, 2648 bus_size_t c) 2649 { 2650 while (c-- > 0) 2651 *a++ = bus_space_read_1(t, h, o); 2652 } 2653 2654 void 2655 bus_space_read_multi_2( 2656 bus_space_tag_t t, 2657 bus_space_handle_t h, 2658 bus_size_t o, 2659 uint16_t *a, 2660 bus_size_t c) 2661 { 2662 while (c-- > 0) 2663 *a++ = bus_space_read_2(t, h, o); 2664 } 2665 2666 void 2667 bus_space_read_multi_4( 2668 bus_space_tag_t t, 2669 bus_space_handle_t h, 2670 bus_size_t o, 2671 uint32_t *a, 2672 bus_size_t c) 2673 { 2674 while (c-- > 0) 2675 *a++ = bus_space_read_4(t, h, o); 2676 } 2677 2678 void 2679 bus_space_read_multi_8( 2680 bus_space_tag_t t, 2681 bus_space_handle_t h, 2682 bus_size_t o, 2683 uint64_t *a, 2684 bus_size_t c) 2685 { 2686 while (c-- > 0) 2687 *a++ = bus_space_read_8(t, h, o); 2688 } 2689 2690 /* 2691 * void bus_space_read_multi_N(bus_space_tag_t tag, 2692 * bus_space_handle_t bsh, bus_size_t offset, 2693 * u_intN_t *addr, bus_size_t count); 2694 * 2695 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 2696 * described by tag/handle/offset and copy into buffer provided. 2697 */ 2698 void 2699 bus_space_read_multi_stream_2( 2700 bus_space_tag_t t, 2701 bus_space_handle_t h, 2702 bus_size_t o, 2703 uint16_t *a, 2704 bus_size_t c) 2705 { 2706 while (c-- > 0) 2707 *a++ = bus_space_read_2_real(t, h, o); 2708 } 2709 2710 void 2711 bus_space_read_multi_stream_4( 2712 bus_space_tag_t t, 2713 bus_space_handle_t h, 2714 bus_size_t o, 2715 uint32_t *a, 2716 bus_size_t c) 2717 { 2718 while (c-- > 0) 2719 *a++ = bus_space_read_4_real(t, h, o); 2720 } 2721 2722 void 2723 bus_space_read_multi_stream_8( 2724 bus_space_tag_t t, 2725 bus_space_handle_t h, 2726 bus_size_t o, 2727 uint64_t *a, 2728 bus_size_t c) 2729 { 2730 while (c-- > 0) 2731 *a++ = bus_space_read_8_real(t, h, o); 2732 } 2733 2734 /* 2735 * void bus_space_write_multi_N(bus_space_tag_t tag, 2736 * bus_space_handle_t bsh, bus_size_t offset, 2737 * const u_intN_t *addr, bus_size_t count); 2738 * 2739 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 2740 * provided to bus space described by tag/handle/offset. 2741 */ 2742 void 2743 bus_space_write_multi_1( 2744 bus_space_tag_t t, 2745 bus_space_handle_t h, 2746 bus_size_t o, 2747 const uint8_t *a, 2748 bus_size_t c) 2749 { 2750 while (c-- > 0) 2751 bus_space_write_1(t, h, o, *a++); 2752 } 2753 2754 void 2755 bus_space_write_multi_2( 2756 bus_space_tag_t t, 2757 bus_space_handle_t h, 2758 bus_size_t o, 2759 const uint16_t *a, 2760 bus_size_t c) 2761 { 2762 while (c-- > 0) 2763 bus_space_write_2(t, h, o, *a++); 2764 } 2765 2766 void 2767 bus_space_write_multi_4( 2768 bus_space_tag_t t, 2769 bus_space_handle_t h, 2770 bus_size_t o, 2771 const uint32_t *a, 2772 bus_size_t c) 2773 { 2774 while (c-- > 0) 2775 bus_space_write_4(t, h, o, *a++); 2776 } 2777 2778 void 2779 bus_space_write_multi_8( 2780 bus_space_tag_t t, 2781 bus_space_handle_t h, 2782 bus_size_t o, 2783 const uint64_t *a, 2784 bus_size_t c) 2785 { 2786 while (c-- > 0) 2787 bus_space_write_8(t, h, o, *a++); 2788 } 2789 2790 /* 2791 * Allocate a new bus tag and have it inherit the methods of the 2792 * given parent. 2793 */ 2794 bus_space_tag_t 2795 bus_space_tag_alloc(bus_space_tag_t parent, void *cookie) 2796 { 2797 struct sparc_bus_space_tag *sbt; 2798 2799 sbt = kmem_zalloc(sizeof(*sbt), KM_SLEEP); 2800 2801 if (parent) { 2802 memcpy(sbt, parent, sizeof(*sbt)); 2803 sbt->parent = parent; 2804 sbt->ranges = NULL; 2805 sbt->nranges = 0; 2806 } 2807 2808 sbt->cookie = cookie; 2809 return (sbt); 2810 } 2811 2812 /* 2813 * Generic routine to translate an address using OpenPROM `ranges'. 2814 */ 2815 int 2816 bus_space_translate_address_generic(struct openprom_range *ranges, int nranges, 2817 bus_addr_t *bap) 2818 { 2819 int i, space = BUS_ADDR_IOSPACE(*bap); 2820 2821 for (i = 0; i < nranges; i++) { 2822 struct openprom_range *rp = &ranges[i]; 2823 2824 if (rp->or_child_space != space) 2825 continue; 2826 2827 /* We've found the connection to the parent bus. */ 2828 *bap = BUS_ADDR(rp->or_parent_space, 2829 rp->or_parent_base + BUS_ADDR_PADDR(*bap)); 2830 return (0); 2831 } 2832 2833 return (EINVAL); 2834 } 2835 2836 static int 2837 sparc_bus_map_iodev(bus_space_tag_t t, bus_addr_t ba, bus_size_t size, int flags, 2838 vaddr_t va, bus_space_handle_t *hp) 2839 { 2840 vaddr_t v; 2841 paddr_t pa; 2842 unsigned int pmtype; 2843 bus_space_tag_t pt; 2844 static vaddr_t iobase; 2845 2846 /* 2847 * This base class bus map function knows about address range 2848 * translation so bus drivers that need no other special 2849 * handling can just keep this method in their tags. 2850 * 2851 * We expect to resolve range translations iteratively, but allow 2852 * for recursion just in case. 2853 */ 2854 while ((pt = t->parent) != NULL) { 2855 if (t->ranges != NULL) { 2856 int error; 2857 2858 if ((error = bus_space_translate_address_generic( 2859 t->ranges, t->nranges, &ba)) != 0) 2860 return (error); 2861 } 2862 if (pt->sparc_bus_map != sparc_bus_map) 2863 return (bus_space_map2(pt, ba, size, flags, va, hp)); 2864 t = pt; 2865 } 2866 2867 if (iobase == 0) 2868 iobase = IODEV_BASE; 2869 2870 size = round_page(size); 2871 if (size == 0) { 2872 printf("sparc_bus_map: zero size\n"); 2873 return (EINVAL); 2874 } 2875 2876 if (va) 2877 v = trunc_page(va); 2878 else { 2879 v = iobase; 2880 iobase += size; 2881 if (iobase > IODEV_END) /* unlikely */ 2882 panic("sparc_bus_map: iobase=0x%lx", iobase); 2883 } 2884 2885 pmtype = PMAP_IOENC(BUS_ADDR_IOSPACE(ba)); 2886 pa = BUS_ADDR_PADDR(ba); 2887 2888 /* note: preserve page offset */ 2889 *hp = (bus_space_handle_t)(v | ((u_long)pa & PGOFSET)); 2890 2891 pa = trunc_page(pa); 2892 do { 2893 pmap_kenter_pa(v, pa | pmtype | PMAP_NC, 2894 VM_PROT_READ | VM_PROT_WRITE, 0); 2895 v += PAGE_SIZE; 2896 pa += PAGE_SIZE; 2897 } while ((size -= PAGE_SIZE) > 0); 2898 2899 pmap_update(pmap_kernel()); 2900 return (0); 2901 } 2902 2903 static int 2904 sparc_bus_map_large(bus_space_tag_t t, bus_addr_t ba, 2905 bus_size_t size, int flags, bus_space_handle_t *hp) 2906 { 2907 vaddr_t v = 0; 2908 2909 if (uvm_map(kernel_map, &v, size, NULL, 0, PAGE_SIZE, 2910 UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_SHARE, UVM_ADV_NORMAL, 2911 0)) == 0) { 2912 return sparc_bus_map_iodev(t, ba, size, flags, v, hp); 2913 } 2914 return -1; 2915 } 2916 2917 int 2918 sparc_bus_map(bus_space_tag_t t, bus_addr_t ba, 2919 bus_size_t size, int flags, vaddr_t va, 2920 bus_space_handle_t *hp) 2921 { 2922 2923 if (flags & BUS_SPACE_MAP_LARGE) { 2924 return sparc_bus_map_large(t, ba, size, flags, hp); 2925 } else 2926 return sparc_bus_map_iodev(t, ba, size, flags, va, hp); 2927 2928 } 2929 2930 int 2931 sparc_bus_unmap(bus_space_tag_t t, bus_space_handle_t bh, bus_size_t size) 2932 { 2933 vaddr_t va = trunc_page((vaddr_t)bh); 2934 2935 /* 2936 * XXX 2937 * mappings with BUS_SPACE_MAP_LARGE need additional care here 2938 * we can just check if the VA is in the IODEV range 2939 */ 2940 2941 pmap_kremove(va, round_page(size)); 2942 pmap_update(pmap_kernel()); 2943 return (0); 2944 } 2945 2946 int 2947 sparc_bus_subregion(bus_space_tag_t tag, bus_space_handle_t handle, 2948 bus_size_t offset, bus_size_t size, 2949 bus_space_handle_t *nhandlep) 2950 { 2951 2952 *nhandlep = handle + offset; 2953 return (0); 2954 } 2955 2956 paddr_t 2957 sparc_bus_mmap(bus_space_tag_t t, bus_addr_t ba, off_t off, 2958 int prot, int flags) 2959 { 2960 u_int pmtype; 2961 paddr_t pa; 2962 bus_space_tag_t pt; 2963 2964 /* 2965 * Base class bus mmap function; see also sparc_bus_map 2966 */ 2967 while ((pt = t->parent) != NULL) { 2968 if (t->ranges != NULL) { 2969 int error; 2970 2971 if ((error = bus_space_translate_address_generic( 2972 t->ranges, t->nranges, &ba)) != 0) 2973 return (-1); 2974 } 2975 if (pt->sparc_bus_mmap != sparc_bus_mmap) 2976 return (bus_space_mmap(pt, ba, off, prot, flags)); 2977 t = pt; 2978 } 2979 2980 pmtype = PMAP_IOENC(BUS_ADDR_IOSPACE(ba)); 2981 pa = trunc_page(BUS_ADDR_PADDR(ba) + off); 2982 2983 return (paddr_t)(pa | pmtype | PMAP_NC); 2984 } 2985 2986 /* 2987 * Establish a temporary bus mapping for device probing. 2988 */ 2989 int 2990 bus_space_probe(bus_space_tag_t tag, bus_addr_t paddr, bus_size_t size, 2991 size_t offset, int flags, 2992 int (*callback)(void *, void *), void *arg) 2993 { 2994 bus_space_handle_t bh; 2995 void *tmp; 2996 int result; 2997 2998 if (bus_space_map2(tag, paddr, size, flags, TMPMAP_VA, &bh) != 0) 2999 return (0); 3000 3001 tmp = (void *)bh; 3002 result = (probeget((char *)tmp + offset, size) != -1); 3003 if (result && callback != NULL) 3004 result = (*callback)(tmp, arg); 3005 bus_space_unmap(tag, bh, size); 3006 return (result); 3007 } 3008 3009 3010 void * 3011 sparc_mainbus_intr_establish(bus_space_tag_t t, int pil, int level, 3012 int (*handler)(void *), void *arg, 3013 void (*fastvec)(void)) 3014 { 3015 struct intrhand *ih; 3016 3017 ih = kmem_alloc(sizeof(struct intrhand), KM_SLEEP); 3018 ih->ih_fun = handler; 3019 ih->ih_arg = arg; 3020 intr_establish(pil, level, ih, fastvec, false); 3021 return (ih); 3022 } 3023 3024 void sparc_bus_barrier (bus_space_tag_t t, bus_space_handle_t h, 3025 bus_size_t offset, bus_size_t size, int flags) 3026 { 3027 3028 /* No default barrier action defined */ 3029 return; 3030 } 3031 3032 static uint8_t 3033 sparc_bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 3034 { 3035 3036 return bus_space_read_1_real(t, h, o); 3037 } 3038 3039 static uint16_t 3040 sparc_bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 3041 { 3042 3043 return bus_space_read_2_real(t, h, o); 3044 } 3045 3046 static uint32_t 3047 sparc_bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 3048 { 3049 3050 return bus_space_read_4_real(t, h, o); 3051 } 3052 3053 static uint64_t 3054 sparc_bus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 3055 { 3056 3057 return bus_space_read_8_real(t, h, o); 3058 } 3059 3060 static void 3061 sparc_bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 3062 uint8_t v) 3063 { 3064 3065 bus_space_write_1_real(t, h, o, v); 3066 } 3067 3068 static void 3069 sparc_bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 3070 uint16_t v) 3071 { 3072 3073 bus_space_write_2_real(t, h, o, v); 3074 } 3075 3076 static void 3077 sparc_bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 3078 uint32_t v) 3079 { 3080 3081 bus_space_write_4_real(t, h, o, v); 3082 } 3083 3084 static void 3085 sparc_bus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 3086 uint64_t v) 3087 { 3088 3089 bus_space_write_8_real(t, h, o, v); 3090 } 3091 3092 struct sparc_bus_space_tag mainbus_space_tag = { 3093 NULL, /* cookie */ 3094 NULL, /* parent bus tag */ 3095 NULL, /* ranges */ 3096 0, /* nranges */ 3097 sparc_bus_map, /* bus_space_map */ 3098 sparc_bus_unmap, /* bus_space_unmap */ 3099 sparc_bus_subregion, /* bus_space_subregion */ 3100 sparc_bus_barrier, /* bus_space_barrier */ 3101 sparc_bus_mmap, /* bus_space_mmap */ 3102 sparc_mainbus_intr_establish, /* bus_intr_establish */ 3103 3104 sparc_bus_space_read_1, /* bus_space_read_1 */ 3105 sparc_bus_space_read_2, /* bus_space_read_2 */ 3106 sparc_bus_space_read_4, /* bus_space_read_4 */ 3107 sparc_bus_space_read_8, /* bus_space_read_8 */ 3108 sparc_bus_space_write_1, /* bus_space_write_1 */ 3109 sparc_bus_space_write_2, /* bus_space_write_2 */ 3110 sparc_bus_space_write_4, /* bus_space_write_4 */ 3111 sparc_bus_space_write_8 /* bus_space_write_8 */ 3112 }; 3113 3114 int 3115 mm_md_physacc(paddr_t pa, vm_prot_t prot) 3116 { 3117 3118 return pmap_pa_exists(pa) ? 0 : EFAULT; 3119 } 3120 3121 int 3122 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled) 3123 { 3124 const vaddr_t v = (vaddr_t)ptr; 3125 3126 *handled = (v >= MSGBUF_VA && v < MSGBUF_VA + PAGE_SIZE) || 3127 (v >= prom_vstart && v < prom_vend && (prot & VM_PROT_WRITE) == 0); 3128 return 0; 3129 } 3130 3131 int 3132 mm_md_readwrite(dev_t dev, struct uio *uio) 3133 { 3134 3135 switch (minor(dev)) { 3136 #if defined(SUN4) 3137 case DEV_EEPROM: 3138 if (cputyp == CPU_SUN4) 3139 return eeprom_uio(uio); 3140 #endif 3141 } 3142 return ENXIO; 3143 } 3144