source: rtems-libbsd/rtemsbsd/include/machine/bus_space-i386.h @ be2e60c

4.115-freebsd-12freebsd-9.3
Last change on this file since be2e60c was e599318, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 9, 2013 at 8:52:54 PM

Update files to match FreeBSD layout

Add compatibility with Newlib header files. Some FreeBSD header files
are mapped by the translation script:

o rtems/bsd/sys/_types.h
o rtems/bsd/sys/errno.h
o rtems/bsd/sys/lock.h
o rtems/bsd/sys/param.h
o rtems/bsd/sys/resource.h
o rtems/bsd/sys/time.h
o rtems/bsd/sys/timespec.h
o rtems/bsd/sys/types.h
o rtems/bsd/sys/unistd.h

It is now possible to include <sys/socket.h> directly for example.

Generate one Makefile which builds everything including tests.

  • Property mode set to 100644
File size: 31.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_bsd_machine
5 *
6 * @brief TODO.
7 *
8 * File origin from FreeBSD 'sys/i386/include/bus.h'.
9 */
10
11/*-
12 * Copyright (c) KATO Takenori, 1999.
13 *
14 * All rights reserved.  Unpublished rights reserved under the copyright
15 * laws of Japan.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 *
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer as
23 *    the first lines of this file unmodified.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 *    notice, this list of conditions and the following disclaimer in the
26 *    documentation and/or other materials provided with the distribution.
27 * 3. The name of the author may not be used to endorse or promote products
28 *    derived from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * $FreeBSD$
42 */
43
44/*      $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $    */
45
46/*-
47 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
48 * All rights reserved.
49 *
50 * This code is derived from software contributed to The NetBSD Foundation
51 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
52 * NASA Ames Research Center.
53 *
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
56 * are met:
57 * 1. Redistributions of source code must retain the above copyright
58 *    notice, this list of conditions and the following disclaimer.
59 * 2. Redistributions in binary form must reproduce the above copyright
60 *    notice, this list of conditions and the following disclaimer in the
61 *    documentation and/or other materials provided with the distribution.
62 * 3. All advertising materials mentioning features or use of this software
63 *    must display the following acknowledgement:
64 *      This product includes software developed by the NetBSD
65 *      Foundation, Inc. and its contributors.
66 * 4. Neither the name of The NetBSD Foundation nor the names of its
67 *    contributors may be used to endorse or promote products derived
68 *    from this software without specific prior written permission.
69 *
70 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
71 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
72 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
73 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
74 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
75 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
76 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
77 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
78 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
79 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
80 * POSSIBILITY OF SUCH DAMAGE.
81 */
82
83/*-
84 * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
85 * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
86 *
87 * Redistribution and use in source and binary forms, with or without
88 * modification, are permitted provided that the following conditions
89 * are met:
90 * 1. Redistributions of source code must retain the above copyright
91 *    notice, this list of conditions and the following disclaimer.
92 * 2. Redistributions in binary form must reproduce the above copyright
93 *    notice, this list of conditions and the following disclaimer in the
94 *    documentation and/or other materials provided with the distribution.
95 * 3. All advertising materials mentioning features or use of this software
96 *    must display the following acknowledgement:
97 *      This product includes software developed by Christopher G. Demetriou
98 *      for the NetBSD Project.
99 * 4. The name of the author may not be used to endorse or promote products
100 *    derived from this software without specific prior written permission
101 *
102 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
103 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
104 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
105 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
106 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
107 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
108 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
109 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
110 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
111 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
112 */
113
114#ifndef _RTEMS_BSD_MACHINE_BUS_I386_H_
115#define _RTEMS_BSD_MACHINE_BUS_I386_H_
116
117#include <machine/_bus.h>
118#include <machine/cpufunc.h>
119#include <machine/resource.h>
120
121#if 0
122#define I386_BUS_SPACE_IO SYS_RES_IOPORT
123#else
124#define I386_BUS_SPACE_IO       0       /* space is i/o space */
125#define I386_BUS_SPACE_MEM      1       /* space is mem space */ 
126#endif
127
128/*
129 * Read a 1, 2, 4, or 8 byte quantity from bus space
130 * described by tag/handle/offset.
131 */
132static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
133                                          bus_space_handle_t handle,
134                                          bus_size_t offset);
135
136static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
137                                           bus_space_handle_t handle,
138                                           bus_size_t offset);
139
140static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
141                                           bus_space_handle_t handle,
142                                           bus_size_t offset);
143
144static __inline u_int8_t
145bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
146                 bus_size_t offset)
147{
148
149        if (tag == I386_BUS_SPACE_IO)
150                return (inb(handle + offset));
151        return (*(volatile u_int8_t *)(handle + offset));
152}
153
154static __inline u_int16_t
155bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
156                 bus_size_t offset)
157{
158
159        if (tag == I386_BUS_SPACE_IO)
160                return (inw(handle + offset));
161        return (*(volatile u_int16_t *)(handle + offset));
162}
163
164static __inline u_int32_t
165bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
166                 bus_size_t offset)
167{
168
169        if (tag == I386_BUS_SPACE_IO)
170                return (inl(handle + offset));
171        return (*(volatile u_int32_t *)(handle + offset));
172}
173
174#if 0   /* Cause a link error for bus_space_read_8 */
175#define bus_space_read_8(t, h, o)       !!! bus_space_read_8 unimplemented !!!
176#endif
177
178/*
179 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
180 * described by tag/handle/offset and copy into buffer provided.
181 */
182static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
183                                            bus_space_handle_t bsh,
184                                            bus_size_t offset, u_int8_t *addr,
185                                            size_t count);
186
187static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
188                                            bus_space_handle_t bsh,
189                                            bus_size_t offset, u_int16_t *addr,
190                                            size_t count);
191
192static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
193                                            bus_space_handle_t bsh,
194                                            bus_size_t offset, u_int32_t *addr,
195                                            size_t count);
196
197static __inline void
198bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
199                       bus_size_t offset, u_int8_t *addr, size_t count)
200{
201
202        if (tag == I386_BUS_SPACE_IO)
203                insb(bsh + offset, addr, count);
204        else {
205#ifdef __GNUCLIKE_ASM
206                __asm __volatile("                              \n\
207                        cld                                     \n\
208                1:      movb (%2),%%al                          \n\
209                        stosb                                   \n\
210                        loop 1b"                                :
211                    "=D" (addr), "=c" (count)                   :
212                    "r" (bsh + offset), "0" (addr), "1" (count) :
213                    "%eax", "memory");
214#else
215# ifndef lint
216#  error "no assembler code for your compiler"
217# endif
218#endif
219        }
220}
221
222static __inline void
223bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
224                       bus_size_t offset, u_int16_t *addr, size_t count)
225{
226
227        if (tag == I386_BUS_SPACE_IO)
228                insw(bsh + offset, addr, count);
229        else {
230#ifdef __GNUCLIKE_ASM
231                __asm __volatile("                              \n\
232                        cld                                     \n\
233                1:      movw (%2),%%ax                          \n\
234                        stosw                                   \n\
235                        loop 1b"                                :
236                    "=D" (addr), "=c" (count)                   :
237                    "r" (bsh + offset), "0" (addr), "1" (count) :
238                    "%eax", "memory");
239#else
240# ifndef lint
241#  error "no assembler code for your compiler"
242# endif
243#endif
244        }
245}
246
247static __inline void
248bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
249                       bus_size_t offset, u_int32_t *addr, size_t count)
250{
251
252        if (tag == I386_BUS_SPACE_IO)
253                insl(bsh + offset, addr, count);
254        else {
255#ifdef __GNUCLIKE_ASM
256                __asm __volatile("                              \n\
257                        cld                                     \n\
258                1:      movl (%2),%%eax                         \n\
259                        stosl                                   \n\
260                        loop 1b"                                :
261                    "=D" (addr), "=c" (count)                   :
262                    "r" (bsh + offset), "0" (addr), "1" (count) :
263                    "%eax", "memory");
264#else
265# ifndef lint
266#  error "no assembler code for your compiler"
267# endif
268#endif
269        }
270}
271
272#if 0   /* Cause a link error for bus_space_read_multi_8 */
273#define bus_space_read_multi_8  !!! bus_space_read_multi_8 unimplemented !!!
274#endif
275
276/*
277 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
278 * described by tag/handle and starting at `offset' and copy into
279 * buffer provided.
280 */
281static __inline void bus_space_read_region_1(bus_space_tag_t tag,
282                                             bus_space_handle_t bsh,
283                                             bus_size_t offset, u_int8_t *addr,
284                                             size_t count);
285
286static __inline void bus_space_read_region_2(bus_space_tag_t tag,
287                                             bus_space_handle_t bsh,
288                                             bus_size_t offset, u_int16_t *addr,
289                                             size_t count);
290
291static __inline void bus_space_read_region_4(bus_space_tag_t tag,
292                                             bus_space_handle_t bsh,
293                                             bus_size_t offset, u_int32_t *addr,
294                                             size_t count);
295
296
297static __inline void
298bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
299                        bus_size_t offset, u_int8_t *addr, size_t count)
300{
301
302        if (tag == I386_BUS_SPACE_IO) {
303                int _port_ = bsh + offset;
304#ifdef __GNUCLIKE_ASM
305                __asm __volatile("                              \n\
306                        cld                                     \n\
307                1:      inb %w2,%%al                            \n\
308                        stosb                                   \n\
309                        incl %2                                 \n\
310                        loop 1b"                                :
311                    "=D" (addr), "=c" (count), "=d" (_port_)    :
312                    "0" (addr), "1" (count), "2" (_port_)       :
313                    "%eax", "memory", "cc");
314#else
315# ifndef lint
316#  error "no assembler code for your compiler"
317# endif
318#endif
319        } else {
320                int _port_ = bsh + offset;
321#ifdef __GNUCLIKE_ASM
322                __asm __volatile("                              \n\
323                        cld                                     \n\
324                        repne                                   \n\
325                        movsb"                                  :
326                    "=D" (addr), "=c" (count), "=S" (_port_)    :
327                    "0" (addr), "1" (count), "2" (_port_)       :
328                    "memory", "cc");
329#else
330# ifndef lint
331#  error "no assembler code for your compiler"
332# endif
333#endif
334        }
335}
336
337static __inline void
338bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
339                        bus_size_t offset, u_int16_t *addr, size_t count)
340{
341
342        if (tag == I386_BUS_SPACE_IO) {
343                int _port_ = bsh + offset;
344#ifdef __GNUCLIKE_ASM
345                __asm __volatile("                              \n\
346                        cld                                     \n\
347                1:      inw %w2,%%ax                            \n\
348                        stosw                                   \n\
349                        addl $2,%2                              \n\
350                        loop 1b"                                :
351                    "=D" (addr), "=c" (count), "=d" (_port_)    :
352                    "0" (addr), "1" (count), "2" (_port_)       :
353                    "%eax", "memory", "cc");
354#else
355# ifndef lint
356#  error "no assembler code for your compiler"
357# endif
358#endif
359        } else {
360                int _port_ = bsh + offset;
361#ifdef __GNUCLIKE_ASM
362                __asm __volatile("                              \n\
363                        cld                                     \n\
364                        repne                                   \n\
365                        movsw"                                  :
366                    "=D" (addr), "=c" (count), "=S" (_port_)    :
367                    "0" (addr), "1" (count), "2" (_port_)       :
368                    "memory", "cc");
369#else
370# ifndef lint
371#  error "no assembler code for your compiler"
372# endif
373#endif
374        }
375}
376
377static __inline void
378bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
379                        bus_size_t offset, u_int32_t *addr, size_t count)
380{
381
382        if (tag == I386_BUS_SPACE_IO) {
383                int _port_ = bsh + offset;
384#ifdef __GNUCLIKE_ASM
385                __asm __volatile("                              \n\
386                        cld                                     \n\
387                1:      inl %w2,%%eax                           \n\
388                        stosl                                   \n\
389                        addl $4,%2                              \n\
390                        loop 1b"                                :
391                    "=D" (addr), "=c" (count), "=d" (_port_)    :
392                    "0" (addr), "1" (count), "2" (_port_)       :
393                    "%eax", "memory", "cc");
394#else
395# ifndef lint
396#  error "no assembler code for your compiler"
397# endif
398#endif
399        } else {
400                int _port_ = bsh + offset;
401#ifdef __GNUCLIKE_ASM
402                __asm __volatile("                              \n\
403                        cld                                     \n\
404                        repne                                   \n\
405                        movsl"                                  :
406                    "=D" (addr), "=c" (count), "=S" (_port_)    :
407                    "0" (addr), "1" (count), "2" (_port_)       :
408                    "memory", "cc");
409#else
410# ifndef lint
411#  error "no assembler code for your compiler"
412# endif
413#endif
414        }
415}
416
417#if 0   /* Cause a link error for bus_space_read_region_8 */
418#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
419#endif
420
421/*
422 * Write the 1, 2, 4, or 8 byte value `value' to bus space
423 * described by tag/handle/offset.
424 */
425
426static __inline void bus_space_write_1(bus_space_tag_t tag,
427                                       bus_space_handle_t bsh,
428                                       bus_size_t offset, u_int8_t value);
429
430static __inline void bus_space_write_2(bus_space_tag_t tag,
431                                       bus_space_handle_t bsh,
432                                       bus_size_t offset, u_int16_t value);
433
434static __inline void bus_space_write_4(bus_space_tag_t tag,
435                                       bus_space_handle_t bsh,
436                                       bus_size_t offset, u_int32_t value);
437
438static __inline void
439bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
440                       bus_size_t offset, u_int8_t value)
441{
442
443        if (tag == I386_BUS_SPACE_IO)
444                outb(bsh + offset, value);
445        else
446                *(volatile u_int8_t *)(bsh + offset) = value;
447}
448
449static __inline void
450bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
451                       bus_size_t offset, u_int16_t value)
452{
453
454        if (tag == I386_BUS_SPACE_IO)
455                outw(bsh + offset, value);
456        else
457                *(volatile u_int16_t *)(bsh + offset) = value;
458}
459
460static __inline void
461bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
462                       bus_size_t offset, u_int32_t value)
463{
464
465        if (tag == I386_BUS_SPACE_IO)
466                outl(bsh + offset, value);
467        else
468                *(volatile u_int32_t *)(bsh + offset) = value;
469}
470
471#if 0   /* Cause a link error for bus_space_write_8 */
472#define bus_space_write_8       !!! bus_space_write_8 not implemented !!!
473#endif
474
475/*
476 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
477 * provided to bus space described by tag/handle/offset.
478 */
479
480static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
481                                             bus_space_handle_t bsh,
482                                             bus_size_t offset,
483                                             const u_int8_t *addr,
484                                             size_t count);
485static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
486                                             bus_space_handle_t bsh,
487                                             bus_size_t offset,
488                                             const u_int16_t *addr,
489                                             size_t count);
490
491static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
492                                             bus_space_handle_t bsh,
493                                             bus_size_t offset,
494                                             const u_int32_t *addr,
495                                             size_t count);
496
497static __inline void
498bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
499                        bus_size_t offset, const u_int8_t *addr, size_t count)
500{
501
502        if (tag == I386_BUS_SPACE_IO)
503                outsb(bsh + offset, addr, count);
504        else {
505#ifdef __GNUCLIKE_ASM
506                __asm __volatile("                              \n\
507                        cld                                     \n\
508                1:      lodsb                                   \n\
509                        movb %%al,(%2)                          \n\
510                        loop 1b"                                :
511                    "=S" (addr), "=c" (count)                   :
512                    "r" (bsh + offset), "0" (addr), "1" (count) :
513                    "%eax", "memory", "cc");
514#else
515# ifndef lint
516#  error "no assembler code for your compiler"
517# endif
518#endif
519        }
520}
521
522static __inline void
523bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
524                        bus_size_t offset, const u_int16_t *addr, size_t count)
525{
526
527        if (tag == I386_BUS_SPACE_IO)
528                outsw(bsh + offset, addr, count);
529        else {
530#ifdef __GNUCLIKE_ASM
531                __asm __volatile("                              \n\
532                        cld                                     \n\
533                1:      lodsw                                   \n\
534                        movw %%ax,(%2)                          \n\
535                        loop 1b"                                :
536                    "=S" (addr), "=c" (count)                   :
537                    "r" (bsh + offset), "0" (addr), "1" (count) :
538                    "%eax", "memory", "cc");
539#else
540# ifndef lint
541#  error "no assembler code for your compiler"
542# endif
543#endif
544        }
545}
546
547static __inline void
548bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
549                        bus_size_t offset, const u_int32_t *addr, size_t count)
550{
551
552        if (tag == I386_BUS_SPACE_IO)
553                outsl(bsh + offset, addr, count);
554        else {
555#ifdef __GNUCLIKE_ASM
556                __asm __volatile("                              \n\
557                        cld                                     \n\
558                1:      lodsl                                   \n\
559                        movl %%eax,(%2)                         \n\
560                        loop 1b"                                :
561                    "=S" (addr), "=c" (count)                   :
562                    "r" (bsh + offset), "0" (addr), "1" (count) :
563                    "%eax", "memory", "cc");
564#else
565# ifndef lint
566#  error "no assembler code for your compiler"
567# endif
568#endif
569        }
570}
571
572#if 0   /* Cause a link error for bus_space_write_multi_8 */
573#define bus_space_write_multi_8(t, h, o, a, c)                          \
574                        !!! bus_space_write_multi_8 unimplemented !!!
575#endif
576
577/*
578 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
579 * to bus space described by tag/handle starting at `offset'.
580 */
581
582static __inline void bus_space_write_region_1(bus_space_tag_t tag,
583                                              bus_space_handle_t bsh,
584                                              bus_size_t offset,
585                                              const u_int8_t *addr,
586                                              size_t count);
587static __inline void bus_space_write_region_2(bus_space_tag_t tag,
588                                              bus_space_handle_t bsh,
589                                              bus_size_t offset,
590                                              const u_int16_t *addr,
591                                              size_t count);
592static __inline void bus_space_write_region_4(bus_space_tag_t tag,
593                                              bus_space_handle_t bsh,
594                                              bus_size_t offset,
595                                              const u_int32_t *addr,
596                                              size_t count);
597
598static __inline void
599bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
600                         bus_size_t offset, const u_int8_t *addr, size_t count)
601{
602
603        if (tag == I386_BUS_SPACE_IO) {
604                int _port_ = bsh + offset;
605#ifdef __GNUCLIKE_ASM
606                __asm __volatile("                              \n\
607                        cld                                     \n\
608                1:      lodsb                                   \n\
609                        outb %%al,%w0                           \n\
610                        incl %0                                 \n\
611                        loop 1b"                                :
612                    "=d" (_port_), "=S" (addr), "=c" (count)    :
613                    "0" (_port_), "1" (addr), "2" (count)       :
614                    "%eax", "memory", "cc");
615#else
616# ifndef lint
617#  error "no assembler code for your compiler"
618# endif
619#endif
620        } else {
621                int _port_ = bsh + offset;
622#ifdef __GNUCLIKE_ASM
623                __asm __volatile("                              \n\
624                        cld                                     \n\
625                        repne                                   \n\
626                        movsb"                                  :
627                    "=D" (_port_), "=S" (addr), "=c" (count)    :
628                    "0" (_port_), "1" (addr), "2" (count)       :
629                    "memory", "cc");
630#else
631# ifndef lint
632#  error "no assembler code for your compiler"
633# endif
634#endif
635        }
636}
637
638static __inline void
639bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
640                         bus_size_t offset, const u_int16_t *addr, size_t count)
641{
642
643        if (tag == I386_BUS_SPACE_IO) {
644                int _port_ = bsh + offset;
645#ifdef __GNUCLIKE_ASM
646                __asm __volatile("                              \n\
647                        cld                                     \n\
648                1:      lodsw                                   \n\
649                        outw %%ax,%w0                           \n\
650                        addl $2,%0                              \n\
651                        loop 1b"                                :
652                    "=d" (_port_), "=S" (addr), "=c" (count)    :
653                    "0" (_port_), "1" (addr), "2" (count)       :
654                    "%eax", "memory", "cc");
655#else
656# ifndef lint
657#  error "no assembler code for your compiler"
658# endif
659#endif
660        } else {
661                int _port_ = bsh + offset;
662#ifdef __GNUCLIKE_ASM
663                __asm __volatile("                              \n\
664                        cld                                     \n\
665                        repne                                   \n\
666                        movsw"                                  :
667                    "=D" (_port_), "=S" (addr), "=c" (count)    :
668                    "0" (_port_), "1" (addr), "2" (count)       :
669                    "memory", "cc");
670#else
671# ifndef lint
672#  error "no assembler code for your compiler"
673# endif
674#endif
675        }
676}
677
678static __inline void
679bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
680                         bus_size_t offset, const u_int32_t *addr, size_t count)
681{
682
683        if (tag == I386_BUS_SPACE_IO) {
684                int _port_ = bsh + offset;
685#ifdef __GNUCLIKE_ASM
686                __asm __volatile("                              \n\
687                        cld                                     \n\
688                1:      lodsl                                   \n\
689                        outl %%eax,%w0                          \n\
690                        addl $4,%0                              \n\
691                        loop 1b"                                :
692                    "=d" (_port_), "=S" (addr), "=c" (count)    :
693                    "0" (_port_), "1" (addr), "2" (count)       :
694                    "%eax", "memory", "cc");
695#else
696# ifndef lint
697#  error "no assembler code for your compiler"
698# endif
699#endif
700        } else {
701                int _port_ = bsh + offset;
702#ifdef __GNUCLIKE_ASM
703                __asm __volatile("                              \n\
704                        cld                                     \n\
705                        repne                                   \n\
706                        movsl"                                  :
707                    "=D" (_port_), "=S" (addr), "=c" (count)    :
708                    "0" (_port_), "1" (addr), "2" (count)       :
709                    "memory", "cc");
710#else
711# ifndef lint
712#  error "no assembler code for your compiler"
713# endif
714#endif
715        }
716}
717
718#if 0   /* Cause a link error for bus_space_write_region_8 */
719#define bus_space_write_region_8                                        \
720                        !!! bus_space_write_region_8 unimplemented !!!
721#endif
722
723/*
724 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
725 * by tag/handle/offset `count' times.
726 */
727
728static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
729                                           bus_space_handle_t bsh,
730                                           bus_size_t offset,
731                                           u_int8_t value, size_t count);
732static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
733                                           bus_space_handle_t bsh,
734                                           bus_size_t offset,
735                                           u_int16_t value, size_t count);
736static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
737                                           bus_space_handle_t bsh,
738                                           bus_size_t offset,
739                                           u_int32_t value, size_t count);
740
741static __inline void
742bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
743                      bus_size_t offset, u_int8_t value, size_t count)
744{
745        bus_space_handle_t addr = bsh + offset;
746
747        if (tag == I386_BUS_SPACE_IO)
748                while (count--)
749                        outb(addr, value);
750        else
751                while (count--)
752                        *(volatile u_int8_t *)(addr) = value;
753}
754
755static __inline void
756bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
757                     bus_size_t offset, u_int16_t value, size_t count)
758{
759        bus_space_handle_t addr = bsh + offset;
760
761        if (tag == I386_BUS_SPACE_IO)
762                while (count--)
763                        outw(addr, value);
764        else
765                while (count--)
766                        *(volatile u_int16_t *)(addr) = value;
767}
768
769static __inline void
770bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
771                      bus_size_t offset, u_int32_t value, size_t count)
772{
773        bus_space_handle_t addr = bsh + offset;
774
775        if (tag == I386_BUS_SPACE_IO)
776                while (count--)
777                        outl(addr, value);
778        else
779                while (count--)
780                        *(volatile u_int32_t *)(addr) = value;
781}
782
783#if 0   /* Cause a link error for bus_space_set_multi_8 */
784#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
785#endif
786
787/*
788 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
789 * by tag/handle starting at `offset'.
790 */
791
792static __inline void bus_space_set_region_1(bus_space_tag_t tag,
793                                            bus_space_handle_t bsh,
794                                            bus_size_t offset, u_int8_t value,
795                                            size_t count);
796static __inline void bus_space_set_region_2(bus_space_tag_t tag,
797                                            bus_space_handle_t bsh,
798                                            bus_size_t offset, u_int16_t value,
799                                            size_t count);
800static __inline void bus_space_set_region_4(bus_space_tag_t tag,
801                                            bus_space_handle_t bsh,
802                                            bus_size_t offset, u_int32_t value,
803                                            size_t count);
804
805static __inline void
806bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
807                       bus_size_t offset, u_int8_t value, size_t count)
808{
809        bus_space_handle_t addr = bsh + offset;
810
811        if (tag == I386_BUS_SPACE_IO)
812                for (; count != 0; count--, addr++)
813                        outb(addr, value);
814        else
815                for (; count != 0; count--, addr++)
816                        *(volatile u_int8_t *)(addr) = value;
817}
818
819static __inline void
820bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
821                       bus_size_t offset, u_int16_t value, size_t count)
822{
823        bus_space_handle_t addr = bsh + offset;
824
825        if (tag == I386_BUS_SPACE_IO)
826                for (; count != 0; count--, addr += 2)
827                        outw(addr, value);
828        else
829                for (; count != 0; count--, addr += 2)
830                        *(volatile u_int16_t *)(addr) = value;
831}
832
833static __inline void
834bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
835                       bus_size_t offset, u_int32_t value, size_t count)
836{
837        bus_space_handle_t addr = bsh + offset;
838
839        if (tag == I386_BUS_SPACE_IO)
840                for (; count != 0; count--, addr += 4)
841                        outl(addr, value);
842        else
843                for (; count != 0; count--, addr += 4)
844                        *(volatile u_int32_t *)(addr) = value;
845}
846
847#if 0   /* Cause a link error for bus_space_set_region_8 */
848#define bus_space_set_region_8  !!! bus_space_set_region_8 unimplemented !!!
849#endif
850
851/*
852 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
853 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
854 */
855
856static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
857                                             bus_space_handle_t bsh1,
858                                             bus_size_t off1,
859                                             bus_space_handle_t bsh2,
860                                             bus_size_t off2, size_t count);
861
862static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
863                                             bus_space_handle_t bsh1,
864                                             bus_size_t off1,
865                                             bus_space_handle_t bsh2,
866                                             bus_size_t off2, size_t count);
867
868static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
869                                             bus_space_handle_t bsh1,
870                                             bus_size_t off1,
871                                             bus_space_handle_t bsh2,
872                                             bus_size_t off2, size_t count);
873
874static __inline void
875bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
876                        bus_size_t off1, bus_space_handle_t bsh2,
877                        bus_size_t off2, size_t count)
878{
879        bus_space_handle_t addr1 = bsh1 + off1;
880        bus_space_handle_t addr2 = bsh2 + off2;
881
882        if (tag == I386_BUS_SPACE_IO) {
883                if (addr1 >= addr2) {
884                        /* src after dest: copy forward */
885                        for (; count != 0; count--, addr1++, addr2++)
886                                outb(addr2, inb(addr1));
887                } else {
888                        /* dest after src: copy backwards */
889                        for (addr1 += (count - 1), addr2 += (count - 1);
890                            count != 0; count--, addr1--, addr2--)
891                                outb(addr2, inb(addr1));
892                }
893        } else {
894                if (addr1 >= addr2) {
895                        /* src after dest: copy forward */
896                        for (; count != 0; count--, addr1++, addr2++)
897                                *(volatile u_int8_t *)(addr2) =
898                                    *(volatile u_int8_t *)(addr1);
899                } else {
900                        /* dest after src: copy backwards */
901                        for (addr1 += (count - 1), addr2 += (count - 1);
902                            count != 0; count--, addr1--, addr2--)
903                                *(volatile u_int8_t *)(addr2) =
904                                    *(volatile u_int8_t *)(addr1);
905                }
906        }
907}
908
909static __inline void
910bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
911                        bus_size_t off1, bus_space_handle_t bsh2,
912                        bus_size_t off2, size_t count)
913{
914        bus_space_handle_t addr1 = bsh1 + off1;
915        bus_space_handle_t addr2 = bsh2 + off2;
916
917        if (tag == I386_BUS_SPACE_IO) {
918                if (addr1 >= addr2) {
919                        /* src after dest: copy forward */
920                        for (; count != 0; count--, addr1 += 2, addr2 += 2)
921                                outw(addr2, inw(addr1));
922                } else {
923                        /* dest after src: copy backwards */
924                        for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
925                            count != 0; count--, addr1 -= 2, addr2 -= 2)
926                                outw(addr2, inw(addr1));
927                }
928        } else {
929                if (addr1 >= addr2) {
930                        /* src after dest: copy forward */
931                        for (; count != 0; count--, addr1 += 2, addr2 += 2)
932                                *(volatile u_int16_t *)(addr2) =
933                                    *(volatile u_int16_t *)(addr1);
934                } else {
935                        /* dest after src: copy backwards */
936                        for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
937                            count != 0; count--, addr1 -= 2, addr2 -= 2)
938                                *(volatile u_int16_t *)(addr2) =
939                                    *(volatile u_int16_t *)(addr1);
940                }
941        }
942}
943
944static __inline void
945bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
946                        bus_size_t off1, bus_space_handle_t bsh2,
947                        bus_size_t off2, size_t count)
948{
949        bus_space_handle_t addr1 = bsh1 + off1;
950        bus_space_handle_t addr2 = bsh2 + off2;
951
952        if (tag == I386_BUS_SPACE_IO) {
953                if (addr1 >= addr2) {
954                        /* src after dest: copy forward */
955                        for (; count != 0; count--, addr1 += 4, addr2 += 4)
956                                outl(addr2, inl(addr1));
957                } else {
958                        /* dest after src: copy backwards */
959                        for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
960                            count != 0; count--, addr1 -= 4, addr2 -= 4)
961                                outl(addr2, inl(addr1));
962                }
963        } else {
964                if (addr1 >= addr2) {
965                        /* src after dest: copy forward */
966                        for (; count != 0; count--, addr1 += 4, addr2 += 4)
967                                *(volatile u_int32_t *)(addr2) =
968                                    *(volatile u_int32_t *)(addr1);
969                } else {
970                        /* dest after src: copy backwards */
971                        for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
972                            count != 0; count--, addr1 -= 4, addr2 -= 4)
973                                *(volatile u_int32_t *)(addr2) =
974                                    *(volatile u_int32_t *)(addr1);
975                }
976        }
977}
978
979#if 0   /* Cause a link error for bus_space_copy_8 */
980#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
981#endif
982
983/*
984 * Bus read/write barrier methods.
985 *
986 *      void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
987 *                             bus_size_t offset, bus_size_t len, int flags);
988 *
989 *
990 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
991 * prevent reordering by the compiler; all Intel x86 processors currently
992 * retire operations outside the CPU in program order.
993 */
994#define BUS_SPACE_BARRIER_READ  0x01            /* force read barrier */
995#define BUS_SPACE_BARRIER_WRITE 0x02            /* force write barrier */
996
997static __inline void
998bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
999                  bus_size_t offset __unused, bus_size_t len __unused, int flags)
1000{
1001#ifdef __GNUCLIKE_ASM
1002        if (flags & BUS_SPACE_BARRIER_READ)
1003                __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1004        else
1005                __asm __volatile("" : : : "memory");
1006#else
1007# ifndef lint
1008#  error "no assembler code for your compiler"
1009# endif
1010#endif
1011}
1012
1013#ifdef BUS_SPACE_NO_LEGACY
1014#undef inb
1015#undef outb
1016#define inb(a) compiler_error
1017#define inw(a) compiler_error
1018#define inl(a) compiler_error
1019#define outb(a, b) compiler_error
1020#define outw(a, b) compiler_error
1021#define outl(a, b) compiler_error
1022#endif
1023
1024#ifndef __rtems__
1025#include <machine/bus_dma.h>
1026#endif
1027
1028/*
1029 * Stream accesses are the same as normal accesses on i386/pc98; there are no
1030 * supported bus systems with an endianess different from the host one.
1031 */
1032#define bus_space_read_stream_1(t, h, o)        bus_space_read_1((t), (h), (o))
1033#define bus_space_read_stream_2(t, h, o)        bus_space_read_2((t), (h), (o))
1034#define bus_space_read_stream_4(t, h, o)        bus_space_read_4((t), (h), (o))
1035
1036#define bus_space_read_multi_stream_1(t, h, o, a, c) \
1037        bus_space_read_multi_1((t), (h), (o), (a), (c))
1038#define bus_space_read_multi_stream_2(t, h, o, a, c) \
1039        bus_space_read_multi_2((t), (h), (o), (a), (c))
1040#define bus_space_read_multi_stream_4(t, h, o, a, c) \
1041        bus_space_read_multi_4((t), (h), (o), (a), (c))
1042
1043#define bus_space_write_stream_1(t, h, o, v) \
1044        bus_space_write_1((t), (h), (o), (v))
1045#define bus_space_write_stream_2(t, h, o, v) \
1046        bus_space_write_2((t), (h), (o), (v))
1047#define bus_space_write_stream_4(t, h, o, v) \
1048        bus_space_write_4((t), (h), (o), (v))
1049
1050#define bus_space_write_multi_stream_1(t, h, o, a, c) \
1051        bus_space_write_multi_1((t), (h), (o), (a), (c))
1052#define bus_space_write_multi_stream_2(t, h, o, a, c) \
1053        bus_space_write_multi_2((t), (h), (o), (a), (c))
1054#define bus_space_write_multi_stream_4(t, h, o, a, c) \
1055        bus_space_write_multi_4((t), (h), (o), (a), (c))
1056
1057#define bus_space_set_multi_stream_1(t, h, o, v, c) \
1058        bus_space_set_multi_1((t), (h), (o), (v), (c))
1059#define bus_space_set_multi_stream_2(t, h, o, v, c) \
1060        bus_space_set_multi_2((t), (h), (o), (v), (c))
1061#define bus_space_set_multi_stream_4(t, h, o, v, c) \
1062        bus_space_set_multi_4((t), (h), (o), (v), (c))
1063
1064#define bus_space_read_region_stream_1(t, h, o, a, c) \
1065        bus_space_read_region_1((t), (h), (o), (a), (c))
1066#define bus_space_read_region_stream_2(t, h, o, a, c) \
1067        bus_space_read_region_2((t), (h), (o), (a), (c))
1068#define bus_space_read_region_stream_4(t, h, o, a, c) \
1069        bus_space_read_region_4((t), (h), (o), (a), (c))
1070
1071#define bus_space_write_region_stream_1(t, h, o, a, c) \
1072        bus_space_write_region_1((t), (h), (o), (a), (c))
1073#define bus_space_write_region_stream_2(t, h, o, a, c) \
1074        bus_space_write_region_2((t), (h), (o), (a), (c))
1075#define bus_space_write_region_stream_4(t, h, o, a, c) \
1076        bus_space_write_region_4((t), (h), (o), (a), (c))
1077
1078#define bus_space_set_region_stream_1(t, h, o, v, c) \
1079        bus_space_set_region_1((t), (h), (o), (v), (c))
1080#define bus_space_set_region_stream_2(t, h, o, v, c) \
1081        bus_space_set_region_2((t), (h), (o), (v), (c))
1082#define bus_space_set_region_stream_4(t, h, o, v, c) \
1083        bus_space_set_region_4((t), (h), (o), (v), (c))
1084
1085#define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1086        bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1087#define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1088        bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1089#define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1090        bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1091
1092#endif /* _RTEMS_BSD_MACHINE_BUS_I386_H_ */
Note: See TracBrowser for help on using the repository browser.