xref: /freebsd/stand/kshim/bsd_busspace.c (revision 2a63c3be)
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