1 /* $FreeBSD$ */ 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 <bsd_kernel.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 int 41 bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 42 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 43 { 44 45 *nbshp = bsh + offset; 46 return (0); 47 } 48 49 void 50 bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, 51 bus_size_t offset, uint8_t *datap, bus_size_t count) 52 { 53 while (count--) { 54 *datap++ = bus_space_read_1(t, h, offset); 55 } 56 } 57 58 void 59 bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, 60 bus_size_t offset, uint16_t *datap, bus_size_t count) 61 { 62 while (count--) { 63 *datap++ = bus_space_read_2(t, h, offset); 64 } 65 } 66 67 void 68 bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, 69 bus_size_t offset, uint32_t *datap, bus_size_t count) 70 { 71 h += offset; 72 73 while (count--) { 74 *datap++ = *((volatile uint32_t *)h); 75 } 76 } 77 78 void 79 bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, 80 bus_size_t offset, uint8_t *datap, bus_size_t count) 81 { 82 while (count--) { 83 uint8_t temp = *datap++; 84 85 bus_space_write_1(t, h, offset, temp); 86 } 87 } 88 89 void 90 bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, 91 bus_size_t offset, uint16_t *datap, bus_size_t count) 92 { 93 while (count--) { 94 uint16_t temp = *datap++; 95 96 bus_space_write_2(t, h, offset, temp); 97 } 98 } 99 100 void 101 bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, 102 bus_size_t offset, uint32_t *datap, bus_size_t count) 103 { 104 h += offset; 105 106 while (count--) { 107 *((volatile uint32_t *)h) = *datap++; 108 } 109 } 110 111 void 112 bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, 113 bus_size_t offset, uint8_t data) 114 { 115 *((volatile uint8_t *)(h + offset)) = data; 116 } 117 118 void 119 bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, 120 bus_size_t offset, uint16_t data) 121 { 122 *((volatile uint16_t *)(h + offset)) = data; 123 } 124 125 void 126 bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, 127 bus_size_t offset, uint32_t data) 128 { 129 *((volatile uint32_t *)(h + offset)) = data; 130 } 131 132 uint8_t 133 bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset) 134 { 135 return (*((volatile uint8_t *)(h + offset))); 136 } 137 138 uint16_t 139 bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset) 140 { 141 return (*((volatile uint16_t *)(h + offset))); 142 } 143 144 uint32_t 145 bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset) 146 { 147 return (*((volatile uint32_t *)(h + offset))); 148 } 149 150 void 151 bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, 152 bus_size_t offset, uint8_t *datap, bus_size_t count) 153 { 154 h += offset; 155 156 while (count--) { 157 *datap++ = *((volatile uint8_t *)h); 158 h += 1; 159 } 160 } 161 162 void 163 bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, 164 bus_size_t offset, uint8_t *datap, bus_size_t count) 165 { 166 h += offset; 167 168 while (count--) { 169 *((volatile uint8_t *)h) = *datap++; 170 h += 1; 171 } 172 } 173 174 void 175 bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, 176 bus_size_t offset, uint32_t *datap, bus_size_t count) 177 { 178 enum { BURST = sizeof(struct burst) / 4 }; 179 180 h += offset; 181 182 while (count >= BURST) { 183 *(struct burst *)datap = *((/* volatile */ struct burst *)h); 184 185 h += BURST * 4; 186 datap += BURST; 187 count -= BURST; 188 } 189 190 while (count--) { 191 *datap++ = *((volatile uint32_t *)h); 192 h += 4; 193 } 194 } 195 196 void 197 bus_space_write_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 *((/* volatile */ struct burst *)h) = *(struct burst *)datap; 206 207 h += BURST * 4; 208 datap += BURST; 209 count -= BURST; 210 } 211 212 while (count--) { 213 *((volatile uint32_t *)h) = *datap++; 214 h += 4; 215 } 216 } 217