1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef _QEMU_VIRTIO_ACCESS_H
16#define _QEMU_VIRTIO_ACCESS_H
17#include "hw/virtio/virtio.h"
18#include "exec/address-spaces.h"
19
20static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
21{
22#if defined(TARGET_IS_BIENDIAN)
23 return virtio_is_big_endian(vdev);
24#elif defined(TARGET_WORDS_BIGENDIAN)
25 if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
26
27 return false;
28 }
29 return true;
30#else
31 return false;
32#endif
33}
34
35static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
36{
37 if (virtio_access_is_big_endian(vdev)) {
38 return lduw_be_phys(&address_space_memory, pa);
39 }
40 return lduw_le_phys(&address_space_memory, pa);
41}
42
43static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
44{
45 if (virtio_access_is_big_endian(vdev)) {
46 return ldl_be_phys(&address_space_memory, pa);
47 }
48 return ldl_le_phys(&address_space_memory, pa);
49}
50
51static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
52{
53 if (virtio_access_is_big_endian(vdev)) {
54 return ldq_be_phys(&address_space_memory, pa);
55 }
56 return ldq_le_phys(&address_space_memory, pa);
57}
58
59static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
60 uint16_t value)
61{
62 if (virtio_access_is_big_endian(vdev)) {
63 stw_be_phys(&address_space_memory, pa, value);
64 } else {
65 stw_le_phys(&address_space_memory, pa, value);
66 }
67}
68
69static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
70 uint32_t value)
71{
72 if (virtio_access_is_big_endian(vdev)) {
73 stl_be_phys(&address_space_memory, pa, value);
74 } else {
75 stl_le_phys(&address_space_memory, pa, value);
76 }
77}
78
79static inline void virtio_stw_p(VirtIODevice *vdev, void *ptr, uint16_t v)
80{
81 if (virtio_access_is_big_endian(vdev)) {
82 stw_be_p(ptr, v);
83 } else {
84 stw_le_p(ptr, v);
85 }
86}
87
88static inline void virtio_stl_p(VirtIODevice *vdev, void *ptr, uint32_t v)
89{
90 if (virtio_access_is_big_endian(vdev)) {
91 stl_be_p(ptr, v);
92 } else {
93 stl_le_p(ptr, v);
94 }
95}
96
97static inline void virtio_stq_p(VirtIODevice *vdev, void *ptr, uint64_t v)
98{
99 if (virtio_access_is_big_endian(vdev)) {
100 stq_be_p(ptr, v);
101 } else {
102 stq_le_p(ptr, v);
103 }
104}
105
106static inline int virtio_lduw_p(VirtIODevice *vdev, const void *ptr)
107{
108 if (virtio_access_is_big_endian(vdev)) {
109 return lduw_be_p(ptr);
110 } else {
111 return lduw_le_p(ptr);
112 }
113}
114
115static inline int virtio_ldl_p(VirtIODevice *vdev, const void *ptr)
116{
117 if (virtio_access_is_big_endian(vdev)) {
118 return ldl_be_p(ptr);
119 } else {
120 return ldl_le_p(ptr);
121 }
122}
123
124static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
125{
126 if (virtio_access_is_big_endian(vdev)) {
127 return ldq_be_p(ptr);
128 } else {
129 return ldq_le_p(ptr);
130 }
131}
132
133static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
134{
135#ifdef HOST_WORDS_BIGENDIAN
136 return virtio_access_is_big_endian(vdev) ? s : bswap16(s);
137#else
138 return virtio_access_is_big_endian(vdev) ? bswap16(s) : s;
139#endif
140}
141
142static inline void virtio_tswap16s(VirtIODevice *vdev, uint16_t *s)
143{
144 *s = virtio_tswap16(vdev, *s);
145}
146
147static inline uint32_t virtio_tswap32(VirtIODevice *vdev, uint32_t s)
148{
149#ifdef HOST_WORDS_BIGENDIAN
150 return virtio_access_is_big_endian(vdev) ? s : bswap32(s);
151#else
152 return virtio_access_is_big_endian(vdev) ? bswap32(s) : s;
153#endif
154}
155
156static inline void virtio_tswap32s(VirtIODevice *vdev, uint32_t *s)
157{
158 *s = virtio_tswap32(vdev, *s);
159}
160
161static inline uint64_t virtio_tswap64(VirtIODevice *vdev, uint64_t s)
162{
163#ifdef HOST_WORDS_BIGENDIAN
164 return virtio_access_is_big_endian(vdev) ? s : bswap64(s);
165#else
166 return virtio_access_is_big_endian(vdev) ? bswap64(s) : s;
167#endif
168}
169
170static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
171{
172 *s = virtio_tswap64(vdev, *s);
173}
174#endif
175