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 (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
23
24 return false;
25 }
26#if defined(TARGET_IS_BIENDIAN)
27 return virtio_is_big_endian(vdev);
28#elif defined(TARGET_WORDS_BIGENDIAN)
29 return true;
30#else
31 return false;
32#endif
33}
34
35static inline bool virtio_legacy_is_cross_endian(VirtIODevice *vdev)
36{
37#ifdef TARGET_IS_BIENDIAN
38#ifdef HOST_WORDS_BIGENDIAN
39 return !virtio_is_big_endian(vdev);
40#else
41 return virtio_is_big_endian(vdev);
42#endif
43#else
44 return false;
45#endif
46}
47
48static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
49{
50 if (virtio_access_is_big_endian(vdev)) {
51 return lduw_be_phys(&address_space_memory, pa);
52 }
53 return lduw_le_phys(&address_space_memory, pa);
54}
55
56static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
57{
58 if (virtio_access_is_big_endian(vdev)) {
59 return ldl_be_phys(&address_space_memory, pa);
60 }
61 return ldl_le_phys(&address_space_memory, pa);
62}
63
64static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
65{
66 if (virtio_access_is_big_endian(vdev)) {
67 return ldq_be_phys(&address_space_memory, pa);
68 }
69 return ldq_le_phys(&address_space_memory, pa);
70}
71
72static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
73 uint16_t value)
74{
75 if (virtio_access_is_big_endian(vdev)) {
76 stw_be_phys(&address_space_memory, pa, value);
77 } else {
78 stw_le_phys(&address_space_memory, pa, value);
79 }
80}
81
82static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
83 uint32_t value)
84{
85 if (virtio_access_is_big_endian(vdev)) {
86 stl_be_phys(&address_space_memory, pa, value);
87 } else {
88 stl_le_phys(&address_space_memory, pa, value);
89 }
90}
91
92static inline void virtio_stw_p(VirtIODevice *vdev, void *ptr, uint16_t v)
93{
94 if (virtio_access_is_big_endian(vdev)) {
95 stw_be_p(ptr, v);
96 } else {
97 stw_le_p(ptr, v);
98 }
99}
100
101static inline void virtio_stl_p(VirtIODevice *vdev, void *ptr, uint32_t v)
102{
103 if (virtio_access_is_big_endian(vdev)) {
104 stl_be_p(ptr, v);
105 } else {
106 stl_le_p(ptr, v);
107 }
108}
109
110static inline void virtio_stq_p(VirtIODevice *vdev, void *ptr, uint64_t v)
111{
112 if (virtio_access_is_big_endian(vdev)) {
113 stq_be_p(ptr, v);
114 } else {
115 stq_le_p(ptr, v);
116 }
117}
118
119static inline int virtio_lduw_p(VirtIODevice *vdev, const void *ptr)
120{
121 if (virtio_access_is_big_endian(vdev)) {
122 return lduw_be_p(ptr);
123 } else {
124 return lduw_le_p(ptr);
125 }
126}
127
128static inline int virtio_ldl_p(VirtIODevice *vdev, const void *ptr)
129{
130 if (virtio_access_is_big_endian(vdev)) {
131 return ldl_be_p(ptr);
132 } else {
133 return ldl_le_p(ptr);
134 }
135}
136
137static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
138{
139 if (virtio_access_is_big_endian(vdev)) {
140 return ldq_be_p(ptr);
141 } else {
142 return ldq_le_p(ptr);
143 }
144}
145
146static inline bool virtio_needs_swap(VirtIODevice *vdev)
147{
148#ifdef HOST_WORDS_BIGENDIAN
149 return virtio_access_is_big_endian(vdev) ? false : true;
150#else
151 return virtio_access_is_big_endian(vdev) ? true : false;
152#endif
153}
154
155static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
156{
157#ifdef HOST_WORDS_BIGENDIAN
158 return virtio_access_is_big_endian(vdev) ? s : bswap16(s);
159#else
160 return virtio_access_is_big_endian(vdev) ? bswap16(s) : s;
161#endif
162}
163
164static inline void virtio_tswap16s(VirtIODevice *vdev, uint16_t *s)
165{
166 *s = virtio_tswap16(vdev, *s);
167}
168
169static inline uint32_t virtio_tswap32(VirtIODevice *vdev, uint32_t s)
170{
171#ifdef HOST_WORDS_BIGENDIAN
172 return virtio_access_is_big_endian(vdev) ? s : bswap32(s);
173#else
174 return virtio_access_is_big_endian(vdev) ? bswap32(s) : s;
175#endif
176}
177
178static inline void virtio_tswap32s(VirtIODevice *vdev, uint32_t *s)
179{
180 *s = virtio_tswap32(vdev, *s);
181}
182
183static inline uint64_t virtio_tswap64(VirtIODevice *vdev, uint64_t s)
184{
185#ifdef HOST_WORDS_BIGENDIAN
186 return virtio_access_is_big_endian(vdev) ? s : bswap64(s);
187#else
188 return virtio_access_is_big_endian(vdev) ? bswap64(s) : s;
189#endif
190}
191
192static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
193{
194 *s = virtio_tswap64(vdev, *s);
195}
196#endif
197