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 ERROR(x...) dprintf("\33[33mvirtio:\33[0m " x) 27 #define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 28 29 30 #define VIRTIO_SIM_MODULE_NAME "bus_managers/virtio/sim/driver_v1" 31 32 33 class VirtioDevice; 34 class VirtioQueue; 35 36 extern device_manager_info *gDeviceManager; 37 38 39 class VirtioDevice { 40 public: 41 VirtioDevice(device_node *node); 42 ~VirtioDevice(); 43 44 status_t InitCheck(); 45 uint32 ID() const { return fID; } 46 47 status_t NegociateFeatures(uint32 supported, 48 uint32* negociated, 49 const char* (*get_feature_name)(uint32)); 50 51 status_t ReadDeviceConfig(uint8 offset, void* buffer, 52 size_t bufferSize); 53 status_t WriteDeviceConfig(uint8 offset, 54 const void* buffer, size_t bufferSize); 55 56 status_t AllocateQueues(size_t count, 57 virtio_queue *queues); 58 status_t SetupInterrupt(virtio_intr_func config_handler, 59 void* configCookie); 60 61 uint16 Alignment() { return fAlignment; } 62 uint32 Features() { return fFeatures; } 63 64 status_t SetupQueue(uint16 queueNumber, 65 phys_addr_t physAddr); 66 void NotifyQueue(uint16 queueNumber); 67 68 status_t QueueInterrupt(uint16 queueNumber); 69 status_t ConfigInterrupt(); 70 71 private: 72 void DumpFeatures(const char* title, 73 uint32 features, 74 const char* (*get_feature_name)(uint32)); 75 76 77 device_node * fNode; 78 uint32 fID; 79 virtio_sim_interface *fController; 80 void * fCookie; 81 status_t fStatus; 82 VirtioQueue** fQueues; 83 size_t fQueueCount; 84 uint32 fFeatures; 85 uint16 fAlignment; 86 87 virtio_intr_func fConfigHandler; 88 void* fConfigCookie; 89 }; 90 91 92 class TransferDescriptor; 93 94 95 class VirtioQueue { 96 public: 97 VirtioQueue(VirtioDevice *device, 98 uint16 queueNumber, uint16 ringSize); 99 ~VirtioQueue(); 100 status_t InitCheck() { return fStatus; } 101 102 void NotifyHost(); 103 status_t Interrupt(); 104 105 bool IsFull() { return fRingFree == 0; } 106 bool IsEmpty() { return fRingFree == fRingSize; } 107 108 status_t QueueRequest(const physical_entry* vector, 109 size_t readVectorCount, 110 size_t writtenVectorCount, 111 virtio_callback_func callback, 112 void *callbackCookie); 113 status_t QueueRequestIndirect( 114 const physical_entry* vector, 115 size_t readVectorCount, 116 size_t writtenVectorCount, 117 virtio_callback_func callback, 118 void *callbackCookie); 119 void EnableInterrupt(); 120 void DisableInterrupt(); 121 122 private: 123 void UpdateAvailable(uint16 index); 124 uint16 QueueVector(uint16 insertIndex, 125 struct vring_desc *desc, 126 const physical_entry* vector, 127 size_t readVectorCount, 128 size_t writtenVectorCount); 129 void Finish(); 130 131 VirtioDevice* fDevice; 132 uint16 fQueueNumber; 133 uint16 fRingSize; 134 uint16 fRingFree; 135 136 struct vring fRing; 137 uint16 fRingHeadIndex; 138 uint16 fRingUsedIndex; 139 status_t fStatus; 140 size_t fAreaSize; 141 area_id fArea; 142 143 TransferDescriptor** fDescriptors; 144 }; 145 146 #endif // VIRTIO_PRIVATE_H 147