Merge lp:~epics-core/epics-base/devlib2mmio into lp:~epics-core/epics-base/3.15
- devlib2mmio
- Merge into 3.15
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrew Johnson | Approve | ||
mdavidsaver | Needs Resubmitting | ||
Review via email: mp+163365@code.launchpad.net |
Commit message
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().
Ben Franksen (bfrk) wrote : | # |
- 12417. By mdavidsaver
-
rtems: mmio for m68k
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).
- 12418. By mdavidsaver
-
update release notes
- 12419. By mdavidsaver
-
fix copyright header
- 12420. By mdavidsaver
-
test epicsMMIO.h
Check byte order swapping.
mdavidsaver (mdavidsaver) wrote : | # |
Added release notes and unit test of byte order swapping. Also added documentation at lp:~mdavidsaver/epics-appdev/devlib2mmio
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-
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-
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 symFindByNameEP
Sorry it has taken me this long to bring this issue to your attention.
- Andrew
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
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.
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|
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.
mdavidsaver (mdavidsaver) wrote : | # |
Are the sys{In|
Also, are the argument types of these functions char|short|int?
- 12422. By mdavidsaver
-
switch to use sysInWord and friends
mdavidsaver (mdavidsaver) wrote : | # |
Done (assuming function prototypes are the same)
- 12423. By Andrew Johnson
-
Fixes for VxWorks implementation.
Andrew Johnson (anj) wrote : | # |
The sys{In|
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(
not ok 5 - H16.u16==BE16
ok 6 - be_ioread16(
not ok 7 - H16.u16==LE16
ok 8 - le_ioread16(
# 32-bit ops
not ok 9 - H32.u32==0x12345678
ok 10 - nat_ioread32(
not ok 11 - H32.u32==BE32
ok 12 - be_ioread32(
not ok 13 - H32.u32==LE32
ok 14 - le_ioread32(
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.
mdavidsaver (mdavidsaver) wrote : | # |
Are there any outstanding issues or requests on this branch?
Andrew Johnson (anj) wrote : | # |
We forgot to test on Windows:
cl -nologo -D__STDC__=0 -D_CRT_
c:\jenkins\
What is arpa/inet.h for?
mdavidsaver (mdavidsaver) wrote : | # |
byte swapping w/ hton*()
Andrew Johnson (anj) wrote : | # |
Needs Winsock2.h on Windows, according to this:
http://
We include that or arpa/inet.h in osdSock.h. I'll fix epicsMMIODef.h and commit.
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.
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
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); |
Am Freitag, 10. Mai 2013, 22:33:26 schrieb mdavidsaver: /code.launchpad .net/~epics- core/epics- base/devlib2mmi o/+merge/ 163365
> 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:/
>
> >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