xref: /qemu/include/hw/virtio/virtio-access.h (revision 63d2ada2)
1 /*
2  * Virtio Accessor Support: In case your target can change endian.
3  *
4  * Copyright IBM, Corp. 2013
5  *
6  * Authors:
7  *  Rusty Russell   <rusty@au.ibm.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) any later version.
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 
20 static 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     return true;
26 #else
27     return false;
28 #endif
29 }
30 
31 static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
32 {
33     if (virtio_access_is_big_endian(vdev)) {
34         return lduw_be_phys(&address_space_memory, pa);
35     }
36     return lduw_le_phys(&address_space_memory, pa);
37 }
38 
39 static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
40 {
41     if (virtio_access_is_big_endian(vdev)) {
42         return ldl_be_phys(&address_space_memory, pa);
43     }
44     return ldl_le_phys(&address_space_memory, pa);
45 }
46 
47 static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
48 {
49     if (virtio_access_is_big_endian(vdev)) {
50         return ldq_be_phys(&address_space_memory, pa);
51     }
52     return ldq_le_phys(&address_space_memory, pa);
53 }
54 
55 static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
56                                    uint16_t value)
57 {
58     if (virtio_access_is_big_endian(vdev)) {
59         stw_be_phys(&address_space_memory, pa, value);
60     } else {
61         stw_le_phys(&address_space_memory, pa, value);
62     }
63 }
64 
65 static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
66                                    uint32_t value)
67 {
68     if (virtio_access_is_big_endian(vdev)) {
69         stl_be_phys(&address_space_memory, pa, value);
70     } else {
71         stl_le_phys(&address_space_memory, pa, value);
72     }
73 }
74 
75 static inline void virtio_stw_p(VirtIODevice *vdev, void *ptr, uint16_t v)
76 {
77     if (virtio_access_is_big_endian(vdev)) {
78         stw_be_p(ptr, v);
79     } else {
80         stw_le_p(ptr, v);
81     }
82 }
83 
84 static inline void virtio_stl_p(VirtIODevice *vdev, void *ptr, uint32_t v)
85 {
86     if (virtio_access_is_big_endian(vdev)) {
87         stl_be_p(ptr, v);
88     } else {
89         stl_le_p(ptr, v);
90     }
91 }
92 
93 static inline void virtio_stq_p(VirtIODevice *vdev, void *ptr, uint64_t v)
94 {
95     if (virtio_access_is_big_endian(vdev)) {
96         stq_be_p(ptr, v);
97     } else {
98         stq_le_p(ptr, v);
99     }
100 }
101 
102 static inline int virtio_lduw_p(VirtIODevice *vdev, const void *ptr)
103 {
104     if (virtio_access_is_big_endian(vdev)) {
105         return lduw_be_p(ptr);
106     } else {
107         return lduw_le_p(ptr);
108     }
109 }
110 
111 static inline int virtio_ldl_p(VirtIODevice *vdev, const void *ptr)
112 {
113     if (virtio_access_is_big_endian(vdev)) {
114         return ldl_be_p(ptr);
115     } else {
116         return ldl_le_p(ptr);
117     }
118 }
119 
120 static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
121 {
122     if (virtio_access_is_big_endian(vdev)) {
123         return ldq_be_p(ptr);
124     } else {
125         return ldq_le_p(ptr);
126     }
127 }
128 
129 static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
130 {
131 #ifdef HOST_WORDS_BIGENDIAN
132     return virtio_access_is_big_endian(vdev) ? s : bswap16(s);
133 #else
134     return virtio_access_is_big_endian(vdev) ? bswap16(s) : s;
135 #endif
136 }
137 
138 static inline void virtio_tswap16s(VirtIODevice *vdev, uint16_t *s)
139 {
140     *s = virtio_tswap16(vdev, *s);
141 }
142 
143 static inline uint32_t virtio_tswap32(VirtIODevice *vdev, uint32_t s)
144 {
145 #ifdef HOST_WORDS_BIGENDIAN
146     return virtio_access_is_big_endian(vdev) ? s : bswap32(s);
147 #else
148     return virtio_access_is_big_endian(vdev) ? bswap32(s) : s;
149 #endif
150 }
151 
152 static inline void virtio_tswap32s(VirtIODevice *vdev, uint32_t *s)
153 {
154     *s = virtio_tswap32(vdev, *s);
155 }
156 
157 static inline uint64_t virtio_tswap64(VirtIODevice *vdev, uint64_t s)
158 {
159 #ifdef HOST_WORDS_BIGENDIAN
160     return virtio_access_is_big_endian(vdev) ? s : bswap64(s);
161 #else
162     return virtio_access_is_big_endian(vdev) ? bswap64(s) : s;
163 #endif
164 }
165 
166 static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
167 {
168     *s = virtio_tswap64(vdev, *s);
169 }
170 #endif /* _QEMU_VIRTIO_ACCESS_H */
171