1 /* 2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef __VIRTMMIO_H__ 16 #define __VIRTMMIO_H__ 17 18 /* NOTE: Only support non-legacy device and little-endian guest. */ 19 20 #include "stdint.h" 21 #include "los_base.h" 22 #include "los_typedef.h" 23 #include "los_hwi.h" 24 25 #define VIRTIO_STATUS_RESET 0 26 #define VIRTIO_STATUS_ACK 1 27 #define VIRTIO_STATUS_DRIVER 2 28 #define VIRTIO_STATUS_DRIVER_OK 4 29 #define VIRTIO_STATUS_FEATURES_OK 8 30 #define VIRTIO_STATUS_DEVICE_NEEDS_RESET 64 31 #define VIRTIO_STATUS_FAILED 128 32 33 #define VIRTIO_FEATURE_WORD0 0 34 #define VIRTIO_F_RING_INDIRECT_DESC (1 << 28) 35 #define VIRTIO_FEATURE_WORD1 1 36 #define VIRTIO_F_VERSION_1 (1 << 0) 37 38 #define VIRTMMIO_REG_MAGICVALUE 0x00 39 #define VIRTMMIO_REG_VERSION 0x04 40 #define VIRTMMIO_REG_DEVICEID 0x08 41 #define VIRTMMIO_REG_DEVFEATURE 0x10 42 #define VIRTMMIO_REG_DEVFEATURESEL 0x14 43 #define VIRTMMIO_REG_DRVFEATURE 0x20 44 #define VIRTMMIO_REG_DRVFEATURESEL 0x24 45 #define VIRTMMIO_REG_QUEUESEL 0x30 46 #define VIRTMMIO_REG_QUEUENUMMAX 0x34 47 #define VIRTMMIO_REG_QUEUENUM 0x38 48 #define VIRTMMIO_REG_QUEUEREADY 0x44 49 #define VIRTMMIO_REG_QUEUENOTIFY 0x50 50 #define VIRTMMIO_REG_INTERRUPTSTATUS 0x60 51 #define VIRTMMIO_REG_INTERRUPTACK 0x64 52 #define VIRTMMIO_REG_STATUS 0x70 53 #define VIRTMMIO_REG_QUEUEDESCLOW 0x80 54 #define VIRTMMIO_REG_QUEUEDESCHIGH 0x84 55 #define VIRTMMIO_REG_QUEUEDRIVERLOW 0x90 56 #define VIRTMMIO_REG_QUEUEDRIVERHIGH 0x94 57 #define VIRTMMIO_REG_QUEUEDEVICELOW 0xA0 58 #define VIRTMMIO_REG_QUEUEDEVICEHIGH 0xA4 59 #define VIRTMMIO_REG_CONFIGGENERATION 0xFC 60 #define VIRTMMIO_REG_CONFIG 0x100 61 62 #define VIRTQ_ALIGN_DESC 16 63 #define VIRTQ_ALIGN_AVAIL 2 64 #define VIRTQ_ALIGN_USED 4 65 66 #define VIRTMMIO_MAGIC 0x74726976 67 #define VIRTMMIO_VERSION 2 68 #define VIRTMMIO_DEVICE_ID_NET 1 69 #define VIRTMMIO_DEVICE_ID_BLK 2 70 #define VIRTMMIO_DEVICE_ID_RNG 4 71 #define VIRTMMIO_DEVICE_ID_GPU 16 72 #define VIRTMMIO_DEVICE_ID_INPUT 18 73 74 /* QEMU 5.2 virtio-mmio */ 75 #define VIRTMMIO_BASE_ADDR 0x0A000000 76 #define VIRTMMIO_BASE_SIZE 0x200 77 #define VIRTMMIO_BASE_IRQ 16 78 #define NUM_VIRTIO_TRANSPORTS 32 79 80 #define VIRTMMIO_IRQ_NOTIFY_USED (1 << 0) 81 82 struct VirtqDesc { 83 uint64_t pAddr; 84 uint32_t len; 85 #define VIRTQ_DESC_F_NEXT (1 << 0) 86 #define VIRTQ_DESC_F_WRITE (1 << 1) 87 uint16_t flag; 88 uint16_t next; 89 }; 90 91 struct VirtqAvail { 92 #define VIRTQ_AVAIL_F_NO_INTERRUPT (1 << 0) 93 uint16_t flag; 94 uint16_t index; 95 uint16_t ring[]; 96 /* We do not use VIRTIO_F_EVENT_IDX, so no other member */ 97 }; 98 99 struct VirtqUsedElem { 100 uint32_t id; /* u32 for padding purpose */ 101 uint32_t len; 102 }; 103 104 struct VirtqUsed { 105 #define VIRTQ_USED_F_NO_NOTIFY (1 << 0) 106 uint16_t flag; 107 uint16_t index; 108 struct VirtqUsedElem ring[]; 109 /* We do not use VIRTIO_F_EVENT_IDX, so no other member */ 110 }; 111 112 struct Virtq { 113 uint16_t qsz; 114 uint16_t last; 115 116 struct VirtqDesc *desc; 117 struct VirtqAvail *avail; 118 struct VirtqUsed *used; 119 }; 120 121 #define VIRTQ_NUM 2 122 123 /* common virtio-mmio device structure, should be first member of specific device */ 124 struct VirtmmioDev { 125 VADDR_T base; /* I/O base address */ 126 #define _IRQ_MASK 0xFF /* higher bytes as registered flag */ 127 int irq; 128 struct Virtq vq[VIRTQ_NUM]; 129 }; 130 131 132 /* discover and fill in 'dev' if found given ID device */ 133 bool VirtmmioDiscover(uint32_t devId, struct VirtmmioDev *dev); 134 135 void VirtmmioInitBegin(const struct VirtmmioDev *dev); 136 137 /* add 'supported'(default 0) according given 'features' */ 138 typedef bool (*VirtioFeatureFn)(uint32_t features, uint32_t *supported, void *dev); 139 140 /* negotiate 'baseDev' feature word 0 & 1 through 'f0' & 'f1'. 'dev' is passed to callbacks */ 141 bool VirtmmioNegotiate(struct VirtmmioDev *baseDev, VirtioFeatureFn f0, VirtioFeatureFn f1, void *dev); 142 143 /* calculate queue space of size 'qsz', conforming to alignment limits */ 144 unsigned VirtqSize(uint16_t qsz); 145 146 /* config pre-allocated continuous memory as two Virtq, started at 'base' with specified queue size */ 147 VADDR_T VirtmmioConfigQueue(struct VirtmmioDev *dev, VADDR_T base, uint16_t qsz[], int len); 148 149 bool VirtmmioRegisterIRQ(struct VirtmmioDev *dev, HWI_PROC_FUNC handle, void *argDev, const char *devName); 150 151 void VritmmioInitEnd(const struct VirtmmioDev *dev); 152 153 void VirtmmioInitFailed(const struct VirtmmioDev *dev); 154 155 uint32_t VirtgpuGetXres(void); 156 uint32_t VirtgpuGetYres(void); 157 158 #endif 159