Merge lp:~epics-core/epics-base/devlib2mmio into lp:~epics-core/epics-base/3.15

Proposed by mdavidsaver
Status: Merged
Merged at revision: 12545
Proposed branch: lp:~epics-core/epics-base/devlib2mmio
Merge into: lp:~epics-core/epics-base/3.15
Diff against target: 686 lines (+601/-0) (has conflicts)
9 files modified
documentation/RELEASE_NOTES.html (+10/-0)
src/libCom/osi/Makefile (+2/-0)
src/libCom/osi/os/RTEMS/epicsMMIO.h (+58/-0)
src/libCom/osi/os/default/epicsMMIO.h (+2/-0)
src/libCom/osi/os/default/epicsMMIODef.h (+268/-0)
src/libCom/osi/os/vxWorks/epicsMMIO.h (+160/-0)
src/libCom/test/Makefile (+5/-0)
src/libCom/test/epicsMMIOTest.c (+87/-0)
src/libCom/test/epicsRunLibComTests.c (+9/-0)
Text conflict in documentation/RELEASE_NOTES.html
Text conflict in src/libCom/test/epicsRunLibComTests.c
To merge this branch: bzr merge lp:~epics-core/epics-base/devlib2mmio
Reviewer Review Type Date Requested Status
Andrew Johnson Approve
mdavidsaver Needs Resubmitting
Review via email: mp+163365@code.launchpad.net

Description of the change

From devLib2
adds calls to handle 8, 16, and 32 bit
Memory Mapped I/O reads and writes.

Adds X_iowriteY() and X_ioreadY().

where X is nat (native), be, or le.
Y is 16 or 32.

Also adds ioread8() and iowrite8().

To post a comment you must log in.
Revision history for this message
Ben Franksen (bfrk) wrote :

Am Freitag, 10. Mai 2013, 22:33:26 schrieb mdavidsaver:
> mdavidsaver has proposed merging lp:~epics-core/epics-base/devlib2mmio into
> lp:epics-base.
>
> Requested reviews:
> EPICS Core Developers (epics-core)
>
> For more details, see:
> https://code.launchpad.net/~epics-core/epics-base/devlib2mmio/+merge/163365
>
> >From devLib2
>
> adds calls to handle 8, 16, and 32 bit
> Memory Mapped I/O reads and writes.
>
> Adds X_iowriteY() and X_ioreadY().
>
> where X is nat (native), be, or le.
> Y is 16 or 32.
>
> Also adds ioread8() and iowrite8().

+1 from me, it's high time something like this gets into base.

Cheers
--
Ben Franksen
() ascii ribbon campaign - against html e-mail
/\ www.asciiribbon.org - against proprietary attachm€nts

________________________________

Helmholtz-Zentrum Berlin für Materialien und Energie GmbH

Mitglied der Hermann von Helmholtz-Gemeinschaft Deutscher Forschungszentren e.V.

Aufsichtsrat: Vorsitzender Prof. Dr. Dr. h.c. mult. Joachim Treusch, stv. Vorsitzende Dr. Beatrix Vierkorn-Rudolph
Geschäftsführung: Prof. Dr. Anke Rita Kaysser-Pyzalla, Thomas Frederking

Sitz Berlin, AG Charlottenburg, 89 HRB 5583

Postadresse:
Hahn-Meitner-Platz 1
D-14109 Berlin

http://www.helmholtz-berlin.de

12417. By mdavidsaver

rtems: mmio for m68k

Revision history for this message
Andrew Johnson (anj) wrote :

Michael, I'd like to merge this branch (I know, finally!), but there's no code in Base that actually uses the macros that it defines, so I don't know whether code using it would even compile for all our supported targets. If it had a test program that instantiated all the routines we would know that it compiles everywhere and can be linked into an executable that can be loaded. It also needs an announcement in the Release Notes, and documentation for the API in the Application Developers Guide (section 20.21 could probably use a major overhaul anyway).

review: Needs Fixing
12418. By mdavidsaver

update release notes

12419. By mdavidsaver

fix copyright header

12420. By mdavidsaver

test epicsMMIO.h

Check byte order swapping.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Added release notes and unit test of byte order swapping. Also added documentation at lp:~mdavidsaver/epics-appdev/devlib2mmio

Revision history for this message
Andrew Johnson (anj) wrote :

When I started testing this code on VxWorks I came up with a major problem: There are two non-standards for the sysIn*/sysOut* PCIbus access routine names, and older (68K-based) boards don't have them at all.

The code works fine on the mv2700, mv5100 and mv6100 BSPs, but it won't load on the mv2100 or mv3100 without modifying the BSP. When I load the libCom tests on those boards I get this:

