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 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 78 private: 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 102 class TransferDescriptor; 103 104 105 class VirtioQueue { 106 public: 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 140 private: 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