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
34class VirtioDevice;
35class VirtioQueue;
36
37extern device_manager_info *gDeviceManager;
38
39
40class VirtioDevice {
41public:
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			void				FreeQueues();
61			status_t			SetupInterrupt(virtio_intr_func config_handler,
62									void *driverCookie);
63			status_t			FreeInterrupts();
64
65			uint16				Alignment() const { return fAlignment; }
66			uint64				Features() const { return fFeatures; }
67
68			void*				DriverCookie() { return fDriverCookie; }
69
70			status_t			SetupQueue(uint16 queueNumber,
71									phys_addr_t physAddr, phys_addr_t phyAvail,
72									phys_addr_t phyUsed);
73			void				NotifyQueue(uint16 queueNumber);
74
75			status_t			QueueInterrupt(uint16 queueNumber);
76			status_t			ConfigInterrupt();
77
78private:
79			void				_DumpFeatures(const char* title,
80									uint64 features,
81									const char* (*get_feature_name)(uint64));
82			void				_DestroyQueues(size_t count);
83
84
85
86			device_node *		fNode;
87			uint32				fID;
88			virtio_sim_interface *fController;
89			void *				fCookie;
90			status_t			fStatus;
91			VirtioQueue**		fQueues;
92			size_t				fQueueCount;
93			uint64				fFeatures;
94			uint16				fAlignment;
95			bool				fVirtio1;
96
97			virtio_intr_func	fConfigHandler;
98			void* 				fDriverCookie;
99};
100
101
102class TransferDescriptor;
103
104
105class VirtioQueue {
106public:
107								VirtioQueue(VirtioDevice *device,
108									uint16 queueNumber, uint16 ringSize);
109								~VirtioQueue();
110			status_t			InitCheck() { return fStatus; }
111
112			void				NotifyHost();
113			status_t			Interrupt();
114
115			bool				IsFull() const { return fRingFree == 0; }
116			bool				IsEmpty() const { return fRingFree == fRingSize; }
117			uint16				Size() const { return fRingSize; }
118
119			VirtioDevice*		Device() { return fDevice; }
120
121			status_t			QueueRequest(const physical_entry* vector,
122									size_t readVectorCount,
123									size_t writtenVectorCount,
124									void *cookie);
125			status_t			QueueRequestIndirect(
126									const physical_entry* vector,
127									size_t readVectorCount,
128									size_t writtenVectorCount,
129									void *cookie);
130
131			status_t			SetupInterrupt(virtio_callback_func handler,
132									void *cookie);
133
134			void				EnableInterrupt();
135			void				DisableInterrupt();
136
137			bool				Dequeue(void** _cookie = NULL,
138									uint32* _usedLength = NULL);
139
140private:
141			void				UpdateAvailable(uint16 index);
142			uint16				QueueVector(uint16 insertIndex,
143									struct vring_desc *desc,
144									const physical_entry* vector,
145									size_t readVectorCount,
146									size_t writtenVectorCount);
147
148			VirtioDevice*		fDevice;
149			uint16				fQueueNumber;
150			uint16				fRingSize;
151			uint16				fRingFree;
152
153			struct vring		fRing;
154			uint16				fRingHeadIndex;
155			uint16				fRingUsedIndex;
156			status_t			fStatus;
157			size_t 				fAreaSize;
158			area_id				fArea;
159
160			uint16				fIndirectMaxSize;
161
162			TransferDescriptor**	fDescriptors;
163
164			virtio_callback_func fCallback;
165			void*				fCookie;
166
167};
168
169#endif // VIRTIO_PRIVATE_H
170