2 * Copyright (c) 2009 RMI Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
32 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/endian.h>
36 #include <sys/malloc.h>
41 #include <vm/vm_kern.h>
42 #include <vm/vm_extern.h>
44 #include <machine/bus.h>
45 #include <machine/cache.h>
48 rmi_bus_space_map(void *t, bus_addr_t addr,
49 bus_size_t size, int flags,
50 bus_space_handle_t * bshp);
53 rmi_bus_space_unmap(void *t, bus_space_handle_t bsh,
57 rmi_bus_space_subregion(void *t,
58 bus_space_handle_t bsh,
59 bus_size_t offset, bus_size_t size,
60 bus_space_handle_t * nbshp);
63 rmi_bus_space_read_1(void *t,
64 bus_space_handle_t handle,
68 rmi_bus_space_read_2(void *t,
69 bus_space_handle_t handle,
73 rmi_bus_space_read_4(void *t,
74 bus_space_handle_t handle,
78 rmi_bus_space_read_multi_1(void *t,
79 bus_space_handle_t handle,
80 bus_size_t offset, u_int8_t * addr,
84 rmi_bus_space_read_multi_2(void *t,
85 bus_space_handle_t handle,
86 bus_size_t offset, u_int16_t * addr,
90 rmi_bus_space_read_multi_4(void *t,
91 bus_space_handle_t handle,
92 bus_size_t offset, u_int32_t * addr,
96 rmi_bus_space_read_region_1(void *t,
97 bus_space_handle_t bsh,
98 bus_size_t offset, u_int8_t * addr,
102 rmi_bus_space_read_region_2(void *t,
103 bus_space_handle_t bsh,
104 bus_size_t offset, u_int16_t * addr,
108 rmi_bus_space_read_region_4(void *t,
109 bus_space_handle_t bsh,
110 bus_size_t offset, u_int32_t * addr,
114 rmi_bus_space_write_1(void *t,
115 bus_space_handle_t handle,
116 bus_size_t offset, u_int8_t value);
119 rmi_bus_space_write_2(void *t,
120 bus_space_handle_t handle,
121 bus_size_t offset, u_int16_t value);
124 rmi_bus_space_write_4(void *t,
125 bus_space_handle_t handle,
126 bus_size_t offset, u_int32_t value);
129 rmi_bus_space_write_multi_1(void *t,
130 bus_space_handle_t handle,
132 const u_int8_t * addr,
136 rmi_bus_space_write_multi_2(void *t,
137 bus_space_handle_t handle,
139 const u_int16_t * addr,
143 rmi_bus_space_write_multi_4(void *t,
144 bus_space_handle_t handle,
146 const u_int32_t * addr,
150 rmi_bus_space_write_region_2(void *t,
151 bus_space_handle_t bsh,
153 const u_int16_t * addr,
157 rmi_bus_space_write_region_4(void *t,
158 bus_space_handle_t bsh,
160 const u_int32_t * addr,
165 rmi_bus_space_set_region_2(void *t,
166 bus_space_handle_t bsh,
167 bus_size_t offset, u_int16_t value,
170 rmi_bus_space_set_region_4(void *t,
171 bus_space_handle_t bsh,
172 bus_size_t offset, u_int32_t value,
176 rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
177 bus_size_t offset __unused, bus_size_t len __unused, int flags);
180 rmi_bus_space_copy_region_2(void *t,
181 bus_space_handle_t bsh1,
183 bus_space_handle_t bsh2,
184 bus_size_t off2, size_t count);
187 rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
191 rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
195 rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
198 rmi_bus_space_read_multi_stream_1(void *t,
199 bus_space_handle_t handle,
200 bus_size_t offset, u_int8_t * addr,
204 rmi_bus_space_read_multi_stream_2(void *t,
205 bus_space_handle_t handle,
206 bus_size_t offset, u_int16_t * addr,
210 rmi_bus_space_read_multi_stream_4(void *t,
211 bus_space_handle_t handle,
212 bus_size_t offset, u_int32_t * addr,
216 rmi_bus_space_write_stream_1(void *t, bus_space_handle_t bsh,
217 bus_size_t offset, u_int8_t value);
219 rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
220 bus_size_t offset, u_int16_t value);
223 rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
224 bus_size_t offset, u_int32_t value);
227 rmi_bus_space_write_multi_stream_1(void *t,
228 bus_space_handle_t handle,
230 const u_int8_t * addr,
233 rmi_bus_space_write_multi_stream_2(void *t,
234 bus_space_handle_t handle,
236 const u_int16_t * addr,
240 rmi_bus_space_write_multi_stream_4(void *t,
241 bus_space_handle_t handle,
243 const u_int32_t * addr,
246 #define TODO() printf("XLR memory bus space function '%s' unimplemented\n", __func__)
248 static struct bus_space local_rmi_bus_space = {
252 /* mapping/unmapping */
255 rmi_bus_space_subregion,
257 /* allocation/deallocation */
262 rmi_bus_space_barrier,
265 rmi_bus_space_read_1,
266 rmi_bus_space_read_2,
267 rmi_bus_space_read_4,
271 rmi_bus_space_read_multi_1,
272 rmi_bus_space_read_multi_2,
273 rmi_bus_space_read_multi_4,
277 rmi_bus_space_read_region_1,
278 rmi_bus_space_read_region_2,
279 rmi_bus_space_read_region_4,
283 rmi_bus_space_write_1,
284 rmi_bus_space_write_2,
285 rmi_bus_space_write_4,
289 rmi_bus_space_write_multi_1,
290 rmi_bus_space_write_multi_2,
291 rmi_bus_space_write_multi_4,
296 rmi_bus_space_write_region_2,
297 rmi_bus_space_write_region_4,
308 rmi_bus_space_set_region_2,
309 rmi_bus_space_set_region_4,
314 rmi_bus_space_copy_region_2,
318 /* read (single) stream */
319 rmi_bus_space_read_stream_1,
320 rmi_bus_space_read_stream_2,
321 rmi_bus_space_read_stream_4,
324 /* read multiple stream */
325 rmi_bus_space_read_multi_stream_1,
326 rmi_bus_space_read_multi_stream_2,
327 rmi_bus_space_read_multi_stream_4,
330 /* read region stream */
331 rmi_bus_space_read_region_1,
332 rmi_bus_space_read_region_2,
333 rmi_bus_space_read_region_4,
336 /* write (single) stream */
337 rmi_bus_space_write_stream_1,
338 rmi_bus_space_write_stream_2,
339 rmi_bus_space_write_stream_4,
342 /* write multiple stream */
343 rmi_bus_space_write_multi_stream_1,
344 rmi_bus_space_write_multi_stream_2,
345 rmi_bus_space_write_multi_stream_4,
348 /* write region stream */
350 rmi_bus_space_write_region_2,
351 rmi_bus_space_write_region_4,
355 /* generic bus_space tag */
356 bus_space_tag_t rmi_bus_space = &local_rmi_bus_space;
359 * Map a region of device bus space into CPU virtual address space.
362 rmi_bus_space_map(void *t __unused, bus_addr_t addr,
363 bus_size_t size __unused, int flags __unused,
364 bus_space_handle_t * bshp)
372 * Unmap a region of device bus space.
375 rmi_bus_space_unmap(void *t __unused, bus_space_handle_t bsh __unused,
376 bus_size_t size __unused)
381 * Get a new handle for a subregion of an already-mapped area of bus space.
385 rmi_bus_space_subregion(void *t __unused, bus_space_handle_t bsh,
386 bus_size_t offset, bus_size_t size __unused,
387 bus_space_handle_t * nbshp)
389 *nbshp = bsh + offset;
394 * Read a 1, 2, 4, or 8 byte quantity from bus space
395 * described by tag/handle/offset.
399 rmi_bus_space_read_1(void *tag, bus_space_handle_t handle,
402 return (u_int8_t) (*(volatile u_int32_t *)(handle + offset));
406 rmi_bus_space_read_2(void *tag, bus_space_handle_t handle,
409 return (u_int16_t)(*(volatile u_int32_t *)(handle + offset));
413 rmi_bus_space_read_4(void *tag, bus_space_handle_t handle,
416 return (*(volatile u_int32_t *)(handle + offset));
421 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
422 * described by tag/handle/offset and copy into buffer provided.
425 rmi_bus_space_read_multi_1(void *tag, bus_space_handle_t handle,
426 bus_size_t offset, u_int8_t * addr, size_t count)
432 rmi_bus_space_read_multi_2(void *tag, bus_space_handle_t handle,
433 bus_size_t offset, u_int16_t * addr, size_t count)
439 rmi_bus_space_read_multi_4(void *tag, bus_space_handle_t handle,
440 bus_size_t offset, u_int32_t * addr, size_t count)
446 * Write the 1, 2, 4, or 8 byte value `value' to bus space
447 * described by tag/handle/offset.
451 rmi_bus_space_write_1(void *tag, bus_space_handle_t handle,
452 bus_size_t offset, u_int8_t value)
454 *(volatile u_int32_t *)(handle + offset) = (u_int32_t)value;
458 rmi_bus_space_write_2(void *tag, bus_space_handle_t handle,
459 bus_size_t offset, u_int16_t value)
461 *(volatile u_int32_t *)(handle + offset) = (u_int32_t)value;
465 rmi_bus_space_write_4(void *tag, bus_space_handle_t handle,
466 bus_size_t offset, u_int32_t value)
468 *(volatile u_int32_t *)(handle + offset) = value;
473 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
474 * provided to bus space described by tag/handle/offset.
479 rmi_bus_space_write_multi_1(void *tag, bus_space_handle_t handle,
480 bus_size_t offset, const u_int8_t * addr, size_t count)
486 rmi_bus_space_write_multi_2(void *tag, bus_space_handle_t handle,
487 bus_size_t offset, const u_int16_t * addr, size_t count)
493 rmi_bus_space_write_multi_4(void *tag, bus_space_handle_t handle,
494 bus_size_t offset, const u_int32_t * addr, size_t count)
500 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
501 * by tag/handle starting at `offset'.
505 rmi_bus_space_set_region_2(void *t, bus_space_handle_t bsh,
506 bus_size_t offset, u_int16_t value, size_t count)
508 bus_addr_t addr = bsh + offset;
510 for (; count != 0; count--, addr += 2)
511 (*(volatile u_int32_t *)(addr)) = value;
515 rmi_bus_space_set_region_4(void *t, bus_space_handle_t bsh,
516 bus_size_t offset, u_int32_t value, size_t count)
518 bus_addr_t addr = bsh + offset;
520 for (; count != 0; count--, addr += 4)
521 (*(volatile u_int32_t *)(addr)) = value;
526 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
527 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
530 rmi_bus_space_copy_region_2(void *t, bus_space_handle_t bsh1,
531 bus_size_t off1, bus_space_handle_t bsh2,
532 bus_size_t off2, size_t count)
534 printf("bus_space_copy_region_2 - unimplemented\n");
538 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
539 * described by tag/handle/offset and copy into buffer provided.
543 rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
547 return *((volatile u_int8_t *)(handle + offset));
552 rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
555 return *(volatile u_int16_t *)(handle + offset);
560 rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
563 return (*(volatile u_int32_t *)(handle + offset));
568 rmi_bus_space_read_multi_stream_1(void *tag, bus_space_handle_t handle,
569 bus_size_t offset, u_int8_t * addr, size_t count)
575 rmi_bus_space_read_multi_stream_2(void *tag, bus_space_handle_t handle,
576 bus_size_t offset, u_int16_t * addr, size_t count)
582 rmi_bus_space_read_multi_stream_4(void *tag, bus_space_handle_t handle,
583 bus_size_t offset, u_int32_t * addr, size_t count)
590 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
591 * described by tag/handle and starting at `offset' and copy into
595 rmi_bus_space_read_region_1(void *t, bus_space_handle_t bsh,
596 bus_size_t offset, u_int8_t * addr, size_t count)
602 rmi_bus_space_read_region_2(void *t, bus_space_handle_t bsh,
603 bus_size_t offset, u_int16_t * addr, size_t count)
609 rmi_bus_space_read_region_4(void *t, bus_space_handle_t bsh,
610 bus_size_t offset, u_int32_t * addr, size_t count)
612 bus_addr_t baddr = bsh + offset;
615 *addr++ = (*(volatile u_int32_t *)(baddr));
621 rmi_bus_space_write_stream_1(void *t, bus_space_handle_t handle,
622 bus_size_t offset, u_int8_t value)
629 rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
630 bus_size_t offset, u_int16_t value)
637 rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
638 bus_size_t offset, u_int32_t value)
645 rmi_bus_space_write_multi_stream_1(void *tag, bus_space_handle_t handle,
646 bus_size_t offset, const u_int8_t * addr, size_t count)
652 rmi_bus_space_write_multi_stream_2(void *tag, bus_space_handle_t handle,
653 bus_size_t offset, const u_int16_t * addr, size_t count)
659 rmi_bus_space_write_multi_stream_4(void *tag, bus_space_handle_t handle,
660 bus_size_t offset, const u_int32_t * addr, size_t count)
666 rmi_bus_space_write_region_2(void *t,
667 bus_space_handle_t bsh,
669 const u_int16_t * addr,
676 rmi_bus_space_write_region_4(void *t, bus_space_handle_t bsh,
677 bus_size_t offset, const u_int32_t * addr, size_t count)
683 rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
684 bus_size_t offset __unused, bus_size_t len __unused, int flags)