Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 *
  3 * Copyright (c) 2011, Microsoft Corporation.
  4 *
  5 * This program is free software; you can redistribute it and/or modify it
  6 * under the terms and conditions of the GNU General Public License,
  7 * version 2, as published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope it will be useful, but WITHOUT
 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 12 * more details.
 13 *
 14 * You should have received a copy of the GNU General Public License along with
 15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 16 * Place - Suite 330, Boston, MA 02111-1307 USA.
 17 *
 18 * Authors:
 19 *   Haiyang Zhang <haiyangz@microsoft.com>
 20 *   Hank Janssen  <hjanssen@microsoft.com>
 21 *   K. Y. Srinivasan <kys@microsoft.com>
 22 *
 23 */
 24
 25#ifndef _HYPERV_VMBUS_H
 26#define _HYPERV_VMBUS_H
 27
 28#include <linux/list.h>
 29#include <asm/sync_bitops.h>
 30#include <linux/atomic.h>
 31#include <linux/hyperv.h>
 32
 33/*
 34 * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
 35 * is set by CPUID(HVCPUID_VERSION_FEATURES).
 36 */
 37enum hv_cpuid_function {
 38	HVCPUID_VERSION_FEATURES		= 0x00000001,
 39	HVCPUID_VENDOR_MAXFUNCTION		= 0x40000000,
 40	HVCPUID_INTERFACE			= 0x40000001,
 41
 42	/*
 43	 * The remaining functions depend on the value of
 44	 * HVCPUID_INTERFACE
 45	 */
 46	HVCPUID_VERSION			= 0x40000002,
 47	HVCPUID_FEATURES			= 0x40000003,
 48	HVCPUID_ENLIGHTENMENT_INFO	= 0x40000004,
 49	HVCPUID_IMPLEMENTATION_LIMITS		= 0x40000005,
 50};
 51
 52/* Define version of the synthetic interrupt controller. */
 53#define HV_SYNIC_VERSION		(1)
 54
 55/* Define the expected SynIC version. */
 56#define HV_SYNIC_VERSION_1		(0x1)
 57
 58/* Define synthetic interrupt controller message constants. */
 59#define HV_MESSAGE_SIZE			(256)
 60#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
 61#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
 62#define HV_ANY_VP			(0xFFFFFFFF)
 63
 64/* Define synthetic interrupt controller flag constants. */
 65#define HV_EVENT_FLAGS_COUNT		(256 * 8)
 66#define HV_EVENT_FLAGS_BYTE_COUNT	(256)
 67#define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
 68
 69/* Define hypervisor message types. */
 70enum hv_message_type {
 71	HVMSG_NONE			= 0x00000000,
 72
 73	/* Memory access messages. */
 74	HVMSG_UNMAPPED_GPA		= 0x80000000,
 75	HVMSG_GPA_INTERCEPT		= 0x80000001,
 76
 77	/* Timer notification messages. */
 78	HVMSG_TIMER_EXPIRED			= 0x80000010,
 79
 80	/* Error messages. */
 81	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
 82	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
 83	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
 84
 85	/* Trace buffer complete messages. */
 86	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
 87
 88	/* Platform-specific processor intercept messages. */
 89	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
 90	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
 91	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
 92	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
 93	HVMSG_X64_APIC_EOI			= 0x80010004,
 94	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
 95};
 96
 97/* Define the number of synthetic interrupt sources. */
 98#define HV_SYNIC_SINT_COUNT		(16)
 99#define HV_SYNIC_STIMER_COUNT		(4)
