Home | History | Annotate | Line # | Download | only in sun3
      1 /*	$NetBSD: bus_subr.c,v 1.19 2026/04/26 10:52:16 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1996 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Adam Glass and Gordon W. Ross.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * bus_xxx support functions, Sun3-specific part.
     34  * The common stuff is in autoconf.c
     35  */
     36 
     37 #include <sys/cdefs.h>
     38 __KERNEL_RCSID(0, "$NetBSD: bus_subr.c,v 1.19 2026/04/26 10:52:16 thorpej Exp $");
     39 
     40 #include <sys/param.h>
     41 #include <sys/systm.h>
     42 #include <sys/device.h>
     43 
     44 #include <uvm/uvm_extern.h>
     45 
     46 #include <machine/autoconf.h>
     47 #include <machine/cpu.h>
     48 #include <machine/mon.h>
     49 #include <machine/pmap.h>
     50 #include <machine/pte.h>
     51 
     52 #include <sun3/sun3/control.h>
     53 #include <sun3/sun3/machdep.h>
     54 #include <sun3/sun3/vme.h>
     55 
     56 /* These are defined in pmap.c */
     57 extern vaddr_t tmp_vpages[];
     58 extern int tmp_vpages_inuse;
     59 
     60 #define OBIO_MASK 0xFFffff
     61 
     62 static const struct {
     63 	int  type;
     64 	long base;
     65 	long mask;
     66 } bus_info[BUS__NTYPES] = {
     67 	{ PMAP_OBIO,  0, OBIO_MASK },
     68 	{ PMAP_OBMEM, 0, ~0 },
     69 	/* VME A16 */
     70 	{ PMAP_VME16, VME16_BASE, VME16_MASK },
     71 	{ PMAP_VME32, VME16_BASE, VME16_MASK },
     72 	/* VME A24 */
     73 	{ PMAP_VME16, VME24_BASE, VME24_MASK },
     74 	{ PMAP_VME32, VME24_BASE, VME24_MASK },
     75 	/* VME A32 */
     76 	{ PMAP_VME16, VME32_BASE, VME32_MASK },
     77 	{ PMAP_VME32, VME32_BASE, VME32_MASK },
     78 };
     79 
     80 /*
     81  * Create a temporary, one-page mapping for a device.
     82  * This is used by some device probe routines that
     83  * need to do peek/write/read tricks.
     84  */
     85 void *
     86 bus_tmapin(int bustype, int pa)
     87 {
     88 	vaddr_t pgva;
     89 	int off, pte;
     90 
     91 	if ((bustype < 0) || (bustype >= BUS__NTYPES))
     92 		panic("bus_tmapin: bustype");
     93 
     94 	off = pa & PGOFSET;
     95 	pa -= off;
     96 
     97 	pa &= bus_info[bustype].mask;
     98 	pa |= bus_info[bustype].base;
     99 
    100 	pte = PA_PGNUM(pa);
    101 	pte |= (bus_info[bustype].type << PG_MOD_SHIFT);
    102 	pte |= (PG_VALID | PG_WRITE | PG_SYSTEM | PG_NC);
    103 
    104 	if (tmp_vpages_inuse)
    105 		panic("bus_tmapin: tmp_vpages_inuse");
    106 	tmp_vpages_inuse++;
    107 
    108 	pgva = tmp_vpages[1];
    109 	set_pte(pgva, pte);
    110 
    111 	return ((void *)(pgva + off));
    112 }
    113 
    114 void
    115 bus_tmapout(void *vp)
    116 {
    117 	vaddr_t pgva;
    118 
    119 	pgva = m68k_trunc_page(vp);
    120 	if (pgva != tmp_vpages[1])
    121 		return;
    122 
    123 	set_pte(pgva, PG_INVAL);
    124 	--tmp_vpages_inuse;
    125 }
    126 
    127 /*
    128  * Make a permanent mapping for a device.
    129  */
    130 void *
    131 bus_mapin(int bustype, int pa, int sz)
    132 {
    133 	vaddr_t va;
    134 	int off;
    135 
    136 	if ((bustype < 0) || (bustype >= BUS__NTYPES))
    137 		panic("bus_mapin: bustype");
    138 
    139 	off = pa & PGOFSET;
    140 	pa -= off;
    141 	sz += off;
    142 	sz = m68k_round_page(sz);
    143 
    144 	/* Borrow PROM mappings if we can. */
    145 	if (bustype == BUS_OBIO) {
    146 		if (find_prom_map(pa, PMAP_OBIO, sz, &va) == 0)
    147 			goto done;
    148 	}
    149 
    150 	pa &= bus_info[bustype].mask;
    151 	pa |= bus_info[bustype].base;
    152 	pa |= bus_info[bustype].type;
    153 	pa |= PMAP_NC;	/* non-cached */
    154 
    155 	/* Get some kernel virtual address space. */
    156 	va = uvm_km_alloc(kernel_map, sz, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA);
    157 	if (va == 0)
    158 		panic("bus_mapin");
    159 
    160 	/* Map it to the specified bus. */
    161 	pmap_map(va, pa, pa + sz, VM_PROT_ALL);
    162 
    163 done:
    164 	return ((void*)(va + off));
    165 }
    166 
    167 void
    168 bus_mapout(void *ptr, int sz)
    169 {
    170 	vaddr_t va;
    171 	int off;
    172 
    173 	va = (vaddr_t)ptr;
    174 
    175 	/* If it was a PROM mapping, do NOT free it! */
    176 	if ((va >= SUN3_MONSTART) && (va < SUN3_MONEND))
    177 		return;
    178 
    179 	off = va & PGOFSET;
    180 	va -= off;
    181 	sz += off;
    182 	sz = m68k_round_page(sz);
    183 
    184 	pmap_remove(pmap_kernel(), va, va + sz);
    185 	pmap_update(pmap_kernel());
    186 	uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY);
    187 }
    188