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