1 /* 2 * Virtio Support 3 * 4 * Copyright IBM, Corp. 2007 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * SPDX-License-Identifier: GPL-2.0-or-later 10 */ 11 12 #include "qemu/osdep.h" 13 #include "hw/virtio/virtio.h" 14 15 uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr) 16 { 17 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 18 uint8_t val; 19 20 if (addr + sizeof(val) > vdev->config_len) { 21 return (uint32_t)-1; 22 } 23 24 k->get_config(vdev, vdev->config); 25 26 val = ldub_p(vdev->config + addr); 27 return val; 28 } 29 30 uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr) 31 { 32 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 33 uint16_t val; 34 35 if (addr + sizeof(val) > vdev->config_len) { 36 return (uint32_t)-1; 37 } 38 39 k->get_config(vdev, vdev->config); 40 41 val = lduw_p(vdev->config + addr); 42 return val; 43 } 44 45 uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr) 46 { 47 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 48 uint32_t val; 49 50 if (addr + sizeof(val) > vdev->config_len) { 51 return (uint32_t)-1; 52 } 53 54 k->get_config(vdev, vdev->config); 55 56 val = ldl_p(vdev->config + addr); 57 return val; 58 } 59 60 void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data) 61 { 62 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 63 uint8_t val = data; 64 65 if (addr + sizeof(val) > vdev->config_len) { 66 return; 67 } 68 69 stb_p(vdev->config + addr, val); 70 71 if (k->set_config) { 72 k->set_config(vdev, vdev->config); 73 } 74 } 75 76 void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data) 77 { 78 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 79 uint16_t val = data; 80 81 if (addr + sizeof(val) > vdev->config_len) { 82 return; 83 } 84 85 stw_p(vdev->config + addr, val); 86 87 if (k->set_config) { 88 k->set_config(vdev, vdev->config); 89 } 90 } 91 92 void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data) 93 { 94 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 95 uint32_t val = data; 96 97 if (addr + sizeof(val) > vdev->config_len) { 98 return; 99 } 100 101 stl_p(vdev->config + addr, val); 102 103 if (k->set_config) { 104 k->set_config(vdev, vdev->config); 105 } 106 } 107 108 uint32_t virtio_config_modern_readb(VirtIODevice *vdev, uint32_t addr) 109 { 110 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 111 uint8_t val; 112 113 if (addr + sizeof(val) > vdev->config_len) { 114 return (uint32_t)-1; 115 } 116 117 k->get_config(vdev, vdev->config); 118 119 val = ldub_p(vdev->config + addr); 120 return val; 121 } 122 123 uint32_t virtio_config_modern_readw(VirtIODevice *vdev, uint32_t addr) 124 { 125 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 126 uint16_t val; 127 128 if (addr + sizeof(val) > vdev->config_len) { 129 return (uint32_t)-1; 130 } 131 132 k->get_config(vdev, vdev->config); 133 134 val = lduw_le_p(vdev->config + addr); 135 return val; 136 } 137 138 uint32_t virtio_config_modern_readl(VirtIODevice *vdev, uint32_t addr) 139 { 140 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 141 uint32_t val; 142 143 if (addr + sizeof(val) > vdev->config_len) { 144 return (uint32_t)-1; 145 } 146 147 k->get_config(vdev, vdev->config); 148 149 val = ldl_le_p(vdev->config + addr); 150 return val; 151 } 152 153 void virtio_config_modern_writeb(VirtIODevice *vdev, 154 uint32_t addr, uint32_t data) 155 { 156 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 157 uint8_t val = data; 158 159 if (addr + sizeof(val) > vdev->config_len) { 160 return; 161 } 162 163 stb_p(vdev->config + addr, val); 164 165 if (k->set_config) { 166 k->set_config(vdev, vdev->config); 167 } 168 } 169 170 void virtio_config_modern_writew(VirtIODevice *vdev, 171 uint32_t addr, uint32_t data) 172 { 173 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 174 uint16_t val = data; 175 176 if (addr + sizeof(val) > vdev->config_len) { 177 return; 178 } 179 180 stw_le_p(vdev->config + addr, val); 181 182 if (k->set_config) { 183 k->set_config(vdev, vdev->config); 184 } 185 } 186 187 void virtio_config_modern_writel(VirtIODevice *vdev, 188 uint32_t addr, uint32_t data) 189 { 190 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); 191 uint32_t val = data; 192 193 if (addr + sizeof(val) > vdev->config_len) { 194 return; 195 } 196 197 stl_le_p(vdev->config + addr, val); 198 199 if (k->set_config) { 200 k->set_config(vdev, vdev->config); 201 } 202 } 203 204