1/* $FreeBSD: stable/11/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 <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 40int 41bus_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 49void 50bus_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 58void 59bus_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 67void 68bus_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 78void 79bus_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 89void 90bus_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 100void 101bus_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 111void 112bus_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 118void 119bus_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 125void 126bus_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 132uint8_t 133bus_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 138uint16_t 139bus_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 144uint32_t 145bus_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 150void 151bus_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 162void 163bus_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 174void 175bus_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 196void 197bus_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