mv3100> load "bin/vxWorks-ppc32sf/libComTestHarness.munch"
Warning: module 0x31a9c0 holds reference to undefined symbol sysIn32.
Warning: module 0x31a9c0 holds reference to undefined symbol sysIn16.
Warning: module 0x31a9c0 holds reference to undefined symbol sysOut16.
Warning: module 0x31a9c0 holds reference to undefined symbol sysOut32.
ld(): module contains undefined symbol(s) and may be unusable.
value = 0 = 0x0

On these BSPs the access routines are named sysInLong(), sysInWord(), sysOutLong() and sysOutWord(), and of course we can't distinguish between them at compile-time since the same object code can be loaded on most boards.

On the 68K-based BSPs that don't have a PCIbus, I get this:

5.5.2> load "bin/vxWorks-68040/libComTestHarness.munch"
undefined symbol: _sysOutByte
undefined symbol: _sysInByte
undefined symbol: _sysOut16
undefined symbol: _sysIn16
undefined symbol: _sysOut32
undefined symbol: _sysIn32
ld error: Module contains undefined symbol(s) and may be unusable.
value = 0 = 0x0

The 68K family use a.out format binaries which don't support weak symbols, but those are available o the PowerPC boards and could be used. A better solution though would be to do symbol look-ups with symFindByNameEPICS() at C++ static initialization time, which will work on all architectures.

Sorry it has taken me this long to bring this issue to your attention.

- Andrew

Revision history for this message
Andrew Johnson (anj) wrote :

AJ to check args for sysInWord(), sysInLong() etc. MD to look at weak symbol implementation for VxWorks. Will try to fix this week.

12421. By mdavidsaver

mmio: vxWorks m68k use default, add weak symbols for old versions

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

I've made at attempt at vxWorks 5.5 support. m68k uses the default (as with RTEMS). For other architectures a weak symbol version of the sysIn* sysOut* functions is added which uses the default implementation.

Revision history for this message
Andrew Johnson (anj) wrote :

This isn't actually VxWorks 5.5 support, it's support for certain BSPs, irrespective of OS version.

I just grepped through the sources for all the BSPs I have installed and noticed that all the PowerPC and Intel ones implement sys{In|Out}{Byte|Word|Long}. It's the sys{In|Out}{16,32} routines that only exist on a subset of the boards, so I think you can drop the weak symbol stuff if you switch to using the former routines. You will still need your default implementation for m68k though.

Note that the BSP implementations add sync and/or eieio instructions as appropriate after doing the I/O operation, which I don't think your native versions can do.

Sorry for misleading you about this, I should have checked more carefully before.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Are the sys{In|Out}{Byte|Word|Long} prototypes present in any public headers?

Also, are the argument types of these functions char|short|int?

review: Needs Fixing
12422. By mdavidsaver

switch to use sysInWord and friends

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Done (assuming function prototypes are the same)

review: Needs Resubmitting
12423. By Andrew Johnson

Fixes for VxWorks implementation.

Revision history for this message
Andrew Johnson (anj) wrote :

The sys{In|Out}{Byte|Word|Long}() routines are declared in sysLib.h. On most architectures the address argument is a ULONG (same as epicsUInt32), except on x86 where it's an int (but that doesn't seem to matter). I removed your redeclarations and added appropriate casts to the various read and write functions, and fixed the 68K check in the header file. The result built on all my architectures and the tests all passed on my mv2100, so I committed my changes.

Then I ran the tests on my mv6100. Here the 16- and 32-bit tests fail (running the exact same binary):

# 16-bit ops
not ok 3 - H16.u16==0x1234
ok 4 - nat_ioread16(&H16.bytes)==0x1234
not ok 5 - H16.u16==BE16
ok 6 - be_ioread16(&H16.bytes)==0x1234
not ok 7 - H16.u16==LE16
ok 8 - le_ioread16(&H16.bytes)==0x1234
# 32-bit ops
not ok 9 - H32.u32==0x12345678
ok 10 - nat_ioread32(&H32.bytes)==0x12345678
not ok 11 - H32.u32==BE32
ok 12 - be_ioread32(&H32.bytes)==0x12345678
not ok 13 - H32.u32==LE32
ok 14 - le_ioread32(&H32.bytes)==0x12345678

Ouch, that looks like a byte-swapping issue, so I made the mistake of looking more closely at the implementations of sysInWord(), sysOutWord() and their relatives.

Children, please stop whatever you are doing immediately, go outside, and run away as far and as fast as you can. Don't stop running until it starts getting dark. Then find someplace to hide, shut your eyes and go to sleep. Never come to this place again.

12424. By Andrew Johnson

Fix vxWorks again, passes the tests on all my CPUs now.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Are there any outstanding issues or requests on this branch?

Revision history for this message
Andrew Johnson (anj) wrote :

Nope.

review: Approve
Revision history for this message
Andrew Johnson (anj) wrote :

We forgot to test on Windows:

