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