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
bus_space_subregion(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size,bus_space_handle_t * nbshp)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
bus_space_read_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)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
bus_space_read_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint16_t * datap,bus_size_t count)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
bus_space_read_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)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
bus_space_write_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)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
bus_space_write_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint16_t * datap,bus_size_t count)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
bus_space_write_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)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
bus_space_write_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t data)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
bus_space_write_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint16_t data)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
bus_space_write_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t data)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
bus_space_read_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset)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
bus_space_read_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset)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
bus_space_read_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset)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
bus_space_read_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)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
bus_space_write_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint8_t * datap,bus_size_t count)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
bus_space_read_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)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
bus_space_write_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t offset,uint32_t * datap,bus_size_t count)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