cl -nologo -D__STDC__=0 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -Ox -GL -Oy- -W3 -w44355 -MT -I. -I../O.Common -I. -I. -I.. -I../../../../include/compiler/msvc -I../../../../include/os/WIN32 -I../../../../include -c ../epicsMMIOTest.c epicsMMIOTest.c
c:\jenkins\win32-1\workspace\epics-base-3.15-win32\include\os\win32\epicsMMIODef.h(116) : fatal error C1083: Cannot open include file: 'arpa/inet.h': No such file or directory

What is arpa/inet.h for?

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

byte swapping w/ hton*()

Revision history for this message
Andrew Johnson (anj) wrote :

Needs Winsock2.h on Windows, according to this:
  http://msdn.microsoft.com/en-us/library/windows/desktop/ms738557(v=vs.85).aspx

We include that or arpa/inet.h in osdSock.h. I'll fix epicsMMIODef.h and commit.

Revision history for this message
Andrew Johnson (anj) wrote :

I also removed the "special RTEMS" code from epicsMMIODef.h. If the comment about the pc386 bsp was correct the fix should go in osdSock.h.

Revision history for this message
Andrew Johnson (anj) wrote :

If you can work out how to fix the remaining name decoration issue please go ahead, I have to switch to other work now.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'documentation/RELEASE_NOTES.html'
2--- documentation/RELEASE_NOTES.html 2014-07-31 17:45:40 +0000
3+++ documentation/RELEASE_NOTES.html 2014-08-01 21:06:59 +0000
4@@ -15,6 +15,7 @@
5 <h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
6 <!-- Insert new items immediately below here ... -->
7
8+<<<<<<< TREE
9 <h3>Implement EPICS_CAS_INTF_ADDR_LIST in rsrv</h3>
10
11 <p>The IOC server can now bind to a single IP address (and optional port number)
12@@ -130,6 +131,15 @@
13 when changing this on applications where the IVOA field of output records is
14 used, IVOA still requires an INVALID severity to trigger value replacement.</p>
15
16+=======
17+<h3>merge MMIO API from devLib2</h3>
18+
19+<p>adds calls to handle 8, 16, and 32 bit Memory Mapped I/O reads and writes.
20+The calls added include X_iowriteY() and X_ioreadY().
21+Where X is nat (native), be, or le, and Y is 16 or 32.
22+Also added are ioread8() and iowrite8().</p>
23+
24+>>>>>>> MERGE-SOURCE
25 <h3>New build target <q>tapfiles</q></h3>
26
27 <p>This new make target runs the same tests as the <q>runtests</q> target, but
28
29=== modified file 'src/libCom/osi/Makefile'
30--- src/libCom/osi/Makefile 2014-05-23 19:14:49 +0000
31+++ src/libCom/osi/Makefile 2014-08-01 21:06:59 +0000
32@@ -61,6 +61,8 @@
33 INC += devLibVME.h
34 INC += devLibVMEImpl.h
35 INC += osdVME.h
36+INC += epicsMMIO.h
37+INC += epicsMMIODef.h
38
39 Com_SRCS += epicsThread.cpp
40 Com_SRCS += epicsMutex.cpp
41
42=== added file 'src/libCom/osi/os/RTEMS/epicsMMIO.h'
43--- src/libCom/osi/os/RTEMS/epicsMMIO.h 1970-01-01 00:00:00 +0000
44+++ src/libCom/osi/os/RTEMS/epicsMMIO.h 2014-08-01 21:06:59 +0000
45@@ -0,0 +1,58 @@
46+/*************************************************************************\
47+* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
48+* Brookhaven National Laboratory.
49+* EPICS BASE is distributed subject to a Software License Agreement found
50+* in file LICENSE that is included with this distribution.
51+\*************************************************************************/
52+/*
53+ * Author: Michael Davidsaver <mdavidsaver@bnl.gov>
54+ */
55+
56+#ifndef EPICSMMIO_H
57+#define EPICSMMIO_H
58+
59+#include <epicsEndian.h>
60+
61+#if defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC)
62+# include <libcpu/io.h>
63+
64+/*NOTE: All READ/WRITE operations have an implicit read or write barrier */
65+
66+# define ioread8(A) in_8((volatile epicsUInt8*)(A))
67+# define iowrite8(A,D) out_8((volatile epicsUInt8*)(A), D)
68+# define le_ioread16(A) in_le16((volatile epicsUInt16*)(A))
69+# define le_ioread32(A) in_le32((volatile epicsUInt32*)(A))
70+# define le_iowrite16(A,D) out_le16((volatile epicsUInt16*)(A), D)
71+# define le_iowrite32(A,D) out_le32((volatile epicsUInt32*)(A), D)
72+# define be_ioread16(A) in_be16((volatile epicsUInt16*)(A))
73+# define be_ioread32(A) in_be32((volatile epicsUInt32*)(A))
74+# define be_iowrite16(A,D) out_be16((volatile epicsUInt16*)(A), D)
75+# define be_iowrite32(A,D) out_be32((volatile epicsUInt32*)(A), D)
76+
77+# define rbarr() iobarrier_r()
78+# define wbarr() iobarrier_w()
79+# define rwbarr() iobarrier_rw()
80+
81+/* Define native operations */
82+# define nat_ioread16 be_ioread16
83+# define nat_ioread32 be_ioread32
84+# define nat_iowrite16 be_iowrite16
85+# define nat_iowrite32 be_iowrite32
86+
87+#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(__m68k__)
88+
89+/* X86 does not need special handling for read/write width.
90+ *
91+ * TODO: Memory barriers?
92+ */
93+
94+#include "epicsMMIODef.h"
95+
96+#else
97+# warning I/O operations not defined for this RTEMS architecture
98+
99+#include "epicsMMIODef.h"
100+
101+#endif /* if defined PPC */
102+
103+#endif /* EPICSMMIO_H */
104
105=== added file 'src/libCom/osi/os/default/epicsMMIO.h'
106--- src/libCom/osi/os/default/epicsMMIO.h 1970-01-01 00:00:00 +0000
107+++ src/libCom/osi/os/default/epicsMMIO.h 2014-08-01 21:06:59 +0000
108@@ -0,0 +1,2 @@
109+
110+#include "epicsMMIODef.h"
111
112=== added file 'src/libCom/osi/os/default/epicsMMIODef.h'
113--- src/libCom/osi/os/default/epicsMMIODef.h 1970-01-01 00:00:00 +0000
114+++ src/libCom/osi/os/default/epicsMMIODef.h 2014-08-01 21:06:59 +0000
115@@ -0,0 +1,268 @@
116+/*************************************************************************\
117+* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
118+* Brookhaven National Laboratory.
119+* EPICS BASE is distributed subject to a Software License Agreement found
120+* in file LICENSE that is included with this distribution.
121+\*************************************************************************/
122+/*
123+ * Author: Michael Davidsaver <mdavidsaver@bnl.gov>
124+ */
125+
126+#ifndef EPICSMMIODEF_H
127+#define EPICSMMIODEF_H
128+
129+#include <epicsTypes.h>
130+#include <epicsEndian.h>
131+#include <shareLib.h>
132+
133+#ifdef __cplusplus
134+# ifndef INLINE
135+# define INLINE inline
136+# endif
137+#endif
138+
139+/** @ingroup mmio
140+ *@{
141+ */
142+
143+/** @brief Read a single byte.
144+ */
145+INLINE
146+epicsUInt8
147+ioread8(volatile void* addr)
148+{
149+ return *(volatile epicsUInt8*)(addr);
150+}
151+
152+/** @brief Write a single byte.
153+ */
154+INLINE
155+void
156+iowrite8(volatile void* addr, epicsUInt8 val)
157+{
158+ *(volatile epicsUInt8*)(addr) = val;
159+}
160+
161+/** @brief Read two bytes in host order.
162+ * Not byte swapping
163+ */
164+INLINE
165+epicsUInt16
166+nat_ioread16(volatile void* addr)
167+{
168+ return *(volatile epicsUInt16*)(addr);
169+}
170+
171+/** @brief Write two byte in host order.
172+ * Not byte swapping
173+ */
174+INLINE
175+void
176+nat_iowrite16(volatile void* addr, epicsUInt16 val)
177+{
178+ *(volatile epicsUInt16*)(addr) = val;
179+}
180+
181+/** @brief Read four bytes in host order.
182+ * Not byte swapping
183+ */
184+INLINE
185+epicsUInt32
186+nat_ioread32(volatile void* addr)
187+{
188+ return *(volatile epicsUInt32*)(addr);
189+}
190+
191+/** @brief Write four byte in host order.
192+ * Not byte swapping
193+ */
194+INLINE
195+void
196+nat_iowrite32(volatile void* addr, epicsUInt32 val)
197+{
198+ *(volatile epicsUInt32*)(addr) = val;
199+}
200+
201+#if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
202+
203+/** @ingroup mmio
204+ *@{
205+ */
206+
207+#define bswap16(value) ((epicsUInt16) ( \
208+ (((epicsUInt16)(value) & 0x00ff) << 8) | \
209+ (((epicsUInt16)(value) & 0xff00) >> 8)))
210+
211+#define bswap32(value) ( \
212+ (((epicsUInt32)(value) & 0x000000ff) << 24) | \
213+ (((epicsUInt32)(value) & 0x0000ff00) << 8) | \
214+ (((epicsUInt32)(value) & 0x00ff0000) >> 8) | \
215+ (((epicsUInt32)(value) & 0xff000000) >> 24))
216+
217+# define be_ioread16(A) nat_ioread16(A)
218+# define be_ioread32(A) nat_ioread32(A)
219+# define be_iowrite16(A,D) nat_iowrite16(A,D)
220+# define be_iowrite32(A,D) nat_iowrite32(A,D)
221+
222+# define le_ioread16(A) bswap16(nat_ioread16(A))
223+# define le_ioread32(A) bswap32(nat_ioread32(A))
224+# define le_iowrite16(A,D) nat_iowrite16(A,bswap16(D))
225+# define le_iowrite32(A,D) nat_iowrite32(A,bswap32(D))
226+
227+/** @} */
228+
229+#elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
230+
231+#include <arpa/inet.h>
232+#ifdef __rtems__
233+ /* some rtems bsps (pc386) don't provide htonl correctly */
234+# include <rtems/endian.h>
235+#endif
236+
237+/** @ingroup mmio
238+ *@{
239+ */
240+
241+/* hton* is optimized or a builtin for most compilers
242+ * so use it if possible
243+ */
244+#define bswap16(v) htons(v)
245+#define bswap32(v) htonl(v)
246+
247+# define be_ioread16(A) bswap16(nat_ioread16(A))
248+# define be_ioread32(A) bswap32(nat_ioread32(A))
249+# define be_iowrite16(A,D) nat_iowrite16(A,bswap16(D))
250+# define be_iowrite32(A,D) nat_iowrite32(A,bswap32(D))
251+
252+# define le_ioread16(A) nat_ioread16(A)
253+# define le_ioread32(A) nat_ioread32(A)
254+# define le_iowrite16(A,D) nat_iowrite16(A,D)
255+# define le_iowrite32(A,D) nat_iowrite32(A,D)
256+
257+/** @} */
258+
259+#else
260+# error Unable to determine native byte order
261+#endif
262+
263+/** @def bswap16
264+ * @brief Unconditional two byte swap
265+ */
266+/** @def bswap32
267+ * @brief Unconditional four byte swap
268+ */
269+/** @def be_ioread16
270+ * @brief Read two byte in big endian order.
271+ */
272+/** @def be_iowrite16
273+ * @brief Write two byte in big endian order.
274+ */
275+/** @def be_ioread32
276+ * @brief Read four byte in big endian order.
277+ */
278+/** @def be_iowrite32
279+ * @brief Write four byte in big endian order.
280+ */
281+/** @def le_ioread16
282+ * @brief Read two byte in little endian order.
283+ */
284+/** @def le_iowrite16
285+ * @brief Write two byte in little endian order.
286+ */
287+/** @def le_ioread32
288+ * @brief Read four byte in little endian order.
289+ */
290+/** @def le_iowrite32
291+ * @brief Write four byte in little endian order.
292+ */
293+
294+/** @ingroup mmio
295+ *@{
296+ */
297+
298+/** @brief Explicit read memory barrier
299+ * Prevents reordering of reads around it.
300+ */
301+#define rbarr() do{}while(0)
302+/** @brief Explicit write memory barrier
303+ * Prevents reordering of writes around it.
304+ */
305+#define wbarr() do{}while(0)
306+/** @brief Explicit read/write memory barrier
307+ * Prevents reordering of reads or writes around it.
308+ */
309+#define rwbarr() do{}while(0)
310+
311+/** @} */
312+
313+/** @defgroup mmio Memory Mapped I/O
314+ *
315+ * Safe operations on I/O memory.
316+ *
317+ *This files defines a set of macros for access to Memory Mapped I/O
318+ *
319+ *They are named T_ioread# and T_iowrite# where # can be 8, 16, or 32.
320+ *'T' can either be 'le', 'be', or 'nat' (except ioread8 and
321+ *iowrite8).
322+ *
323+ *The macros defined use OS specific extensions (when available)
324+ *to ensure the following.
325+ *
326+ *@li Width. A 16 bit operation will not be broken into two 8 bit operations,
327+ * or one half of a 32 bit operation.
328+ *
329+ *@li Order. Writes to two different registers will not be reordered.
330+ * This only applies to MMIO operations, not between MMIO and
331+ * normal memory operations.
332+ *
333+ *PCI access should use either 'le_' or 'be_' as determined by the
334+ *device byte order.
335+ *
336+ *VME access should always use 'nat_'. If the device byte order is
337+ *little endian then an explicit swap is required.
338+ *
339+ *@section mmioex Examples:
340+ *
341+ *@subsection mmioexbe Big endian device:
342+ *
343+ *@b PCI
344+ *
345+ @code
346+ be_iowrite16(base+off, 14);
347+ var = be_ioread16(base+off);
348+ @endcode
349+ *
350+ *@b VME
351+ *
352+ @code
353+ nat_iowrite16(base+off, 14);
354+ var = nat_ioread16(base+off);
355+ @endcode
356+ *
357+ *@subsection mmioexle Little endian device
358+ *
359+ *@b PCI
360+ @code
361+ le_iowrite16(base+off, 14);
362+ var = le_ioread16(base+off);
363+ @endcode
364+ *@b VME
365+ @code
366+ nat_iowrite16(base+off, bswap16(14));
367+ var = bswap16(nat_iowrite16(base+off));
368+ @endcode
369+ *This difference arises because VME bridges implement hardware byte
370+ *swapping on little endian systems, while PCI bridges do not.
371+ *Software accessing PCI devices must know if byte swapping is required.
372+ *This conditional swap is implemented by the 'be_' and 'le_' macros.
373+ *
374+ *This is a fundamental difference between PCI and VME.
375+ *
376+ *Software accessing PCI @b must do conditional swapping.
377+ *
378+ *Software accessing VME must @b not do conditional swapping.
379+ *
380+ *@note All read and write operations have an implicit read or write barrier.
381+ */
382+
383+#endif /* EPICSMMIODEF_H */
384
385=== added file 'src/libCom/osi/os/vxWorks/epicsMMIO.h'
386--- src/libCom/osi/os/vxWorks/epicsMMIO.h 1970-01-01 00:00:00 +0000
387+++ src/libCom/osi/os/vxWorks/epicsMMIO.h 2014-08-01 21:06:59 +0000
388@@ -0,0 +1,160 @@
389+/*************************************************************************\
390+* Copyright (c) 2014 Brookhaven Science Associates, as Operator of
391+* Brookhaven National Laboratory.
392+* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne
393+* National Laboratory.
394+* Copyright (c) 2006 The Regents of the University of California,
395+* as Operator of Los Alamos National Laboratory.
396+* Copyright (c) 2006 The Board of Trustees of the Leland Stanford Junior
397+* University, as Operator of the Stanford Linear Accelerator Center.
398+* EPICS BASE is distributed subject to a Software License Agreement found
399+* in file LICENSE that is included with this distribution.
400+\*************************************************************************/
401+/*
402+ * Original Author: Eric Bjorklund (was called mrfSyncIO.h)
403+ * Author: Michael Davidsaver <mdavidsaver@bnl.gov>
404+ */
405+
406+#ifndef EPICSMMIO_H
407+#define EPICSMMIO_H
408+
409+#if (CPU_FAMILY != PPC) && (CPU_FAMILY != I80X86)
410+# include "epicsMMIODef.h"
411+#else
412+
413+/**************************************************************************************************/
414+/* Required Header Files */
415+/**************************************************************************************************/
416+
417+/* This is needed on vxWorks 6.8 */
418+#ifndef _VSB_CONFIG_FILE
419+# define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h>
420+#endif
421+
422+#include <vxWorks.h> /* vxWorks common definitions */
423+#include <sysLib.h> /* vxWorks System Library Definitions */
424+#include <version.h> /* vxWorks Version Definitions */
425+
426+#include <epicsTypes.h> /* EPICS Common Type Definitions */
427+#include <epicsEndian.h> /* EPICS Byte Order Definitions */
428+
429+/*=====================
430+ * vxAtomicLib.h (which defines the memory barrier macros)
431+ * is available on vxWorks 6.6 and above.
432+ */
433+
434+#if _WRS_VXWORKS_MAJOR > 6
435+# include <vxAtomicLib.h>
436+#elif _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR >= 6
437+# include <vxAtomicLib.h>
438+#endif
439+
440+#define bswap16(value) ((epicsUInt16) ( \
441+ (((epicsUInt16)(value) & 0x00ff) << 8) | \
442+ (((epicsUInt16)(value) & 0xff00) >> 8)))
443+
444+#define bswap32(value) ( \
445+ (((epicsUInt32)(value) & 0x000000ff) << 24) | \
446+ (((epicsUInt32)(value) & 0x0000ff00) << 8) | \
447+ (((epicsUInt32)(value) & 0x00ff0000) >> 8) | \
448+ (((epicsUInt32)(value) & 0xff000000) >> 24))
449+
450+#if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
451+# define be16_to_cpu(X) (epicsUInt16)(X)
452+# define be32_to_cpu(X) (epicsUInt32)(X)
453+# define le16_to_cpu(X) bswap16(X)
454+# define le32_to_cpu(X) bswap32(X)
455+
456+#elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
457+# define be16_to_cpu(X) bswap16(X)
458+# define be32_to_cpu(X) bswap32(X)
459+# define le16_to_cpu(X) (epicsUInt16)(X)
460+# define le32_to_cpu(X) (epicsUInt32)(X)
461+
462+#else
463+# error Unable to determine native byte order
464+#endif
465+
466+#if CPU_FAMILY == PPC
467+
468+/* All PowerPC BSPs that I have studied implement these functions
469+ * with the same definition, byte-swapping the data and adding a
470+ * sync and/or eieio instruction as necessary on that CPU board.
471+ * They do *not* all implement the sys{In/Out}{Byte/Word/Long}
472+ * functions to do the same thing though, so we can't use them.
473+ */
474+
475+UINT8 sysPciInByte(UINT8 *addr);
476+void sysPciOutByte(UINT8 *addr, UINT8 data);
477+UINT16 sysPciInWord(UINT16 *addr);
478+void sysPciOutWord(UINT16 *addr, UINT16 data);
479+UINT32 sysPciInLong (UINT32 *addr);
480+void sysPciOutLong (UINT32 *addr, UINT32 data);
481+
482+#define ioread8(address) sysPciInByte((UINT8 *)(address))
483+#define iowrite8(address,data) sysPciOutByte((UINT8 *)(address), (epicsUInt8)(data))
484+
485+#define nat_ioread16(address) bswap16(sysPciInWord((UINT16 *)(address)))
486+#define nat_ioread32(address) bswap32(sysPciInLong((UINT32 *)(address)))
487+
488+#define nat_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), bswap16(data))
489+#define nat_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), bswap32(data))
490+
491+#define be_ioread16(address) bswap16(sysPciInWord((UINT16 *)(address)))
492+#define be_ioread32(address) bswap32(sysPciInLong((UINT32 *)(address)))
493+
494+#define be_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), bswap16(data))
495+#define be_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), bswap32(data))
496+
497+#define le_ioread16(address) sysPciInWord((UINT16 *)(address))
498+#define le_ioread32(address) sysPciInLong((UINT32 *)(address))
499+
500+#define le_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), (data))
501+#define le_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), (data))
502+
503+#else /* CPU_FAMILY == I80X86 */
504+
505+/* All Intel BSPs should implement the sys{In/Out}{Byte/Word/Long}
506+ * functions, which are declared in the sysLib.h header.
507+ */
508+
509+#define ioread8(address) sysInByte ((epicsUInt32)(address))
510+#define iowrite8(address,data) sysOutByte ((epicsUInt32)(address), (epicsUInt8)(data))
511+
512+#define nat_ioread16(address) sysInWord ((epicsUInt32)(address))
513+#define nat_ioread32(address) sysInLong ((epicsUInt32)(address))
514+
515+#define nat_iowrite16(address,data) sysOutWord((epicsUInt32)(address),(data))
516+#define nat_iowrite32(address,data) sysOutLong((epicsUInt32)(address),(data))
517+
518+#define be_ioread16(address) be16_to_cpu (sysInWord ((epicsUInt32)(address)))
519+#define be_ioread32(address) be32_to_cpu (sysInLong ((epicsUInt32)(address)))
520+
521+#define be_iowrite16(address,data) sysOutWord ((epicsUInt32)(address), be16_to_cpu((epicsUInt16)(data)))
522+#define be_iowrite32(address,data) sysOutLong ((epicsUInt32)(address), be32_to_cpu((epicsUInt32)(data)))
523+
524+#define le_ioread16(address) le16_to_cpu (sysInWord ((epicsUInt32)(address)))
525+#define le_ioread32(address) le32_to_cpu (sysInLong ((epicsUInt32)(address)))
526+
527+#define le_iowrite16(address,data) sysOutWord ((epicsUInt32)(address), le16_to_cpu((epicsUInt16)(data)))
528+#define le_iowrite32(address,data) sysOutLong ((epicsUInt32)(address), le32_to_cpu((epicsUInt32)(data)))
529+
530+#endif /* I80X86 */
531+
532+
533+#ifndef VX_MEM_BARRIER_R
534+# define VX_MEM_BARRIER_R() do{}while(0)
535+#endif
536+#ifndef VX_MEM_BARRIER_W
537+# define VX_MEM_BARRIER_W() do{}while(0)
538+#endif
539+#ifndef VX_MEM_BARRIER_RW
540+# define VX_MEM_BARRIER_RW() do{}while(0)
541+#endif
542+
543+#define rbarr() VX_MEM_BARRIER_R()
544+#define wbarr() VX_MEM_BARRIER_W()
545+#define rwbarr() VX_MEM_BARRIER_RW()
546+
547+#endif /* CPU_FAMILY */
548+#endif /* EPICSMMIO_H */
549
550=== modified file 'src/libCom/test/Makefile'
551--- src/libCom/test/Makefile 2014-07-29 21:05:24 +0000
552+++ src/libCom/test/Makefile 2014-08-01 21:06:59 +0000
553@@ -37,6 +37,11 @@
554 testHarness_SRCS += epicsMathTest.c
555 TESTS += epicsMathTest
556
557+TESTPROD_HOST += epicsMMIOTest
558+epicsMMIOTest_SRCS += epicsMMIOTest.c
559+testHarness_SRCS += epicsMMIOTest.c
560+TESTS += epicsMMIOTest
561+
562 TESTPROD_HOST += epicsEllTest
563 epicsEllTest_SRCS += epicsEllTest.c
564 testHarness_SRCS += epicsEllTest.c
565
566=== added file 'src/libCom/test/epicsMMIOTest.c'
567--- src/libCom/test/epicsMMIOTest.c 1970-01-01 00:00:00 +0000
568+++ src/libCom/test/epicsMMIOTest.c 2014-08-01 21:06:59 +0000
569@@ -0,0 +1,87 @@
570+/*************************************************************************\
571+* Copyright (c) 2013 Brookhaven Science Associates, as Operator of
572+* Brookhaven National Laboratory.
573+* EPICS BASE is distributed subject to a Software License Agreement found
574+* in file LICENSE that is included with this distribution.
575+\*************************************************************************/
576+/*
577+ * Author: Michael Davidsaver <mdavidsaver@bnl.gov>
578+ */
579+
580+#include "epicsAssert.h"
581+#include "epicsEndian.h"
582+#include "epicsTypes.h"
583+#include "epicsUnitTest.h"
584+#include "testMain.h"
585+
586+#include "epicsMMIO.h"
587+
588+#if EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG
589+#define BE16 0x1234
590+#define BE32 0x12345678
591+#define LE16 0x3412
592+#define LE32 0x78563412
593+#else
594+#define LE16 0x1234
595+#define LE32 0x12345678
596+#define BE16 0x3412
597+#define BE32 0x78563412
598+#endif
599+
600+union hydra16 {
601+ epicsUInt16 u16;
602+ epicsUInt8 bytes[2];
603+};
604+
605+union hydra32 {
606+ epicsUInt32 u32;
607+ epicsUInt8 bytes[4];
608+};
609+
610+MAIN(epicsMMIOTest)
611+{
612+ epicsUInt8 B;
613+ union hydra16 H16;
614+ union hydra32 H32;
615+
616+ STATIC_ASSERT(sizeof(H16)==2);
617+ STATIC_ASSERT(sizeof(H32)==4);
618+
619+ testPlan(0);
620+
621+ testDiag("8-bit ops");
622+
623+ iowrite8(&B, 5);
624+ testOk1(B==5);
625+ testOk1(ioread8(&B)==5);
626+
627+ testDiag("16-bit ops");
628+
629+ nat_iowrite16(&H16.bytes, 0x1234);
630+ testOk1(H16.u16==0x1234);
631+ testOk1(nat_ioread16(&H16.bytes)==0x1234);
632+
633+ be_iowrite16(&H16.bytes, 0x1234);
634+ testOk1(H16.u16==BE16);
635+ testOk1(be_ioread16(&H16.bytes)==0x1234);
636+
637+ le_iowrite16(&H16.bytes, 0x1234);
638+ testOk1(H16.u16==LE16);
639+ testOk1(le_ioread16(&H16.bytes)==0x1234);
640+
641+ testDiag("32-bit ops");
642+
643+ nat_iowrite32(&H32.bytes, 0x12345678);
644+ testOk1(H32.u32==0x12345678);
645+ testOk1(nat_ioread32(&H32.bytes)==0x12345678);
646+
647+ be_iowrite32(&H32.bytes, 0x12345678);
648+ testOk1(H32.u32==BE32);
649+ testOk1(be_ioread32(&H32.bytes)==0x12345678);
650+
651+ le_iowrite32(&H32.bytes, 0x12345678);
652+ testOk1(H32.u32==LE32);
653+ testOk1(le_ioread32(&H32.bytes)==0x12345678);
654+
655+ return testDone();
656+}
657
658=== modified file 'src/libCom/test/epicsRunLibComTests.c'
659--- src/libCom/test/epicsRunLibComTests.c 2014-07-31 17:45:40 +0000
660+++ src/libCom/test/epicsRunLibComTests.c 2014-08-01 21:06:59 +0000
661@@ -18,7 +18,11 @@
662
663 int epicsThreadTest(void);
664 int epicsTimerTest(void);
665+<<<<<<< TREE
666 int epicsSpinTest(void);
667+=======
668+int epicsMMIOTest(void);
669+>>>>>>> MERGE-SOURCE
670 int epicsAlgorithm(void);
671 int epicsEllTest(void);
672 int epicsEnvTest(void);
673@@ -62,8 +66,13 @@
674 */
675 runTest(epicsTimerTest);
676
677+<<<<<<< TREE
678 runTest(epicsSpinTest);
679
680+=======
681+ runTest(epicsMMIOTest);
682+
683+>>>>>>> MERGE-SOURCE
684 runTest(epicsAlgorithm);
685
686 runTest(epicsEllTest);

Subscribers

People subscribed via source and target branches

to all changes: