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
virtio_config_readb(VirtIODevice * vdev,uint32_t addr)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
virtio_config_readw(VirtIODevice * vdev,uint32_t addr)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
virtio_config_readl(VirtIODevice * vdev,uint32_t addr)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
virtio_config_writeb(VirtIODevice * vdev,uint32_t addr,uint32_t data)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
virtio_config_writew(VirtIODevice * vdev,uint32_t addr,uint32_t data)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
virtio_config_writel(VirtIODevice * vdev,uint32_t addr,uint32_t data)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
virtio_config_modern_readb(VirtIODevice * vdev,uint32_t addr)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
virtio_config_modern_readw(VirtIODevice * vdev,uint32_t addr)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
virtio_config_modern_readl(VirtIODevice * vdev,uint32_t addr)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
virtio_config_modern_writeb(VirtIODevice * vdev,uint32_t addr,uint32_t data)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
virtio_config_modern_writew(VirtIODevice * vdev,uint32_t addr,uint32_t data)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
virtio_config_modern_writel(VirtIODevice * vdev,uint32_t addr,uint32_t data)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