Home | History | Annotate | Line # | Download | only in virt68k
      1 /*	$NetBSD: bus_space.c,v 1.1 2024/01/02 07:41:02 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Steve C. Woodford and Jason R. Thorpe.
      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 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.1 2024/01/02 07:41:02 thorpej Exp $");
     34 
     35 #define _VIRT68K_BUS_DMA_PRIVATE    /* For _bus_dmamem_map/_bus_dmamem_unmap */
     36 #define _VIRT68K_BUS_SPACE_PRIVATE
     37 
     38 #include <sys/param.h>
     39 #include <sys/systm.h>
     40 
     41 #include <uvm/uvm_extern.h>
     42 
     43 #include <machine/cpu.h>
     44 #include <machine/pte.h>
     45 #include <machine/bus.h>
     46 
     47 static	void	peek1(void *, void *);
     48 static	void	peek2(void *, void *);
     49 static	void	peek4(void *, void *);
     50 static	void	poke1(void *, u_int);
     51 static	void	poke2(void *, u_int);
     52 static	void	poke4(void *, u_int);
     53 static	int	do_peek(void (*)(void *, void *), void *, void *);
     54 static	int	do_poke(void (*)(void *, u_int), void *, u_int);
     55 
     56 /*
     57  * Used in locore.s/trap.c to determine if faults are being trapped.
     58  */
     59 label_t *nofault;
     60 
     61 /* ARGSUSED */
     62 int
     63 _bus_space_map(void *cookie, bus_addr_t addr, bus_size_t size, int flags,
     64     bus_space_handle_t *bushp)
     65 {
     66 	/*
     67 	 * All devices on virt68k are direct-mapped by TT registers.
     68 	 */
     69 	if (addr < VIRT68K_IO_BASE) {
     70 		return EINVAL;
     71 	}
     72 
     73 	*bushp = (bus_space_handle_t)addr;
     74 	return 0;
     75 }
     76 
     77 /* ARGSUSED */
     78 void
     79 _bus_space_unmap(void *cookie, bus_space_handle_t bush, bus_size_t size)
     80 {
     81 	KASSERT((bus_addr_t)bush >= VIRT68K_IO_BASE);
     82 }
     83 
     84 /* ARGSUSED */
     85 int
     86 _bus_space_peek_1(void *cookie, bus_space_handle_t bush, bus_size_t offset,
     87     uint8_t *valuep)
     88 {
     89 	uint8_t v;
     90 
     91 	if (valuep == NULL)
     92 		valuep = &v;
     93 
     94 	return do_peek(&peek1, (void *)(bush + offset), (void *)valuep);
     95 }
     96 
     97 /* ARGSUSED */
     98 int
     99 _bus_space_peek_2(void *cookie, bus_space_handle_t bush, bus_size_t offset,
    100     uint16_t *valuep)
    101 {
    102 	uint16_t v;
    103 
    104 	if (valuep == NULL)
    105 		valuep = &v;
    106 
    107 	return do_peek(&peek2, (void *)(bush + offset), (void *)valuep);
    108 }
    109 
    110 /* ARGSUSED */
    111 int
    112 _bus_space_peek_4(void *cookie, bus_space_handle_t bush, bus_size_t offset,
    113     uint32_t *valuep)
    114 {
    115 	uint32_t v;
    116 
    117 	if (valuep == NULL)
    118 		valuep = &v;
    119 
    120 	return do_peek(&peek4, (void *)(bush + offset), (void *)valuep);
    121 }
    122 
    123 /* ARGSUSED */
    124 int
    125 _bus_space_poke_1(void *cookie, bus_space_handle_t bush, bus_size_t offset,
    126     uint8_t value)
    127 {
    128 
    129 	return do_poke(&poke1, (void *)(bush + offset), (u_int)value);
    130 }
    131 
    132 /* ARGSUSED */
    133 int
    134 _bus_space_poke_2(void *cookie, bus_space_handle_t bush, bus_size_t offset,
    135     uint16_t value)
    136 {
    137 
    138 	return do_poke(&poke2, (void *)(bush + offset), (u_int)value);
    139 }
    140 
    141 /* ARGSUSED */
    142 int
    143 _bus_space_poke_4(void *cookie, bus_space_handle_t bush, bus_size_t offset,
    144     uint32_t value)
    145 {
    146 
    147 	return do_poke(&poke4, (void *)(bush + offset), (u_int)value);
    148 }
    149 
    150 static void
    151 peek1(void *addr, void *vp)
    152 {
    153 
    154 	*((uint8_t *)vp) =  *((uint8_t *)addr);
    155 }
    156 
    157 static void
    158 peek2(void *addr, void *vp)
    159 {
    160 
    161 	*((uint16_t *)vp) = *((uint16_t *)addr);
    162 }
    163 
    164 static void
    165 peek4(void *addr, void *vp)
    166 {
    167 
    168 	*((uint32_t *)vp) = *((uint32_t *)addr);
    169 }
    170 
    171 static void
    172 poke1(void *addr, u_int value)
    173 {
    174 
    175 	*((uint8_t *)addr) = value;
    176 }
    177 
    178 static void
    179 poke2(void *addr, u_int value)
    180 {
    181 
    182 	*((uint16_t *)addr) = value;
    183 }
    184 
    185 static void
    186 poke4(void *addr, u_int value)
    187 {
    188 
    189 	*((uint32_t *)addr) = value;
    190 }
    191 
    192 static int
    193 do_peek(void (*peekfn)(void *, void *), void *addr, void *valuep)
    194 {
    195 	label_t faultbuf;
    196 
    197 	nofault = &faultbuf;
    198 	if (setjmp(&faultbuf)) {
    199 		nofault = NULL;
    200 		return 1;
    201 	}
    202 
    203 	(*peekfn)(addr, valuep);
    204 
    205 	nofault = NULL;
    206 	return 0;
    207 }
    208 
    209 static int
    210 do_poke(void (*pokefn)(void *, u_int), void *addr, u_int value)
    211 {
    212 	label_t faultbuf;
    213 
    214 	nofault = &faultbuf;
    215 	if (setjmp(&faultbuf)) {
    216 		nofault = NULL;
    217 		return 1;
    218 	}
    219 
    220 	(*pokefn)(addr, value);
    221 
    222 	nofault = NULL;
    223 	return 0;
    224 }
    225