Browse Source

[hyperv] Add support for VMBus devices

Add support for an abstraction of a VMBus device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
d1894970db

+ 1
- 0
src/Makefile View File

@@ -86,6 +86,7 @@ SRCDIRS		+= drivers/infiniband
86 86
 SRCDIRS		+= interface/pxe interface/efi interface/smbios
87 87
 SRCDIRS		+= interface/bofm
88 88
 SRCDIRS		+= interface/xen
89
+SRCDIRS		+= interface/hyperv
89 90
 SRCDIRS		+= tests
90 91
 SRCDIRS		+= crypto crypto/axtls crypto/matrixssl
91 92
 SRCDIRS		+= hci hci/commands hci/tui

+ 8
- 0
src/arch/x86/drivers/hyperv/hyperv.c View File

@@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
38 38
 #include <ipxe/cpuid.h>
39 39
 #include <ipxe/msr.h>
40 40
 #include <ipxe/hyperv.h>
41
+#include <ipxe/vmbus.h>
41 42
 #include "hyperv.h"
42 43
 
43 44
 /** Maximum time to wait for a message response
@@ -506,9 +507,15 @@ static int hv_probe ( struct root_device *rootdev ) {
506 507
 	if ( ( rc = hv_map_synic ( hv ) ) != 0 )
507 508
 		goto err_map_synic;
508 509
 
510
+	/* Probe Hyper-V devices */
511
+	if ( ( rc = vmbus_probe ( hv, &rootdev->dev ) ) != 0 )
512
+		goto err_vmbus_probe;
513
+
509 514
 	rootdev_set_drvdata ( rootdev, hv );
510 515
 	return 0;
511 516
 
517
+	vmbus_remove ( hv, &rootdev->dev );
518
+ err_vmbus_probe:
512 519
 	hv_unmap_synic ( hv );
513 520
  err_map_synic:
514 521
 	hv_unmap_hypercall ( hv );
