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