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