xref: /openbmc/qemu/hw/virtio/virtio-config-io.c (revision d2dfe0b5)
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