100
101/* Define invalid partition identifier. */
102#define HV_PARTITION_ID_INVALID		((u64)0x0)
103
104/* Define connection identifier type. */
105union hv_connection_id {
106	u32 asu32;
107	struct {
108		u32 id:24;
109		u32 reserved:8;
110	} u;
111};
112
113/* Define port identifier type. */
114union hv_port_id {
115	u32 asu32;
116	struct {
117		u32 id:24;
118		u32 reserved:8;
119	} u ;
120};
121
122/* Define port type. */
123enum hv_port_type {
124	HVPORT_MSG	= 1,
125	HVPORT_EVENT		= 2,
126	HVPORT_MONITOR	= 3
127};
128
129/* Define port information structure. */
130struct hv_port_info {
131	enum hv_port_type port_type;
132	u32 padding;
133	union {
134		struct {
135			u32 target_sint;
136			u32 target_vp;
137			u64 rsvdz;
138		} message_port_info;
139		struct {
140			u32 target_sint;
141			u32 target_vp;
142			u16 base_flag_bumber;
143			u16 flag_count;
144			u32 rsvdz;
145		} event_port_info;
146		struct {
147			u64 monitor_address;
148			u64 rsvdz;
149		} monitor_port_info;
150	};
151};
152
153struct hv_connection_info {
154	enum hv_port_type port_type;
155	u32 padding;
156	union {
157		struct {
158			u64 rsvdz;
159		} message_connection_info;
160		struct {
161			u64 rsvdz;
162		} event_connection_info;
163		struct {
164			u64 monitor_address;
165		} monitor_connection_info;
166	};
167};
168
169/* Define synthetic interrupt controller message flags. */
170union hv_message_flags {
171	u8 asu8;
172	struct {
173		u8 msg_pending:1;
174		u8 reserved:7;
175	};
176};
177
178/* Define synthetic interrupt controller message header. */
179struct hv_message_header {
180	enum hv_message_type message_type;
181	u8 payload_size;
182	union hv_message_flags message_flags;
183	u8 reserved[2];
184	union {
185		u64 sender;
186		union hv_port_id port;
187	};
188};
189
190/* Define timer message payload structure. */
191struct hv_timer_message_payload {
192	u32 timer_index;
193	u32 reserved;
194	u64 expiration_time;	/* When the timer expired */
195	u64 delivery_time;	/* When the message was delivered */
196};
197
198/* Define synthetic interrupt controller message format. */
199struct hv_message {
200	struct hv_message_header header;
201	union {
202		u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
203	} u ;
204};
205
206/* Define the number of message buffers associated with each port. */
207#define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
208
209/* Define the synthetic interrupt message page layout. */
210struct hv_message_page {
211	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
212};
213
214/* Define the synthetic interrupt controller event flags format. */
215union hv_synic_event_flags {
216	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
217	u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT];
218};
219
220/* Define the synthetic interrupt flags page layout. */
221struct hv_synic_event_flags_page {
222	union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT];
223};
224
225/* Define SynIC control register. */
226union hv_synic_scontrol {
227	u64 as_uint64;
228	struct {
229		u64 enable:1;
230		u64 reserved:63;
231	};
232};
233
234/* Define synthetic interrupt source. */
235union hv_synic_sint {
236	u64 as_uint64;
237	struct {
238		u64 vector:8;
239		u64 reserved1:8;
240		u64 masked:1;
241		u64 auto_eoi:1;
242		u64 reserved2:46;
243	};
244};
245
246/* Define the format of the SIMP register */
247union hv_synic_simp {
248	u64 as_uint64;
249	struct {
250		u64 simp_enabled:1;
251		u64 preserved:11;
252		u64 base_simp_gpa:52;
253	};
254};
255
256/* Define the format of the SIEFP register */
257union hv_synic_siefp {
258	u64 as_uint64;
259	struct {
260		u64 siefp_enabled:1;
261		u64 preserved:11;
262		u64 base_siefp_gpa:52;
263	};
264};
265
266/* Definitions for the monitored notification facility */
267union hv_monitor_trigger_group {
268	u64 as_uint64;
269	struct {
270		u32 pending;
271		u32 armed;
272	};
273};
274
275struct hv_monitor_parameter {
276	union hv_connection_id connectionid;
277	u16 flagnumber;
278	u16 rsvdz;
279};
280
281union hv_monitor_trigger_state {
282	u32 asu32;
283
284	struct {
285		u32 group_enable:4;
286		u32 rsvdz:28;
287	};
288};
289
290/* struct hv_monitor_page Layout */
291/* ------------------------------------------------------ */
292/* | 0   | TriggerState (4 bytes) | Rsvd1 (4 bytes)     | */
293/* | 8   | TriggerGroup[0]                              | */
294/* | 10  | TriggerGroup[1]                              | */
295/* | 18  | TriggerGroup[2]                              | */
296/* | 20  | TriggerGroup[3]                              | */
297/* | 28  | Rsvd2[0]                                     | */
298/* | 30  | Rsvd2[1]                                     | */
299/* | 38  | Rsvd2[2]                                     | */
300/* | 40  | NextCheckTime[0][0]    | NextCheckTime[0][1] | */
301/* | ...                                                | */
302/* | 240 | Latency[0][0..3]                             | */
303/* | 340 | Rsvz3[0]                                     | */
304/* | 440 | Parameter[0][0]                              | */
305/* | 448 | Parameter[0][1]                              | */
306/* | ...                                                | */
307/* | 840 | Rsvd4[0]                                     | */
308/* ------------------------------------------------------ */
309struct hv_monitor_page {
310	union hv_monitor_trigger_state trigger_state;
311	u32 rsvdz1;
312
313	union hv_monitor_trigger_group trigger_group[4];
314	u64 rsvdz2[3];
315
316	s32 next_checktime[4][32];
317
318	u16 latency[4][32];
319	u64 rsvdz3[32];
320
321	struct hv_monitor_parameter parameter[4][32];
322
323	u8 rsvdz4[1984];
324};
325
326/* Declare the various hypercall operations. */
327enum hv_call_code {
328	HVCALL_POST_MESSAGE	= 0x005c,
329	HVCALL_SIGNAL_EVENT	= 0x005d,
330};
331
332/* Definition of the hv_post_message hypercall input structure. */
333struct hv_input_post_message {
334	union hv_connection_id connectionid;
335	u32 reserved;
336	enum hv_message_type message_type;
337	u32 payload_size;
338	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
339};
340
341/* Definition of the hv_signal_event hypercall input structure. */
342struct hv_input_signal_event {
343	union hv_connection_id connectionid;
344	u16 flag_number;
345	u16 rsvdz;
346};
347
348/*
349 * Versioning definitions used for guests reporting themselves to the
350 * hypervisor, and visa versa.
351 */
352
353/* Version info reported by guest OS's */
354enum hv_guest_os_vendor {
355	HVGUESTOS_VENDOR_MICROSOFT	= 0x0001
356};
357
358enum hv_guest_os_microsoft_ids {
359	HVGUESTOS_MICROSOFT_UNDEFINED	= 0x00,
360	HVGUESTOS_MICROSOFT_MSDOS		= 0x01,
361	HVGUESTOS_MICROSOFT_WINDOWS3X	= 0x02,
362	HVGUESTOS_MICROSOFT_WINDOWS9X	= 0x03,
363	HVGUESTOS_MICROSOFT_WINDOWSNT	= 0x04,
364	HVGUESTOS_MICROSOFT_WINDOWSCE	= 0x05
365};
366
367/*
368 * Declare the MSR used to identify the guest OS.
369 */
370#define HV_X64_MSR_GUEST_OS_ID	0x40000000
371
372union hv_x64_msr_guest_os_id_contents {
373	u64 as_uint64;
374	struct {
375		u64 build_number:16;
376		u64 service_version:8; /* Service Pack, etc. */
377		u64 minor_version:8;
378		u64 major_version:8;
379		u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
380		u64 vendor_id:16; /* enum hv_guest_os_vendor */
381	};
382};
383
384/*
385 * Declare the MSR used to setup pages used to communicate with the hypervisor.
386 */
387#define HV_X64_MSR_HYPERCALL	0x40000001
388
389union hv_x64_msr_hypercall_contents {
390	u64 as_uint64;
391	struct {
392		u64 enable:1;
393		u64 reserved:11;
394		u64 guest_physical_address:52;
395	};
396};
397
398
399enum {
400	VMBUS_MESSAGE_CONNECTION_ID	= 1,
401	VMBUS_MESSAGE_PORT_ID		= 1,
402	VMBUS_EVENT_CONNECTION_ID	= 2,
403	VMBUS_EVENT_PORT_ID		= 2,
404	VMBUS_MONITOR_CONNECTION_ID	= 3,
405	VMBUS_MONITOR_PORT_ID		= 3,
406	VMBUS_MESSAGE_SINT		= 2,
407};
408
409/* #defines */
410
411#define HV_PRESENT_BIT			0x80000000
412
413#define HV_LINUX_GUEST_ID_LO		0x00000000
414#define HV_LINUX_GUEST_ID_HI		0xB16B00B5
415#define HV_LINUX_GUEST_ID		(((u64)HV_LINUX_GUEST_ID_HI << 32) | \
416					   HV_LINUX_GUEST_ID_LO)
417
418#define HV_CPU_POWER_MANAGEMENT		(1 << 0)
419#define HV_RECOMMENDATIONS_MAX		4
420
421#define HV_X64_MAX			5
422#define HV_CAPS_MAX			8
423
424
425#define HV_HYPERCALL_PARAM_ALIGN	sizeof(u64)
426
427
428/* Service definitions */
429
430#define HV_SERVICE_PARENT_PORT				(0)
431#define HV_SERVICE_PARENT_CONNECTION			(0)
432
433#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS		(0)
434#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER	(1)
435#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE	(2)
436#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED	(3)
437
438#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID		(1)
439#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID		(2)
440#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID	(3)
441#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID	(4)
442#define HV_SERVICE_MAX_MESSAGE_ID				(4)
443
444#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
445#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
446
447/* #define VMBUS_REVISION_NUMBER	6 */
448
449/* Our local vmbus's port and connection id. Anything >0 is fine */
450/* #define VMBUS_PORT_ID		11 */
451
452/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
453static const uuid_le VMBUS_SERVICE_ID = {
454	.b = {
455		0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
456		0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
457	},
458};
459
460
461
462struct hv_input_signal_event_buffer {
463	u64 align8;
464	struct hv_input_signal_event event;
465};
466
467struct hv_context {
468	/* We only support running on top of Hyper-V
469	* So at this point this really can only contain the Hyper-V ID
470	*/
471	u64 guestid;
472
473	void *hypercall_page;
474
475	bool synic_initialized;
476
477	/*
478	 * This is used as an input param to HvCallSignalEvent hypercall. The
479	 * input param is immutable in our usage and must be dynamic mem (vs
480	 * stack or global). */
481	struct hv_input_signal_event_buffer *signal_event_buffer;
482	/* 8-bytes aligned of the buffer above */
483	struct hv_input_signal_event *signal_event_param;
484
485	void *synic_message_page[NR_CPUS];
486	void *synic_event_page[NR_CPUS];
487};
488
489extern struct hv_context hv_context;
490
491
492/* Hv Interface */
493
494extern int hv_init(void);
495
496extern void hv_cleanup(void);
497
498extern int hv_post_message(union hv_connection_id connection_id,
499			 enum hv_message_type message_type,
500			 void *payload, size_t payload_size);
501
502extern u16 hv_signal_event(void);
503
504extern void hv_synic_init(void *irqarg);
505
506extern void hv_synic_cleanup(void *arg);
507
508
509/* Interface */
510
511
512int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer,
513		   u32 buflen);
514
515void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
516
517int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info,
518		    struct scatterlist *sglist,
519		    u32 sgcount);
520
521int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
522		   u32 buflen);
523
524int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
525		   void *buffer,
526		   u32 buflen,
527		   u32 offset);
528
529u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
530
531void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
532			    struct hv_ring_buffer_debug_info *debug_info);
533
534/*
535 * Maximum channels is determined by the size of the interrupt page
536 * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
537 * and the other is receive endpoint interrupt
538 */
539#define MAX_NUM_CHANNELS	((PAGE_SIZE >> 1) << 3)	/* 16348 channels */
540
541/* The value here must be in multiple of 32 */
542/* TODO: Need to make this configurable */
543#define MAX_NUM_CHANNELS_SUPPORTED	256
544
545
546enum vmbus_connect_state {
547	DISCONNECTED,
548	CONNECTING,
549	CONNECTED,
550	DISCONNECTING
551};
552
553#define MAX_SIZE_CHANNEL_MESSAGE	HV_MESSAGE_PAYLOAD_BYTE_COUNT
554
555struct vmbus_connection {
556	enum vmbus_connect_state conn_state;
557
558	atomic_t next_gpadl_handle;
559
560	/*
561	 * Represents channel interrupts. Each bit position represents a
562	 * channel.  When a channel sends an interrupt via VMBUS, it finds its
563	 * bit in the sendInterruptPage, set it and calls Hv to generate a port
564	 * event. The other end receives the port event and parse the
565	 * recvInterruptPage to see which bit is set
566	 */
567	void *int_page;
568	void *send_int_page;
569	void *recv_int_page;
570
571	/*
572	 * 2 pages - 1st page for parent->child notification and 2nd
573	 * is child->parent notification
574	 */
575	void *monitor_pages;
576	struct list_head chn_msg_list;
577	spinlock_t channelmsg_lock;
578
579	/* List of channels */
580	struct list_head chn_list;
581	spinlock_t channel_lock;
582
583	struct workqueue_struct *work_queue;
584};
585
586
587struct vmbus_msginfo {
588	/* Bookkeeping stuff */
589	struct list_head msglist_entry;
590
591	/* The message itself */
592	unsigned char msg[0];
593};
594
595
596extern struct vmbus_connection vmbus_connection;
597
598/* General vmbus interface */
599
600struct hv_device *vmbus_device_create(uuid_le *type,
601					 uuid_le *instance,
602					 struct vmbus_channel *channel);
603
604int vmbus_device_register(struct hv_device *child_device_obj);
605void vmbus_device_unregister(struct hv_device *device_obj);
606
607/* static void */
608/* VmbusChildDeviceDestroy( */
609/* struct hv_device *); */
610
611struct vmbus_channel *relid2channel(u32 relid);
612
613void vmbus_free_channels(void);
614
615/* Connection interface */
616
617int vmbus_connect(void);
618
619int vmbus_post_msg(void *buffer, size_t buflen);
620
621int vmbus_set_event(u32 child_relid);
622
623void vmbus_on_event(unsigned long data);
624
625
626#endif /* _HYPERV_VMBUS_H */