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