1 /* $FreeBSD: releng/12.2/stand/kshim/bsd_busspace.c 291400 2015-11-27 18:14:45Z zbb $ */ 2 /*- 3 * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include "implementation/freebsd_sys.h" 28 29 struct burst { 30 uint32_t dw0; 31 uint32_t dw1; 32 uint32_t dw2; 33 uint32_t dw3; 34 uint32_t dw4; 35 uint32_t dw5; 36 uint32_t dw6; 37 uint32_t dw7; 38 }; 39 40 void bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, uint8_t data); 41 void bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, uint16_t data); 42 void bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, uint32_t data); 43 44 uint8_t bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset); 45 uint16_t bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset); 46 uint32_t bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset); 47 48 void bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, 49 uint8_t *datap, bus_size_t count); 50 void bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, 51 uint16_t *datap, bus_size_t count); 52 void bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, 53 uint32_t *datap, bus_size_t count); 54 55 void bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, 56 uint8_t *datap, bus_size_t count); 57 void bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, 58 uint16_t *datap, bus_size_t count); 59 void bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, 60 uint32_t *datap, bus_size_t count); 61 62 void bus_space_read_region_1(bus_space_tag_t space, bus_space_handle_t handle, bus_size_t offset, 63 uint8_t *datap, bus_size_t count); 64 void bus_space_write_region_1(bus_space_tag_t space, bus_space_handle_t handle, bus_size_t offset, 65 uint8_t *datap, bus_size_t count); 66 void bus_space_read_region_4(bus_space_tag_t space, bus_space_handle_t handle, bus_size_t offset, 67 uint32_t *datap, bus_size_t count); 68 void bus_space_write_region_4(bus_space_tag_t space, bus_space_handle_t handle, bus_size_t offset, 69 uint32_t *datap, bus_size_t count); 70 71 void 72 bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, 73 bus_size_t offset, uint8_t *datap, bus_size_t count) 74 { 75 while (count--) { 76 *datap++ = bus_space_read_1(t, h, offset); 77 } 78 } 79 80 void 81 bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, 82 bus_size_t offset, uint16_t *datap, bus_size_t count) 83 { 84 while (count--) { 85 *datap++ = bus_space_read_2(t, h, offset); 86 } 87 } 88 89 void 90 bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, 91 bus_size_t offset, uint32_t *datap, bus_size_t count) 92 { 93 h += offset; 94 95 while (count--) { 96 *datap++ = *((volatile uint32_t *)h); 97 } 98 } 99 100 void 101 bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, 102 bus_size_t offset, uint8_t *datap, bus_size_t count) 103 { 104 while (count--) { 105 uint8_t temp = *datap++; 106 107 bus_space_write_1(t, h, offset, temp); 108 } 109 } 110 111 void 112 bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, 113 bus_size_t offset, uint16_t *datap, bus_size_t count) 114 { 115 while (count--) { 116 uint16_t temp = *datap++; 117 118 bus_space_write_2(t, h, offset, temp); 119 } 120 } 121 122 void 123 bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, 124 bus_size_t offset, uint32_t *datap, bus_size_t count) 125 { 126 h += offset; 127 128 while (count--) { 129 *((volatile uint32_t *)h) = *datap++; 130 } 131 } 132 133 void 134 bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, 135 bus_size_t offset, uint8_t data) 136 { 137 *((volatile uint8_t *)(h + offset)) = data; 138 } 139 140 void 141 bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, 142 bus_size_t offset, uint16_t data) 143 { 144 *((volatile uint16_t *)(h + offset)) = data; 145 } 146 147 void 148 bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, 149 bus_size_t offset, uint32_t data) 150 { 151 *((volatile uint32_t *)(h + offset)) = data; 152 } 153 154 uint8_t 155 bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset) 156 { 157 return (*((volatile uint8_t *)(h + offset))); 158 } 159 160 uint16_t 161 bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset) 162 { 163 return (*((volatile uint16_t *)(h + offset))); 164 } 165 166 uint32_t 167 bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset) 168 { 169 return (*((volatile uint32_t *)(h + offset))); 170 } 171 172 void 173 bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, 174 bus_size_t offset, uint8_t *datap, bus_size_t count) 175 { 176 h += offset; 177 178 while (count--) { 179 *datap++ = *((volatile uint8_t *)h); 180 h += 1; 181 } 182 } 183 184 void 185 bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, 186 bus_size_t offset, uint8_t *datap, bus_size_t count) 187 { 188 h += offset; 189 190 while (count--) { 191 *((volatile uint8_t *)h) = *datap++; 192 h += 1; 193 } 194 } 195 196 void 197 bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, 198 bus_size_t offset, uint32_t *datap, bus_size_t count) 199 { 200 enum { BURST = sizeof(struct burst) / 4 }; 201 202 h += offset; 203 204 while (count >= BURST) { 205 *(struct burst *)datap = *((/* volatile */ struct burst *)h); 206 207 h += BURST * 4; 208 datap += BURST; 209 count -= BURST; 210 } 211 212 while (count--) { 213 *datap++ = *((volatile uint32_t *)h); 214 h += 4; 215 } 216 } 217 218 void 219 bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h, 220 bus_size_t offset, uint32_t *datap, bus_size_t count) 221 { 222 enum { BURST = sizeof(struct burst) / 4 }; 223 224 h += offset; 225 226 while (count >= BURST) { 227 *((/* volatile */ struct burst *)h) = *(struct burst *)datap; 228 229 h += BURST * 4; 230 datap += BURST; 231 count -= BURST; 232 } 233 234 while (count--) { 235 *((volatile uint32_t *)h) = *datap++; 236 h += 4; 237 } 238 } 239