xref: /qemu/include/hw/virtio/virtio-access.h (revision 1be5a765c08cee3a9587c8a8d3fc2ea247b13f9c)
10f5d1d2aSGreg Kurz /*
20f5d1d2aSGreg Kurz  * Virtio Accessor Support: In case your target can change endian.
30f5d1d2aSGreg Kurz  *
40f5d1d2aSGreg Kurz  * Copyright IBM, Corp. 2013
50f5d1d2aSGreg Kurz  *
60f5d1d2aSGreg Kurz  * Authors:
70f5d1d2aSGreg Kurz  *  Rusty Russell   <rusty@au.ibm.com>
80f5d1d2aSGreg Kurz  *
90f5d1d2aSGreg Kurz  * This program is free software; you can redistribute it and/or modify
100f5d1d2aSGreg Kurz  * it under the terms of the GNU General Public License as published by
110f5d1d2aSGreg Kurz  * the Free Software Foundation, either version 2 of the License, or
120f5d1d2aSGreg Kurz  * (at your option) any later version.
130f5d1d2aSGreg Kurz  *
140f5d1d2aSGreg Kurz  */
152a6a4076SMarkus Armbruster 
162a6a4076SMarkus Armbruster #ifndef QEMU_VIRTIO_ACCESS_H
172a6a4076SMarkus Armbruster #define QEMU_VIRTIO_ACCESS_H
182a6a4076SMarkus Armbruster 
19ec150c7eSMarkus Armbruster #include "exec/hwaddr.h"
200f5d1d2aSGreg Kurz #include "hw/virtio/virtio.h"
218607f5c3SJason Wang #include "hw/virtio/virtio-bus.h"
220f5d1d2aSGreg Kurz 
23c02d7030SGreg Kurz #if defined(TARGET_PPC64) || defined(TARGET_ARM)
24c02d7030SGreg Kurz #define LEGACY_VIRTIO_IS_BIENDIAN 1
25c02d7030SGreg Kurz #endif
26c02d7030SGreg Kurz 
virtio_access_is_big_endian(VirtIODevice * vdev)270f5d1d2aSGreg Kurz static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
280f5d1d2aSGreg Kurz {
29c02d7030SGreg Kurz #if defined(LEGACY_VIRTIO_IS_BIENDIAN)
30e5157e31SGreg Kurz     return virtio_is_big_endian(vdev);
31*ee3eb3a7SMarc-André Lureau #elif TARGET_BIG_ENDIAN
3295129d6fSCornelia Huck     if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
333c185597SCornelia Huck         /* Devices conforming to VIRTIO 1.0 or later are always LE. */
343c185597SCornelia Huck         return false;
353c185597SCornelia Huck     }
360f5d1d2aSGreg Kurz     return true;
370f5d1d2aSGreg Kurz #else
380f5d1d2aSGreg Kurz     return false;
390f5d1d2aSGreg Kurz #endif
400f5d1d2aSGreg Kurz }
410f5d1d2aSGreg Kurz 
virtio_lduw_phys(VirtIODevice * vdev,hwaddr pa)420f5d1d2aSGreg Kurz static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
430f5d1d2aSGreg Kurz {
448607f5c3SJason Wang     AddressSpace *dma_as = vdev->dma_as;
458607f5c3SJason Wang 
460f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
478607f5c3SJason Wang         return lduw_be_phys(dma_as, pa);
480f5d1d2aSGreg Kurz     }
498607f5c3SJason Wang     return lduw_le_phys(dma_as, pa);
500f5d1d2aSGreg Kurz }
510f5d1d2aSGreg Kurz 
virtio_ldl_phys(VirtIODevice * vdev,hwaddr pa)520f5d1d2aSGreg Kurz static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
530f5d1d2aSGreg Kurz {
548607f5c3SJason Wang     AddressSpace *dma_as = vdev->dma_as;
558607f5c3SJason Wang 
560f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
578607f5c3SJason Wang         return ldl_be_phys(dma_as, pa);
580f5d1d2aSGreg Kurz     }
598607f5c3SJason Wang     return ldl_le_phys(dma_as, pa);
600f5d1d2aSGreg Kurz }
610f5d1d2aSGreg Kurz 
virtio_ldq_phys(VirtIODevice * vdev,hwaddr pa)620f5d1d2aSGreg Kurz static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
630f5d1d2aSGreg Kurz {
648607f5c3SJason Wang     AddressSpace *dma_as = vdev->dma_as;
658607f5c3SJason Wang 
660f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
678607f5c3SJason Wang         return ldq_be_phys(dma_as, pa);
680f5d1d2aSGreg Kurz     }
698607f5c3SJason Wang     return ldq_le_phys(dma_as, pa);
700f5d1d2aSGreg Kurz }
710f5d1d2aSGreg Kurz 
virtio_stw_phys(VirtIODevice * vdev,hwaddr pa,uint16_t value)720f5d1d2aSGreg Kurz static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
730f5d1d2aSGreg Kurz                                    uint16_t value)
740f5d1d2aSGreg Kurz {
758607f5c3SJason Wang     AddressSpace *dma_as = vdev->dma_as;
768607f5c3SJason Wang 
770f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
788607f5c3SJason Wang         stw_be_phys(dma_as, pa, value);
790f5d1d2aSGreg Kurz     } else {
808607f5c3SJason Wang         stw_le_phys(dma_as, pa, value);
810f5d1d2aSGreg Kurz     }
820f5d1d2aSGreg Kurz }
830f5d1d2aSGreg Kurz 
virtio_stl_phys(VirtIODevice * vdev,hwaddr pa,uint32_t value)840f5d1d2aSGreg Kurz static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
850f5d1d2aSGreg Kurz                                    uint32_t value)
860f5d1d2aSGreg Kurz {
878607f5c3SJason Wang     AddressSpace *dma_as = vdev->dma_as;
888607f5c3SJason Wang 
890f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
908607f5c3SJason Wang         stl_be_phys(dma_as, pa, value);
910f5d1d2aSGreg Kurz     } else {
928607f5c3SJason Wang         stl_le_phys(dma_as, pa, value);
930f5d1d2aSGreg Kurz     }
940f5d1d2aSGreg Kurz }
950f5d1d2aSGreg Kurz 
virtio_stw_p(VirtIODevice * vdev,void * ptr,uint16_t v)960f5d1d2aSGreg Kurz static inline void virtio_stw_p(VirtIODevice *vdev, void *ptr, uint16_t v)
970f5d1d2aSGreg Kurz {
980f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
990f5d1d2aSGreg Kurz         stw_be_p(ptr, v);
1000f5d1d2aSGreg Kurz     } else {
1010f5d1d2aSGreg Kurz         stw_le_p(ptr, v);
1020f5d1d2aSGreg Kurz     }
1030f5d1d2aSGreg Kurz }
1040f5d1d2aSGreg Kurz 
virtio_stl_p(VirtIODevice * vdev,void * ptr,uint32_t v)1050f5d1d2aSGreg Kurz static inline void virtio_stl_p(VirtIODevice *vdev, void *ptr, uint32_t v)
1060f5d1d2aSGreg Kurz {
1070f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
1080f5d1d2aSGreg Kurz         stl_be_p(ptr, v);
1090f5d1d2aSGreg Kurz     } else {
1100f5d1d2aSGreg Kurz         stl_le_p(ptr, v);
1110f5d1d2aSGreg Kurz     }
1120f5d1d2aSGreg Kurz }
1130f5d1d2aSGreg Kurz 
virtio_stq_p(VirtIODevice * vdev,void * ptr,uint64_t v)1140f5d1d2aSGreg Kurz static inline void virtio_stq_p(VirtIODevice *vdev, void *ptr, uint64_t v)
1150f5d1d2aSGreg Kurz {
1160f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
1170f5d1d2aSGreg Kurz         stq_be_p(ptr, v);
1180f5d1d2aSGreg Kurz     } else {
1190f5d1d2aSGreg Kurz         stq_le_p(ptr, v);
1200f5d1d2aSGreg Kurz     }
1210f5d1d2aSGreg Kurz }
1220f5d1d2aSGreg Kurz 
virtio_lduw_p(VirtIODevice * vdev,const void * ptr)1230f5d1d2aSGreg Kurz static inline int virtio_lduw_p(VirtIODevice *vdev, const void *ptr)
1240f5d1d2aSGreg Kurz {
1250f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
1260f5d1d2aSGreg Kurz         return lduw_be_p(ptr);
1270f5d1d2aSGreg Kurz     } else {
1280f5d1d2aSGreg Kurz         return lduw_le_p(ptr);
1290f5d1d2aSGreg Kurz     }
1300f5d1d2aSGreg Kurz }
1310f5d1d2aSGreg Kurz 
virtio_ldl_p(VirtIODevice * vdev,const void * ptr)1320f5d1d2aSGreg Kurz static inline int virtio_ldl_p(VirtIODevice *vdev, const void *ptr)
1330f5d1d2aSGreg Kurz {
1340f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
1350f5d1d2aSGreg Kurz         return ldl_be_p(ptr);
1360f5d1d2aSGreg Kurz     } else {
1370f5d1d2aSGreg Kurz         return ldl_le_p(ptr);
1380f5d1d2aSGreg Kurz     }
1390f5d1d2aSGreg Kurz }
1400f5d1d2aSGreg Kurz 
virtio_ldq_p(VirtIODevice * vdev,const void * ptr)1410f5d1d2aSGreg Kurz static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
1420f5d1d2aSGreg Kurz {
1430f5d1d2aSGreg Kurz     if (virtio_access_is_big_endian(vdev)) {
1440f5d1d2aSGreg Kurz         return ldq_be_p(ptr);
1450f5d1d2aSGreg Kurz     } else {
1460f5d1d2aSGreg Kurz         return ldq_le_p(ptr);
1470f5d1d2aSGreg Kurz     }
1480f5d1d2aSGreg Kurz }
1490f5d1d2aSGreg Kurz 
virtio_tswap16(VirtIODevice * vdev,uint16_t s)1500f5d1d2aSGreg Kurz static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
1510f5d1d2aSGreg Kurz {
152e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
1530f5d1d2aSGreg Kurz     return virtio_access_is_big_endian(vdev) ? s : bswap16(s);
1540f5d1d2aSGreg Kurz #else
1550f5d1d2aSGreg Kurz     return virtio_access_is_big_endian(vdev) ? bswap16(s) : s;
1560f5d1d2aSGreg Kurz #endif
1570f5d1d2aSGreg Kurz }
1580f5d1d2aSGreg Kurz 
virtio_lduw_phys_cached(VirtIODevice * vdev,MemoryRegionCache * cache,hwaddr pa)159e6a830d6SPaolo Bonzini static inline uint16_t virtio_lduw_phys_cached(VirtIODevice *vdev,
160e6a830d6SPaolo Bonzini                                                MemoryRegionCache *cache,
161e6a830d6SPaolo Bonzini                                                hwaddr pa)
162e6a830d6SPaolo Bonzini {
163e6a830d6SPaolo Bonzini     if (virtio_access_is_big_endian(vdev)) {
164e6a830d6SPaolo Bonzini         return lduw_be_phys_cached(cache, pa);
165e6a830d6SPaolo Bonzini     }
166e6a830d6SPaolo Bonzini     return lduw_le_phys_cached(cache, pa);
167e6a830d6SPaolo Bonzini }
168e6a830d6SPaolo Bonzini 
virtio_ldl_phys_cached(VirtIODevice * vdev,MemoryRegionCache * cache,hwaddr pa)169e6a830d6SPaolo Bonzini static inline uint32_t virtio_ldl_phys_cached(VirtIODevice *vdev,
170e6a830d6SPaolo Bonzini                                               MemoryRegionCache *cache,
171e6a830d6SPaolo Bonzini                                               hwaddr pa)
172e6a830d6SPaolo Bonzini {
173e6a830d6SPaolo Bonzini     if (virtio_access_is_big_endian(vdev)) {
174e6a830d6SPaolo Bonzini         return ldl_be_phys_cached(cache, pa);
175e6a830d6SPaolo Bonzini     }
176e6a830d6SPaolo Bonzini     return ldl_le_phys_cached(cache, pa);
177e6a830d6SPaolo Bonzini }
178e6a830d6SPaolo Bonzini 
virtio_ldq_phys_cached(VirtIODevice * vdev,MemoryRegionCache * cache,hwaddr pa)179e6a830d6SPaolo Bonzini static inline uint64_t virtio_ldq_phys_cached(VirtIODevice *vdev,
180e6a830d6SPaolo Bonzini                                               MemoryRegionCache *cache,
181e6a830d6SPaolo Bonzini                                               hwaddr pa)
182e6a830d6SPaolo Bonzini {
183e6a830d6SPaolo Bonzini     if (virtio_access_is_big_endian(vdev)) {
184e6a830d6SPaolo Bonzini         return ldq_be_phys_cached(cache, pa);
185e6a830d6SPaolo Bonzini     }
186e6a830d6SPaolo Bonzini     return ldq_le_phys_cached(cache, pa);
187e6a830d6SPaolo Bonzini }
188e6a830d6SPaolo Bonzini 
virtio_stw_phys_cached(VirtIODevice * vdev,MemoryRegionCache * cache,hwaddr pa,uint16_t value)189e6a830d6SPaolo Bonzini static inline void virtio_stw_phys_cached(VirtIODevice *vdev,
190e6a830d6SPaolo Bonzini                                           MemoryRegionCache *cache,
191e6a830d6SPaolo Bonzini                                           hwaddr pa, uint16_t value)
192e6a830d6SPaolo Bonzini {
193e6a830d6SPaolo Bonzini     if (virtio_access_is_big_endian(vdev)) {
194e6a830d6SPaolo Bonzini         stw_be_phys_cached(cache, pa, value);
195e6a830d6SPaolo Bonzini     } else {
196e6a830d6SPaolo Bonzini         stw_le_phys_cached(cache, pa, value);
197e6a830d6SPaolo Bonzini     }
198e6a830d6SPaolo Bonzini }
199e6a830d6SPaolo Bonzini 
virtio_stl_phys_cached(VirtIODevice * vdev,MemoryRegionCache * cache,hwaddr pa,uint32_t value)200e6a830d6SPaolo Bonzini static inline void virtio_stl_phys_cached(VirtIODevice *vdev,
201e6a830d6SPaolo Bonzini                                           MemoryRegionCache *cache,
202e6a830d6SPaolo Bonzini                                           hwaddr pa, uint32_t value)
203e6a830d6SPaolo Bonzini {
204e6a830d6SPaolo Bonzini     if (virtio_access_is_big_endian(vdev)) {
205e6a830d6SPaolo Bonzini         stl_be_phys_cached(cache, pa, value);
206e6a830d6SPaolo Bonzini     } else {
207e6a830d6SPaolo Bonzini         stl_le_phys_cached(cache, pa, value);
208e6a830d6SPaolo Bonzini     }
209e6a830d6SPaolo Bonzini }
210e6a830d6SPaolo Bonzini 
virtio_tswap16s(VirtIODevice * vdev,uint16_t * s)2110f5d1d2aSGreg Kurz static inline void virtio_tswap16s(VirtIODevice *vdev, uint16_t *s)
2120f5d1d2aSGreg Kurz {
2130f5d1d2aSGreg Kurz     *s = virtio_tswap16(vdev, *s);
2140f5d1d2aSGreg Kurz }
2150f5d1d2aSGreg Kurz 
virtio_tswap32(VirtIODevice * vdev,uint32_t s)2160f5d1d2aSGreg Kurz static inline uint32_t virtio_tswap32(VirtIODevice *vdev, uint32_t s)
2170f5d1d2aSGreg Kurz {
218e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
2190f5d1d2aSGreg Kurz     return virtio_access_is_big_endian(vdev) ? s : bswap32(s);
2200f5d1d2aSGreg Kurz #else
2210f5d1d2aSGreg Kurz     return virtio_access_is_big_endian(vdev) ? bswap32(s) : s;
2220f5d1d2aSGreg Kurz #endif
2230f5d1d2aSGreg Kurz }
2240f5d1d2aSGreg Kurz 
virtio_tswap32s(VirtIODevice * vdev,uint32_t * s)2250f5d1d2aSGreg Kurz static inline void virtio_tswap32s(VirtIODevice *vdev, uint32_t *s)
2260f5d1d2aSGreg Kurz {
2270f5d1d2aSGreg Kurz     *s = virtio_tswap32(vdev, *s);
2280f5d1d2aSGreg Kurz }
2290f5d1d2aSGreg Kurz 
virtio_tswap64(VirtIODevice * vdev,uint64_t s)2300f5d1d2aSGreg Kurz static inline uint64_t virtio_tswap64(VirtIODevice *vdev, uint64_t s)
2310f5d1d2aSGreg Kurz {
232e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
2330f5d1d2aSGreg Kurz     return virtio_access_is_big_endian(vdev) ? s : bswap64(s);
2340f5d1d2aSGreg Kurz #else
2350f5d1d2aSGreg Kurz     return virtio_access_is_big_endian(vdev) ? bswap64(s) : s;
2360f5d1d2aSGreg Kurz #endif
2370f5d1d2aSGreg Kurz }
2380f5d1d2aSGreg Kurz 
virtio_tswap64s(VirtIODevice * vdev,uint64_t * s)2390f5d1d2aSGreg Kurz static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
2400f5d1d2aSGreg Kurz {
2410f5d1d2aSGreg Kurz     *s = virtio_tswap64(vdev, *s);
2420f5d1d2aSGreg Kurz }
2432a6a4076SMarkus Armbruster #endif /* QEMU_VIRTIO_ACCESS_H */
244