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