xref: /haiku/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h (revision 225b6382637a7346d5378ee45a6581b4e2616055)
1 /*
2  * Copyright 2013, Jérôme Duval, korli@users.berlios.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef VIRTIO_PRIVATE_H
6 #define VIRTIO_PRIVATE_H
7 
8 
9 #include <new>
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include <lock.h>
14 #include <util/AutoLock.h>
15 #include <virtio.h>
16 
17 #include "virtio_ring.h"
18 
19 
20 //#define VIRTIO_TRACE
21 #ifdef VIRTIO_TRACE
22 #	define TRACE(x...)		dprintf("\33[33mvirtio:\33[0m " x)
23 #else
24 #	define TRACE(x...)
25 #endif
26 #define ERROR(x...)			dprintf("\33[33mvirtio:\33[0m " x)
27 #define CALLED() 			TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
28 
29 
30 #define VIRTIO_SIM_MODULE_NAME		"bus_managers/virtio/sim/driver_v1"
31 
32 
33 class VirtioDevice;
34 class VirtioQueue;
35 
36 extern device_manager_info *gDeviceManager;
37 
38 
39 class VirtioDevice {
40 public:
41 								VirtioDevice(device_node *node);
42 								~VirtioDevice();
43 
44 			status_t			InitCheck();
45 			uint32				ID() const { return fID; }
46 
47 			status_t 			NegociateFeatures(uint32 supported,
48 									uint32* negociated,
49 									const char* (*get_feature_name)(uint32));
50 
51 			status_t			ReadDeviceConfig(uint8 offset, void* buffer,
52 									size_t bufferSize);
53 			status_t			WriteDeviceConfig(uint8 offset,
54 									const void* buffer, size_t bufferSize);
55 
56 			status_t			AllocateQueues(size_t count,
57 									virtio_queue *queues);
58 			status_t			SetupInterrupt(virtio_intr_func config_handler,
59 									void* configCookie);
60 
61 			uint16				Alignment() { return fAlignment; }
62 			uint32				Features() { return fFeatures; }
63 
64 			status_t			SetupQueue(uint16 queueNumber,
65 									phys_addr_t physAddr);
66 			void				NotifyQueue(uint16 queueNumber);
67 
68 			status_t			QueueInterrupt(uint16 queueNumber);
69 			status_t			ConfigInterrupt();
70 
71 private:
72 			void				DumpFeatures(const char* title,
73 									uint32 features,
74 									const char* (*get_feature_name)(uint32));
75 
76 
77 			device_node *		fNode;
78 			uint32				fID;
79 			virtio_sim_interface *fController;
80 			void *				fCookie;
81 			status_t			fStatus;
82 			VirtioQueue**		fQueues;
83 			size_t				fQueueCount;
84 			uint32				fFeatures;
85 			uint16				fAlignment;
86 
87 			virtio_intr_func	fConfigHandler;
88 			void* 				fConfigCookie;
89 };
90 
91 
92 class TransferDescriptor;
93 
94 
95 class VirtioQueue {
96 public:
97 								VirtioQueue(VirtioDevice *device,
98 									uint16 queueNumber, uint16 ringSize);
99 								~VirtioQueue();
100 			status_t			InitCheck() { return fStatus; }
101 
102 			void				NotifyHost();
103 			status_t			Interrupt();
104 
105 			bool				IsFull() { return fRingFree == 0; }
106 			bool				IsEmpty() { return fRingFree == fRingSize; }
107 
108 			status_t			QueueRequest(const physical_entry* vector,
109 									size_t readVectorCount,
110 									size_t writtenVectorCount,
111 									virtio_callback_func callback,
112 									void *callbackCookie);
113 			status_t			QueueRequestIndirect(
114 									const physical_entry* vector,
115 									size_t readVectorCount,
116 									size_t writtenVectorCount,
117 									virtio_callback_func callback,
118 									void *callbackCookie);
119 			void				EnableInterrupt();
120 			void				DisableInterrupt();
121 
122 private:
123 			void				UpdateAvailable(uint16 index);
124 			uint16				QueueVector(uint16 insertIndex,
125 									struct vring_desc *desc,
126 									const physical_entry* vector,
127 									size_t readVectorCount,
128 									size_t writtenVectorCount);
129 			void				Finish();
130 
131 			VirtioDevice*		fDevice;
132 			uint16				fQueueNumber;
133 			uint16				fRingSize;
134 			uint16				fRingFree;
135 
136 			struct vring		fRing;
137 			uint16				fRingHeadIndex;
138 			uint16				fRingUsedIndex;
139 			status_t			fStatus;
140 			size_t 				fAreaSize;
141 			area_id				fArea;
142 
143 			TransferDescriptor**	fDescriptors;
144 };
145 
146 #endif // VIRTIO_PRIVATE_H
147