iPXE
virtio.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27/** @file
28 *
29 * Virtual I/O device
30 *
31 */
32
33#include <string.h>
34#include <assert.h>
35#include <errno.h>
36#include <unistd.h>
37#include <ipxe/pci.h>
38#include <ipxe/virtio.h>
39
40/******************************************************************************
41 *
42 * Original ("legacy") device operations
43 *
44 ******************************************************************************
45 */
46
47/**
48 * Reset device
49 *
50 * @v virtio Virtio device
51 * @ret rc Return status code
52 */
53static int virtio_legacy_reset ( struct virtio_device *virtio ) {
55 unsigned int i;
56
57 /* Reset device */
58 iowrite8 ( 0, virtio->common + VIRTIO_LEG_STAT );
59
60 /* Wait for reset to complete */
61 for ( i = 0 ; i < VIRTIO_RESET_MAX_WAIT_MS ; i++ ) {
62 stat = ioread8 ( virtio->common + VIRTIO_LEG_STAT );
63 if ( ! stat )
64 return 0;
65 mdelay ( 1 );
66 }
67
68 DBGC ( virtio, "VIRTIO %s could not reset device\n", virtio->name );
69 return -ETIMEDOUT;
70}
71
72/**
73 * Report driver status
74 *
75 * @v virtio Virtio device
76 * @ret stat Actual device status
77 */
78static unsigned int virtio_legacy_status ( struct virtio_device *virtio ) {
79
80 /* Report device status */
81 iowrite8 ( virtio->stat, virtio->common + VIRTIO_LEG_STAT );
82
83 /* Read back device status */
84 return ioread8 ( virtio->common + VIRTIO_LEG_STAT );
85}
86
87/**
88 * Get supported features
89 *
90 * @v virtio Virtio device
91 */
92static void virtio_legacy_supported ( struct virtio_device *virtio ) {
93 struct virtio_features *supported = &virtio->supported;
94 unsigned int i;
95
96 /* Get device supported features */
97 supported->word[0] = ioread32 ( virtio->common + VIRTIO_LEG_FEAT );
98
99 /* Legacy devices have only a single 32-bit feature register */
100 for ( i = 1 ; i < VIRTIO_FEATURE_WORDS ; i++ )
101 supported->word[i] = 0;
102}
103
104/**
105 * Negotiate device features
106 *
107 * @v virtio Virtio device
108 */
109static void virtio_legacy_negotiate ( struct virtio_device *virtio ) {
110 struct virtio_features *features = &virtio->features;
111 unsigned int i;
112
113 /* Set in-use features */
114 iowrite32 ( features->word[0], virtio->common + VIRTIO_LEG_USED );
115
116 /* Legacy devices have only a single 32-bit feature register */
117 for ( i = 1 ; i < VIRTIO_FEATURE_WORDS ; i++ )
118 assert ( features->word[i] == 0 );
119}
120
121/**
122 * Set queue size
123 *
124 * @v virtio Virtio device
125 * @v queue Virtio queue
126 * @v count Requested size
127 */
128static void virtio_legacy_size ( struct virtio_device *virtio,
129 struct virtio_queue *queue,
130 unsigned int count ) {
131 size_t len;
132
133 /* Select queue */
134 iowrite16 ( queue->index, virtio->common + VIRTIO_LEG_SEL );
135
136 /* Get (fixed) queue size */
137 count = ioread16 ( virtio->common + VIRTIO_LEG_SIZE );
138
139 /* Calculate queue length */
143
144 /* Record queue size */
145 queue->count = count;
146 queue->len = len;
147}
148
149/**
150 * Enable queue
151 *
152 * @v virtio Virtio device
153 * @v queue Virtio queue
154 */
155static void virtio_legacy_enable ( struct virtio_device *virtio,
156 struct virtio_queue *queue ) {
157 unsigned int count = queue->count;
158 void *base = queue->desc;
159 size_t len;
160
161 /* Select queue */
162 iowrite16 ( queue->index, virtio->common + VIRTIO_LEG_SEL );
163
164 /* Lay out queue regions */
166 queue->sq = ( base + len );
168 queue->cq = ( base + len );
170 assert ( len == queue->len );
171
172 /* Program queue base page address */
173 iowrite32 ( ( dma ( &queue->map, queue->desc ) / VIRTIO_PAGE ),
174 virtio->common + VIRTIO_LEG_BASE );
175}
176
177/** Original ("legacy") device operations */
179 .reset = virtio_legacy_reset,
180 .status = virtio_legacy_status,
181 .supported = virtio_legacy_supported,
182 .negotiate = virtio_legacy_negotiate,
183 .size = virtio_legacy_size,
184 .enable = virtio_legacy_enable,
185};
186
187/******************************************************************************
188 *
189 * PCI ("modern") device operations
190 *
191 ******************************************************************************
192 */
193
194/**
195 * Reset device
196 *
197 * @v virtio Virtio device
198 * @ret rc Return status code
199 */
200static int virtio_pci_reset ( struct virtio_device *virtio ) {
202 unsigned int i;
203
204 /* Reset device */
205 iowrite8 ( 0, virtio->common + VIRTIO_PCI_STAT );
206
207 /* Wait for reset to complete */
208 for ( i = 0 ; i < VIRTIO_RESET_MAX_WAIT_MS ; i++ ) {
209 stat = ioread8 ( virtio->common + VIRTIO_PCI_STAT );
210 if ( ! stat )
211 return 0;
212 mdelay ( 1 );
213 }
214
215 DBGC ( virtio, "VIRTIO %s could not reset device\n", virtio->name );
216 return -ETIMEDOUT;
217}
218
219/**
220 * Report driver status
221 *
222 * @v virtio Virtio device
223 * @ret stat Actual device status
224 */
225static unsigned int virtio_pci_status ( struct virtio_device *virtio ) {
226
227 /* Report device status */
228 iowrite8 ( virtio->stat, virtio->common + VIRTIO_PCI_STAT );
229
230 /* Read back device status */
231 return ioread8 ( virtio->common + VIRTIO_PCI_STAT );
232}
233
234/**
235 * Get supported features
236 *
237 * @v virtio Virtio device
238 */
239static void virtio_pci_supported ( struct virtio_device *virtio ) {
240 struct virtio_features *supported = &virtio->supported;
241 unsigned int i;
242
243 /* Get device supported features */
244 for ( i = 0 ; i < VIRTIO_FEATURE_WORDS ; i++ ) {
245 iowrite32 ( i, virtio->common + VIRTIO_PCI_FEAT_SEL );
246 supported->word[i] =
247 ioread32 ( virtio->common + VIRTIO_PCI_FEAT );
248 }
249}
250
251/**
252 * Negotiate device features
253 *
254 * @v virtio Virtio device
255 */
256static void virtio_pci_negotiate ( struct virtio_device *virtio ) {
257 struct virtio_features *features = &virtio->features;
258 unsigned int i;
259
260 /* Set in-use features */
261 for ( i = 0 ; i < VIRTIO_FEATURE_WORDS ; i++ ) {
262 iowrite32 ( i, virtio->common + VIRTIO_PCI_USED_SEL );
263 iowrite32 ( features->word[i],
264 virtio->common + VIRTIO_PCI_USED );
265 }
266}
267
268/**
269 * Set queue size
270 *
271 * @v virtio Virtio device
272 * @v queue Virtio queue
273 * @v count Requested size
274 */
275static void virtio_pci_size ( struct virtio_device *virtio,
276 struct virtio_queue *queue,
277 unsigned int count ) {
278 unsigned int max;
279 size_t len;
280
281 /* Select queue */
282 iowrite16 ( queue->index, virtio->common + VIRTIO_PCI_SEL );
283
284 /* Set queue size */
285 max = ioread16 ( virtio->common + VIRTIO_PCI_SIZE );
286 if ( count > max )
287 count = max;
288 iowrite16 ( count, virtio->common + VIRTIO_PCI_SIZE );
289
290 /* Calculate queue length */
294
295 /* Record queue size */
296 queue->count = count;
297 queue->len = len;
298}
299
300/**
301 * Program queue address
302 *
303 * @v virtio Virtio device
304 * @v queue Virtio queue
305 * @v addr Address
306 * @v offset Register offset
307 */
308static void virtio_pci_address ( struct virtio_device *virtio,
309 struct virtio_queue *queue,
310 void *addr, unsigned int offset ) {
312
313 /* Program address */
314 phys = dma ( &queue->map, addr );
315 iowrite32 ( ( phys & 0xffffffffUL ), ( virtio->common + offset + 0 ) );
316 if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
317 iowrite32 ( ( ( ( uint64_t ) phys ) >> 32 ),
318 ( virtio->common + offset + 4 ) );
319 } else {
320 iowrite32 ( 0, ( virtio->common + offset + 4 ) );
321 }
322}
323
324/**
325 * Enable queue
326 *
327 * @v virtio Virtio device
328 * @v queue Virtio queue
329 */
330static void virtio_pci_enable ( struct virtio_device *virtio,
331 struct virtio_queue *queue ) {
332 unsigned int count = queue->count;
333 void *base = queue->desc;
334 size_t len;
335
336 /* Select queue */
337 iowrite16 ( queue->index, virtio->common + VIRTIO_PCI_SEL );
338
339 /* Lay out queue regions */
341 queue->sq = ( base + len );
343 queue->cq = ( base + len );
345 assert ( len == queue->len );
346
347 /* Program queue addresses */
348 virtio_pci_address ( virtio, queue, queue->desc, VIRTIO_PCI_DESC );
351
352 /* Enable queue */
353 iowrite16 ( 1, virtio->common + VIRTIO_PCI_ENABLE );
354}
355
356/** PCI ("modern") device operations */
358 .reset = virtio_pci_reset,
359 .status = virtio_pci_status,
360 .supported = virtio_pci_supported,
361 .negotiate = virtio_pci_negotiate,
362 .size = virtio_pci_size,
363 .enable = virtio_pci_enable,
364};
365
366/**
367 * Find PCI capability
368 *
369 * @v virtio Virtio device
370 * @v pci PCI device
371 * @v type Capability type
372 * @v cap Virtio PCI capability to fill in
373 * @ret rc Return status code
374 */
375static int virtio_pci_cap ( struct virtio_device *virtio,
376 struct pci_device *pci, unsigned int type,
377 struct virtio_pci_capability *cap ) {
378 unsigned int reg;
379 int pos;
380
381 /* Scan through vendor capabilities */
382 for ( pos = pci_find_capability ( pci, PCI_CAP_ID_VNDR ) ; pos > 0 ;
383 pos = pci_find_next_capability ( pci, pos, PCI_CAP_ID_VNDR ) ) {
384
385 /* Check length */
386 pci_read_config_byte ( pci, ( pos + PCI_CAP_LEN ), &cap->len );
387 if ( cap->len < VIRTIO_PCI_CAP_END ) {
388 DBGC ( virtio, "VIRTIO %s capability +%#02x too short "
389 "(%d bytes)\n", virtio->name, pos, cap->len );
390 continue;
391 }
392
393 /* Read values */
395 &cap->type );
397 &cap->bar );
399 &cap->offset );
400
401 /* Check type */
402 if ( cap->type != type )
403 continue;
404 DBGC2 ( virtio, "VIRTIO %s capability type %d BAR%d+%#04x\n",
405 virtio->name, type, cap->bar, cap->offset );
406
407 /* Check BAR */
408 reg = PCI_BASE_ADDRESS ( cap->bar );
409 if ( reg > PCI_BASE_ADDRESS_5 )
410 continue;
411
412 /* Check BAR accessibility */
413 if ( ! pci_bar_start ( pci, reg ) ) {
414 DBGC ( virtio, "VIRTIO %s capability type %d BAR%d is "
415 "not usable\n", virtio->name, type, cap->bar );
416 continue;
417 }
418
419 /* Success */
420 cap->pos = pos;
421 return 0;
422 }
423
424 DBGC ( virtio, "VIRTIO %s has no usable capability type %d\n",
425 virtio->name, type );
426 cap->pos = 0;
427 return -ENOENT;
428}
429
430/**
431 * Map PCI capability
432 *
433 * @v virtio Virtio device
434 * @v pci PCI device
435 * @v cap Virtio PCI capability
436 * @ret io_addr I/O address, or NULL on error
437 */
438static void * virtio_pci_map_cap ( struct virtio_device *virtio,
439 struct pci_device *pci,
440 struct virtio_pci_capability *cap ) {
441 unsigned long addr;
442 unsigned int reg;
443 int is_io_bar;
444 void *io_addr;
445
446 /* Get BAR start address and type */
447 reg = PCI_BASE_ADDRESS ( cap->bar );
448 addr = pci_bar_start ( pci, reg );
449 if ( ! addr ) {
450 DBGC ( virtio, "VIRTIO %s BAR%d is not usable\n",
451 virtio->name, cap->bar );
452 return NULL;
453 }
454
455 /* Map memory or I/O BAR */
456 addr += cap->offset;
457 is_io_bar = pci_bar_is_io ( pci, reg );
458 io_addr = ( is_io_bar ? ( ( void * ) addr ) :
459 pci_ioremap ( pci, addr, VIRTIO_PAGE ) );
460 if ( ! io_addr ) {
461 DBGC ( virtio, "VIRTIO %s could not map BAR%d+%#04x\n",
462 virtio->name, cap->bar, cap->offset );
463 return NULL;
464 }
465
466 DBGC2 ( virtio, "VIRTIO %s mapped BAR%d+%#04x (%s %#08lx)\n",
467 virtio->name, cap->bar, cap->offset,
468 ( is_io_bar ? "IO" : "MEM" ), addr );
469 return io_addr;
470}
471
472/**
473 * Map PCI device
474 *
475 * @v virtio Virtio device
476 * @v pci PCI device
477 * @ret rc Return status code
478 */
479int virtio_pci_map ( struct virtio_device *virtio, struct pci_device *pci ) {
481 struct virtio_pci_capability notify;
483 unsigned int msix;
484 uint32_t mult;
486 int rc;
487
488 /* Initialise device */
489 virtio->name = pci->dev.name;
490 virtio->dma = &pci->dma;
491
492 /* Fix up PCI device */
493 adjust_pci_device ( pci );
494
495 /* Check if MSI-X is enabled */
496 msix = pci_find_capability ( pci, PCI_CAP_ID_MSIX );
497 if ( msix ) {
498 pci_read_config_word ( pci, msix, &ctrl );
499 if ( ! ( ctrl & PCI_MSIX_CTRL_ENABLE ) )
500 msix = 0;
501 }
502
503 /* Locate virtio capabilities */
505 virtio_pci_cap ( virtio, pci, VIRTIO_PCI_CAP_TYPE_NOTIFY, &notify );
507
508 /* Use modern interface if available */
509 if ( common.pos && notify.pos && device.pos &&
510 ( notify.len >= VIRTIO_PCI_CAP_NOTIFY_END ) ) {
511
512 /* Use modern interface */
513 virtio->op = &virtio_pci_operations;
514 dma_set_mask_64bit ( virtio->dma );
515
516 /* Read notification doorbell multiplier */
517 pci_read_config_dword ( pci, ( notify.pos +
519 &mult );
520 virtio->multiplier = mult;
521 DBGC ( virtio, "VIRTIO %s using modern interface (mult x%d)\n",
522 virtio->name, virtio->multiplier );
523
524 } else {
525
526 /* Use legacy interface */
527 virtio->op = &virtio_legacy_operations;
528 common.bar = 0;
529 common.offset = 0;
530 notify.bar = 0;
531 notify.offset = VIRTIO_LEG_DB;
532 device.bar = 0;
533 device.offset = ( msix ? VIRTIO_LEG_DEV_MSIX :
535 DBGC ( virtio, "VIRTIO %s using legacy interface (MSI-X "
536 "%sabled)\n", virtio->name, ( msix ? "en" : "dis" ) );
537 }
538
539 /* Map registers */
540 virtio->common = virtio_pci_map_cap ( virtio, pci, &common );
541 if ( ! virtio->common ) {
542 rc = -ENODEV;
543 goto err_common;
544 }
545 virtio->notify = virtio_pci_map_cap ( virtio, pci, &notify );
546 if ( ! virtio->notify ) {
547 rc = -ENODEV;
548 goto err_notify;
549 }
550 virtio->device = virtio_pci_map_cap ( virtio, pci, &device );
551 if ( ! virtio->device ) {
552 rc = -ENODEV;
553 goto err_device;
554 }
555
556 return 0;
557
558 iounmap ( virtio->device );
559 err_device:
560 iounmap ( virtio->notify );
561 err_notify:
562 iounmap ( virtio->common );
563 err_common:
564 return rc;
565}
566
567/******************************************************************************
568 *
569 * Transport-independent operations
570 *
571 ******************************************************************************
572 */
573
574/**
575 * Reset device
576 *
577 * @v virtio Virtio device
578 * @ret rc Return status code
579 */
580int virtio_reset ( struct virtio_device *virtio ) {
581 int rc;
582
583 /* Clear driver status */
584 virtio->stat = 0;
585
586 /* Reset device */
587 if ( ( rc = virtio->op->reset ( virtio ) ) != 0 ) {
588 DBGC ( virtio, "VIRTIO %s could not reset: %s\n",
589 virtio->name, strerror ( rc ) );
590 return rc;
591 }
592
593 return 0;
594}
595
596/**
597 * Report driver status
598 *
599 * @v virtio Virtio device
600 * @v stat Additional driver status bits
601 * @ret stat Actual device status
602 */
603unsigned int virtio_status ( struct virtio_device *virtio,
604 unsigned int stat ) {
605
606 /* Set new driver status bits */
607 virtio->stat |= stat;
608
609 /* Report driver status */
610 return virtio->op->status ( virtio );
611}
612
613/**
614 * Negotiate features
615 *
616 * @v virtio Virtio device
617 * @v driver Driver supported features
618 */
619static void virtio_negotiate ( struct virtio_device *virtio,
620 const struct virtio_features *driver ) {
621 struct virtio_features *device = &virtio->supported;
622 struct virtio_features *features = &virtio->features;
623 unsigned int i;
624
625 /* Get device supported features */
626 virtio->op->supported ( virtio );
627
628 /* Negotiate mutually supported features */
629 for ( i = 0 ; i < VIRTIO_FEATURE_WORDS ; i++ )
630 features->word[i] = ( device->word[i] & driver->word[i] );
631 virtio->op->negotiate ( virtio );
632
633 /* Show features */
634 DBGC ( virtio, "VIRTIO %s features", virtio->name );
635 for ( i = 0 ; i < VIRTIO_FEATURE_WORDS ; i++ )
636 DBGC ( virtio, "%s%08x", ( i ? ":" : " " ), device->word[i] );
637 DBGC ( virtio, " /" );
638 for ( i = 0 ; i < VIRTIO_FEATURE_WORDS ; i++ )
639 DBGC ( virtio, "%s%08x", ( i ? ":" : " " ), features->word[i] );
640 DBGC ( virtio, "\n" );
641}
642
643/**
644 * Initialise device
645 *
646 * @v virtio Virtio device
647 * @v driver Driver supported features
648 * @ret rc Return status code
649 */
650int virtio_init ( struct virtio_device *virtio,
651 const struct virtio_features *driver ) {
652 unsigned int stat;
653 int rc;
654
655 /* Reset device */
656 if ( ( rc = virtio_reset ( virtio ) ) != 0 )
657 goto err_reset;
658
659 /* Acknowledge device existence */
661
662 /* Report driver existence */
664
665 /* Negotiate features */
666 virtio_negotiate ( virtio, driver );
667
668 /* Report feature negotiation completion, if applicable */
669 if ( virtio->features.word[1] & VIRTIO_FEAT1_MODERN ) {
671 if ( ! ( stat & VIRTIO_STAT_FEATURES_OK ) ) {
672 DBGC ( virtio, "VIRTIO %s did not accept features\n",
673 virtio->name );
674 rc = -ENOTSUP;
675 goto err_features;
676 }
677 }
678
679 return 0;
680
681 err_features:
682 virtio_reset ( virtio );
683 err_reset:
685 return rc;
686}
687
688/**
689 * Enable queue
690 *
691 * @v virtio Virtio device
692 * @v queue Virtio queue
693 * @v count Requested queue size
694 * @ret rc Return status code
695 */
696int virtio_enable ( struct virtio_device *virtio, struct virtio_queue *queue,
697 unsigned int count ) {
698 unsigned int offset;
699 int rc;
700
701 /* Reset counters */
702 queue->prod = 0;
703 queue->cons = 0;
704
705 /* Determine queue size */
706 virtio->op->size ( virtio, queue, count );
707 if ( ( queue->count == 0 ) ||
708 ( queue->count & ( queue->count - 1 ) ) ) {
709 DBGC ( virtio, "VIRTIO %s Q%d invalid size %d\n",
710 virtio->name, queue->index, queue->count );
711 rc = -ENODEV;
712 goto err_count;
713 }
714 queue->mask = ( queue->count - 1 );
715
716 /* Allocate and initialise queue */
717 queue->desc = dma_alloc ( virtio->dma, &queue->map, queue->len,
718 VIRTIO_PAGE );
719 if ( ! queue->desc ) {
720 rc = -ENOMEM;
721 goto err_alloc;
722 }
723 memset ( queue->desc, 0, queue->len );
724
725 /* Enable queue */
726 virtio->op->enable ( virtio, queue );
727 DBGC ( virtio, "VIRTIO %s Q%d %dx descriptors at [%#08lx,%#08lx)\n",
728 virtio->name, queue->index, queue->count,
729 virt_to_phys ( queue->desc ),
730 ( virt_to_phys ( queue->desc ) +
731 virtio_desc_size ( queue->count ) ) );
732 DBGC ( virtio, "VIRTIO %s Q%d %dx submissions at [%#08lx,%#08lx)\n",
733 virtio->name, queue->index, queue->count,
734 virt_to_phys ( queue->sq ),
735 ( virt_to_phys ( queue->sq ) +
736 virtio_sq_size ( queue->count ) ) );
737 DBGC ( virtio, "VIRTIO %s Q%d %dx completions at [%#08lx,%#08lx)\n",
738 virtio->name, queue->index, queue->count,
739 virt_to_phys ( queue->cq ),
740 ( virt_to_phys ( queue->cq ) +
741 virtio_cq_size ( queue->count ) ) );
742
743 /* Calculate doorbell register address */
744 offset = ( queue->index * virtio->multiplier );
745 queue->db = ( virtio->notify + offset );
746 DBGC ( virtio, "VIRTIO %s Q%d doorbell at +%#04x\n",
747 virtio->name, queue->index, offset );
748
749 return 0;
750
751 dma_free ( &queue->map, queue->desc, queue->len );
752 queue->desc = NULL;
753 err_alloc:
754 err_count:
755 return rc;
756}
757
758/**
759 * Free queue
760 *
761 * @v virtio Virtio device
762 * @v queue Virtio queue
763 */
764void virtio_free ( struct virtio_device *virtio, struct virtio_queue *queue ) {
765
766 /* Free queue */
767 if ( queue->desc ) {
768 dma_free ( &queue->map, queue->desc, queue->len );
769 queue->desc = NULL;
770 DBGC ( virtio, "VIRTIO %s Q%d freed\n",
771 virtio->name, queue->index );
772 }
773}
774
775/**
776 * Unmap device
777 *
778 * @v virtio Virtio device
779 */
780void virtio_unmap ( struct virtio_device *virtio ) {
781
782 /* Unmap device-specific registers */
783 iounmap ( virtio->device );
784
785 /* Unmap notification doorbells */
786 iounmap ( virtio->notify );
787
788 /* Unmap common registers */
789 iounmap ( virtio->common );
790}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
unsigned long physaddr_t
Definition stdint.h:20
unsigned long long uint64_t
Definition stdint.h:13
unsigned char uint8_t
Definition stdint.h:10
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define max(x, y)
Definition ath.h:41
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint8_t ctrl
Ring control.
Definition dwmac.h:7
uint32_t stat
Completion status.
Definition dwmac.h:1
ring len
Length.
Definition dwmac.h:226
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint32_t features
Supported features.
Definition ena.h:5
uint32_t type
Operating system type.
Definition ena.h:1
uint16_t supported
Bitmask of supported option values.
Definition ena.h:1
uint16_t queue
Queue ID.
Definition ena.h:11
static signed char phys[4]
Definition epic100.c:88
Error codes.
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define ENOENT
No such file or directory.
Definition errno.h:515
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ENODEV
No such device.
Definition errno.h:510
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#define VIRTIO_STAT_FEATURES_OK
Guest driver has set features.
Definition virtio.h:52
#define VIRTIO_STAT_ACKNOWLEDGE
Guest has found device.
Definition virtio.h:49
#define VIRTIO_STAT_FAIL
Guest driver has failed.
Definition virtio.h:53
#define VIRTIO_STAT_DRIVER
Guest driver exists.
Definition virtio.h:50
#define VIRTIO_LEG_SEL
Legacy queue select register.
Definition virtio.h:42
#define VIRTIO_LEG_BASE
Legacy queue base address register.
Definition virtio.h:36
#define VIRTIO_LEG_USED
Legacy negotiated in-use features register.
Definition virtio.h:33
#define VIRTIO_LEG_DEV_MSIX
Legacy device-specific register (if MSI-X is enabled).
Definition virtio.h:59
#define VIRTIO_LEG_FEAT
Legacy device supported features register.
Definition virtio.h:30
#define VIRTIO_LEG_SIZE
Legacy queue size register.
Definition virtio.h:39
#define VIRTIO_LEG_DB
Legacy queue doorbell notification register.
Definition virtio.h:45
#define VIRTIO_LEG_STAT
Legacy driver status register.
Definition virtio.h:48
#define VIRTIO_LEG_DEV
Legacy device-specific registers.
Definition virtio.h:56
#define VIRTIO_PCI_CAP_BAR
Capability BAR index.
Definition virtio.h:75
#define VIRTIO_PCI_CAP_NOTIFY_END
Notification doorbell capability minimum length.
Definition virtio.h:87
#define VIRTIO_PCI_CAP_TYPE_NOTIFY
Notification doorbells.
Definition virtio.h:71
#define VIRTIO_PCI_CAP_OFFSET
Capability BAR offset.
Definition virtio.h:78
#define VIRTIO_PCI_CAP_NOTIFY_MULT
Notification doorbell capability multiplier offset.
Definition virtio.h:84
#define VIRTIO_PCI_CAP_TYPE_DEVICE
Device-specific registers.
Definition virtio.h:72
#define VIRTIO_PCI_CAP_TYPE_COMMON
Common registers.
Definition virtio.h:70
#define VIRTIO_PCI_CAP_END
Capability minimum length.
Definition virtio.h:81
#define VIRTIO_PCI_CAP_TYPE
Capability type.
Definition virtio.h:69
#define VIRTIO_PCI_FEAT
PCI device supported features register.
Definition virtio.h:114
#define VIRTIO_PCI_SEL
PCI queue select register.
Definition virtio.h:129
#define VIRTIO_PCI_STAT
PCI device status register.
Definition virtio.h:123
#define VIRTIO_PCI_USED_SEL
PCI negotiated in-use features select register.
Definition virtio.h:117
#define VIRTIO_PCI_FEAT_SEL
PCI device supported features select register.
Definition virtio.h:111
#define VIRTIO_PCI_USED
PCI negotiated in-use features register.
Definition virtio.h:120
#define VIRTIO_PCI_SIZE
PCI queue size register.
Definition virtio.h:132
#define VIRTIO_PCI_DESC
PCI queue descriptor array base address register.
Definition virtio.h:141
#define VIRTIO_PCI_CQ
PCI queue completion queue base address register.
Definition virtio.h:147
#define VIRTIO_PCI_SQ
PCI queue submission queue base address register.
Definition virtio.h:144
#define VIRTIO_PCI_ENABLE
PCI queue enable register.
Definition virtio.h:135
struct ib_cm_common common
Definition ib_mad.h:0
#define ioread16(io_addr)
Definition io.h:350
#define ioread32(io_addr)
Definition io.h:360
#define iowrite8(data, io_addr)
Definition io.h:370
#define iowrite16(data, io_addr)
Definition io.h:380
#define ioread8(io_addr)
Definition io.h:340
#define iowrite32(data, io_addr)
Definition io.h:390
void iounmap(volatile const void *io_addr)
Unmap I/O address.
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
static __always_inline void dma_set_mask_64bit(struct dma_device *dma)
Set 64-bit addressable space mask.
Definition dma.h:467
void dma_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
void * dma_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer.
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
uint32_t base
Base.
Definition librm.h:3
static unsigned int unsigned int reg
Definition myson.h:162
int pci_bar_is_io(struct pci_device *pci, unsigned int reg)
Get PCI BAR type.
Definition pci.c:90
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition pci.c:255
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition pci.c:111
PCI bus.
#define PCI_CAP_ID_VNDR
Vendor-specific.
Definition pci.h:97
#define PCI_CAP_LEN
Capability length.
Definition pci.h:106
#define PCI_MSIX_CTRL_ENABLE
Enable MSI-X.
Definition pci.h:120
#define PCI_CAP_ID_MSIX
MSI-X.
Definition pci.h:99
#define PCI_BASE_ADDRESS(n)
PCI base address registers.
Definition pci.h:62
#define PCI_BASE_ADDRESS_5
Definition pci.h:68
int pci_find_next_capability(struct pci_device *pci, int pos, int cap)
Look for another PCI capability.
Definition pciextra.c:76
int pci_find_capability(struct pci_device *pci, int cap)
Look for a PCI capability.
Definition pciextra.c:39
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A hardware device.
Definition device.h:77
char name[40]
Name.
Definition device.h:79
A PCI device.
Definition pci.h:214
struct device dev
Generic device.
Definition pci.h:216
struct dma_device dma
DMA device.
Definition pci.h:218
A virtio device.
Definition virtio.h:311
struct virtio_features features
Negotiated features.
Definition virtio.h:329
const char * name
Device name.
Definition virtio.h:313
unsigned int multiplier
Notification doorbell multiplier.
Definition virtio.h:331
void * notify
Doorbell notification registers.
Definition virtio.h:321
void * common
Common registers.
Definition virtio.h:319
void * device
Device-specific registers.
Definition virtio.h:323
struct virtio_operations * op
Device operations.
Definition virtio.h:315
struct dma_device * dma
DMA device.
Definition virtio.h:317
unsigned int stat
Driver status.
Definition virtio.h:325
struct virtio_features supported
Device supported features.
Definition virtio.h:327
A virtio feature set.
Definition virtio.h:299
uint32_t word[VIRTIO_FEATURE_WORDS]
Feature words.
Definition virtio.h:301
Virtio device operations.
Definition virtio.h:335
void(* negotiate)(struct virtio_device *virtio)
Set negotiated features.
Definition virtio.h:361
void(* enable)(struct virtio_device *virtio, struct virtio_queue *queue)
Enable queue.
Definition virtio.h:377
void(* supported)(struct virtio_device *virtio)
Get supported features.
Definition virtio.h:355
int(* reset)(struct virtio_device *virtio)
Reset device.
Definition virtio.h:342
unsigned int(* status)(struct virtio_device *virtio)
Report driver status.
Definition virtio.h:349
void(* size)(struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
Set queue size.
Definition virtio.h:369
A virtio PCI capability.
Definition virtio.h:92
uint32_t offset
Offset within BAR.
Definition virtio.h:102
uint8_t type
Capability type.
Definition virtio.h:94
uint8_t len
Capability length.
Definition virtio.h:98
uint8_t pos
Capability offset.
Definition virtio.h:96
uint8_t bar
BAR number.
Definition virtio.h:100
A virtio queue.
Definition virtio.h:207
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
static unsigned int virtio_pci_status(struct virtio_device *virtio)
Report driver status.
Definition virtio.c:225
static int virtio_legacy_reset(struct virtio_device *virtio)
Reset device.
Definition virtio.c:53
static void virtio_legacy_supported(struct virtio_device *virtio)
Get supported features.
Definition virtio.c:92
int virtio_init(struct virtio_device *virtio, const struct virtio_features *driver)
Initialise device.
Definition virtio.c:650
static struct virtio_operations virtio_pci_operations
PCI ("modern") device operations.
Definition virtio.c:357
static void virtio_legacy_negotiate(struct virtio_device *virtio)
Negotiate device features.
Definition virtio.c:109
unsigned int virtio_status(struct virtio_device *virtio, unsigned int stat)
Report driver status.
Definition virtio.c:603
static unsigned int virtio_legacy_status(struct virtio_device *virtio)
Report driver status.
Definition virtio.c:78
int virtio_enable(struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
Enable queue.
Definition virtio.c:696
static void virtio_pci_size(struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
Set queue size.
Definition virtio.c:275
int virtio_reset(struct virtio_device *virtio)
Reset device.
Definition virtio.c:580
static void virtio_negotiate(struct virtio_device *virtio, const struct virtio_features *driver)
Negotiate features.
Definition virtio.c:619
static int virtio_pci_reset(struct virtio_device *virtio)
Reset device.
Definition virtio.c:200
static int virtio_pci_cap(struct virtio_device *virtio, struct pci_device *pci, unsigned int type, struct virtio_pci_capability *cap)
Find PCI capability.
Definition virtio.c:375
void virtio_free(struct virtio_device *virtio, struct virtio_queue *queue)
Free queue.
Definition virtio.c:764
static void * virtio_pci_map_cap(struct virtio_device *virtio, struct pci_device *pci, struct virtio_pci_capability *cap)
Map PCI capability.
Definition virtio.c:438
static struct virtio_operations virtio_legacy_operations
Original ("legacy") device operations.
Definition virtio.c:178
static void virtio_legacy_size(struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
Set queue size.
Definition virtio.c:128
static void virtio_pci_enable(struct virtio_device *virtio, struct virtio_queue *queue)
Enable queue.
Definition virtio.c:330
static void virtio_pci_supported(struct virtio_device *virtio)
Get supported features.
Definition virtio.c:239
void virtio_unmap(struct virtio_device *virtio)
Unmap device.
Definition virtio.c:780
static void virtio_pci_negotiate(struct virtio_device *virtio)
Negotiate device features.
Definition virtio.c:256
static void virtio_legacy_enable(struct virtio_device *virtio, struct virtio_queue *queue)
Enable queue.
Definition virtio.c:155
int virtio_pci_map(struct virtio_device *virtio, struct pci_device *pci)
Map PCI device.
Definition virtio.c:479
static void virtio_pci_address(struct virtio_device *virtio, struct virtio_queue *queue, void *addr, unsigned int offset)
Program queue address.
Definition virtio.c:308
Virtual I/O device.
#define VIRTIO_FEATURE_WORDS
Number of 32-bit feature words.
Definition virtio.h:296
#define VIRTIO_FEAT1_MODERN
Virtio version 1.0 or above.
Definition virtio.h:308
#define VIRTIO_RESET_MAX_WAIT_MS
Maximum time to wait for reset (in ms).
Definition virtio.h:22
static size_t virtio_align(size_t size)
Calculate aligned size.
Definition virtio.h:251
static size_t virtio_cq_size(unsigned int count)
Calculate (unaligned) completion queue size.
Definition virtio.h:289
static size_t virtio_sq_size(unsigned int count)
Calculate (unaligned) submission queue size.
Definition virtio.h:276
static size_t virtio_desc_size(unsigned int count)
Calculate (unaligned) descriptor array size.
Definition virtio.h:263
#define VIRTIO_PAGE
Virtio page alignment.
Definition virtio.h:19