iPXE
virtio-ring.c
Go to the documentation of this file.
1/* virtio-pci.c - virtio ring management
2 *
3 * (c) Copyright 2008 Bull S.A.S.
4 *
5 * Author: Laurent Vivier <Laurent.Vivier@bull.net>
6 *
7 * some parts from Linux Virtio Ring
8 *
9 * Copyright Rusty Russell IBM Corporation 2007
10 *
11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
12 * See the COPYING file in the top-level directory.
13 *
14 *
15 */
16
17FILE_LICENCE ( GPL2_OR_LATER );
18
19#include "etherboot.h"
20#include "ipxe/io.h"
21#include "ipxe/virtio-pci.h"
22#include "ipxe/virtio-ring.h"
23
24#define BUG() do { \
25 printf("BUG: failure at %s:%d/%s()!\n", \
26 __FILE__, __LINE__, __FUNCTION__); \
27 while(1); \
28} while (0)
29#define BUG_ON(condition) do { if (condition) BUG(); } while (0)
30
31/*
32 * vring_free
33 *
34 * put at the begin of the free list the current desc[head]
35 */
36
37void vring_detach(struct vring_virtqueue *vq, unsigned int head)
38{
39 struct vring *vr = &vq->vring;
40 unsigned int i;
41
42 /* find end of given descriptor */
43
44 i = head;
45 while (vr->desc[i].flags & VRING_DESC_F_NEXT)
46 i = vr->desc[i].next;
47
48 /* link it with free list and point to it */
49
50 vr->desc[i].next = vq->free_head;
51 wmb();
52 vq->free_head = head;
53}
54
55/*
56 * vring_get_buf
57 *
58 * get a buffer from the used list
59 *
60 */
61
62void *vring_get_buf(struct vring_virtqueue *vq, unsigned int *len)
63{
64 struct vring *vr = &vq->vring;
65 struct vring_used_elem *elem;
66 u32 id;
67 void *opaque;
68
70
71 elem = &vr->used->ring[vq->last_used_idx % vr->num];
72 wmb();
73 id = elem->id;
74 if (len != NULL)
75 *len = elem->len;
76
77 opaque = vq->vdata[id];
78
79 vring_detach(vq, id);
80
81 vq->last_used_idx++;
82
83 return opaque;
84}
85
87 struct vring_list list[],
88 unsigned int out, unsigned int in,
89 void *opaque, int num_added)
90{
91 struct vring *vr = &vq->vring;
92 int i, avail, head, prev;
93
94 BUG_ON(out + in == 0);
95
96 prev = 0;
97 head = vq->free_head;
98 for (i = head; out; i = vr->desc[i].next, out--) {
99
101 vr->desc[i].addr = list->addr;
102 vr->desc[i].len = list->length;
103 prev = i;
104 list++;
105 }
106 for ( ; in; i = vr->desc[i].next, in--) {
107
109 vr->desc[i].addr = list->addr;
110 vr->desc[i].len = list->length;
111 prev = i;
112 list++;
113 }
114 vr->desc[prev].flags &= ~VRING_DESC_F_NEXT;
115
116 vq->free_head = i;
117
118 vq->vdata[head] = opaque;
119
120 avail = (vr->avail->idx + num_added) % vr->num;
121 vr->avail->ring[avail] = head;
122 wmb();
123}
124
125void vring_kick(struct virtio_pci_modern_device *vdev, unsigned int ioaddr,
126 struct vring_virtqueue *vq, int num_added)
127{
128 struct vring *vr = &vq->vring;
129
130 wmb();
131 vr->avail->idx += num_added;
132
133 mb();
134 if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY)) {
135 if (vdev) {
136 /* virtio 1.0 */
137 vpm_notify(vdev, vq);
138 } else {
139 /* legacy virtio */
141 }
142 }
143}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
__be32 in[4]
Definition CIB_PRM.h:7
__be32 out[4]
Definition CIB_PRM.h:8
static unsigned long ioaddr
Definition davicom.c:129
ring len
Length.
Definition dwmac.h:226
uint8_t id
Request identifier.
Definition ena.h:1
uint8_t head
Head number.
Definition int13.h:23
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
iPXE I/O API
void mb(void)
Memory barrier.
#define wmb()
Definition io.h:546
u16 ring[0]
Definition virtio-ring.h:47
physaddr_t addr
Definition virtio-ring.h:92
unsigned int length
Definition virtio-ring.h:93
struct vring_used_elem ring[]
Definition virtio-ring.h:60
struct vring vring
Definition virtio-ring.h:81
struct vring_desc * desc
Definition virtio-ring.h:65
struct vring_avail * avail
Definition virtio-ring.h:66
unsigned int num
Definition virtio-ring.h:64
struct vring_used * used
Definition virtio-ring.h:67
#define u32
Definition vga.h:21
void vpm_notify(struct virtio_pci_modern_device *vdev, struct vring_virtqueue *vq)
Definition virtio-pci.c:354
static void vp_notify(unsigned int ioaddr, int queue_index)
Definition virtio-pci.h:183
void vring_kick(struct virtio_pci_modern_device *vdev, unsigned int ioaddr, struct vring_virtqueue *vq, int num_added)
void vring_detach(struct vring_virtqueue *vq, unsigned int head)
Definition virtio-ring.c:37
void * vring_get_buf(struct vring_virtqueue *vq, unsigned int *len)
Definition virtio-ring.c:62
#define BUG_ON(condition)
Definition virtio-ring.c:29
void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[], unsigned int out, unsigned int in, void *opaque, int num_added)
Definition virtio-ring.c:86
#define VRING_DESC_F_WRITE
Definition virtio-ring.h:29
static int vring_more_used(struct vring_virtqueue *vq)
#define VRING_USED_F_NO_NOTIFY
Definition virtio-ring.h:33
#define VRING_DESC_F_NEXT
Definition virtio-ring.h:28