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