1 /* $OpenBSD: virtio_mmio.c,v 1.9 2021/04/15 17:06:59 patrick Exp $ */ 2 /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ 3 4 /* 5 * Copyright (c) 2014 Patrick Wildt <patrick@blueri.se> 6 * Copyright (c) 2012 Stefan Fritsch. 7 * Copyright (c) 2010 Minoura Makoto. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/kernel.h> 34 #include <sys/device.h> 35 #include <sys/mutex.h> 36 37 #include <dev/pv/virtioreg.h> 38 #include <dev/pv/virtiovar.h> 39 40 #include <machine/fdt.h> 41 42 #include <dev/ofw/fdt.h> 43 #include <dev/ofw/openfirm.h> 44 45 #define VIRTIO_MMIO_MAGIC ('v' | 'i' << 8 | 'r' << 16 | 't' << 24) 46 47 #define VIRTIO_MMIO_MAGIC_VALUE 0x000 48 #define VIRTIO_MMIO_VERSION 0x004 49 #define VIRTIO_MMIO_DEVICE_ID 0x008 50 #define VIRTIO_MMIO_VENDOR_ID 0x00c 51 #define VIRTIO_MMIO_HOST_FEATURES 0x010 52 #define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 53 #define VIRTIO_MMIO_GUEST_FEATURES 0x020 54 #define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024 55 #define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 56 #define VIRTIO_MMIO_QUEUE_SEL 0x030 57 #define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 58 #define VIRTIO_MMIO_QUEUE_NUM 0x038 59 #define VIRTIO_MMIO_QUEUE_ALIGN 0x03c 60 #define VIRTIO_MMIO_QUEUE_PFN 0x040 61 #define VIRTIO_MMIO_QUEUE_READY 0x044 62 #define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 63 #define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 64 #define VIRTIO_MMIO_INTERRUPT_ACK 0x064 65 #define VIRTIO_MMIO_STATUS 0x070 66 #define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 67 #define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 68 #define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090 69 #define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094 70 #define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0 71 #define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4 72 #define VIRTIO_MMIO_CONFIG 0x100 73 74 #define VIRTIO_MMIO_INT_VRING (1 << 0) 75 #define VIRTIO_MMIO_INT_CONFIG (1 << 1) 76 77 #define DEVNAME(sc) (sc)->sc_dev.dv_xname 78 79 /* 80 * XXX: Before being used on big endian arches, the access to config registers 81 * XXX: needs to be reviewed/fixed. The non-device specific registers are 82 * XXX: PCI-endian while the device specific registers are native endian. 83 */ 84 85 int virtio_mmio_match(struct device *, void *, void *); 86 void virtio_mmio_attach(struct device *, struct device *, void *); 87 int virtio_mmio_detach(struct device *, int); 88 89 void virtio_mmio_kick(struct virtio_softc *, uint16_t); 90 uint8_t virtio_mmio_read_device_config_1(struct virtio_softc *, int); 91 uint16_t virtio_mmio_read_device_config_2(struct virtio_softc *, int); 92 uint32_t virtio_mmio_read_device_config_4(struct virtio_softc *, int); 93 uint64_t virtio_mmio_read_device_config_8(struct virtio_softc *, int); 94 void virtio_mmio_write_device_config_1(struct virtio_softc *, int, uint8_t); 95 void virtio_mmio_write_device_config_2(struct virtio_softc *, int, uint16_t); 96 void virtio_mmio_write_device_config_4(struct virtio_softc *, int, uint32_t); 97 void virtio_mmio_write_device_config_8(struct virtio_softc *, int, uint64_t); 98 uint16_t virtio_mmio_read_queue_size(struct virtio_softc *, uint16_t); 99 void virtio_mmio_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t); 100 void virtio_mmio_set_status(struct virtio_softc *, int); 101 int virtio_mmio_negotiate_features(struct virtio_softc *, 102 const struct virtio_feature_name *); 103 int virtio_mmio_intr(void *); 104 105 struct virtio_mmio_softc { 106 struct virtio_softc sc_sc; 107 108 bus_space_tag_t sc_iot; 109 bus_space_handle_t sc_ioh; 110 bus_size_t sc_iosize; 111 bus_dma_tag_t sc_dmat; 112 113 void *sc_ih; 114 115 int sc_config_offset; 116 uint32_t sc_version; 117 }; 118 119 struct cfattach virtio_mmio_ca = { 120 sizeof(struct virtio_mmio_softc), 121 virtio_mmio_match, 122 virtio_mmio_attach, 123 virtio_mmio_detach, 124 NULL 125 }; 126 127 struct cfattach virtio_mmio_fdt_ca = { 128 sizeof(struct virtio_mmio_softc), 129 NULL, 130 virtio_mmio_attach, 131 virtio_mmio_detach, 132 NULL 133 }; 134 135 struct virtio_ops virtio_mmio_ops = { 136 virtio_mmio_kick, 137 virtio_mmio_read_device_config_1, 138 virtio_mmio_read_device_config_2, 139 virtio_mmio_read_device_config_4, 140 virtio_mmio_read_device_config_8, 141 virtio_mmio_write_device_config_1, 142 virtio_mmio_write_device_config_2, 143 virtio_mmio_write_device_config_4, 144 virtio_mmio_write_device_config_8, 145 virtio_mmio_read_queue_size, 146 virtio_mmio_setup_queue, 147 virtio_mmio_set_status, 148 virtio_mmio_negotiate_features, 149 virtio_mmio_intr, 150 }; 151 152 uint16_t 153 virtio_mmio_read_queue_size(struct virtio_softc *vsc, uint16_t idx) 154 { 155 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 156 bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_SEL, idx); 157 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, 158 VIRTIO_MMIO_QUEUE_NUM_MAX); 159 } 160 161 void 162 virtio_mmio_setup_queue(struct virtio_softc *vsc, struct virtqueue *vq, 163 uint64_t addr) 164 { 165 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 166 bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_SEL, 167 vq->vq_index); 168 bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_NUM, 169 bus_space_read_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_NUM_MAX)); 170 if (sc->sc_version == 1) { 171 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 172 VIRTIO_MMIO_QUEUE_ALIGN, PAGE_SIZE); 173 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 174 VIRTIO_MMIO_QUEUE_PFN, addr / VIRTIO_PAGE_SIZE); 175 } else { 176 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 177 VIRTIO_MMIO_QUEUE_DESC_LOW, addr); 178 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 179 VIRTIO_MMIO_QUEUE_DESC_HIGH, addr >> 32); 180 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 181 VIRTIO_MMIO_QUEUE_AVAIL_LOW, 182 addr + vq->vq_availoffset); 183 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 184 VIRTIO_MMIO_QUEUE_AVAIL_HIGH, 185 (addr + vq->vq_availoffset) >> 32); 186 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 187 VIRTIO_MMIO_QUEUE_USED_LOW, 188 addr + vq->vq_usedoffset); 189 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 190 VIRTIO_MMIO_QUEUE_USED_HIGH, 191 (addr + vq->vq_usedoffset) >> 32); 192 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 193 VIRTIO_MMIO_QUEUE_READY, 1); 194 } 195 } 196 197 void 198 virtio_mmio_set_status(struct virtio_softc *vsc, int status) 199 { 200 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 201 int old = 0; 202 203 if (status != 0) 204 old = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 205 VIRTIO_MMIO_STATUS); 206 bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_STATUS, 207 status|old); 208 } 209 210 int 211 virtio_mmio_match(struct device *parent, void *cfdata, void *aux) 212 { 213 struct fdt_attach_args *faa = aux; 214 215 return OF_is_compatible(faa->fa_node, "virtio,mmio"); 216 } 217 218 void 219 virtio_mmio_attach(struct device *parent, struct device *self, void *aux) 220 { 221 struct fdt_attach_args *faa = aux; 222 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)self; 223 struct virtio_softc *vsc = &sc->sc_sc; 224 uint32_t id, magic; 225 226 if (faa->fa_nreg < 1) { 227 printf(": no register data\n"); 228 return; 229 } 230 231 sc->sc_iosize = faa->fa_reg[0].size; 232 sc->sc_iot = faa->fa_iot; 233 sc->sc_dmat = faa->fa_dmat; 234 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, faa->fa_reg[0].size, 235 0, &sc->sc_ioh)) 236 panic("%s: bus_space_map failed!", __func__); 237 238 magic = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 239 VIRTIO_MMIO_MAGIC_VALUE); 240 if (magic != VIRTIO_MMIO_MAGIC) { 241 printf(": wrong magic value 0x%08x; giving up\n", magic); 242 return; 243 } 244 245 sc->sc_version = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 246 VIRTIO_MMIO_VERSION); 247 if (sc->sc_version < 1 || sc->sc_version > 2) { 248 printf(": unknown version 0x%02x; giving up\n", sc->sc_version); 249 return; 250 } 251 252 id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_DEVICE_ID); 253 printf(": Virtio %s Device", virtio_device_string(id)); 254 255 if (sc->sc_version == 1) 256 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 257 VIRTIO_MMIO_GUEST_PAGE_SIZE, PAGE_SIZE); 258 259 printf("\n"); 260 261 /* No device connected. */ 262 if (id == 0) 263 return; 264 265 vsc->sc_ops = &virtio_mmio_ops; 266 vsc->sc_dmat = sc->sc_dmat; 267 sc->sc_config_offset = VIRTIO_MMIO_CONFIG; 268 269 virtio_device_reset(vsc); 270 virtio_mmio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK); 271 virtio_mmio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); 272 273 /* XXX: use softc as aux... */ 274 vsc->sc_childdevid = id; 275 vsc->sc_child = NULL; 276 config_found(self, sc, NULL); 277 if (vsc->sc_child == NULL) { 278 printf("%s: no matching child driver; not configured\n", 279 vsc->sc_dev.dv_xname); 280 goto fail_1; 281 } 282 if (vsc->sc_child == VIRTIO_CHILD_ERROR) { 283 printf("%s: virtio configuration failed\n", 284 vsc->sc_dev.dv_xname); 285 goto fail_1; 286 } 287 288 sc->sc_ih = fdt_intr_establish(faa->fa_node, vsc->sc_ipl, 289 virtio_mmio_intr, sc, vsc->sc_dev.dv_xname); 290 if (sc->sc_ih == NULL) { 291 printf("%s: couldn't establish interrupt\n", 292 vsc->sc_dev.dv_xname); 293 goto fail_2; 294 } 295 296 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); 297 return; 298 299 fail_2: 300 config_detach(vsc->sc_child, 0); 301 fail_1: 302 /* no mmio_mapreg_unmap() or mmio_intr_unmap() */ 303 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 304 } 305 306 int 307 virtio_mmio_detach(struct device *self, int flags) 308 { 309 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)self; 310 struct virtio_softc *vsc = &sc->sc_sc; 311 int r; 312 313 if (vsc->sc_child != 0 && vsc->sc_child != VIRTIO_CHILD_ERROR) { 314 r = config_detach(vsc->sc_child, flags); 315 if (r) 316 return r; 317 } 318 KASSERT(vsc->sc_child == 0 || vsc->sc_child == VIRTIO_CHILD_ERROR); 319 KASSERT(vsc->sc_vqs == 0); 320 fdt_intr_disestablish(sc->sc_ih); 321 sc->sc_ih = 0; 322 if (sc->sc_iosize) 323 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); 324 sc->sc_iosize = 0; 325 326 return 0; 327 } 328 329 /* 330 * Feature negotiation. 331 * Prints available / negotiated features if guest_feature_names != NULL and 332 * VIRTIO_DEBUG is 1 333 */ 334 int 335 virtio_mmio_negotiate_features(struct virtio_softc *vsc, 336 const struct virtio_feature_name *guest_feature_names) 337 { 338 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 339 uint64_t host, neg; 340 341 vsc->sc_active_features = 0; 342 343 /* 344 * We enable indirect descriptors by default. They can be switched 345 * off by setting bit 1 in the driver flags, see config(8). 346 */ 347 if (!(vsc->sc_dev.dv_cfdata->cf_flags & VIRTIO_CF_NO_INDIRECT) && 348 !(vsc->sc_child->dv_cfdata->cf_flags & VIRTIO_CF_NO_INDIRECT)) { 349 vsc->sc_driver_features |= VIRTIO_F_RING_INDIRECT_DESC; 350 } else if (guest_feature_names != NULL) { 351 printf("RingIndirectDesc disabled by UKC\n"); 352 } 353 /* 354 * The driver must add VIRTIO_F_RING_EVENT_IDX if it supports it. 355 * If it did, check if it is disabled by bit 2 in the driver flags. 356 */ 357 if ((vsc->sc_driver_features & VIRTIO_F_RING_EVENT_IDX) && 358 ((vsc->sc_dev.dv_cfdata->cf_flags & VIRTIO_CF_NO_EVENT_IDX) || 359 (vsc->sc_child->dv_cfdata->cf_flags & VIRTIO_CF_NO_EVENT_IDX))) { 360 if (guest_feature_names != NULL) 361 printf(" RingEventIdx disabled by UKC"); 362 vsc->sc_driver_features &= ~(VIRTIO_F_RING_EVENT_IDX); 363 } 364 365 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 366 VIRTIO_MMIO_HOST_FEATURES_SEL, 0); 367 host = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 368 VIRTIO_MMIO_HOST_FEATURES); 369 neg = host & vsc->sc_driver_features; 370 #if VIRTIO_DEBUG 371 if (guest_feature_names) 372 virtio_log_features(host, neg, guest_feature_names); 373 #endif 374 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 375 VIRTIO_MMIO_GUEST_FEATURES_SEL, 0); 376 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 377 VIRTIO_MMIO_GUEST_FEATURES, neg); 378 vsc->sc_active_features = neg; 379 if (neg & VIRTIO_F_RING_INDIRECT_DESC) 380 vsc->sc_indirect = 1; 381 else 382 vsc->sc_indirect = 0; 383 384 return 0; 385 } 386 387 /* 388 * Device configuration registers. 389 */ 390 uint8_t 391 virtio_mmio_read_device_config_1(struct virtio_softc *vsc, int index) 392 { 393 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 394 return bus_space_read_1(sc->sc_iot, sc->sc_ioh, 395 sc->sc_config_offset + index); 396 } 397 398 uint16_t 399 virtio_mmio_read_device_config_2(struct virtio_softc *vsc, int index) 400 { 401 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 402 return bus_space_read_2(sc->sc_iot, sc->sc_ioh, 403 sc->sc_config_offset + index); 404 } 405 406 uint32_t 407 virtio_mmio_read_device_config_4(struct virtio_softc *vsc, int index) 408 { 409 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 410 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, 411 sc->sc_config_offset + index); 412 } 413 414 uint64_t 415 virtio_mmio_read_device_config_8(struct virtio_softc *vsc, int index) 416 { 417 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 418 uint64_t r; 419 420 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 421 sc->sc_config_offset + index + sizeof(uint32_t)); 422 r <<= 32; 423 r += bus_space_read_4(sc->sc_iot, sc->sc_ioh, 424 sc->sc_config_offset + index); 425 return r; 426 } 427 428 void 429 virtio_mmio_write_device_config_1(struct virtio_softc *vsc, 430 int index, uint8_t value) 431 { 432 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 433 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 434 sc->sc_config_offset + index, value); 435 } 436 437 void 438 virtio_mmio_write_device_config_2(struct virtio_softc *vsc, 439 int index, uint16_t value) 440 { 441 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 442 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 443 sc->sc_config_offset + index, value); 444 } 445 446 void 447 virtio_mmio_write_device_config_4(struct virtio_softc *vsc, 448 int index, uint32_t value) 449 { 450 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 451 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 452 sc->sc_config_offset + index, value); 453 } 454 455 void 456 virtio_mmio_write_device_config_8(struct virtio_softc *vsc, 457 int index, uint64_t value) 458 { 459 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 460 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 461 sc->sc_config_offset + index, 462 value & 0xffffffff); 463 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 464 sc->sc_config_offset + index + sizeof(uint32_t), 465 value >> 32); 466 } 467 468 /* 469 * Interrupt handler. 470 */ 471 int 472 virtio_mmio_intr(void *arg) 473 { 474 struct virtio_mmio_softc *sc = arg; 475 struct virtio_softc *vsc = &sc->sc_sc; 476 int isr, r = 0; 477 478 /* check and ack the interrupt */ 479 isr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 480 VIRTIO_MMIO_INTERRUPT_STATUS); 481 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 482 VIRTIO_MMIO_INTERRUPT_ACK, isr); 483 if ((isr & VIRTIO_MMIO_INT_CONFIG) && 484 (vsc->sc_config_change != NULL)) 485 r = (vsc->sc_config_change)(vsc); 486 if ((isr & VIRTIO_MMIO_INT_VRING)) 487 r |= virtio_check_vqs(vsc); 488 489 return r; 490 } 491 492 void 493 virtio_mmio_kick(struct virtio_softc *vsc, uint16_t idx) 494 { 495 struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; 496 bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_NOTIFY, 497 idx); 498 } 499