Revision 99a0949b hw/virtio.c
b/hw/virtio.c | ||
---|---|---|
57 | 57 |
typedef struct VRing |
58 | 58 |
{ |
59 | 59 |
unsigned int num; |
60 |
target_phys_addr_t desc;
|
|
61 |
target_phys_addr_t avail;
|
|
62 |
target_phys_addr_t used;
|
|
60 |
a_target_phys_addr desc;
|
|
61 |
a_target_phys_addr avail;
|
|
62 |
a_target_phys_addr used;
|
|
63 | 63 |
} VRing; |
64 | 64 |
|
65 | 65 |
struct VirtQueue |
66 | 66 |
{ |
67 | 67 |
VRing vring; |
68 |
target_phys_addr_t pa;
|
|
68 |
a_target_phys_addr pa;
|
|
69 | 69 |
uint16_t last_avail_idx; |
70 | 70 |
int inuse; |
71 | 71 |
uint16_t vector; |
... | ... | |
77 | 77 |
/* virt queue functions */ |
78 | 78 |
static void virtqueue_init(VirtQueue *vq) |
79 | 79 |
{ |
80 |
target_phys_addr_t pa = vq->pa;
|
|
80 |
a_target_phys_addr pa = vq->pa;
|
|
81 | 81 |
|
82 | 82 |
vq->vring.desc = pa; |
83 | 83 |
vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc); |
... | ... | |
86 | 86 |
VIRTIO_PCI_VRING_ALIGN); |
87 | 87 |
} |
88 | 88 |
|
89 |
static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa, int i)
|
|
89 |
static inline uint64_t vring_desc_addr(a_target_phys_addr desc_pa, int i)
|
|
90 | 90 |
{ |
91 |
target_phys_addr_t pa;
|
|
91 |
a_target_phys_addr pa;
|
|
92 | 92 |
pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr); |
93 | 93 |
return ldq_phys(pa); |
94 | 94 |
} |
95 | 95 |
|
96 |
static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa, int i)
|
|
96 |
static inline uint32_t vring_desc_len(a_target_phys_addr desc_pa, int i)
|
|
97 | 97 |
{ |
98 |
target_phys_addr_t pa;
|
|
98 |
a_target_phys_addr pa;
|
|
99 | 99 |
pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len); |
100 | 100 |
return ldl_phys(pa); |
101 | 101 |
} |
102 | 102 |
|
103 |
static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa, int i)
|
|
103 |
static inline uint16_t vring_desc_flags(a_target_phys_addr desc_pa, int i)
|
|
104 | 104 |
{ |
105 |
target_phys_addr_t pa;
|
|
105 |
a_target_phys_addr pa;
|
|
106 | 106 |
pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags); |
107 | 107 |
return lduw_phys(pa); |
108 | 108 |
} |
109 | 109 |
|
110 |
static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa, int i)
|
|
110 |
static inline uint16_t vring_desc_next(a_target_phys_addr desc_pa, int i)
|
|
111 | 111 |
{ |
112 |
target_phys_addr_t pa;
|
|
112 |
a_target_phys_addr pa;
|
|
113 | 113 |
pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next); |
114 | 114 |
return lduw_phys(pa); |
115 | 115 |
} |
116 | 116 |
|
117 | 117 |
static inline uint16_t vring_avail_flags(VirtQueue *vq) |
118 | 118 |
{ |
119 |
target_phys_addr_t pa;
|
|
119 |
a_target_phys_addr pa;
|
|
120 | 120 |
pa = vq->vring.avail + offsetof(VRingAvail, flags); |
121 | 121 |
return lduw_phys(pa); |
122 | 122 |
} |
123 | 123 |
|
124 | 124 |
static inline uint16_t vring_avail_idx(VirtQueue *vq) |
125 | 125 |
{ |
126 |
target_phys_addr_t pa;
|
|
126 |
a_target_phys_addr pa;
|
|
127 | 127 |
pa = vq->vring.avail + offsetof(VRingAvail, idx); |
128 | 128 |
return lduw_phys(pa); |
129 | 129 |
} |
130 | 130 |
|
131 | 131 |
static inline uint16_t vring_avail_ring(VirtQueue *vq, int i) |
132 | 132 |
{ |
133 |
target_phys_addr_t pa;
|
|
133 |
a_target_phys_addr pa;
|
|
134 | 134 |
pa = vq->vring.avail + offsetof(VRingAvail, ring[i]); |
135 | 135 |
return lduw_phys(pa); |
136 | 136 |
} |
137 | 137 |
|
138 | 138 |
static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val) |
139 | 139 |
{ |
140 |
target_phys_addr_t pa;
|
|
140 |
a_target_phys_addr pa;
|
|
141 | 141 |
pa = vq->vring.used + offsetof(VRingUsed, ring[i].id); |
142 | 142 |
stl_phys(pa, val); |
143 | 143 |
} |
144 | 144 |
|
145 | 145 |
static inline void vring_used_ring_len(VirtQueue *vq, int i, uint32_t val) |
146 | 146 |
{ |
147 |
target_phys_addr_t pa;
|
|
147 |
a_target_phys_addr pa;
|
|
148 | 148 |
pa = vq->vring.used + offsetof(VRingUsed, ring[i].len); |
149 | 149 |
stl_phys(pa, val); |
150 | 150 |
} |
151 | 151 |
|
152 | 152 |
static uint16_t vring_used_idx(VirtQueue *vq) |
153 | 153 |
{ |
154 |
target_phys_addr_t pa;
|
|
154 |
a_target_phys_addr pa;
|
|
155 | 155 |
pa = vq->vring.used + offsetof(VRingUsed, idx); |
156 | 156 |
return lduw_phys(pa); |
157 | 157 |
} |
158 | 158 |
|
159 | 159 |
static inline void vring_used_idx_increment(VirtQueue *vq, uint16_t val) |
160 | 160 |
{ |
161 |
target_phys_addr_t pa;
|
|
161 |
a_target_phys_addr pa;
|
|
162 | 162 |
pa = vq->vring.used + offsetof(VRingUsed, idx); |
163 | 163 |
stw_phys(pa, vring_used_idx(vq) + val); |
164 | 164 |
} |
165 | 165 |
|
166 | 166 |
static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask) |
167 | 167 |
{ |
168 |
target_phys_addr_t pa;
|
|
168 |
a_target_phys_addr pa;
|
|
169 | 169 |
pa = vq->vring.used + offsetof(VRingUsed, flags); |
170 | 170 |
stw_phys(pa, lduw_phys(pa) | mask); |
171 | 171 |
} |
172 | 172 |
|
173 | 173 |
static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask) |
174 | 174 |
{ |
175 |
target_phys_addr_t pa;
|
|
175 |
a_target_phys_addr pa;
|
|
176 | 176 |
pa = vq->vring.used + offsetof(VRingUsed, flags); |
177 | 177 |
stw_phys(pa, lduw_phys(pa) & ~mask); |
178 | 178 |
} |
... | ... | |
270 | 270 |
return head; |
271 | 271 |
} |
272 | 272 |
|
273 |
static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa,
|
|
273 |
static unsigned virtqueue_next_desc(a_target_phys_addr desc_pa,
|
|
274 | 274 |
unsigned int i, unsigned int max) |
275 | 275 |
{ |
276 | 276 |
unsigned int next; |
... | ... | |
302 | 302 |
total_bufs = in_total = out_total = 0; |
303 | 303 |
while (virtqueue_num_heads(vq, idx)) { |
304 | 304 |
unsigned int max, num_bufs, indirect = 0; |
305 |
target_phys_addr_t desc_pa;
|
|
305 |
a_target_phys_addr desc_pa;
|
|
306 | 306 |
int i; |
307 | 307 |
|
308 | 308 |
max = vq->vring.num; |
... | ... | |
359 | 359 |
int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) |
360 | 360 |
{ |
361 | 361 |
unsigned int i, head, max; |
362 |
target_phys_addr_t desc_pa = vq->vring.desc;
|
|
363 |
target_phys_addr_t len;
|
|
362 |
a_target_phys_addr desc_pa = vq->vring.desc;
|
|
363 |
a_target_phys_addr len;
|
|
364 | 364 |
|
365 | 365 |
if (!virtqueue_num_heads(vq, vq->last_avail_idx)) |
366 | 366 |
return 0; |
... | ... | |
537 | 537 |
vdev->set_config(vdev, vdev->config); |
538 | 538 |
} |
539 | 539 |
|
540 |
void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
|
|
540 |
void virtio_queue_set_addr(VirtIODevice *vdev, int n, a_target_phys_addr addr)
|
|
541 | 541 |
{ |
542 | 542 |
vdev->vq[n].pa = addr; |
543 | 543 |
virtqueue_init(&vdev->vq[n]); |
544 | 544 |
} |
545 | 545 |
|
546 |
target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
|
|
546 |
a_target_phys_addr virtio_queue_get_addr(VirtIODevice *vdev, int n)
|
|
547 | 547 |
{ |
548 | 548 |
return vdev->vq[n].pa; |
549 | 549 |
} |
Also available in: Unified diff