1 /*        $NetBSD: machdep.c,v 1.343 2025/04/24 01:52:38 riastradh 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.343 2025/04/24 01:52:38 riastradh 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
cpu_startup(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
setregs(struct lwp * l,struct exec_package * pack,vaddr_t stack)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
sysctl_machdep_boot(SYSCTLFN_ARGS)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
sendsig_siginfo(const ksiginfo_t * ksi,const sigset_t * mask)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
cpu_getmcontext(struct lwp * l,mcontext_t * mcp,unsigned int * flags)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
cpu_mcontext_validate(struct lwp * l,const mcontext_t * mc)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
cpu_setmcontext(struct lwp * l,const mcontext_t * mcp,unsigned int flags)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
cpu_reboot(int howto,char * user_boot_string)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
cpu_dumpconf(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 *
reserve_dumppages(void * p)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
dumpsys(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
stackdump(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
cpu_exec_aout_makecmds(struct lwp * l,struct exec_package * epp)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
oldmon_w_trace(u_long va)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
oldmon_w_cmd(u_long va,char * ar)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
ldcontrolb(void * addr)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
wzero(void * vb,u_int l)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
wcopy(const void * vb1,void * vb2,u_int l)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 #ifdef MODULAR
1241 void
module_init_md(void)1242 module_init_md(void)
1243 {
1244 }
1245 #endif
1246 
1247 static size_t
_bus_dmamap_mapsize(int const nsegments)1248 _bus_dmamap_mapsize(int const nsegments)
1249 {
1250           KASSERT(nsegments > 0);
1251           return sizeof(struct sparc_bus_dmamap) +
1252               (sizeof(bus_dma_segment_t) * (nsegments - 1));
1253 }
1254 
1255 /*
1256  * Common function for DMA map creation.  May be called by bus-specific
1257  * DMA map creation functions.
1258  */
1259 int
_bus_dmamap_create(bus_dma_tag_t t,bus_size_t size,int nsegments,bus_size_t maxsegsz,bus_size_t boundary,int flags,bus_dmamap_t * dmamp)1260 _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
1261                        bus_size_t maxsegsz, bus_size_t boundary, int flags,
1262                        bus_dmamap_t *dmamp)
1263 {
1264           struct sparc_bus_dmamap *map;
1265           void *mapstore;
1266 
1267           /*
1268            * Allocate and initialize the DMA map.  The end of the map
1269            * is a variable-sized array of segments, so we allocate enough
1270            * room for them in one shot.
1271            *
1272            * Note we don't preserve the WAITOK or NOWAIT flags.  Preservation
1273            * of ALLOCNOW notifies others that we've reserved these resources,
1274            * and they are not to be freed.
1275            *
1276            * The bus_dmamap_t includes one bus_dma_segment_t, hence
1277            * the (nsegments - 1).
1278            */
1279           if ((mapstore = kmem_zalloc(_bus_dmamap_mapsize(nsegments),
1280               (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL)
1281                     return (ENOMEM);
1282 
1283           map = (struct sparc_bus_dmamap *)mapstore;
1284           map->_dm_size = size;
1285           map->_dm_segcnt = nsegments;
1286           map->_dm_maxmaxsegsz = maxsegsz;
1287           map->_dm_boundary = boundary;
1288           map->_dm_align = PAGE_SIZE;
1289           map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
1290           map->dm_maxsegsz = maxsegsz;
1291           map->dm_mapsize = 0;                    /* no valid mappings */
1292           map->dm_nsegs = 0;
1293 
1294           *dmamp = map;
1295           return (0);
1296 }
1297 
1298 /*
1299  * Common function for DMA map destruction.  May be called by bus-specific
1300  * DMA map destruction functions.
1301  */
1302 void
_bus_dmamap_destroy(bus_dma_tag_t t,bus_dmamap_t map)1303 _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
1304 {
1305 
1306           kmem_free(map, _bus_dmamap_mapsize(map->_dm_segcnt));
1307 }
1308 
1309 /*
1310  * Like _bus_dmamap_load(), but for mbufs.
1311  */
1312 int
_bus_dmamap_load_mbuf(bus_dma_tag_t t,bus_dmamap_t map,struct mbuf * m,int flags)1313 _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map,
1314                           struct mbuf *m, int flags)
1315 {
1316 
1317           panic("_bus_dmamap_load_mbuf: not implemented");
1318 }
1319 
1320 /*
1321  * Like _bus_dmamap_load(), but for uios.
1322  */
1323 int
_bus_dmamap_load_uio(bus_dma_tag_t t,bus_dmamap_t map,struct uio * uio,int flags)1324 _bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map,
1325                          struct uio *uio, int flags)
1326 {
1327 
1328           panic("_bus_dmamap_load_uio: not implemented");
1329 }
1330 
1331 /*
1332  * Like _bus_dmamap_load(), but for raw memory allocated with
1333  * bus_dmamem_alloc().
1334  */
1335 int
_bus_dmamap_load_raw(bus_dma_tag_t t,bus_dmamap_t map,bus_dma_segment_t * segs,int nsegs,bus_size_t size,int flags)1336 _bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map,
1337                          bus_dma_segment_t *segs, int nsegs, bus_size_t size,
1338                          int flags)
1339 {
1340 
1341           panic("_bus_dmamap_load_raw: not implemented");
1342 }
1343 
1344 /*
1345  * Common function for DMA map synchronization.  May be called
1346  * by bus-specific DMA map synchronization functions.
1347  */
1348 void
_bus_dmamap_sync(bus_dma_tag_t t,bus_dmamap_t map,bus_addr_t offset,bus_size_t len,int ops)1349 _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map,
1350                      bus_addr_t offset, bus_size_t len, int ops)
1351 {
1352 }
1353 
1354 /*
1355  * Common function for DMA-safe memory allocation.  May be called
1356  * by bus-specific DMA memory allocation functions.
1357  */
1358 int
_bus_dmamem_alloc(bus_dma_tag_t t,bus_size_t size,bus_size_t alignment,bus_size_t boundary,bus_dma_segment_t * segs,int nsegs,int * rsegs,int flags)1359 _bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size,
1360                       bus_size_t alignment, bus_size_t boundary,
1361                       bus_dma_segment_t *segs, int nsegs, int *rsegs,
1362                       int flags)
1363 {
1364           vaddr_t low, high;
1365           struct pglist *mlist;
1366           int error;
1367 
1368           /* Always round the size. */
1369           size = round_page(size);
1370           low = vm_first_phys;
1371           high = vm_first_phys + vm_num_phys - PAGE_SIZE;
1372 
1373           if ((mlist = kmem_alloc(sizeof(*mlist),
1374               (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL)
1375                     return (ENOMEM);
1376 
1377           /*
1378            * Allocate pages from the VM system.
1379            */
1380           error = uvm_pglistalloc(size, low, high, 0, 0,
1381                                         mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
1382           if (error) {
1383                     kmem_free(mlist, sizeof(*mlist));
1384                     return (error);
1385           }
1386 
1387           /*
1388            * Simply keep a pointer around to the linked list, so
1389            * bus_dmamap_free() can return it.
1390            *
1391            * NOBODY SHOULD TOUCH THE pageq.queue FIELDS WHILE THESE PAGES
1392            * ARE IN OUR CUSTODY.
1393            */
1394           segs[0]._ds_mlist = mlist;
1395 
1396           /*
1397            * We now have physical pages, but no DVMA addresses yet. These
1398            * will be allocated in bus_dmamap_load*() routines. Hence we
1399            * save any alignment and boundary requirements in this DMA
1400            * segment.
1401            */
1402           segs[0].ds_addr = 0;
1403           segs[0].ds_len = 0;
1404           segs[0]._ds_va = 0;
1405           *rsegs = 1;
1406           return (0);
1407 }
1408 
1409 /*
1410  * Common function for freeing DMA-safe memory.  May be called by
1411  * bus-specific DMA memory free functions.
1412  */
1413 void
_bus_dmamem_free(bus_dma_tag_t t,bus_dma_segment_t * segs,int nsegs)1414 _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
1415 {
1416           struct pglist *mlist = segs[0]._ds_mlist;
1417 
1418           if (nsegs != 1)
1419                     panic("bus_dmamem_free: nsegs = %d", nsegs);
1420 
1421           /*
1422            * Return the list of pages back to the VM system.
1423            */
1424           uvm_pglistfree(mlist);
1425           kmem_free(mlist, sizeof(*mlist));
1426 }
1427 
1428 /*
1429  * Common function for unmapping DMA-safe memory.  May be called by
1430  * bus-specific DMA memory unmapping functions.
1431  */
1432 void
_bus_dmamem_unmap(bus_dma_tag_t t,void * kva,size_t size)1433 _bus_dmamem_unmap(bus_dma_tag_t t, void *kva, size_t size)
1434 {
1435 
1436 #ifdef DIAGNOSTIC
1437           if ((u_long)kva & PAGE_MASK)
1438                     panic("_bus_dmamem_unmap");
1439 #endif
1440 
1441           size = round_page(size);
1442           pmap_kremove((vaddr_t)kva, size);
1443           pmap_update(pmap_kernel());
1444           uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY);
1445 }
1446 
1447 /*
1448  * Common function for mmap(2)'ing DMA-safe memory.  May be called by
1449  * bus-specific DMA mmap(2)'ing functions.
1450  */
1451 paddr_t
_bus_dmamem_mmap(bus_dma_tag_t t,bus_dma_segment_t * segs,int nsegs,off_t off,int prot,int flags)1452 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
1453                      off_t off, int prot, int flags)
1454 {
1455 
1456           panic("_bus_dmamem_mmap: not implemented");
1457 }
1458 
1459 /*
1460  * Utility to allocate an aligned kernel virtual address range
1461  */
1462 vaddr_t
_bus_dma_valloc_skewed(size_t size,u_long boundary,u_long align,u_long skew)1463 _bus_dma_valloc_skewed(size_t size, u_long boundary, u_long align, u_long skew)
1464 {
1465           size_t oversize;
1466           vaddr_t va, sva;
1467 
1468           /*
1469            * Find a region of kernel virtual addresses that is aligned
1470            * to the given address modulo the requested alignment, i.e.
1471            *
1472            *        (va - skew) == 0 mod align
1473            *
1474            * The following conditions apply to the arguments:
1475            *
1476            *        - `size' must be a multiple of the VM page size
1477            *        - `align' must be a power of two
1478            *           and greater than or equal to the VM page size
1479            *        - `skew' must be smaller than `align'
1480            *        - `size' must be smaller than `boundary'
1481            */
1482 
1483 #ifdef DIAGNOSTIC
1484           if ((size & PAGE_MASK) != 0)
1485                     panic("_bus_dma_valloc_skewed: invalid size %lx", size);
1486           if ((align & PAGE_MASK) != 0)
1487                     panic("_bus_dma_valloc_skewed: invalid alignment %lx", align);
1488           if (align < skew)
1489                     panic("_bus_dma_valloc_skewed: align %lx < skew %lx",
1490                               align, skew);
1491 #endif
1492 
1493           /* XXX - Implement this! */
1494           if (boundary) {
1495                     printf("_bus_dma_valloc_skewed: "
1496                               "boundary check not implemented");
1497                     return (0);
1498           }
1499 
1500           /*
1501            * First, find a region large enough to contain any aligned chunk
1502            */
1503           oversize = size + align - PAGE_SIZE;
1504           sva = vm_map_min(kernel_map);
1505           if (uvm_map(kernel_map, &sva, oversize, NULL, UVM_UNKNOWN_OFFSET,
1506               align, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE,
1507               UVM_ADV_RANDOM, UVM_FLAG_NOWAIT)))
1508                     return (0);
1509 
1510           /*
1511            * Compute start of aligned region
1512            */
1513           va = sva;
1514           va += (skew + align - va) & (align - 1);
1515 
1516           /*
1517            * Return excess virtual addresses
1518            */
1519           if (va != sva)
1520                     (void)uvm_unmap(kernel_map, sva, va);
1521           if (va + size != sva + oversize)
1522                     (void)uvm_unmap(kernel_map, va + size, sva + oversize);
1523 
1524           return (va);
1525 }
1526 
1527 /* sun4/sun4c DMA map functions */
1528 int       sun4_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
1529                                         bus_size_t, struct proc *, int);
1530 int       sun4_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
1531                                         bus_dma_segment_t *, int, bus_size_t, int);
1532 void      sun4_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
1533 int       sun4_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *,
1534                                         int, size_t, void **, int);
1535 
1536 /*
1537  * sun4/sun4c: load DMA map with a linear buffer.
1538  */
1539 int
sun4_dmamap_load(bus_dma_tag_t t,bus_dmamap_t map,void * buf,bus_size_t buflen,struct proc * p,int flags)1540 sun4_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map,
1541                      void *buf, bus_size_t buflen,
1542                      struct proc *p, int flags)
1543 {
1544           bus_size_t sgsize;
1545           vaddr_t va = (vaddr_t)buf;
1546           int pagesz = PAGE_SIZE;
1547           vaddr_t dva;
1548           pmap_t pmap;
1549 
1550           /*
1551            * Make sure that on error condition we return "no valid mappings".
1552            */
1553           map->dm_nsegs = 0;
1554 
1555           if (buflen > map->_dm_size)
1556                     return (EINVAL);
1557 
1558           cache_flush(buf, buflen);
1559 
1560           if ((map->_dm_flags & BUS_DMA_24BIT) == 0) {
1561                     /*
1562                      * XXX Need to implement "don't DMA across this boundary".
1563                      */
1564                     if (map->_dm_boundary != 0) {
1565                               bus_addr_t baddr;
1566 
1567                               /* Calculate first boundary line after `buf' */
1568                               baddr = ((bus_addr_t)va + map->_dm_boundary) &
1569                                                   -map->_dm_boundary;
1570 
1571                               /*
1572                                * If the requested segment crosses the boundary,
1573                                * we can't grant a direct map. For now, steal some
1574                                * space from the `24BIT' map instead.
1575                                *
1576                                * (XXX - no overflow detection here)
1577                                */
1578                               if (buflen > (baddr - (bus_addr_t)va))
1579                                         goto no_fit;
1580                     }
1581                     map->dm_mapsize = buflen;
1582                     map->dm_nsegs = 1;
1583                     map->dm_segs[0].ds_addr = (bus_addr_t)va;
1584                     map->dm_segs[0].ds_len = buflen;
1585                     map->_dm_flags |= _BUS_DMA_DIRECTMAP;
1586                     return (0);
1587           }
1588 
1589 no_fit:
1590           sgsize = round_page(buflen + (va & (pagesz - 1)));
1591 
1592           const vm_flag_t vmflags = VM_BESTFIT |
1593               ((flags & BUS_DMA_NOWAIT) ? VM_NOSLEEP : VM_SLEEP);
1594 
1595           if (vmem_xalloc(dvmamap24, sgsize,
1596                               0,                            /* alignment */
1597                               0,                            /* phase */
1598                               map->_dm_boundary,  /* nocross */
1599                               VMEM_ADDR_MIN,                /* minaddr */
1600                               VMEM_ADDR_MAX,                /* maxaddr */
1601                               vmflags,
1602                               &dva) != 0) {
1603                     return (ENOMEM);
1604           }
1605 
1606           /*
1607            * We always use just one segment.
1608            */
1609           map->dm_mapsize = buflen;
1610           map->dm_segs[0].ds_addr = dva + (va & (pagesz - 1));
1611           map->dm_segs[0].ds_len = buflen;
1612           map->dm_segs[0]._ds_sgsize = sgsize;
1613 
1614           if (p != NULL)
1615                     pmap = p->p_vmspace->vm_map.pmap;
1616           else
1617                     pmap = pmap_kernel();
1618 
1619           for (; buflen > 0; ) {
1620                     paddr_t pa;
1621 
1622                     /*
1623                      * Get the physical address for this page.
1624                      */
1625                     (void) pmap_extract(pmap, va, &pa);
1626 
1627                     /*
1628                      * Compute the segment size, and adjust counts.
1629                      */
1630                     sgsize = pagesz - (va & (pagesz - 1));
1631                     if (buflen < sgsize)
1632                               sgsize = buflen;
1633 
1634 #ifdef notyet
1635 #if defined(SUN4)
1636                     if (have_iocache)
1637                               pa |= PG_IOC;
1638 #endif
1639 #endif
1640                     pmap_kenter_pa(dva, (pa & -pagesz) | PMAP_NC,
1641                         VM_PROT_READ | VM_PROT_WRITE, 0);
1642 
1643                     dva += pagesz;
1644                     va += sgsize;
1645                     buflen -= sgsize;
1646           }
1647           pmap_update(pmap_kernel());
1648 
1649           map->dm_nsegs = 1;
1650           return (0);
1651 }
1652 
1653 /*
1654  * Like _bus_dmamap_load(), but for raw memory allocated with
1655  * bus_dmamem_alloc().
1656  */
1657 int
sun4_dmamap_load_raw(bus_dma_tag_t t,bus_dmamap_t map,bus_dma_segment_t * segs,int nsegs,bus_size_t size,int flags)1658 sun4_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map,
1659                          bus_dma_segment_t *segs, int nsegs, bus_size_t size,
1660                          int flags)
1661 {
1662           struct vm_page *m;
1663           paddr_t pa;
1664           vaddr_t dva;
1665           bus_size_t sgsize;
1666           struct pglist *mlist;
1667           int pagesz = PAGE_SIZE;
1668           int error;
1669 
1670           map->dm_nsegs = 0;
1671           sgsize = (size + pagesz - 1) & -pagesz;
1672 
1673           /* Allocate DVMA addresses */
1674           if ((map->_dm_flags & BUS_DMA_24BIT) != 0) {
1675                     const vm_flag_t vmflags = VM_BESTFIT |
1676                         ((flags & BUS_DMA_NOWAIT) ? VM_NOSLEEP : VM_SLEEP);
1677 
1678                     error = vmem_xalloc(dvmamap24, sgsize,
1679                                             0,                        /* alignment */
1680                                             0,                        /* phase */
1681                                             map->_dm_boundary,        /* nocross */
1682                                             VMEM_ADDR_MIN,  /* minaddr */
1683                                             VMEM_ADDR_MAX,  /* maxaddr */
1684                                             vmflags,
1685                                             &dva);
1686                     if (error)
1687                               return (error);
1688           } else {
1689                     /* Any properly aligned virtual address will do */
1690                     dva = _bus_dma_valloc_skewed(sgsize, map->_dm_boundary,
1691                                                        pagesz, 0);
1692                     if (dva == 0)
1693                               return (ENOMEM);
1694           }
1695 
1696           map->dm_segs[0].ds_addr = dva;
1697           map->dm_segs[0].ds_len = size;
1698           map->dm_segs[0]._ds_sgsize = sgsize;
1699 
1700           /* Map physical pages into IOMMU */
1701           mlist = segs[0]._ds_mlist;
1702           for (m = TAILQ_FIRST(mlist); m != NULL; m = TAILQ_NEXT(m,pageq.queue)) {
1703                     if (sgsize == 0)
1704                               panic("sun4_dmamap_load_raw: size botch");
1705                     pa = VM_PAGE_TO_PHYS(m);
1706 #ifdef notyet
1707 #if defined(SUN4)
1708                     if (have_iocache)
1709                               pa |= PG_IOC;
1710 #endif
1711 #endif
1712                     pmap_kenter_pa(dva, (pa & -pagesz) | PMAP_NC,
1713                         VM_PROT_READ | VM_PROT_WRITE, 0);
1714 
1715                     dva += pagesz;
1716                     sgsize -= pagesz;
1717           }
1718           pmap_update(pmap_kernel());
1719 
1720           map->dm_nsegs = 1;
1721           map->dm_mapsize = size;
1722 
1723           return (0);
1724 }
1725 
1726 /*
1727  * sun4/sun4c function for unloading a DMA map.
1728  */
1729 void
sun4_dmamap_unload(bus_dma_tag_t t,bus_dmamap_t map)1730 sun4_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
1731 {
1732           bus_dma_segment_t *segs = map->dm_segs;
1733           int nsegs = map->dm_nsegs;
1734           int flags = map->_dm_flags;
1735           vaddr_t dva;
1736           bus_size_t len;
1737           int i;
1738 
1739           map->dm_maxsegsz = map->_dm_maxmaxsegsz;
1740 
1741           if ((flags & _BUS_DMA_DIRECTMAP) != 0) {
1742                     /* Nothing to release */
1743                     map->dm_mapsize = 0;
1744                     map->dm_nsegs = 0;
1745                     map->_dm_flags &= ~_BUS_DMA_DIRECTMAP;
1746                     return;
1747           }
1748 
1749           for (i = 0; i < nsegs; i++) {
1750                     dva = segs[i].ds_addr & -PAGE_SIZE;
1751                     len = segs[i]._ds_sgsize;
1752 
1753                     pmap_kremove(dva, len);
1754 
1755                     if ((flags & BUS_DMA_24BIT) != 0) {
1756                               vmem_xfree(dvmamap24, dva, len);
1757                     } else {
1758                               uvm_unmap(kernel_map, dva, dva + len);
1759                     }
1760           }
1761           pmap_update(pmap_kernel());
1762 
1763           /* Mark the mappings as invalid. */
1764           map->dm_mapsize = 0;
1765           map->dm_nsegs = 0;
1766 }
1767 
1768 /*
1769  * Common function for mapping DMA-safe memory.  May be called by
1770  * bus-specific DMA memory map functions.
1771  */
1772 int
sun4_dmamem_map(bus_dma_tag_t t,bus_dma_segment_t * segs,int nsegs,size_t size,void ** kvap,int flags)1773 sun4_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
1774                     size_t size, void **kvap, int flags)
1775 {
1776           struct vm_page *m;
1777           vaddr_t va;
1778           struct pglist *mlist;
1779           const uvm_flag_t kmflags =
1780               (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0;
1781 
1782           if (nsegs != 1)
1783                     panic("sun4_dmamem_map: nsegs = %d", nsegs);
1784 
1785           size = round_page(size);
1786 
1787           va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags);
1788           if (va == 0)
1789                     return (ENOMEM);
1790 
1791           segs[0]._ds_va = va;
1792           *kvap = (void *)va;
1793 
1794           mlist = segs[0]._ds_mlist;
1795           TAILQ_FOREACH(m, mlist, pageq.queue) {
1796                     paddr_t pa;
1797 
1798                     if (size == 0)
1799                               panic("sun4_dmamem_map: size botch");
1800 
1801                     pa = VM_PAGE_TO_PHYS(m);
1802                     pmap_kenter_pa(va, pa | PMAP_NC,
1803                         VM_PROT_READ | VM_PROT_WRITE, 0);
1804 
1805                     va += PAGE_SIZE;
1806                     size -= PAGE_SIZE;
1807           }
1808           pmap_update(pmap_kernel());
1809 
1810           return (0);
1811 }
1812 
1813 
1814 struct sparc_bus_dma_tag mainbus_dma_tag = {
1815           NULL,
1816           _bus_dmamap_create,
1817           _bus_dmamap_destroy,
1818           sun4_dmamap_load,
1819           _bus_dmamap_load_mbuf,
1820           _bus_dmamap_load_uio,
1821           sun4_dmamap_load_raw,
1822           sun4_dmamap_unload,
1823           _bus_dmamap_sync,
1824 
1825           _bus_dmamem_alloc,
1826           _bus_dmamem_free,
1827           sun4_dmamem_map,
1828           _bus_dmamem_unmap,
1829           _bus_dmamem_mmap
1830 };
1831 
1832 
1833 /*
1834  * Base bus space handlers.
1835  */
1836 static int          sparc_bus_map(bus_space_tag_t, bus_addr_t,
1837                                             bus_size_t, int, vaddr_t,
1838                                             bus_space_handle_t *);
1839 static int          sparc_bus_unmap(bus_space_tag_t, bus_space_handle_t,
1840                                              bus_size_t);
1841 static int          sparc_bus_subregion(bus_space_tag_t, bus_space_handle_t,
1842                                                    bus_size_t, bus_size_t,
1843                                                    bus_space_handle_t *);
1844 static paddr_t      sparc_bus_mmap(bus_space_tag_t, bus_addr_t, off_t,
1845                                             int, int);
1846 static void         *sparc_mainbus_intr_establish(bus_space_tag_t, int, int,
1847                                                                int (*)(void *),
1848                                                                void *,
1849                                                                void (*)(void));
1850 static void     sparc_bus_barrier(bus_space_tag_t, bus_space_handle_t,
1851                                                   bus_size_t, bus_size_t, int);
1852 
1853 int
bus_space_map(bus_space_tag_t t,bus_addr_t a,bus_size_t s,int f,bus_space_handle_t * hp)1854 bus_space_map(
1855           bus_space_tag_t     t,
1856           bus_addr_t          a,
1857           bus_size_t          s,
1858           int                 f,
1859           bus_space_handle_t *hp)
1860 {
1861           return (*t->sparc_bus_map)(t, a, s, f, (vaddr_t)0, hp);
1862 }
1863 
1864 int
bus_space_map2(bus_space_tag_t t,bus_addr_t a,bus_size_t s,int f,vaddr_t v,bus_space_handle_t * hp)1865 bus_space_map2(
1866           bus_space_tag_t     t,
1867           bus_addr_t          a,
1868           bus_size_t          s,
1869           int                 f,
1870           vaddr_t             v,
1871           bus_space_handle_t *hp)
1872 {
1873           return (*t->sparc_bus_map)(t, a, s, f, v, hp);
1874 }
1875 
1876 void
bus_space_unmap(bus_space_tag_t t,bus_space_handle_t h,bus_size_t s)1877 bus_space_unmap(
1878           bus_space_tag_t t,
1879           bus_space_handle_t h,
1880           bus_size_t          s)
1881 {
1882           (*t->sparc_bus_unmap)(t, h, s);
1883 }
1884 
1885 int
bus_space_subregion(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,bus_size_t s,bus_space_handle_t * hp)1886 bus_space_subregion(
1887           bus_space_tag_t     t,
1888           bus_space_handle_t h,
1889           bus_size_t          o,
1890           bus_size_t          s,
1891           bus_space_handle_t *hp)
1892 {
1893           return (*t->sparc_bus_subregion)(t, h, o, s, hp);
1894 }
1895 
1896 paddr_t
bus_space_mmap(bus_space_tag_t t,bus_addr_t a,off_t o,int p,int f)1897 bus_space_mmap(
1898           bus_space_tag_t     t,
1899           bus_addr_t          a,
1900           off_t               o,
1901           int                 p,
1902           int                 f)
1903 {
1904           return (*t->sparc_bus_mmap)(t, a, o, p, f);
1905 }
1906 
1907 void *
bus_intr_establish(bus_space_tag_t t,int p,int l,int (* h)(void *),void * a)1908 bus_intr_establish(
1909           bus_space_tag_t t,
1910           int       p,
1911           int       l,
1912           int       (*h)(void *),
1913           void      *a)
1914 {
1915           return (*t->sparc_intr_establish)(t, p, l, h, a, NULL);
1916 }
1917 
1918 void *
bus_intr_establish2(bus_space_tag_t t,int p,int l,int (* h)(void *),void * a,void (* v)(void))1919 bus_intr_establish2(
1920           bus_space_tag_t t,
1921           int       p,
1922           int       l,
1923           int       (*h)(void *),
1924           void      *a,
1925           void      (*v)(void))
1926 {
1927           return (*t->sparc_intr_establish)(t, p, l, h, a, v);
1928 }
1929 
1930 void
bus_space_barrier(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,bus_size_t s,int f)1931 bus_space_barrier(
1932           bus_space_tag_t t,
1933           bus_space_handle_t h,
1934           bus_size_t o,
1935           bus_size_t s,
1936           int f)
1937 {
1938           (*t->sparc_bus_barrier)(t, h, o, s, f);
1939 }
1940 
1941 void
bus_space_write_multi_stream_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t * a,bus_size_t c)1942 bus_space_write_multi_stream_2(
1943           bus_space_tag_t               t,
1944           bus_space_handle_t  h,
1945           bus_size_t                    o,
1946           const uint16_t                *a,
1947           bus_size_t                    c)
1948 {
1949           while (c-- > 0)
1950                     bus_space_write_2_real(t, h, o, *a++);
1951 }
1952 
1953 void
bus_space_write_multi_stream_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t * a,bus_size_t c)1954 bus_space_write_multi_stream_4(
1955           bus_space_tag_t               t,
1956           bus_space_handle_t  h,
1957           bus_size_t                    o,
1958           const uint32_t                *a,
1959           bus_size_t                    c)
1960 {
1961           while (c-- > 0)
1962                     bus_space_write_4_real(t, h, o, *a++);
1963 }
1964 
1965 void
bus_space_write_multi_stream_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t * a,bus_size_t c)1966 bus_space_write_multi_stream_8(
1967           bus_space_tag_t               t,
1968           bus_space_handle_t  h,
1969           bus_size_t                    o,
1970           const uint64_t                *a,
1971           bus_size_t                    c)
1972 {
1973           while (c-- > 0)
1974                     bus_space_write_8_real(t, h, o, *a++);
1975 }
1976 
1977 
1978 /*
1979  *        void bus_space_set_multi_N(bus_space_tag_t tag,
1980  *            bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
1981  *            bus_size_t count);
1982  *
1983  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
1984  * by tag/handle/offset `count' times.
1985  */
1986 void
bus_space_set_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t v,bus_size_t c)1987 bus_space_set_multi_1(
1988           bus_space_tag_t               t,
1989           bus_space_handle_t  h,
1990           bus_size_t                    o,
1991           const uint8_t                 v,
1992           bus_size_t                    c)
1993 {
1994           while (c-- > 0)
1995                     bus_space_write_1(t, h, o, v);
1996 }
1997 
1998 void
bus_space_set_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t v,bus_size_t c)1999 bus_space_set_multi_2(
2000           bus_space_tag_t               t,
2001           bus_space_handle_t  h,
2002           bus_size_t                    o,
2003           const uint16_t                v,
2004           bus_size_t                    c)
2005 {
2006           while (c-- > 0)
2007                     bus_space_write_2(t, h, o, v);
2008 }
2009 
2010 void
bus_space_set_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t v,bus_size_t c)2011 bus_space_set_multi_4(
2012           bus_space_tag_t               t,
2013           bus_space_handle_t  h,
2014           bus_size_t                    o,
2015           const uint32_t                v,
2016           bus_size_t                    c)
2017 {
2018           while (c-- > 0)
2019                     bus_space_write_4(t, h, o, v);
2020 }
2021 
2022 void
bus_space_set_multi_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t v,bus_size_t c)2023 bus_space_set_multi_8(
2024           bus_space_tag_t               t,
2025           bus_space_handle_t  h,
2026           bus_size_t                    o,
2027           const uint64_t                v,
2028           bus_size_t                    c)
2029 {
2030           while (c-- > 0)
2031                     bus_space_write_8(t, h, o, v);
2032 }
2033 
2034 
2035 /*
2036  *        void bus_space_read_region_N(bus_space_tag_t tag,
2037  *            bus_space_handle_t bsh, bus_size_t off,
2038  *            u_intN_t *addr, bus_size_t count);
2039  *
2040  */
2041 void
bus_space_read_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t * a,bus_size_t c)2042 bus_space_read_region_1(
2043           bus_space_tag_t               t,
2044           bus_space_handle_t  h,
2045           bus_size_t                    o,
2046           uint8_t                       *a,
2047           bus_size_t                    c)
2048 {
2049           for (; c; a++, c--, o++)
2050                     *a = bus_space_read_1(t, h, o);
2051 }
2052 
2053 void
bus_space_read_region_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t * a,bus_size_t c)2054 bus_space_read_region_2(
2055           bus_space_tag_t               t,
2056           bus_space_handle_t  h,
2057           bus_size_t                    o,
2058           uint16_t            *a,
2059           bus_size_t                    c)
2060 {
2061           for (; c; a++, c--, o+=2)
2062                     *a = bus_space_read_2(t, h, o);
2063 }
2064 
2065 void
bus_space_read_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t * a,bus_size_t c)2066 bus_space_read_region_4(
2067           bus_space_tag_t               t,
2068           bus_space_handle_t  h,
2069           bus_size_t                    o,
2070           uint32_t            *a,
2071           bus_size_t                    c)
2072 {
2073           for (; c; a++, c--, o+=4)
2074                     *a = bus_space_read_4(t, h, o);
2075 }
2076 
2077 void
bus_space_read_region_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t * a,bus_size_t c)2078 bus_space_read_region_8(
2079           bus_space_tag_t               t,
2080           bus_space_handle_t  h,
2081           bus_size_t                    o,
2082           uint64_t            *a,
2083           bus_size_t                    c)
2084 {
2085           for (; c; a++, c--, o+=8)
2086                     *a = bus_space_read_8(t, h, o);
2087 }
2088 
2089 /*
2090  *        void bus_space_write_region_N(bus_space_tag_t tag,
2091  *            bus_space_handle_t bsh, bus_size_t off,
2092  *            u_intN_t *addr, bus_size_t count);
2093  *
2094  */
2095 void
bus_space_write_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t * a,bus_size_t c)2096 bus_space_write_region_1(
2097           bus_space_tag_t               t,
2098           bus_space_handle_t  h,
2099           bus_size_t                    o,
2100           const uint8_t                 *a,
2101           bus_size_t                    c)
2102 {
2103           for (; c; a++, c--, o++)
2104                     bus_space_write_1(t, h, o, *a);
2105 }
2106 
2107 void
bus_space_write_region_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t * a,bus_size_t c)2108 bus_space_write_region_2(
2109           bus_space_tag_t               t,
2110           bus_space_handle_t  h,
2111           bus_size_t                    o,
2112           const uint16_t                *a,
2113           bus_size_t                    c)
2114 {
2115           for (; c; a++, c--, o+=2)
2116                     bus_space_write_2(t, h, o, *a);
2117 }
2118 
2119 void
bus_space_write_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t * a,bus_size_t c)2120 bus_space_write_region_4(
2121           bus_space_tag_t               t,
2122           bus_space_handle_t  h,
2123           bus_size_t                    o,
2124           const uint32_t                *a,
2125           bus_size_t                    c)
2126 {
2127           for (; c; a++, c--, o+=4)
2128                     bus_space_write_4(t, h, o, *a);
2129 }
2130 
2131 void
bus_space_write_region_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t * a,bus_size_t c)2132 bus_space_write_region_8(
2133           bus_space_tag_t               t,
2134           bus_space_handle_t  h,
2135           bus_size_t                    o,
2136           const uint64_t                *a,
2137           bus_size_t                    c)
2138 {
2139           for (; c; a++, c--, o+=8)
2140                     bus_space_write_8(t, h, o, *a);
2141 }
2142 
2143 
2144 /*
2145  *        void bus_space_set_region_N(bus_space_tag_t tag,
2146  *            bus_space_handle_t bsh, bus_size_t off,
2147  *            u_intN_t *addr, bus_size_t count);
2148  *
2149  */
2150 void
bus_space_set_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t v,bus_size_t c)2151 bus_space_set_region_1(
2152           bus_space_tag_t               t,
2153           bus_space_handle_t  h,
2154           bus_size_t                    o,
2155           const uint8_t                 v,
2156           bus_size_t                    c)
2157 {
2158           for (; c; c--, o++)
2159                     bus_space_write_1(t, h, o, v);
2160 }
2161 
2162 void
bus_space_set_region_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t v,bus_size_t c)2163 bus_space_set_region_2(
2164           bus_space_tag_t               t,
2165           bus_space_handle_t  h,
2166           bus_size_t                    o,
2167           const uint16_t                v,
2168           bus_size_t                    c)
2169 {
2170           for (; c; c--, o+=2)
2171                     bus_space_write_2(t, h, o, v);
2172 }
2173 
2174 void
bus_space_set_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t v,bus_size_t c)2175 bus_space_set_region_4(
2176           bus_space_tag_t               t,
2177           bus_space_handle_t  h,
2178           bus_size_t                    o,
2179           const uint32_t                v,
2180           bus_size_t                    c)
2181 {
2182           for (; c; c--, o+=4)
2183                     bus_space_write_4(t, h, o, v);
2184 }
2185 
2186 void
bus_space_set_region_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t v,bus_size_t c)2187 bus_space_set_region_8(
2188           bus_space_tag_t               t,
2189           bus_space_handle_t  h,
2190           bus_size_t                    o,
2191           const uint64_t                v,
2192           bus_size_t                    c)
2193 {
2194           for (; c; c--, o+=8)
2195                     bus_space_write_8(t, h, o, v);
2196 }
2197 
2198 
2199 /*
2200  *        void bus_space_copy_region_N(bus_space_tag_t tag,
2201  *            bus_space_handle_t bsh1, bus_size_t off1,
2202  *            bus_space_handle_t bsh2, bus_size_t off2,
2203  *            bus_size_t count);
2204  *
2205  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
2206  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
2207  */
2208 void
bus_space_copy_region_1(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2209 bus_space_copy_region_1(
2210           bus_space_tag_t               t,
2211           bus_space_handle_t  h1,
2212           bus_size_t                    o1,
2213           bus_space_handle_t  h2,
2214           bus_size_t                    o2,
2215           bus_size_t                    c)
2216 {
2217           for (; c; c--, o1++, o2++)
2218               bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2));
2219 }
2220 
2221 void
bus_space_copy_region_2(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2222 bus_space_copy_region_2(
2223           bus_space_tag_t               t,
2224           bus_space_handle_t  h1,
2225           bus_size_t                    o1,
2226           bus_space_handle_t  h2,
2227           bus_size_t                    o2,
2228           bus_size_t                    c)
2229 {
2230           for (; c; c--, o1+=2, o2+=2)
2231               bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2));
2232 }
2233 
2234 void
bus_space_copy_region_4(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2235 bus_space_copy_region_4(
2236           bus_space_tag_t               t,
2237           bus_space_handle_t  h1,
2238           bus_size_t                    o1,
2239           bus_space_handle_t  h2,
2240           bus_size_t                    o2,
2241           bus_size_t                    c)
2242 {
2243           for (; c; c--, o1+=4, o2+=4)
2244               bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2));
2245 }
2246 
2247 void
bus_space_copy_region_8(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2248 bus_space_copy_region_8(
2249           bus_space_tag_t               t,
2250           bus_space_handle_t  h1,
2251           bus_size_t                    o1,
2252           bus_space_handle_t  h2,
2253           bus_size_t                    o2,
2254           bus_size_t                    c)
2255 {
2256           for (; c; c--, o1+=8, o2+=8)
2257               bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2));
2258 }
2259 
2260 /*
2261  *        void bus_space_read_region_stream_N(bus_space_tag_t tag,
2262  *            bus_space_handle_t bsh, bus_size_t off,
2263  *            u_intN_t *addr, bus_size_t count);
2264  *
2265  */
2266 void
bus_space_read_region_stream_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t * a,bus_size_t c)2267 bus_space_read_region_stream_1(
2268           bus_space_tag_t               t,
2269           bus_space_handle_t  h,
2270           bus_size_t                    o,
2271           uint8_t                       *a,
2272           bus_size_t                    c)
2273 {
2274           for (; c; a++, c--, o++)
2275                     *a = bus_space_read_stream_1(t, h, o);
2276 }
2277 void
bus_space_read_region_stream_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t * a,bus_size_t c)2278 bus_space_read_region_stream_2(
2279           bus_space_tag_t               t,
2280           bus_space_handle_t  h,
2281           bus_size_t                    o,
2282           uint16_t            *a,
2283           bus_size_t                    c)
2284 {
2285           for (; c; a++, c--, o+=2)
2286                     *a = bus_space_read_stream_2(t, h, o);
2287  }
2288 void
bus_space_read_region_stream_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t * a,bus_size_t c)2289 bus_space_read_region_stream_4(
2290           bus_space_tag_t               t,
2291           bus_space_handle_t  h,
2292           bus_size_t                    o,
2293           uint32_t            *a,
2294           bus_size_t                    c)
2295 {
2296           for (; c; a++, c--, o+=4)
2297                     *a = bus_space_read_stream_4(t, h, o);
2298 }
2299 void
bus_space_read_region_stream_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t * a,bus_size_t c)2300 bus_space_read_region_stream_8(
2301           bus_space_tag_t               t,
2302           bus_space_handle_t  h,
2303           bus_size_t                    o,
2304           uint64_t            *a,
2305           bus_size_t                    c)
2306 {
2307           for (; c; a++, c--, o+=8)
2308                     *a = bus_space_read_stream_8(t, h, o);
2309 }
2310 
2311 /*
2312  *        void bus_space_write_region_stream_N(bus_space_tag_t tag,
2313  *            bus_space_handle_t bsh, bus_size_t off,
2314  *            u_intN_t *addr, bus_size_t count);
2315  *
2316  */
2317 void
bus_space_write_region_stream_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t * a,bus_size_t c)2318 bus_space_write_region_stream_1(
2319           bus_space_tag_t               t,
2320           bus_space_handle_t  h,
2321           bus_size_t                    o,
2322           const uint8_t                 *a,
2323           bus_size_t                    c)
2324 {
2325           for (; c; a++, c--, o++)
2326                     bus_space_write_stream_1(t, h, o, *a);
2327 }
2328 
2329 void
bus_space_write_region_stream_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t * a,bus_size_t c)2330 bus_space_write_region_stream_2(
2331           bus_space_tag_t               t,
2332           bus_space_handle_t  h,
2333           bus_size_t                    o,
2334           const uint16_t                *a,
2335           bus_size_t                    c)
2336 {
2337           for (; c; a++, c--, o+=2)
2338                     bus_space_write_stream_2(t, h, o, *a);
2339 }
2340 
2341 void
bus_space_write_region_stream_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t * a,bus_size_t c)2342 bus_space_write_region_stream_4(
2343           bus_space_tag_t               t,
2344           bus_space_handle_t  h,
2345           bus_size_t                    o,
2346           const uint32_t                *a,
2347           bus_size_t                    c)
2348 {
2349           for (; c; a++, c--, o+=4)
2350                     bus_space_write_stream_4(t, h, o, *a);
2351 }
2352 
2353 void
bus_space_write_region_stream_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t * a,bus_size_t c)2354 bus_space_write_region_stream_8(
2355           bus_space_tag_t               t,
2356           bus_space_handle_t  h,
2357           bus_size_t                    o,
2358           const uint64_t                *a,
2359           bus_size_t                    c)
2360 {
2361           for (; c; a++, c--, o+=8)
2362                     bus_space_write_stream_8(t, h, o, *a);
2363 }
2364 
2365 
2366 /*
2367  *        void bus_space_set_region_stream_N(bus_space_tag_t tag,
2368  *            bus_space_handle_t bsh, bus_size_t off,
2369  *            u_intN_t *addr, bus_size_t count);
2370  *
2371  */
2372 void
bus_space_set_region_stream_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t v,bus_size_t c)2373 bus_space_set_region_stream_1(
2374           bus_space_tag_t               t,
2375           bus_space_handle_t  h,
2376           bus_size_t                    o,
2377           const uint8_t                 v,
2378           bus_size_t                    c)
2379 {
2380           for (; c; c--, o++)
2381                     bus_space_write_stream_1(t, h, o, v);
2382 }
2383 
2384 void
bus_space_set_region_stream_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t v,bus_size_t c)2385 bus_space_set_region_stream_2(
2386           bus_space_tag_t               t,
2387           bus_space_handle_t  h,
2388           bus_size_t                    o,
2389           const uint16_t                v,
2390           bus_size_t                    c)
2391 {
2392           for (; c; c--, o+=2)
2393                     bus_space_write_stream_2(t, h, o, v);
2394 }
2395 
2396 void
bus_space_set_region_stream_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t v,bus_size_t c)2397 bus_space_set_region_stream_4(
2398           bus_space_tag_t               t,
2399           bus_space_handle_t  h,
2400           bus_size_t                    o,
2401           const uint32_t                v,
2402           bus_size_t                    c)
2403 {
2404           for (; c; c--, o+=4)
2405                     bus_space_write_stream_4(t, h, o, v);
2406 }
2407 
2408 void
bus_space_set_region_stream_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t v,bus_size_t c)2409 bus_space_set_region_stream_8(
2410           bus_space_tag_t               t,
2411           bus_space_handle_t  h,
2412           bus_size_t                    o,
2413           const uint64_t                v,
2414           bus_size_t                    c)
2415 {
2416           for (; c; c--, o+=8)
2417                     bus_space_write_stream_8(t, h, o, v);
2418 }
2419 
2420 /*
2421  *        void bus_space_copy_region_stream_N(bus_space_tag_t tag,
2422  *            bus_space_handle_t bsh1, bus_size_t off1,
2423  *            bus_space_handle_t bsh2, bus_size_t off2,
2424  *            bus_size_t count);
2425  *
2426  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
2427  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
2428  */
2429 
2430 void
bus_space_copy_region_stream_1(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2431 bus_space_copy_region_stream_1(
2432           bus_space_tag_t               t,
2433           bus_space_handle_t  h1,
2434           bus_size_t                    o1,
2435           bus_space_handle_t  h2,
2436           bus_size_t                    o2,
2437           bus_size_t                    c)
2438 {
2439           for (; c; c--, o1++, o2++)
2440               bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2, o2));
2441 }
2442 
2443 void
bus_space_copy_region_stream_2(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2444 bus_space_copy_region_stream_2(
2445           bus_space_tag_t               t,
2446           bus_space_handle_t  h1,
2447           bus_size_t                    o1,
2448           bus_space_handle_t  h2,
2449           bus_size_t                    o2,
2450           bus_size_t                    c)
2451 {
2452           for (; c; c--, o1+=2, o2+=2)
2453               bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2, o2));
2454 }
2455 
2456 void
bus_space_copy_region_stream_4(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2457 bus_space_copy_region_stream_4(
2458           bus_space_tag_t               t,
2459           bus_space_handle_t  h1,
2460           bus_size_t                    o1,
2461           bus_space_handle_t  h2,
2462           bus_size_t                    o2,
2463           bus_size_t                    c)
2464 {
2465           for (; c; c--, o1+=4, o2+=4)
2466               bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2, o2));
2467 }
2468 
2469 void
bus_space_copy_region_stream_8(bus_space_tag_t t,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)2470 bus_space_copy_region_stream_8(
2471           bus_space_tag_t               t,
2472           bus_space_handle_t  h1,
2473           bus_size_t                    o1,
2474           bus_space_handle_t  h2,
2475           bus_size_t                    o2,
2476           bus_size_t                    c)
2477 {
2478           for (; c; c--, o1+=8, o2+=8)
2479               bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2));
2480 }
2481 
2482 void
bus_space_write_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t v)2483 bus_space_write_1(
2484           bus_space_tag_t               t,
2485           bus_space_handle_t  h,
2486           bus_size_t                    o,
2487           uint8_t                       v)
2488 {
2489           (*t->sparc_write_1)(t, h, o, v);
2490 }
2491 
2492 void
bus_space_write_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t v)2493 bus_space_write_2(
2494           bus_space_tag_t               t,
2495           bus_space_handle_t  h,
2496           bus_size_t                    o,
2497           uint16_t            v)
2498 {
2499           (*t->sparc_write_2)(t, h, o, v);
2500 }
2501 
2502 void
bus_space_write_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t v)2503 bus_space_write_4(
2504           bus_space_tag_t               t,
2505           bus_space_handle_t  h,
2506           bus_size_t                    o,
2507           uint32_t            v)
2508 {
2509           (*t->sparc_write_4)(t, h, o, v);
2510 }
2511 
2512 void
bus_space_write_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t v)2513 bus_space_write_8(
2514           bus_space_tag_t               t,
2515           bus_space_handle_t  h,
2516           bus_size_t                    o,
2517           uint64_t            v)
2518 {
2519           (*t->sparc_write_8)(t, h, o, v);
2520 }
2521 
2522 #if __SLIM_SPARC_BUS_SPACE
2523 
2524 void
bus_space_write_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t v)2525 bus_space_write_1(
2526           bus_space_tag_t               t,
2527           bus_space_handle_t  h,
2528           bus_size_t                    o,
2529           uint8_t                       v)
2530 {
2531           __insn_barrier();
2532           bus_space_write_1_real(t, h, o, v);
2533 }
2534 
2535 void
bus_space_write_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t v)2536 bus_space_write_2(
2537           bus_space_tag_t               t,
2538           bus_space_handle_t  h,
2539           bus_size_t                    o,
2540           uint16_t            v)
2541 {
2542           __insn_barrier();
2543           bus_space_write_2_real(t, h, o, v);
2544 }
2545 
2546 void
bus_space_write_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t v)2547 bus_space_write_4(
2548           bus_space_tag_t               t,
2549           bus_space_handle_t  h,
2550           bus_size_t                    o,
2551           uint32_t            v)
2552 {
2553           __insn_barrier();
2554           bus_space_write_4_real(t, h, o, v);
2555 }
2556 
2557 void
bus_space_write_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t v)2558 bus_space_write_8(
2559           bus_space_tag_t               t,
2560           bus_space_handle_t  h,
2561           bus_size_t                    o,
2562           uint64_t            v)
2563 {
2564           __insn_barrier();
2565           bus_space_write_8_real(t, h, o, v);
2566 }
2567 
2568 #endif /* __SLIM_SPARC_BUS_SPACE */
2569 
2570 uint8_t
bus_space_read_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2571 bus_space_read_1(
2572           bus_space_tag_t               t,
2573           bus_space_handle_t  h,
2574           bus_size_t                    o)
2575 {
2576           return (*t->sparc_read_1)(t, h, o);
2577 }
2578 
2579 uint16_t
bus_space_read_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2580 bus_space_read_2(
2581           bus_space_tag_t               t,
2582           bus_space_handle_t  h,
2583           bus_size_t                    o)
2584 {
2585           return (*t->sparc_read_2)(t, h, o);
2586 }
2587 
2588 uint32_t
bus_space_read_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2589 bus_space_read_4(
2590           bus_space_tag_t               t,
2591           bus_space_handle_t  h,
2592           bus_size_t                    o)
2593 {
2594           return (*t->sparc_read_4)(t, h, o);
2595 }
2596 
2597 uint64_t
bus_space_read_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2598 bus_space_read_8(
2599           bus_space_tag_t               t,
2600           bus_space_handle_t  h,
2601           bus_size_t                    o)
2602 {
2603           return (*t->sparc_read_8)(t, h, o);
2604 }
2605 
2606 #if __SLIM_SPARC_BUS_SPACE
2607 uint8_t
bus_space_read_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2608 bus_space_read_1(
2609           bus_space_tag_t               t,
2610           bus_space_handle_t  h,
2611           bus_size_t                    o)
2612 {
2613           __insn_barrier();
2614           return bus_space_read_1_real(t, h, o);
2615 }
2616 
2617 uint16_t
bus_space_read_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2618 bus_space_read_2(
2619           bus_space_tag_t               t,
2620           bus_space_handle_t  h,
2621           bus_size_t                    o)
2622 {
2623           __insn_barrier();
2624           return bus_space_read_2_real(t, h, o);
2625 }
2626 
2627 uint32_t
bus_space_read_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2628 bus_space_read_4(
2629           bus_space_tag_t               t,
2630           bus_space_handle_t  h,
2631           bus_size_t                    o)
2632 {
2633           __insn_barrier();
2634           return bus_space_read_4_real(t, h, o);
2635 }
2636 
2637 uint64_t
bus_space_read_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)2638 bus_space_read_8(
2639           bus_space_tag_t               t,
2640           bus_space_handle_t  h,
2641           bus_size_t                    o)
2642 {
2643           __insn_barrier();
2644           return bus_space_read_8_real(t, h, o);
2645 }
2646 
2647 #endif /* __SLIM_SPARC_BUS_SPACE */
2648 
2649 void
bus_space_read_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t * a,bus_size_t c)2650 bus_space_read_multi_1(
2651           bus_space_tag_t               t,
2652           bus_space_handle_t  h,
2653           bus_size_t                    o,
2654           uint8_t                       *a,
2655           bus_size_t                    c)
2656 {
2657           while (c-- > 0)
2658                     *a++ = bus_space_read_1(t, h, o);
2659 }
2660 
2661 void
bus_space_read_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t * a,bus_size_t c)2662 bus_space_read_multi_2(
2663           bus_space_tag_t               t,
2664           bus_space_handle_t  h,
2665           bus_size_t                    o,
2666           uint16_t            *a,
2667           bus_size_t                    c)
2668 {
2669           while (c-- > 0)
2670                     *a++ = bus_space_read_2(t, h, o);
2671 }
2672 
2673 void
bus_space_read_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t * a,bus_size_t c)2674 bus_space_read_multi_4(
2675           bus_space_tag_t               t,
2676           bus_space_handle_t  h,
2677           bus_size_t                    o,
2678           uint32_t            *a,
2679           bus_size_t                    c)
2680 {
2681           while (c-- > 0)
2682                     *a++ = bus_space_read_4(t, h, o);
2683 }
2684 
2685 void
bus_space_read_multi_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t * a,bus_size_t c)2686 bus_space_read_multi_8(
2687           bus_space_tag_t               t,
2688           bus_space_handle_t  h,
2689           bus_size_t                    o,
2690           uint64_t            *a,
2691           bus_size_t                    c)
2692 {
2693           while (c-- > 0)
2694                     *a++ = bus_space_read_8(t, h, o);
2695 }
2696 
2697 /*
2698  *        void bus_space_read_multi_N(bus_space_tag_t tag,
2699  *            bus_space_handle_t bsh, bus_size_t offset,
2700  *            u_intN_t *addr, bus_size_t count);
2701  *
2702  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
2703  * described by tag/handle/offset and copy into buffer provided.
2704  */
2705 void
bus_space_read_multi_stream_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t * a,bus_size_t c)2706 bus_space_read_multi_stream_2(
2707           bus_space_tag_t               t,
2708           bus_space_handle_t  h,
2709           bus_size_t                    o,
2710           uint16_t            *a,
2711           bus_size_t                    c)
2712 {
2713           while (c-- > 0)
2714                     *a++ = bus_space_read_2_real(t, h, o);
2715 }
2716 
2717 void
bus_space_read_multi_stream_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t * a,bus_size_t c)2718 bus_space_read_multi_stream_4(
2719           bus_space_tag_t               t,
2720           bus_space_handle_t  h,
2721           bus_size_t                    o,
2722           uint32_t            *a,
2723           bus_size_t                    c)
2724 {
2725           while (c-- > 0)
2726                     *a++ = bus_space_read_4_real(t, h, o);
2727 }
2728 
2729 void
bus_space_read_multi_stream_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t * a,bus_size_t c)2730 bus_space_read_multi_stream_8(
2731           bus_space_tag_t               t,
2732           bus_space_handle_t  h,
2733           bus_size_t                    o,
2734           uint64_t            *a,
2735           bus_size_t                    c)
2736 {
2737           while (c-- > 0)
2738                     *a++ = bus_space_read_8_real(t, h, o);
2739 }
2740 
2741 /*
2742  *        void bus_space_write_multi_N(bus_space_tag_t tag,
2743  *            bus_space_handle_t bsh, bus_size_t offset,
2744  *            const u_intN_t *addr, bus_size_t count);
2745  *
2746  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
2747  * provided to bus space described by tag/handle/offset.
2748  */
2749 void
bus_space_write_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t * a,bus_size_t c)2750 bus_space_write_multi_1(
2751           bus_space_tag_t               t,
2752           bus_space_handle_t  h,
2753           bus_size_t                    o,
2754           const uint8_t                 *a,
2755           bus_size_t                    c)
2756 {
2757           while (c-- > 0)
2758                     bus_space_write_1(t, h, o, *a++);
2759 }
2760 
2761 void
bus_space_write_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t * a,bus_size_t c)2762 bus_space_write_multi_2(
2763           bus_space_tag_t               t,
2764           bus_space_handle_t  h,
2765           bus_size_t                    o,
2766           const uint16_t                *a,
2767           bus_size_t                    c)
2768 {
2769           while (c-- > 0)
2770                     bus_space_write_2(t, h, o, *a++);
2771 }
2772 
2773 void
bus_space_write_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t * a,bus_size_t c)2774 bus_space_write_multi_4(
2775           bus_space_tag_t               t,
2776           bus_space_handle_t  h,
2777           bus_size_t                    o,
2778           const uint32_t                *a,
2779           bus_size_t                    c)
2780 {
2781           while (c-- > 0)
2782                     bus_space_write_4(t, h, o, *a++);
2783 }
2784 
2785 void
bus_space_write_multi_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t * a,bus_size_t c)2786 bus_space_write_multi_8(
2787           bus_space_tag_t               t,
2788           bus_space_handle_t  h,
2789           bus_size_t                    o,
2790           const uint64_t                *a,
2791           bus_size_t                    c)
2792 {
2793           while (c-- > 0)
2794                     bus_space_write_8(t, h, o, *a++);
2795 }
2796 
2797 /*
2798  * Allocate a new bus tag and have it inherit the methods of the
2799  * given parent.
2800  */
2801 bus_space_tag_t
bus_space_tag_alloc(bus_space_tag_t parent,void * cookie)2802 bus_space_tag_alloc(bus_space_tag_t parent, void *cookie)
2803 {
2804           struct sparc_bus_space_tag *sbt;
2805 
2806           sbt = kmem_zalloc(sizeof(*sbt), KM_SLEEP);
2807 
2808           if (parent) {
2809                     memcpy(sbt, parent, sizeof(*sbt));
2810                     sbt->parent = parent;
2811                     sbt->ranges = NULL;
2812                     sbt->nranges = 0;
2813           }
2814 
2815           sbt->cookie = cookie;
2816           return (sbt);
2817 }
2818 
2819 /*
2820  * Generic routine to translate an address using OpenPROM `ranges'.
2821  */
2822 int
bus_space_translate_address_generic(struct openprom_range * ranges,int nranges,bus_addr_t * bap)2823 bus_space_translate_address_generic(struct openprom_range *ranges, int nranges,
2824     bus_addr_t *bap)
2825 {
2826           int i, space = BUS_ADDR_IOSPACE(*bap);
2827 
2828           for (i = 0; i < nranges; i++) {
2829                     struct openprom_range *rp = &ranges[i];
2830 
2831                     if (rp->or_child_space != space)
2832                               continue;
2833 
2834                     /* We've found the connection to the parent bus. */
2835                     *bap = BUS_ADDR(rp->or_parent_space,
2836                         rp->or_parent_base + BUS_ADDR_PADDR(*bap));
2837                     return (0);
2838           }
2839 
2840           return (EINVAL);
2841 }
2842 
2843 static int
sparc_bus_map_iodev(bus_space_tag_t t,bus_addr_t ba,bus_size_t size,int flags,vaddr_t va,bus_space_handle_t * hp)2844 sparc_bus_map_iodev(bus_space_tag_t t, bus_addr_t ba, bus_size_t size, int flags,
2845                 vaddr_t va, bus_space_handle_t *hp)
2846 {
2847           vaddr_t v;
2848           paddr_t pa;
2849           unsigned int pmtype;
2850           bus_space_tag_t pt;
2851 static    vaddr_t iobase;
2852 
2853           /*
2854            * This base class bus map function knows about address range
2855            * translation so bus drivers that need no other special
2856            * handling can just keep this method in their tags.
2857            *
2858            * We expect to resolve range translations iteratively, but allow
2859            * for recursion just in case.
2860            */
2861           while ((pt = t->parent) != NULL) {
2862                     if (t->ranges != NULL) {
2863                               int error;
2864 
2865                               if ((error = bus_space_translate_address_generic(
2866                                                   t->ranges, t->nranges, &ba)) != 0)
2867                                         return (error);
2868                     }
2869                     if (pt->sparc_bus_map != sparc_bus_map)
2870                               return (bus_space_map2(pt, ba, size, flags, va, hp));
2871                     t = pt;
2872           }
2873 
2874           if (iobase == 0)
2875                     iobase = IODEV_BASE;
2876 
2877           size = round_page(size);
2878           if (size == 0) {
2879                     printf("sparc_bus_map: zero size\n");
2880                     return (EINVAL);
2881           }
2882 
2883           if (va)
2884                     v = trunc_page(va);
2885           else {
2886                     v = iobase;
2887                     iobase += size;
2888                     if (iobase > IODEV_END)       /* unlikely */
2889                               panic("sparc_bus_map: iobase=0x%lx", iobase);
2890           }
2891 
2892           pmtype = PMAP_IOENC(BUS_ADDR_IOSPACE(ba));
2893           pa = BUS_ADDR_PADDR(ba);
2894 
2895           /* note: preserve page offset */
2896           *hp = (bus_space_handle_t)(v | ((u_long)pa & PGOFSET));
2897 
2898           pa = trunc_page(pa);
2899           do {
2900                     pmap_kenter_pa(v, pa | pmtype | PMAP_NC,
2901                         VM_PROT_READ | VM_PROT_WRITE, 0);
2902                     v += PAGE_SIZE;
2903                     pa += PAGE_SIZE;
2904           } while ((size -= PAGE_SIZE) > 0);
2905 
2906           pmap_update(pmap_kernel());
2907           return (0);
2908 }
2909 
2910 static int
sparc_bus_map_large(bus_space_tag_t t,bus_addr_t ba,bus_size_t size,int flags,bus_space_handle_t * hp)2911 sparc_bus_map_large(bus_space_tag_t t, bus_addr_t ba,
2912                         bus_size_t size, int flags, bus_space_handle_t *hp)
2913 {
2914           vaddr_t v = 0;
2915 
2916           if (uvm_map(kernel_map, &v, size, NULL, 0, PAGE_SIZE,
2917               UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_SHARE, UVM_ADV_NORMAL,
2918                               0)) == 0) {
2919                     return sparc_bus_map_iodev(t, ba, size, flags, v, hp);
2920           }
2921           return -1;
2922 }
2923 
2924 int
sparc_bus_map(bus_space_tag_t t,bus_addr_t ba,bus_size_t size,int flags,vaddr_t va,bus_space_handle_t * hp)2925 sparc_bus_map(bus_space_tag_t t, bus_addr_t ba,
2926                         bus_size_t size, int flags, vaddr_t va,
2927                         bus_space_handle_t *hp)
2928 {
2929 
2930           if (flags & BUS_SPACE_MAP_LARGE) {
2931                     return sparc_bus_map_large(t, ba, size, flags, hp);
2932           } else
2933                     return sparc_bus_map_iodev(t, ba, size, flags, va, hp);
2934 
2935 }
2936 
2937 int
sparc_bus_unmap(bus_space_tag_t t,bus_space_handle_t bh,bus_size_t size)2938 sparc_bus_unmap(bus_space_tag_t t, bus_space_handle_t bh, bus_size_t size)
2939 {
2940           vaddr_t va = trunc_page((vaddr_t)bh);
2941 
2942           /*
2943            * XXX
2944            * mappings with BUS_SPACE_MAP_LARGE need additional care here
2945            * we can just check if the VA is in the IODEV range
2946            */
2947 
2948           pmap_kremove(va, round_page(size));
2949           pmap_update(pmap_kernel());
2950           return (0);
2951 }
2952 
2953 int
sparc_bus_subregion(bus_space_tag_t tag,bus_space_handle_t handle,bus_size_t offset,bus_size_t size,bus_space_handle_t * nhandlep)2954 sparc_bus_subregion(bus_space_tag_t tag, bus_space_handle_t handle,
2955                         bus_size_t offset, bus_size_t size,
2956                         bus_space_handle_t *nhandlep)
2957 {
2958 
2959           *nhandlep = handle + offset;
2960           return (0);
2961 }
2962 
2963 paddr_t
sparc_bus_mmap(bus_space_tag_t t,bus_addr_t ba,off_t off,int prot,int flags)2964 sparc_bus_mmap(bus_space_tag_t t, bus_addr_t ba, off_t off,
2965                  int prot, int flags)
2966 {
2967           u_int pmtype;
2968           paddr_t pa;
2969           bus_space_tag_t pt;
2970 
2971           /*
2972            * Base class bus mmap function; see also sparc_bus_map
2973            */
2974           while ((pt = t->parent) != NULL) {
2975                     if (t->ranges != NULL) {
2976                               int error;
2977 
2978                               if ((error = bus_space_translate_address_generic(
2979                                                   t->ranges, t->nranges, &ba)) != 0)
2980                                         return (-1);
2981                     }
2982                     if (pt->sparc_bus_mmap != sparc_bus_mmap)
2983                               return (bus_space_mmap(pt, ba, off, prot, flags));
2984                     t = pt;
2985           }
2986 
2987           pmtype = PMAP_IOENC(BUS_ADDR_IOSPACE(ba));
2988           pa = trunc_page(BUS_ADDR_PADDR(ba) + off);
2989 
2990           return (paddr_t)(pa | pmtype | PMAP_NC);
2991 }
2992 
2993 /*
2994  * Establish a temporary bus mapping for device probing.
2995  */
2996 int
bus_space_probe(bus_space_tag_t tag,bus_addr_t paddr,bus_size_t size,size_t offset,int flags,int (* callback)(void *,void *),void * arg)2997 bus_space_probe(bus_space_tag_t tag, bus_addr_t paddr, bus_size_t size,
2998                     size_t offset, int flags,
2999                     int (*callback)(void *, void *), void *arg)
3000 {
3001           bus_space_handle_t bh;
3002           void *tmp;
3003           int result;
3004 
3005           if (bus_space_map2(tag, paddr, size, flags, TMPMAP_VA, &bh) != 0)
3006                     return (0);
3007 
3008           tmp = (void *)bh;
3009           result = (probeget((char *)tmp + offset, size) != -1);
3010           if (result && callback != NULL)
3011                     result = (*callback)(tmp, arg);
3012           bus_space_unmap(tag, bh, size);
3013           return (result);
3014 }
3015 
3016 
3017 void *
sparc_mainbus_intr_establish(bus_space_tag_t t,int pil,int level,int (* handler)(void *),void * arg,void (* fastvec)(void))3018 sparc_mainbus_intr_establish(bus_space_tag_t t, int pil, int level,
3019                                    int (*handler)(void *), void *arg,
3020                                    void (*fastvec)(void))
3021 {
3022           struct intrhand *ih;
3023 
3024           ih = kmem_alloc(sizeof(struct intrhand), KM_SLEEP);
3025           ih->ih_fun = handler;
3026           ih->ih_arg = arg;
3027           intr_establish(pil, level, ih, fastvec, false);
3028           return (ih);
3029 }
3030 
sparc_bus_barrier(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,bus_size_t size,int flags)3031 void sparc_bus_barrier (bus_space_tag_t t, bus_space_handle_t h,
3032                               bus_size_t offset, bus_size_t size, int flags)
3033 {
3034 
3035           /* No default barrier action defined */
3036           return;
3037 }
3038 
3039 static uint8_t
sparc_bus_space_read_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)3040 sparc_bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
3041 {
3042 
3043           return bus_space_read_1_real(t, h, o);
3044 }
3045 
3046 static uint16_t
sparc_bus_space_read_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)3047 sparc_bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
3048 {
3049 
3050           return bus_space_read_2_real(t, h, o);
3051 }
3052 
3053 static uint32_t
sparc_bus_space_read_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)3054 sparc_bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
3055 {
3056 
3057           return bus_space_read_4_real(t, h, o);
3058 }
3059 
3060 static uint64_t
sparc_bus_space_read_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)3061 sparc_bus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
3062 {
3063 
3064           return bus_space_read_8_real(t, h, o);
3065 }
3066 
3067 static void
sparc_bus_space_write_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t v)3068 sparc_bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
3069                               uint8_t v)
3070 {
3071 
3072           bus_space_write_1_real(t, h, o, v);
3073 }
3074 
3075 static void
sparc_bus_space_write_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t v)3076 sparc_bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
3077                               uint16_t v)
3078 {
3079 
3080           bus_space_write_2_real(t, h, o, v);
3081 }
3082 
3083 static void
sparc_bus_space_write_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t v)3084 sparc_bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
3085                               uint32_t v)
3086 {
3087 
3088           bus_space_write_4_real(t, h, o, v);
3089 }
3090 
3091 static void
sparc_bus_space_write_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t v)3092 sparc_bus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
3093                               uint64_t v)
3094 {
3095 
3096           bus_space_write_8_real(t, h, o, v);
3097 }
3098 
3099 struct sparc_bus_space_tag mainbus_space_tag = {
3100           NULL,                                   /* cookie */
3101           NULL,                                   /* parent bus tag */
3102           NULL,                                   /* ranges */
3103           0,                                      /* nranges */
3104           sparc_bus_map,                          /* bus_space_map */
3105           sparc_bus_unmap,              /* bus_space_unmap */
3106           sparc_bus_subregion,                    /* bus_space_subregion */
3107           sparc_bus_barrier,            /* bus_space_barrier */
3108           sparc_bus_mmap,                         /* bus_space_mmap */
3109           sparc_mainbus_intr_establish, /* bus_intr_establish */
3110 
3111           sparc_bus_space_read_1,                 /* bus_space_read_1 */
3112           sparc_bus_space_read_2,                 /* bus_space_read_2 */
3113           sparc_bus_space_read_4,                 /* bus_space_read_4 */
3114           sparc_bus_space_read_8,                 /* bus_space_read_8 */
3115           sparc_bus_space_write_1,      /* bus_space_write_1 */
3116           sparc_bus_space_write_2,      /* bus_space_write_2 */
3117           sparc_bus_space_write_4,      /* bus_space_write_4 */
3118           sparc_bus_space_write_8                 /* bus_space_write_8 */
3119 };
3120 
3121 int
mm_md_physacc(paddr_t pa,vm_prot_t prot)3122 mm_md_physacc(paddr_t pa, vm_prot_t prot)
3123 {
3124 
3125           return pmap_pa_exists(pa) ? 0 : EFAULT;
3126 }
3127 
3128 int
mm_md_kernacc(void * ptr,vm_prot_t prot,bool * handled)3129 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
3130 {
3131           const vaddr_t v = (vaddr_t)ptr;
3132 
3133           *handled = (v >= MSGBUF_VA && v < MSGBUF_VA + PAGE_SIZE) ||
3134               (v >= prom_vstart && v < prom_vend && (prot & VM_PROT_WRITE) == 0);
3135           return 0;
3136 }
3137 
3138 int
mm_md_readwrite(dev_t dev,struct uio * uio)3139 mm_md_readwrite(dev_t dev, struct uio *uio)
3140 {
3141 
3142           switch (minor(dev)) {
3143 #if defined(SUN4)
3144           case DEV_EEPROM:
3145                     if (cputyp == CPU_SUN4)
3146                               return eeprom_uio(uio);
3147 #endif
3148           }
3149           return ENXIO;
3150 }
3151