source: rtems-libbsd/rtemsbsd/include/machine/bus.h

6-freebsd-12
Last change on this file was 1524f95, checked in by Chris Johns <chrisj@…>, on 10/04/23 at 05:13:45

i386/pc686: Fix kernel bus DMA for the PC686 BSP

The x86 provides it own bus space support. Use the generic
bus space calls. This however requires the BUS_SPACE_MEM tag
be provided for all architectures. Make the generic value
match the x86 value.

  • Property mode set to 100644
File size: 28.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_bsd_machine
5 *
6 * @brief TODO.
7 *
8 * File origin from FreeBSD 'sys/amd64/include/bus.h'.
9 *
10 * Conditionally supports PCI IO regions (IO Ports).
11 */
12
13/*-
14 * Copyright (c) 2021 Chris Johns.  All rights reserved.
15 *
16 * Copyright (c) 2009, 2015 embedded brains GmbH.  All rights reserved.
17 *
18 *  embedded brains GmbH
19 *  Dornierstr. 4
20 *  82178 Puchheim
21 *  Germany
22 *  <rtems@embedded-brains.de>
23 *
24 * Copyright (c) KATO Takenori, 1999.
25 *
26 * All rights reserved.  Unpublished rights reserved under the copyright
27 * laws of Japan.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * 1. Redistributions of source code must retain the above copyright
34 *    notice, this list of conditions and the following disclaimer as
35 *    the first lines of this file unmodified.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 *    notice, this list of conditions and the following disclaimer in the
38 *    documentation and/or other materials provided with the distribution.
39 * 3. The name of the author may not be used to endorse or promote products
40 *    derived from this software without specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */
53
54/*-
55 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
56 * All rights reserved.
57 *
58 * This code is derived from software contributed to The NetBSD Foundation
59 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
60 * NASA Ames Research Center.
61 *
62 * Redistribution and use in source and binary forms, with or without
63 * modification, are permitted provided that the following conditions
64 * are met:
65 * 1. Redistributions of source code must retain the above copyright
66 *    notice, this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright
68 *    notice, this list of conditions and the following disclaimer in the
69 *    documentation and/or other materials provided with the distribution.
70 * 3. All advertising materials mentioning features or use of this software
71 *    must display the following acknowledgement:
72 *      This product includes software developed by the NetBSD
73 *      Foundation, Inc. and its contributors.
74 * 4. Neither the name of The NetBSD Foundation nor the names of its
75 *    contributors may be used to endorse or promote products derived
76 *    from this software without specific prior written permission.
77 *
78 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
79 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
80 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
81 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
82 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
83 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
84 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
85 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
86 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
87 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
88 * POSSIBILITY OF SUCH DAMAGE.
89 */
90
91/*-
92 * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
93 * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
94 *
95 * Redistribution and use in source and binary forms, with or without
96 * modification, are permitted provided that the following conditions
97 * are met:
98 * 1. Redistributions of source code must retain the above copyright
99 *    notice, this list of conditions and the following disclaimer.
100 * 2. Redistributions in binary form must reproduce the above copyright
101 *    notice, this list of conditions and the following disclaimer in the
102 *    documentation and/or other materials provided with the distribution.
103 * 3. All advertising materials mentioning features or use of this software
104 *    must display the following acknowledgement:
105 *      This product includes software developed by Christopher G. Demetriou
106 *      for the NetBSD Project.
107 * 4. The name of the author may not be used to endorse or promote products
108 *    derived from this software without specific prior written permission
109 *
110 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
111 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
112 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
113 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
114 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
115 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
116 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
117 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
119 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120 */
121
122#ifndef _RTEMS_BSD_MACHINE_BUS_H_
123#define _RTEMS_BSD_MACHINE_BUS_H_
124
125#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_KERNEL_SPACE_H_
126#error "the header file <machine/rtems-bsd-kernel-space.h> must be included first"
127#endif
128
129#ifdef __i386__
130  #error "x86 has its own bus.h; check your include paths are correct"
131#endif
132
133#include <bsp.h>
134
135/*
136 * BSP PCI Support
137 *
138 * The RTEMS Nexus bus support can optionaly support PC PCI spaces that
139 * mapped to BSP speciic address spaces. Add the following define to
140 * the BSP header file to enable this support:
141 *
142 *  #define BSP_HAS_PC_PCI
143 *
144 * If enabled a BSP must support the following IO region calls:
145 *
146 * inb  : read 8 bits
147 * outb : write 8 bits
148 * inw  : read 16 bits
149 * outw : write 16 bits
150 * inl  : read 32 bits
151 * outl : write 32 bits
152 *
153 * The BSP needs to provide the DRAM address space offset
154 * PCI_DRAM_OFFSET. This is the base address of the DRAM as seen by a
155 * PCI master.
156 *
157 * i386 BSPs have a special bus.h file and do not use this file.
158 */
159
160#ifdef BSP_HAS_PC_PCI
161
162/*
163 * Values for the bus space tag, not to be used directly by MI code.
164 */
165#define BSP_BUS_SPACE_IO        0       /* space is i/o space */
166#define BSP_BUS_SPACE_MEM       1       /* space is mem space */
167
168#endif /* BSP_HAS_PC_PCI */
169
170/*
171 * Provide a memory tag for the DMA bus interface
172 */
173#ifdef BSP_BUS_SPACE_MEM
174#define BUS_SPACE_MEM BSP_BUS_SPACE_MEM
175#else
176#define BUS_SPACE_MEM 1
177#endif
178
179/*
180 * Bus address alignment.
181 */
182#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
183
184/*
185 * Bus address maxima.
186 */
187#define BUS_SPACE_MAXADDR_24BIT 0xffffffU
188#define BUS_SPACE_MAXADDR_32BIT 0xffffffffU
189#define BUS_SPACE_MAXADDR       UINTPTR_MAX
190#define BUS_SPACE_MAXSIZE_24BIT 0xffffffU
191#define BUS_SPACE_MAXSIZE_32BIT 0xffffffffU
192#define BUS_SPACE_MAXSIZE       UINTPTR_MAX
193
194/*
195 * Bus access.
196 */
197#define BUS_SPACE_INVALID_DATA  (~0U)
198#define BUS_SPACE_UNRESTRICTED  (~0U)
199
200/*
201 * Bus read/write barrier method.
202 */
203#define BUS_SPACE_BARRIER_READ  0x01            /* force read barrier */
204#define BUS_SPACE_BARRIER_WRITE 0x02            /* force write barrier */
205
206/*
207 * Bus address and size types
208 */
209typedef uintptr_t bus_addr_t;
210typedef uintptr_t bus_size_t;
211
212/*
213 * Access methods for bus resources and address space.
214 */
215typedef int bus_space_tag_t;
216typedef uintptr_t bus_space_handle_t;
217
218/*
219 * Map a region of device bus space into CPU virtual address space.
220 */
221
222static __inline int
223bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
224              bus_size_t size __unused, int flags __unused,
225              bus_space_handle_t *bshp)
226{
227        *bshp = addr;
228        return (0);
229}
230
231/*
232 * Unmap a region of device bus space.
233 */
234static __inline void
235bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused,
236    bus_size_t size __unused)
237{
238        /* Do nothing */
239}
240
241
242/*
243 * Get a new handle for a subregion of an already-mapped area of bus space.
244 */
245static __inline int
246bus_space_subregion(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
247    bus_size_t ofs, bus_size_t size, bus_space_handle_t *nbshp)
248{
249        *nbshp = bsh + ofs;
250        return (0);
251}
252
253
254/*
255 * Allocate a region of memory that is accessible to devices in bus space.
256 */
257int
258bus_space_alloc(bus_space_tag_t bst __unused, bus_addr_t rstart, bus_addr_t rend,
259    bus_size_t size, bus_size_t align, bus_size_t boundary, int flags,
260    bus_addr_t *addrp, bus_space_handle_t *bshp);
261
262
263/*
264 * Free a region of bus space accessible memory.
265 */
266void
267bus_space_free(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t size);
268
269static __inline void
270bus_space_barrier(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs,
271    bus_size_t size, int flags)
272{
273        /* Do nothing */
274}
275
276/*
277 * BSP Bus Space Map Support
278 *
279 * A BSP can provide the following as C macros in the BSP header
280 * (bsp.h) to speicalise for special BSP specific bus operations:
281 *
282 *  RTEMS_BSP_READ_1
283 *  RTEMS_BSP_READ_2
284 *  RTEMS_BSP_READ_4
285 *  RTEMS_BSP_READ_8
286 *  RTEMS_BSP_WRITE_1
287 *  RTEMS_BSP_WRITE_2
288 *  RTEMS_BSP_WRITE_4
289 *  RTEMS_BSP_WRITE_8
290 */
291
292static __inline uint8_t
293bsp_bus_space_read_1(const uint8_t __volatile *bsp)
294{
295#if defined(RTEMS_BSP_READ_1)
296        return RTEMS_BSP_READ_1(bsp);
297#else
298        return (*bsp);
299#endif
300}
301
302static __inline uint16_t
303bsp_bus_space_read_2(const uint16_t __volatile *bsp)
304{
305#if defined(RTEMS_BSP_READ_2)
306        return RTEMS_BSP_READ_2(bsp);
307#else
308        return (*bsp);
309#endif
310}
311
312static __inline uint32_t
313bsp_bus_space_read_4(const uint32_t __volatile *bsp)
314{
315#if defined(RTEMS_BSP_READ_4)
316        return RTEMS_BSP_READ_4(bsp);
317#else
318        return (*bsp);
319#endif
320}
321
322static __inline uint64_t
323bsp_bus_space_read_8(const uint64_t __volatile *bsp)
324{
325#if defined(RTEMS_BSP_READ_8)
326        return RTEMS_BSP_READ_8(bsp);
327#else
328        return (*bsp);
329#endif
330}
331
332static __inline void
333bsp_bus_space_write_1(uint8_t __volatile *bsp, uint8_t val)
334{
335#if defined(RTEMS_BSP_WRITE_1)
336        RTEMS_BSP_WRITE_1(bsp, val);
337#else
338        *bsp = val;
339#endif
340}
341
342static __inline void
343bsp_bus_space_write_2(uint16_t __volatile *bsp, uint16_t val)
344{
345#if defined(RTEMS_BSP_WRITE_2)
346        RTEMS_BSP_WRITE_2(bsp, val);
347#else
348        *bsp = val;
349#endif
350}
351
352static __inline void
353bsp_bus_space_write_4(uint32_t __volatile *bsp, uint32_t val)
354{
355#if defined(RTEMS_BSP_WRITE_4)
356        RTEMS_BSP_WRITE_4(bsp, val);
357#else
358        *bsp = val;
359#endif
360}
361
362static __inline void
363bsp_bus_space_write_8(uint64_t __volatile *bsp, uint64_t val)
364{
365#if defined(RTEMS_BSP_WRITE_8)
366        RTEMS_BSP_WRITE_8(bsp, val);
367#else
368        *bsp = val;
369#endif
370}
371
372
373/*
374 * Read 1 unit of data from bus space described by the tag, handle and ofs
375 * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
376 * data is returned.
377 */
378static __inline uint8_t
379bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
380{
381#ifdef BSP_HAS_PC_PCI
382        if (bst == BSP_BUS_SPACE_IO) {
383                return inb(bsh + ofs);
384        }
385#endif
386        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
387        return bsp_bus_space_read_1(bsp);
388}
389
390static __inline uint16_t
391bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
392{
393#ifdef BSP_HAS_PC_PCI
394        if (bst == BSP_BUS_SPACE_IO) {
395                return inw(bsh + ofs);
396        }
397#endif
398        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
399        return bsp_bus_space_read_2(bsp);
400}
401
402static __inline uint32_t
403bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
404{
405#ifdef BSP_HAS_PC_PCI
406        if (bst == BSP_BUS_SPACE_IO) {
407                return inl(bsh + ofs);
408        }
409#endif
410        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
411        return bsp_bus_space_read_4(bsp);
412}
413
414static __inline uint64_t
415bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
416{
417#ifdef BSP_HAS_PC_PCI
418        if (bst == BSP_BUS_SPACE_IO)
419                return BUS_SPACE_INVALID_DATA;
420#endif
421        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
422        return bsp_bus_space_read_8(bsp);
423}
424
425
426/*
427 * Write 1 unit of data to bus space described by the tag, handle and ofs
428 * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
429 * data is passed by value.
430 */
431static __inline void
432bus_space_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
433    uint8_t val)
434{
435#ifdef BSP_HAS_PC_PCI
436        if (bst == BSP_BUS_SPACE_IO) {
437                outb(val, bsh + ofs);
438                return;
439        }
440#endif
441        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
442        bsp_bus_space_write_1(bsp, val);
443}
444
445static __inline void
446bus_space_write_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
447    uint16_t val)
448{
449#ifdef BSP_HAS_PC_PCI
450        if (bst == BSP_BUS_SPACE_IO) {
451                outw(val, bsh + ofs);
452                return;
453        }
454#endif
455        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
456        bsp_bus_space_write_2(bsp, val);
457}
458
459static __inline void
460bus_space_write_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
461    uint32_t val)
462{
463#ifdef BSP_HAS_PC_PCI
464        if (bst == BSP_BUS_SPACE_IO) {
465                outl(val, bsh + ofs);
466                return;
467        }
468#endif
469        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
470        bsp_bus_space_write_4(bsp, val);
471}
472
473static __inline void
474bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
475    uint64_t val)
476{
477#ifdef BSP_HAS_PC_PCI
478        if (bst == BSP_BUS_SPACE_IO) {
479                return;
480        }
481#endif
482        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
483        bsp_bus_space_write_8(bsp, val);
484}
485
486
487/*
488 * Read count units of data from bus space described by the tag, handle and
489 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
490 * data is returned in the buffer passed by reference.
491 */
492static __inline void
493bus_space_read_multi_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
494    bus_size_t ofs, uint8_t *bufp, bus_size_t count)
495{
496        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
497        while (count-- > 0) {
498                *bufp++ = bsp_bus_space_read_1(bsp);
499        }
500}
501
502static __inline void
503bus_space_read_multi_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
504    bus_size_t ofs, uint16_t *bufp, bus_size_t count)
505{
506        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
507        while (count-- > 0) {
508                *bufp++ = bsp_bus_space_read_2(bsp);
509        }
510}
511
512static __inline void
513bus_space_read_multi_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
514    bus_size_t ofs, uint32_t *bufp, bus_size_t count)
515{
516        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
517        while (count-- > 0) {
518                *bufp++ = bsp_bus_space_read_4(bsp);
519        }
520}
521
522static __inline void
523bus_space_read_multi_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
524    bus_size_t ofs, uint64_t *bufp, bus_size_t count)
525{
526        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
527        while (count-- > 0) {
528                *bufp++ = bsp_bus_space_read_8(bsp);
529        }
530}
531
532
533/*
534 * Write count units of data to bus space described by the tag, handle and
535 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
536 * data is read from the buffer passed by reference.
537 */
538static __inline void
539bus_space_write_multi_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
540    bus_size_t ofs, const uint8_t *bufp, bus_size_t count)
541{
542        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
543        while (count-- > 0) {
544                bsp_bus_space_write_1(bsp, *bufp++);
545        }
546}
547
548static __inline void
549bus_space_write_multi_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
550    bus_size_t ofs, const uint16_t *bufp, bus_size_t count)
551{
552        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
553        while (count-- > 0) {
554                bsp_bus_space_write_2(bsp, *bufp++);
555        }
556}
557
558static __inline void
559bus_space_write_multi_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
560    bus_size_t ofs, const uint32_t *bufp, bus_size_t count)
561{
562        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
563        while (count-- > 0) {
564                bsp_bus_space_write_4(bsp, *bufp++);
565        }
566}
567
568static __inline void
569bus_space_write_multi_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
570    bus_size_t ofs, const uint64_t *bufp, bus_size_t count)
571{
572        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
573        while (count-- > 0) {
574                bsp_bus_space_write_8(bsp, *bufp++);
575        }
576}
577
578
579/*
580 * Read count units of data from bus space described by the tag, handle and
581 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
582 * data is written to the buffer passed by reference and read from successive
583 * bus space addresses. Access is unordered.
584 */
585static __inline void
586bus_space_read_region_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
587    bus_size_t ofs, uint8_t *bufp, bus_size_t count)
588{
589        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
590        while (count-- > 0) {
591                *bufp++ = bsp_bus_space_read_1(bsp++);
592        }
593}
594
595static __inline void
596bus_space_read_region_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
597    bus_size_t ofs, uint16_t *bufp, bus_size_t count)
598{
599        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
600        while (count-- > 0) {
601                *bufp++ = bsp_bus_space_read_2(bsp++);
602        }
603}
604
605static __inline void
606bus_space_read_region_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
607    bus_size_t ofs, uint32_t *bufp, bus_size_t count)
608{
609        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
610        while (count-- > 0) {
611                *bufp++ = bsp_bus_space_read_4(bsp++);
612        }
613}
614
615static __inline void
616bus_space_read_region_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
617    bus_size_t ofs, uint64_t *bufp, bus_size_t count)
618{
619        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
620        while (count-- > 0) {
621                *bufp++ = bsp_bus_space_read_8(bsp++);
622        }
623}
624
625
626/*
627 * Write count units of data from bus space described by the tag, handle and
628 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
629 * data is read from the buffer passed by reference and written to successive
630 * bus space addresses. Access is unordered.
631 */
632static __inline void
633bus_space_write_region_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
634    bus_size_t ofs, const uint8_t *bufp, bus_size_t count)
635{
636        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
637        while (count-- > 0) {
638                bsp_bus_space_write_1(bsp++, *bufp++);
639        }
640}
641
642static __inline void
643bus_space_write_region_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
644    bus_size_t ofs, const uint16_t *bufp, bus_size_t count)
645{
646        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
647        while (count-- > 0) {
648                bsp_bus_space_write_2(bsp++, *bufp++);
649        }
650}
651
652static __inline void
653bus_space_write_region_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
654    bus_size_t ofs, const uint32_t *bufp, bus_size_t count)
655{
656        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
657        while (count-- > 0) {
658                bsp_bus_space_write_4(bsp++, *bufp++);
659        }
660}
661
662static __inline void
663bus_space_write_region_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
664    bus_size_t ofs, const uint64_t *bufp, bus_size_t count)
665{
666        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
667        while (count-- > 0) {
668                bsp_bus_space_write_8(bsp++, *bufp++);
669        }
670}
671
672
673/*
674 * Write count units of data from bus space described by the tag, handle and
675 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
676 * data is passed by value. Writes are unordered.
677 */
678static __inline void
679bus_space_set_multi_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
680    bus_size_t ofs, uint8_t val, bus_size_t count)
681{
682        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
683        while (count-- > 0) {
684                bsp_bus_space_write_1(bsp, val);
685        }
686}
687
688static __inline void
689bus_space_set_multi_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
690    bus_size_t ofs, uint16_t val, bus_size_t count)
691{
692        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
693        while (count-- > 0) {
694                bsp_bus_space_write_2(bsp, val);
695        }
696}
697
698static __inline void
699bus_space_set_multi_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
700    bus_size_t ofs, uint32_t val, bus_size_t count)
701{
702        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
703        while (count-- > 0) {
704                bsp_bus_space_write_4(bsp, val);
705        }
706}
707
708static __inline void
709bus_space_set_multi_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
710    bus_size_t ofs, uint64_t val, bus_size_t count)
711{
712        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
713        while (count-- > 0) {
714                bsp_bus_space_write_8(bsp, val);
715        }
716}
717
718
719/*
720 * Write count units of data from bus space described by the tag, handle and
721 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
722 * data is passed by value and written to successive bus space addresses.
723 * Writes are unordered.
724 */
725static __inline void
726bus_space_set_region_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
727    bus_size_t ofs, uint8_t val, bus_size_t count)
728{
729        uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs);
730        while (count-- > 0) {
731                bsp_bus_space_write_1(bsp++, val);
732        }
733}
734
735static __inline void
736bus_space_set_region_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
737    bus_size_t ofs, uint16_t val, bus_size_t count)
738{
739        uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs);
740        while (count-- > 0) {
741                bsp_bus_space_write_2(bsp++, val);
742        }
743}
744
745static __inline void
746bus_space_set_region_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
747    bus_size_t ofs, uint32_t val, bus_size_t count)
748{
749        uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs);
750        while (count-- > 0) {
751                bsp_bus_space_write_4(bsp++, val);
752        }
753}
754
755static __inline void
756bus_space_set_region_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
757    bus_size_t ofs, uint64_t val, bus_size_t count)
758{
759        uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs);
760        while (count-- > 0) {
761                bsp_bus_space_write_8(bsp++, val);
762        }
763}
764
765
766/*
767 * Copy count units of data from bus space described by the tag and the first
768 * handle and ofs pair to bus space described by the tag and the second handle
769 * and ofs pair. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes.
770 * The data is read from successive bus space addresses and also written to
771 * successive bus space addresses. Both reads and writes are unordered.
772 */
773static __inline void
774bus_space_copy_region_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh1,
775    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, bus_size_t count)
776{
777        uint8_t __volatile *dst = (uint8_t __volatile *)(bsh1 + ofs1);
778        uint8_t __volatile *src = (uint8_t __volatile *)(bsh2 + ofs2);
779        if (dst > src) {
780                src += count - 1;
781                dst += count - 1;
782                while (count-- > 0) {
783                        bsp_bus_space_write_1(dst, bsp_bus_space_read_1(src));
784                        src--;
785                        dst--;
786                }
787        } else {
788                while (count-- > 0) {
789                        bsp_bus_space_write_1(dst, bsp_bus_space_read_1(src));
790                        src++;
791                        dst++;
792                }
793        }
794}
795
796static __inline void
797bus_space_copy_region_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh1,
798    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, bus_size_t count)
799{
800        uint16_t __volatile *dst = (uint16_t __volatile *)(bsh1 + ofs1);
801        uint16_t __volatile *src = (uint16_t __volatile *)(bsh2 + ofs2);;
802        if (dst > src) {
803                src += count - 1;
804                dst += count - 1;
805                while (count-- > 0) {
806                        bsp_bus_space_write_2(dst, bsp_bus_space_read_2(src));
807                        src--;
808                        dst--;
809                }
810        } else {
811                while (count-- > 0) {
812                        bsp_bus_space_write_2(dst, bsp_bus_space_read_2(src));
813                        src++;
814                        dst++;
815                }
816        }
817}
818
819static __inline void
820bus_space_copy_region_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh1,
821    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, bus_size_t count)
822{
823        uint32_t __volatile *dst = (uint32_t __volatile *)(bsh1 + ofs1);
824        uint32_t __volatile *src = (uint32_t __volatile *)(bsh2 + ofs2);;
825        if (dst > src) {
826                src += count - 1;
827                dst += count - 1;
828                while (count-- > 0) {
829                        bsp_bus_space_write_4(dst, bsp_bus_space_read_4(src));
830                        src--;
831                        dst--;
832                }
833        } else {
834                while (count-- > 0) {
835                        bsp_bus_space_write_4(dst, bsp_bus_space_read_4(src));
836                        src++;
837                        dst++;
838                }
839        }
840}
841
842static __inline void
843bus_space_copy_region_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh1,
844    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, bus_size_t count)
845{
846        uint64_t __volatile *dst = (uint64_t __volatile *)(bsh1 + ofs1);
847        uint64_t __volatile *src = (uint64_t __volatile *)(bsh2 + ofs2);;
848        if (dst > src) {
849                src += count - 1;
850                dst += count - 1;
851                while (count-- > 0) {
852                        bsp_bus_space_write_8(dst, bsp_bus_space_read_8(src));
853                        src--;
854                        dst--;
855                }
856        } else {
857                while (count-- > 0) {
858                        bsp_bus_space_write_8(dst, bsp_bus_space_read_8(src));
859                        src++;
860                        dst++;
861                }
862        }
863}
864
865
866/*
867 * Stream accesses are the same as normal accesses on RTEMS; there are no
868 * supported bus systems with an endianess different from the host one.
869 */
870#define bus_space_read_stream_1(t, h, o)        \
871        bus_space_read_1(t, h, o)
872#define bus_space_read_stream_2(t, h, o)        \
873        bus_space_read_2(t, h, o)
874#define bus_space_read_stream_4(t, h, o)        \
875        bus_space_read_4(t, h, o)
876#define bus_space_read_stream_8(t, h, o)        \
877        bus_space_read_8(t, h, o)
878
879#define bus_space_read_multi_stream_1(t, h, o, a, c)    \
880        bus_space_read_multi_1(t, h, o, a, c)
881#define bus_space_read_multi_stream_2(t, h, o, a, c)    \
882        bus_space_read_multi_2(t, h, o, a, c)
883#define bus_space_read_multi_stream_4(t, h, o, a, c)    \
884        bus_space_read_multi_4(t, h, o, a, c)
885#define bus_space_read_multi_stream_8(t, h, o, a, c)    \
886        bus_space_read_multi_8(t, h, o, a, c)
887
888#define bus_space_write_stream_1(t, h, o, v)    \
889        bus_space_write_1(t, h, o, v)
890#define bus_space_write_stream_2(t, h, o, v)    \
891        bus_space_write_2(t, h, o, v)
892#define bus_space_write_stream_4(t, h, o, v)    \
893        bus_space_write_4(t, h, o, v)
894#define bus_space_write_stream_8(t, h, o, v)    \
895        bus_space_write_8(t, h, o, v)
896
897#define bus_space_write_multi_stream_1(t, h, o, a, c)   \
898        bus_space_write_multi_1(t, h, o, a, c)
899#define bus_space_write_multi_stream_2(t, h, o, a, c)   \
900        bus_space_write_multi_2(t, h, o, a, c)
901#define bus_space_write_multi_stream_4(t, h, o, a, c)   \
902        bus_space_write_multi_4(t, h, o, a, c)
903#define bus_space_write_multi_stream_8(t, h, o, a, c)   \
904        bus_space_write_multi_8(t, h, o, a, c)
905
906#define bus_space_set_multi_stream_1(t, h, o, v, c)     \
907        bus_space_set_multi_1(t, h, o, v, c)
908#define bus_space_set_multi_stream_2(t, h, o, v, c)     \
909        bus_space_set_multi_2(t, h, o, v, c)
910#define bus_space_set_multi_stream_4(t, h, o, v, c)     \
911        bus_space_set_multi_4(t, h, o, v, c)
912#define bus_space_set_multi_stream_8(t, h, o, v, c)     \
913        bus_space_set_multi_8(t, h, o, v, c)
914
915#define bus_space_read_region_stream_1(t, h, o, a, c)   \
916        bus_space_read_region_1(t, h, o, a, c)
917#define bus_space_read_region_stream_2(t, h, o, a, c)   \
918        bus_space_read_region_2(t, h, o, a, c)
919#define bus_space_read_region_stream_4(t, h, o, a, c)   \
920        bus_space_read_region_4(t, h, o, a, c)
921#define bus_space_read_region_stream_8(t, h, o, a, c)   \
922        bus_space_read_region_8(t, h, o, a, c)
923
924#define bus_space_write_region_stream_1(t, h, o, a, c)  \
925        bus_space_write_region_1(t, h, o, a, c)
926#define bus_space_write_region_stream_2(t, h, o, a, c)  \
927        bus_space_write_region_2(t, h, o, a, c)
928#define bus_space_write_region_stream_4(t, h, o, a, c)  \
929        bus_space_write_region_4(t, h, o, a, c)
930#define bus_space_write_region_stream_8(t, h, o, a, c)  \
931        bus_space_write_region_8(t, h, o, a, c)
932
933#define bus_space_set_region_stream_1(t, h, o, v, c)    \
934        bus_space_set_region_1(t, h, o, v, c)
935#define bus_space_set_region_stream_2(t, h, o, v, c)    \
936        bus_space_set_region_2(t, h, o, v, c)
937#define bus_space_set_region_stream_4(t, h, o, v, c)    \
938        bus_space_set_region_4(t, h, o, v, c)
939#define bus_space_set_region_stream_8(t, h, o, v, c)    \
940        bus_space_set_region_8(t, h, o, v, c)
941
942#define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c)    \
943        bus_space_copy_region_1(t, h1, o1, h2, o2, c)
944#define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c)    \
945        bus_space_copy_region_2(t, h1, o1, h2, o2, c)
946#define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c)    \
947        bus_space_copy_region_4(t, h1, o1, h2, o2, c)
948#define bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c)    \
949        bus_space_copy_region_8(t, h1, o1, h2, o2, c)
950
951#include <machine/bus_dma.h>
952
953#endif /* _RTEMS_BSD_MACHINE_BUS_H_ */
Note: See TracBrowser for help on using the repository browser.