1 /* $NetBSD: external_io.c,v 1.3 2018/03/16 17:56:32 ryo Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Mark Brinicombe. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Mark Brinicombe. 18 * 4. The name of the company nor the name of the author may be used to 19 * endorse or promote products derived from this software without specific 20 * prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * bus_space I/O functions for external bus 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: external_io.c,v 1.3 2018/03/16 17:56:32 ryo Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/bus.h> 45 46 /* Proto types for all the bus_space structure functions */ 47 48 bs_protos(external); 49 bs_protos(bs_notimpl); 50 bs_protos(mainbus); 51 52 /* Declare the external bus space tag */ 53 struct bus_space external_bs_tag = { 54 /* cookie */ 55 .bs_cookie = (void *) 0, /* Shift to apply to registers */ 56 57 /* mapping/unmapping */ 58 .bs_map = mainbus_bs_map, 59 .bs_unmap = mainbus_bs_unmap, 60 .bs_subregion = external_bs_subregion, 61 62 /* allocation/deallocation */ 63 .bs_alloc = mainbus_bs_alloc, 64 .bs_free = mainbus_bs_free, 65 66 /* get kernel virtual address */ 67 .bs_vaddr = 0, /* there is no linear mapping */ 68 69 /* mmap bus space for userland */ 70 .bs_mmap = mainbus_bs_mmap, 71 72 /* barrier */ 73 .bs_barrier = mainbus_bs_barrier, 74 75 /* read (single) */ 76 .bs_r_1 = external_bs_r_1, 77 .bs_r_2 = bs_notimpl_bs_r_2, 78 .bs_r_4 = external_bs_r_4, 79 .bs_r_8 = bs_notimpl_bs_r_8, 80 81 /* read multiple */ 82 .bs_rm_1 = external_bs_rm_1, 83 .bs_rm_2 = external_bs_rm_2, 84 .bs_rm_4 = external_bs_rm_4, 85 .bs_rm_8 = bs_notimpl_bs_rm_8, 86 87 /* read region */ 88 .bs_rr_1 = external_bs_rr_1, 89 .bs_rr_2 = external_bs_rr_2, 90 .bs_rr_4 = bs_notimpl_bs_rr_4, 91 .bs_rr_8 = bs_notimpl_bs_rr_8, 92 93 /* write (single) */ 94 .bs_w_1 = external_bs_w_1, 95 .bs_w_2 = bs_notimpl_bs_w_2, 96 .bs_w_4 = external_bs_w_4, 97 .bs_w_8 = bs_notimpl_bs_w_8, 98 99 /* write multiple */ 100 .bs_wm_1 = external_bs_wm_1, 101 .bs_wm_2 = external_bs_wm_2, 102 .bs_wm_4 = external_bs_wm_4, 103 .bs_wm_8 = bs_notimpl_bs_wm_8, 104 105 /* write region */ 106 .bs_wr_1 = external_bs_wr_1, 107 .bs_wr_2 = external_bs_wr_2, 108 .bs_wr_4 = bs_notimpl_bs_wr_4, 109 .bs_wr_8 = bs_notimpl_bs_wr_8, 110 111 /* set multiple */ 112 .bs_sm_1 = bs_notimpl_bs_sm_1, 113 .bs_sm_2 = bs_notimpl_bs_sm_2, 114 .bs_sm_4 = bs_notimpl_bs_sm_4, 115 .bs_sm_8 = bs_notimpl_bs_sm_8, 116 117 /* set region */ 118 .bs_sr_1 = external_bs_sr_1, 119 .bs_sr_2 = external_bs_sr_2, 120 .bs_sr_4 = bs_notimpl_bs_sr_4, 121 .bs_sr_8 = bs_notimpl_bs_sr_8, 122 123 /* copy */ 124 .bs_c_1 = bs_notimpl_bs_c_1, 125 .bs_c_2 = bs_notimpl_bs_c_2, 126 .bs_c_4 = bs_notimpl_bs_c_4, 127 .bs_c_8 = bs_notimpl_bs_c_8, 128 }; 129 130 /* bus space functions */ 131 132 int 133 external_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset, 134 bus_size_t size, bus_space_handle_t *nbshp) 135 { 136 137 *nbshp = bsh + offset; 138 return 0; 139 } 140 141 /* Rough-and-ready implementations from arm26 */ 142 void 143 external_bs_rr_1(void *cookie, bus_space_handle_t bsh, 144 bus_size_t offset, uint8_t *datap, bus_size_t count) 145 { 146 int i; 147 148 for (i = 0; i < count; i++) 149 datap[i] = external_bs_r_1(cookie, bsh, offset + i); 150 } 151 152 void 153 external_bs_rr_2(void *cookie, bus_space_handle_t bsh, 154 bus_size_t offset, uint16_t *datap, bus_size_t count) 155 { 156 int i; 157 158 for (i = 0; count - i > 1 && i < count; i += 2) 159 *(uint32_t *)(&datap[i]) = 160 external_bs_r_4(cookie, bsh, offset + (i << 1)); 161 for (; i < count; i++) 162 datap[i] = 163 external_bs_r_1(cookie, bsh, offset + (i << 1)) | 164 external_bs_r_1(cookie, bsh, offset + (i << 1) + 1); 165 } 166 167 void 168 external_bs_wr_1(void *cookie, bus_space_handle_t bsh, 169 bus_size_t offset, uint8_t const *datap, bus_size_t count) 170 { 171 int i; 172 173 for (i = 0; i < count; i++) 174 external_bs_w_1(cookie, bsh, offset + i, datap[i]); 175 } 176 177 void 178 external_bs_wr_2(void *cookie, bus_space_handle_t bsh, 179 bus_size_t offset, uint16_t const *datap, bus_size_t count) 180 { 181 int i; 182 uint16_t v; 183 184 for (i = 0; count - i > 1 && i < count; i += 2) 185 external_bs_w_4(cookie, bsh, offset + (i << 1), 186 *(const uint32_t *)(&datap[i])); 187 for (; i < count; i++) { 188 v = datap[i]; 189 external_bs_w_1(cookie, bsh, offset + (i << 1), v & 0xff); 190 external_bs_w_1(cookie, bsh, offset + (i << 1) + 1, v >> 8); 191 } 192 } 193 194 void 195 external_bs_sr_1(void *cookie, bus_space_handle_t bsh, 196 bus_size_t offset, uint8_t value, bus_size_t count) 197 { 198 int i; 199 200 for (i = 0; i < count; i++) 201 external_bs_w_1(cookie, bsh, offset + i, value); 202 } 203 204 void 205 external_bs_sr_2(void *cookie, bus_space_handle_t bsh, 206 bus_size_t offset, uint16_t value, bus_size_t count) 207 { 208 int i; 209 210 for (i = 0; count - i > 1 && i < count; i += 2) 211 external_bs_w_4(cookie, bsh, offset + (i << 1), 212 value | (value << 16)); 213 for (; i < count; i++) { 214 external_bs_w_1(cookie, bsh, offset + (i << 1), value & 0xff); 215 external_bs_w_1(cookie, bsh, offset + (i << 1) + 1, value >> 8); 216 } 217 } 218