@@ -532,6 +539,7 @@ static int hv_probe ( struct root_device *rootdev ) {
532 539
 static void hv_remove ( struct root_device *rootdev ) {
533 540
 	struct hv_hypervisor *hv = rootdev_get_drvdata ( rootdev );
534 541
 
542
+	vmbus_remove ( hv, &rootdev->dev );
535 543
 	hv_unmap_synic ( hv );
536 544
 	hv_unmap_hypercall ( hv );
537 545
 	hv_free_message ( hv );

+ 3
- 0
src/include/ipxe/device.h View File

@@ -63,6 +63,9 @@ struct device_description {
63 63
 /** Xen bus type */
64 64
 #define BUS_TYPE_XEN 8
65 65
 
66
+/** Hyper-V bus type */
67
+#define BUS_TYPE_HV 9
68
+
66 69
 /** A hardware device */
67 70
 struct device {
68 71
 	/** Name */

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -309,6 +309,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
309 309
 #define ERRFILE_xengrant	      ( ERRFILE_OTHER | 0x00440000 )
310 310
 #define ERRFILE_efi_utils	      ( ERRFILE_OTHER | 0x00450000 )
311 311
 #define ERRFILE_efi_wrap	      ( ERRFILE_OTHER | 0x00460000 )
312
+#define ERRFILE_vmbus		      ( ERRFILE_OTHER | 0x00470000 )
312 313
 
313 314
 /** @} */
314 315
 

+ 2
- 0
src/include/ipxe/hyperv.h View File

@@ -197,6 +197,8 @@ struct hv_hypervisor {
197 197
 	struct hv_synic synic;
198 198
 	/** Message buffer */
199 199
 	union hv_message_buffer *message;
200
+	/** Virtual machine bus */
201
+	struct vmbus *vmbus;
200 202
 };
201 203
 
202 204
 #include <bits/hyperv.h>

+ 629
- 0
src/include/ipxe/vmbus.h View File

@@ -0,0 +1,629 @@
1
+#ifndef _IPXE_VMBUS_H
2
+#define _IPXE_VMBUS_H
3
+
4
+/** @file
5
+ *
6
+ * Hyper-V virtual machine bus
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+#include <byteswap.h>
13
+#include <ipxe/uuid.h>
14
+#include <ipxe/device.h>
15
+#include <ipxe/tables.h>
16
+#include <ipxe/uaccess.h>
17
+#include <ipxe/iobuf.h>
18
+#include <ipxe/hyperv.h>
19
+
20
+/** VMBus message connection ID */
21
+#define VMBUS_MESSAGE_ID 1
22
+
23
+/** VMBus event connection ID */
24
+#define VMBUS_EVENT_ID 2
25
+
26
+/** VMBus message type */
27
+#define VMBUS_MESSAGE_TYPE 1
28
+
29
+/** VMBus message synthetic interrupt */
30
+#define VMBUS_MESSAGE_SINT 2
31
+
32
+/** VMBus version number */
33
+union vmbus_version {
34
+	/** Raw version */
35
+	uint32_t raw;
36
+	/** Major/minor version */
37
+	struct {
38
+		/** Minor version */
39
+		uint16_t minor;
40
+		/** Major version */
41
+		uint16_t major;
42
+	};
43
+} __attribute__ (( packed ));
44
+
45
+/** Oldest known VMBus protocol version (Windows Server 2008) */
46
+#define VMBUS_VERSION_WS2008 ( ( 0 << 16 ) | ( 13 << 0 ) )
47
+
48
+/** Guest physical address range descriptor */
49
+struct vmbus_gpa_range {
50
+	/** Byte count */
51
+	uint32_t len;
52
+	/** Starting byte offset */
53
+	uint32_t offset;
54
+	/** Page frame numbers
55
+	 *
56
+	 * The length of this array is implied by the byte count and
57
+	 * starting offset.
58
+	 */
59
+	uint64_t pfn[0];
60
+} __attribute__ (( packed ));
61
+
62
+/** VMBus message header */
63
+struct vmbus_message_header {
64
+	/** Message type */
65
+	uint32_t type;
66
+	/** Reserved */
67
+	uint32_t reserved;
68
+} __attribute__ (( packed ));
69
+
70
+/** VMBus message types */
71
+enum vmbus_message_type {
72
+	VMBUS_OFFER_CHANNEL = 1,
73
+	VMBUS_REQUEST_OFFERS = 3,
74
+	VMBUS_ALL_OFFERS_DELIVERED = 4,
75
+	VMBUS_OPEN_CHANNEL = 5,
76
+	VMBUS_OPEN_CHANNEL_RESULT = 6,
77
+	VMBUS_CLOSE_CHANNEL = 7,
78
+	VMBUS_GPADL_HEADER = 8,
79
+	VMBUS_GPADL_CREATED = 10,
80
+	VMBUS_GPADL_TEARDOWN = 11,
81
+	VMBUS_GPADL_TORNDOWN = 12,
82
+	VMBUS_INITIATE_CONTACT = 14,
83
+	VMBUS_VERSION_RESPONSE = 15,
84
+	VMBUS_UNLOAD = 16,
85
+};
86
+
87
+/** VMBus "offer channel" message */
88
+struct vmbus_offer_channel {
89
+	/** Message header */
90
+	struct vmbus_message_header header;
91
+	/** Channel type */
92
+	union uuid type;
93
+	/** Channel instance */
94
+	union uuid instance;
95
+	/** Reserved */
96
+	uint8_t reserved_a[16];
97
+	/** Flags */
98
+	uint16_t flags;
99
+	/** Reserved */
100
+	uint8_t reserved_b[2];
101
+	/** User data */
102
+	uint8_t data[120];
103
+	/** Reserved */
104
+	uint8_t reserved_c[4];
105
+	/** Channel ID */
106
+	uint32_t channel;
107
+	/** Monitor ID */
108
+	uint8_t monitor;
109
+	/** Monitor exists */
110
+	uint8_t monitored;
111
+	/** Reserved */
112
+	uint8_t reserved[2];
113
+	/** Connection ID */
114
+	uint32_t connection;
115
+} __attribute__ (( packed ));
116
+
117
+/** VMBus "open channel" message */
118
+struct vmbus_open_channel {
119
+	/** Message header */
120
+	struct vmbus_message_header header;
121
+	/** Channel ID */
122
+	uint32_t channel;
123
+	/** Open ID */
124
+	uint32_t id;
125
+	/** Ring buffer GPADL ID */
126
+	uint32_t gpadl;
127
+	/** Reserved */
128
+	uint32_t reserved;
129
+	/** Outbound ring buffer size (in pages) */
130
+	uint32_t out_pages;
131
+	/** User-specific data */
132
+	uint8_t data[120];
133
+} __attribute__ (( packed ));
134
+
135
+/** VMBus "open channel result" message */
136
+struct vmbus_open_channel_result {
137
+	/** Message header */
138
+	struct vmbus_message_header header;
139
+	/** Channel ID */
140
+	uint32_t channel;
141
+	/** Open ID */
142
+	uint32_t id;
143
+	/** Status */
144
+	uint32_t status;
145
+} __attribute__ (( packed ));
146
+
147
+/** VMBus "close channel" message */
148
+struct vmbus_close_channel {
149
+	/** Message header */
150
+	struct vmbus_message_header header;
151
+	/** Channel ID */
152
+	uint32_t channel;
153
+} __attribute__ (( packed ));
154
+
155
+/** VMBus "GPADL header" message */
156
+struct vmbus_gpadl_header {
157
+	/** Message header */
158
+	struct vmbus_message_header header;
159
+	/** Channel ID */
160
+	uint32_t channel;
161
+	/** GPADL ID */
162
+	uint32_t gpadl;
163
+	/** Length of range descriptors */
164
+	uint16_t range_len;
165
+	/** Number of range descriptors */
166
+	uint16_t range_count;
167
+	/** Range descriptors */
168
+	struct vmbus_gpa_range range[0];
169
+} __attribute__ (( packed ));
170
+
171
+/** VMBus "GPADL created" message */
172
+struct vmbus_gpadl_created {
173
+	/** Message header */
174
+	struct vmbus_message_header header;
175
+	/** Channel ID */
176
+	uint32_t channel;
177
+	/** GPADL ID */
178
+	uint32_t gpadl;
179
+	/** Creation status */
180
+	uint32_t status;
181
+} __attribute__ (( packed ));
182
+
183
+/** VMBus "GPADL teardown" message */
184
+struct vmbus_gpadl_teardown {
185
+	/** Message header */
186
+	struct vmbus_message_header header;
187
+	/** Channel ID */
188
+	uint32_t channel;
189
+	/** GPADL ID */
190
+	uint32_t gpadl;
191
+} __attribute__ (( packed ));
192
+
193
+/** VMBus "GPADL torndown" message */
194
+struct vmbus_gpadl_torndown {
195
+	/** Message header */
196
+	struct vmbus_message_header header;
197
+	/** GPADL ID */
198
+	uint32_t gpadl;
199
+} __attribute__ (( packed ));
200
+
201
+/** VMBus "initiate contact" message */
202
+struct vmbus_initiate_contact {
203
+	/** Message header */
204
+	struct vmbus_message_header header;
205
+	/** Requested version */
206
+	union vmbus_version version;
207
+	/** Target virtual CPU */
208
+	uint32_t vcpu;
209
+	/** Interrupt page base address */
210
+	uint64_t intr;
211
+	/** Parent to child monitor page base address */
212
+	uint64_t monitor_in;
213
+	/** Child to parent monitor page base address */
214
+	uint64_t monitor_out;
215
+} __attribute__ (( packed ));
216
+
217
+/** VMBus "version response" message */
218
+struct vmbus_version_response {
219
+	/** Message header */
220
+	struct vmbus_message_header header;
221
+	/** Version is supported */
222
+	uint8_t supported;
223
+	/** Reserved */
224
+	uint8_t reserved[3];
225
+	/** Version */
226
+	union vmbus_version version;
227
+} __attribute__ (( packed ));
228
+
229
+/** VMBus message */
230
+union vmbus_message {
231
+	/** Common message header */
232
+	struct vmbus_message_header header;
233
+	/** "Offer channel" message */
234
+	struct vmbus_offer_channel offer;
235
+	/** "Open channel" message */
236
+	struct vmbus_open_channel open;
237
+	/** "Open channel result" message */
238
+	struct vmbus_open_channel_result opened;
239
+	/** "Close channel" message */
240
+	struct vmbus_close_channel close;
241
+	/** "GPADL header" message */
242
+	struct vmbus_gpadl_header gpadlhdr;
243
+	/** "GPADL created" message */
244
+	struct vmbus_gpadl_created created;
245
+	/** "GPADL teardown" message */
246
+	struct vmbus_gpadl_teardown teardown;
247
+	/** "GPADL torndown" message */
248
+	struct vmbus_gpadl_torndown torndown;
249
+	/** "Initiate contact" message */
250
+	struct vmbus_initiate_contact initiate;
251
+	/** "Version response" message */
252
+	struct vmbus_version_response version;
253
+};
254
+
255
+/** VMBus packet header */
256
+struct vmbus_packet_header {
257
+	/** Type */
258
+	uint16_t type;
259
+	/** Length of packet header (in quadwords) */
260
+	uint16_t hdr_qlen;
261
+	/** Length of packet (in quadwords) */
262
+	uint16_t qlen;
263
+	/** Flags */
264
+	uint16_t flags;
265
+	/** Transaction ID
266
+	 *
267
+	 * This is an opaque token: we therefore treat it as
268
+	 * native-endian and don't worry about byte-swapping.
269
+	 */
270
+	uint64_t xid;
271
+} __attribute__ (( packed ));
272
+
273
+/** VMBus packet types */
274
+enum vmbus_packet_type {
275
+	VMBUS_DATA_INBAND = 6,
276
+	VMBUS_DATA_XFER_PAGES = 7,
277
+	VMBUS_DATA_GPA_DIRECT = 9,
278
+	VMBUS_CANCELLATION = 10,
279
+	VMBUS_COMPLETION = 11,
280
+};
281
+
282
+/** VMBus packet flags */
283
+enum vmbus_packet_flags {
284
+	VMBUS_COMPLETION_REQUESTED = 0x0001,
285
+};
286
+
287
+/** VMBus GPA direct header */
288
+struct vmbus_gpa_direct_header {
289
+	/** Packet header */
290
+	struct vmbus_packet_header header;
291
+	/** Reserved */
292
+	uint32_t reserved;
293
+	/** Number of range descriptors */
294
+	uint32_t range_count;
295
+	/** Range descriptors */
296
+	struct vmbus_gpa_range range[0];
297
+} __attribute__ (( packed ));
298
+
299
+/** VMBus transfer page range */
300
+struct vmbus_xfer_page_range {
301
+	/** Length */
302
+	uint32_t len;
303
+	/** Offset */
304
+	uint32_t offset;
305
+} __attribute__ (( packed ));
306
+
307
+/** VMBus transfer page header */
308
+struct vmbus_xfer_page_header {
309
+	/** Packet header */
310
+	struct vmbus_packet_header header;
311
+	/** Page set ID */
312
+	uint16_t pageset;
313
+	/** Sender owns page set */
314
+	uint8_t owner;
315
+	/** Reserved */
316
+	uint8_t reserved;
317
+	/** Number of range descriptors */
318
+	uint32_t range_count;
319
+	/** Range descriptors */
320
+	struct vmbus_xfer_page_range range[0];
321
+} __attribute__ (( packed ));
322
+
323
+/** Maximum expected size of VMBus packet header */
324
+#define VMBUS_PACKET_MAX_HEADER_LEN 64
325
+
326
+/** VMBus maximum-sized packet header */
327
+union vmbus_packet_header_max {
328
+	/** Common header */
329
+	struct vmbus_packet_header header;
330
+	/** GPA direct header */
331
+	struct vmbus_gpa_direct_header gpa;
332
+	/** Transfer page header */
333
+	struct vmbus_xfer_page_header xfer;
334
+	/** Padding to maximum supported size */
335
+	uint8_t padding[VMBUS_PACKET_MAX_HEADER_LEN];
336
+} __attribute__ (( packed ));
337
+
338
+/** VMBus packet footer */
339
+struct vmbus_packet_footer {
340
+	/** Reserved */
341
+	uint32_t reserved;
342
+	/** Producer index of the first byte of the packet */
343
+	uint32_t prod;
344
+} __attribute__ (( packed ));
345
+
346
+/** VMBus ring buffer
347
+ *
348
+ * This is the structure of the each of the ring buffers created when
349
+ * a VMBus channel is opened.
350
+ */
351
+struct vmbus_ring {
352
+	/** Producer index (modulo ring length) */
353
+	uint32_t prod;
354
+	/** Consumer index (modulo ring length) */
355
+	uint32_t cons;
356
+	/** Interrupt mask */
357
+	uint32_t intr_mask;
358
+	/** Reserved */
359
+	uint8_t reserved[4084];
360
+	/** Ring buffer contents */
361
+	uint8_t data[0];
362
+} __attribute__ (( packed ));
363
+
364
+/** VMBus interrupt page */
365
+struct vmbus_interrupt {
366
+	/** Inbound interrupts */
367
+	uint8_t in[ PAGE_SIZE / 2 ];
368
+	/** Outbound interrupts */
369
+	uint8_t out[ PAGE_SIZE / 2 ];
370
+} __attribute__ (( packed ));
371
+
372
+/** A virtual machine bus */
373
+struct vmbus {
374
+	/** Interrupt page */
375
+	struct vmbus_interrupt *intr;
376
+	/** Inbound notifications */
377
+	struct hv_monitor *monitor_in;
378
+	/** Outbound notifications */
379
+	struct hv_monitor *monitor_out;
380
+	/** Received message buffer */
381
+	const union vmbus_message *message;
382
+};
383
+
384
+struct vmbus_device;
385
+
386
+/** VMBus channel operations */
387
+struct vmbus_channel_operations {
388
+	/**
389
+	 * Handle received control packet
390
+	 *
391
+	 * @v vmdev		VMBus device
392
+	 * @v xid		Transaction ID
393
+	 * @v data		Data
394
+	 * @v len		Length of data
395
+	 * @ret rc		Return status code
396
+	 */
397
+	int ( * recv_control ) ( struct vmbus_device *vmdev, uint64_t xid,
398
+				 const void *data, size_t len );
399
+	/**
400
+	 * Handle received data packet
401
+	 *
402
+	 * @v vmdev		VMBus device
403
+	 * @v xid		Transaction ID
404
+	 * @v data		Data
405
+	 * @v len		Length of data
406
+	 * @v iobuf		I/O buffer, or NULL if allocation failed
407
+	 * @ret rc		Return status code
408
+	 *
409
+	 * This function takes ownership of the I/O buffer.  It should
410
+	 * eventually call vmbus_send_completion() to indicate to the
411
+	 * host that the buffer can be reused.
412
+	 *
413
+	 * Note that this function will be called even if we failed to
414
+	 * allocate or populate the I/O buffer; this is to allow for a
415
+	 * completion to be sent even in the event of a transient
416
+	 * memory shortage failure.
417
+	 */
418
+	int ( * recv_data ) ( struct vmbus_device *vmdev, uint64_t xid,
419
+			      const void *data, size_t len,
420
+			      struct io_buffer *iobuf );
421
+	/**
422
+	 * Handle received completion packet
423
+	 *
424
+	 * @v vmdev		VMBus device
425
+	 * @v xid		Transaction ID
426
+	 * @v data		Data
427
+	 * @v len		Length of data
428
+	 * @ret rc		Return status code
429
+	 */
430
+	int ( * recv_completion ) ( struct vmbus_device *vmdev, uint64_t xid,
431
+				    const void *data, size_t len );
432
+	/**
433
+	 * Handle received cancellation packet
434
+	 *
435
+	 * @v vmdev		VMBus device
436
+	 * @v xid		Transaction ID
437
+	 * @ret rc		Return status code
438
+	 */
439
+	int ( * recv_cancellation ) ( struct vmbus_device *vmdev,
440
+				      uint64_t xid );
441
+};
442
+
443
+struct vmbus_xfer_pages;
444
+
445
+/** VMBus transfer page set operations */
446
+struct vmbus_xfer_pages_operations {
447
+	/**
448
+	 * Copy data from transfer page
449
+	 *
450
+	 * @v pages		Transfer page set
451
+	 * @v data		Data buffer
452
+	 * @v offset		Offset within page set
453
+	 * @v len		Length within page set
454
+	 * @ret rc		Return status code
455
+	 */
456
+	int ( * copy ) ( struct vmbus_xfer_pages *pages, void *data,
457
+			 size_t offset, size_t len );
458
+};
459
+
460
+/** VMBus transfer page set */
461
+struct vmbus_xfer_pages {
462
+	/** List of all transfer page sets */
463
+	struct list_head list;
464
+	/** Page set ID (in protocol byte order) */
465
+	uint16_t pageset;
466
+	/** Page set operations */
467
+	struct vmbus_xfer_pages_operations *op;
468
+};
469
+
470
+/** A VMBus device */
471
+struct vmbus_device {
472
+	/** Generic iPXE device */
473
+	struct device dev;
474
+	/** Hyper-V hypervisor */
475
+	struct hv_hypervisor *hv;
476
+
477
+	/** Channel ID */
478
+	unsigned int channel;
479
+	/** Monitor ID */
480
+	unsigned int monitor;
481
+	/** Signal channel
482
+	 *
483
+	 * @v vmdev		VMBus device
484
+	 */
485
+	void ( * signal ) ( struct vmbus_device *vmdev );
486
+
487
+	/** Outbound ring buffer length */
488
+	uint32_t out_len;
489
+	/** Inbound ring buffer length */
490
+	uint32_t in_len;
491
+	/** Outbound ring buffer */
492
+	struct vmbus_ring *out;
493
+	/** Inbound ring buffer */
494
+	struct vmbus_ring *in;
495
+	/** Ring buffer GPADL ID */
496
+	unsigned int gpadl;
497
+
498
+	/** Channel operations */
499
+	struct vmbus_channel_operations *op;
500
+	/** Maximum expected data packet length */
501
+	size_t mtu;
502
+	/** Packet buffer */
503
+	void *packet;
504
+	/** List of transfer page sets */
505
+	struct list_head pages;
506
+
507
+	/** Driver */
508
+	struct vmbus_driver *driver;
509
+	/** Driver-private data */
510
+	void *priv;
511
+};
512
+
513
+/** A VMBus device driver */
514
+struct vmbus_driver {
515
+	/** Name */
516
+	const char *name;
517
+	/** Device type */
518
+	union uuid type;
519
+	/** Probe device
520
+	 *
521
+	 * @v vmdev		VMBus device
522
+	 * @ret rc		Return status code
523
+	 */
524
+	int ( * probe ) ( struct vmbus_device *vmdev );
525
+	/** Remove device
526
+	 *
527
+	 * @v vmdev		VMBus device
528
+	 */
529
+	void ( * remove ) ( struct vmbus_device *vmdev );
530
+};
531
+
532
+/** VMBus device driver table */
533
+#define VMBUS_DRIVERS __table ( struct vmbus_driver, "vmbus_drivers" )
534
+
535
+/** Declare a VMBus device driver */
536
+#define __vmbus_driver __table_entry ( VMBUS_DRIVERS, 01 )
537
+
538
+/**
539
+ * Set VMBus device driver-private data
540
+ *
541
+ * @v vmdev		VMBus device
542
+ * @v priv		Private data
543
+ */
544
+static inline void vmbus_set_drvdata ( struct vmbus_device *vmdev, void *priv ){
545
+	vmdev->priv = priv;
546
+}
547
+
548
+/**
549
+ * Get VMBus device driver-private data
550
+ *
551
+ * @v vmdev		VMBus device
552
+ * @ret priv		Private data
553
+ */
554
+static inline void * vmbus_get_drvdata ( struct vmbus_device *vmdev ) {
555
+	return vmdev->priv;
556
+}
557
+
558
+/** Construct VMBus type */
559
+#define VMBUS_TYPE( a, b, c, d, e0, e1, e2, e3, e4, e5 ) {		\
560
+	.canonical = {							\
561
+		cpu_to_le32 ( a ), cpu_to_le16 ( b ),			\
562
+		cpu_to_le16 ( c ), cpu_to_be16 ( d ),			\
563
+		{ e0, e1, e2, e3, e4, e5 }				\
564
+	 } }
565
+
566
+/**
567
+ * Check if data is present in ring buffer
568
+ *
569
+ * @v vmdev		VMBus device
570
+ * @v has_data		Data is present
571
+ */
572
+static inline __attribute__ (( always_inline )) int
573
+vmbus_has_data ( struct vmbus_device *vmdev ) {
574
+
575
+	return ( vmdev->in->prod != vmdev->in->cons );
576
+}
577
+
578
+/**
579
+ * Register transfer page set
580
+ *
581
+ * @v vmdev		VMBus device
582
+ * @v pages		Transfer page set
583
+ * @ret rc		Return status code
584
+ */
585
+static inline __attribute__ (( always_inline )) int
586
+vmbus_register_pages ( struct vmbus_device *vmdev,
587
+		       struct vmbus_xfer_pages *pages ) {
588
+
589
+	list_add ( &pages->list, &vmdev->pages );
590
+	return 0;
591
+}
592
+
593
+/**
594
+ * Unregister transfer page set
595
+ *
596
+ * @v vmdev		VMBus device
597
+ * @v pages		Transfer page set
598
+ */
599
+static inline __attribute__ (( always_inline )) void
600
+vmbus_unregister_pages ( struct vmbus_device *vmdev,
601
+			 struct vmbus_xfer_pages *pages ) {
602
+
603
+	list_check_contains_entry ( pages, &vmdev->pages, list );
604
+	list_del ( &pages->list );
605
+}
606
+
607
+extern int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
608
+				   size_t len );
609
+extern int vmbus_gpadl_teardown ( struct vmbus_device *vmdev,
610
+				  unsigned int gpadl );
611
+extern int vmbus_open ( struct vmbus_device *vmdev,
612
+			struct vmbus_channel_operations *op,
613
+			size_t out_len, size_t in_len, size_t mtu );
614
+extern void vmbus_close ( struct vmbus_device *vmdev );
615
+extern int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
616
+				const void *data, size_t len );
617
+extern int vmbus_send_data ( struct vmbus_device *vmdev, uint64_t xid,
618
+			     const void *data, size_t len,
619
+			     struct io_buffer *iobuf );
620
+extern int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
621
+				   const void *data, size_t len );
622
+extern int vmbus_send_cancellation ( struct vmbus_device *vmdev, uint64_t xid );
623
+extern int vmbus_poll ( struct vmbus_device *vmdev );
624
+extern void vmbus_dump_channel ( struct vmbus_device *vmdev );
625
+
626
+extern int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent );
627
+extern void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent );
628
+
629
+#endif /* _IPXE_VMBUS_H */

+ 1261
- 0
src/interface/hyperv/vmbus.c
File diff suppressed because it is too large
View File


Loading…
Cancel
Save