xref: /haiku/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
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 TRACE_ALWAYS(x...)	dprintf("\33[33mvirtio:\33[0m " x)
27 #define ERROR(x...)			TRACE_ALWAYS(x)
28 #define CALLED() 			TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
29 
30 
31 #define VIRTIO_SIM_MODULE_NAME		"bus_managers/virtio/sim/driver_v1"
32 
33 
34 class VirtioDevice;
35 class VirtioQueue;
36 
37 extern device_manager_info *gDeviceManager;
38 
39 
40 class VirtioDevice {
41 public:
42 								VirtioDevice(device_node *node);
43 								~VirtioDevice();
44 
45 			status_t			InitCheck();
46 			uint32				ID() const { return fID; }
47 
48 			status_t 			NegotiateFeatures(uint64 supported,
49 									uint64* negotiated,
50 									const char* (*get_feature_name)(uint64));
51 			status_t 			ClearFeature(uint64 feature);
52 
53 			status_t			ReadDeviceConfig(uint8 offset, void* buffer,
54 									size_t bufferSize);
55 			status_t			WriteDeviceConfig(uint8 offset,
56 									const void* buffer, size_t bufferSize);
57 
58 			status_t			AllocateQueues(size_t count,
59 									virtio_queue *queues,
60 									uint16 *requestedSizes);
61 			void				FreeQueues();
62 			status_t			SetupInterrupt(virtio_intr_func config_handler,
63 									void *driverCookie);
64 			status_t			FreeInterrupts();
65 
66 			uint16				Alignment() const { return fAlignment; }
67 			uint64				Features() const { return fFeatures; }
68 
69 			void*				DriverCookie() { return fDriverCookie; }
70 
71 			status_t			SetupQueue(uint16 queueNumber,
72 									phys_addr_t physAddr, phys_addr_t phyAvail,
73 									phys_addr_t phyUsed);
74 			void				NotifyQueue(uint16 queueNumber);
75 
76 			status_t			QueueInterrupt(uint16 queueNumber);
77 			status_t			ConfigInterrupt();
78 
79 private:
80 			void				_DumpFeatures(const char* title,
81 									uint64 features,
82 									const char* (*get_feature_name)(uint64));
83 			void				_DestroyQueues(size_t count);
84 
85 
86 
87 			device_node *		fNode;
88 			uint32				fID;
89 			virtio_sim_interface *fController;
90 			void *				fCookie;
91 			status_t			fStatus;
92 			VirtioQueue**		fQueues;
93 			size_t				fQueueCount;
94 			uint64				fFeatures;
95 			uint16				fAlignment;
96 			bool				fVirtio1;
97 
98 			virtio_intr_func	fConfigHandler;
99 			void* 				fDriverCookie;
100 };
101 
102 
103 class TransferDescriptor;
104 
105 
106 class VirtioQueue {
107 public:
108 								VirtioQueue(VirtioDevice *device,
109 									uint16 queueNumber, uint16 ringSize);
110 								~VirtioQueue();
111 			status_t			InitCheck() { return fStatus; }
112 
113 			void				NotifyHost();
114 			status_t			Interrupt();
115 
116 			bool				IsFull() const { return fRingFree == 0; }
117 			bool				IsEmpty() const { return fRingFree == fRingSize; }
118 			uint16				Size() const { return fRingSize; }
119 
120 			VirtioDevice*		Device() { return fDevice; }
121 
122 			status_t			QueueRequest(const physical_entry* vector,
123 									size_t readVectorCount,
124 									size_t writtenVectorCount,
125 									void *cookie);
126 			status_t			QueueRequestIndirect(
127 									const physical_entry* vector,
128 									size_t readVectorCount,
129 									size_t writtenVectorCount,
130 									void *cookie);
131 
132 			status_t			SetupInterrupt(virtio_callback_func handler,
133 									void *cookie);
134 
135 			void				EnableInterrupt();
136 			void				DisableInterrupt();
137 
138 			bool				Dequeue(void** _cookie = NULL,
139 									uint32* _usedLength = NULL);
140 
141 private:
142 			void				UpdateAvailable(uint16 index);
143 			uint16				QueueVector(uint16 insertIndex,
144 									struct vring_desc *desc,
145 									const physical_entry* vector,
146 									size_t readVectorCount,
147 									size_t writtenVectorCount);
148 
149 			VirtioDevice*		fDevice;
150 			uint16				fQueueNumber;
151 			uint16				fRingSize;
152 			uint16				fRingFree;
153 
154 			struct vring		fRing;
155 			uint16				fRingHeadIndex;
156 			uint16				fRingUsedIndex;
157 			status_t			fStatus;
158 			size_t 				fAreaSize;
159 			area_id				fArea;
160 
161 			uint16				fIndirectMaxSize;
162 
163 			TransferDescriptor**	fDescriptors;
164 
165 			virtio_callback_func fCallback;
166 			void*				fCookie;
167 
168 };
169 
170 #endif // VIRTIO_PRIVATE_H
171