qemu/include/hw/virtio/virtio-access.h
<<
>>
Prefs
   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
  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        /* Devices conforming to VIRTIO 1.0 or later are always LE. */
  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 /* _QEMU_VIRTIO_ACCESS_H */
 175