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