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