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