• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_reg.h"
22 #include "stdbool.h"
23 #include "los_arch_context.h"
24 
25 typedef unsigned long VADDR_T;
26 typedef unsigned long PADDR_T;
27 
28 #define IO_DEVICE_ADDR(paddr)               (paddr)
29 #define VMM_TO_DMA_ADDR(vaddr)              (vaddr)
30 #define DMA_TO_VMM_ADDR(vaddr)              (vaddr)
31 #define IRQ_SPI_BASE                        RISCV_SYS_MAX_IRQ
32 
33 #define DSB                                 dsb()
34 #define FENCE_WRITE_UINT32(value, addr)     ({ DSB; *((volatile UINT32 *)((UINTPTR)(addr))) = (value); })
35 
36 uint64_t u32_to_u64(uint32_t addr);
37 
38 #define VIRTIO_STATUS_RESET                 0
39 #define VIRTIO_STATUS_ACK                   1
40 #define VIRTIO_STATUS_DRIVER                2
41 #define VIRTIO_STATUS_DRIVER_OK             4
42 #define VIRTIO_STATUS_FEATURES_OK           8
43 #define VIRTIO_STATUS_DEVICE_NEEDS_RESET    64
44 #define VIRTIO_STATUS_FAILED                128
45 
46 #define VIRTIO_FEATURE_WORD0                0
47 #define VIRTIO_F_RING_INDIRECT_DESC         (1 << 28)
48 #define VIRTIO_FEATURE_WORD1                1
49 #define VIRTIO_F_VERSION_1                  (1 << 0)
50 
51 #define VIRTMMIO_REG_MAGICVALUE             0x00
52 #define VIRTMMIO_REG_VERSION                0x04
53 #define VIRTMMIO_REG_DEVICEID               0x08
54 #define VIRTMMIO_REG_DEVFEATURE             0x10
55 #define VIRTMMIO_REG_DEVFEATURESEL          0x14
56 #define VIRTMMIO_REG_DRVFEATURE             0x20
57 #define VIRTMMIO_REG_DRVFEATURESEL          0x24
58 #define VIRTMMIO_REG_QUEUESEL               0x30
59 #define VIRTMMIO_REG_QUEUENUMMAX            0x34
60 #define VIRTMMIO_REG_QUEUENUM               0x38
61 #define VIRTMMIO_REG_QUEUEREADY             0x44
62 #define VIRTMMIO_REG_QUEUENOTIFY            0x50
63 #define VIRTMMIO_REG_INTERRUPTSTATUS        0x60
64 #define VIRTMMIO_REG_INTERRUPTACK           0x64
65 #define VIRTMMIO_REG_STATUS                 0x70
66 #define VIRTMMIO_REG_QUEUEDESCLOW           0x80
67 #define VIRTMMIO_REG_QUEUEDESCHIGH          0x84
68 #define VIRTMMIO_REG_QUEUEDRIVERLOW         0x90
69 #define VIRTMMIO_REG_QUEUEDRIVERHIGH        0x94
70 #define VIRTMMIO_REG_QUEUEDEVICELOW         0xA0
71 #define VIRTMMIO_REG_QUEUEDEVICEHIGH        0xA4
72 #define VIRTMMIO_REG_CONFIGGENERATION       0xFC
73 #define VIRTMMIO_REG_CONFIG                 0x100
74 
75 #define VIRTQ_ALIGN_DESC                    16
76 #define VIRTQ_ALIGN_AVAIL                   2
77 #define VIRTQ_ALIGN_USED                    4
78 
79 #define VIRTMMIO_MAGIC                      0x74726976
80 #define VIRTMMIO_VERSION                    2
81 #define VIRTMMIO_DEVICE_ID_NET              1
82 #define VIRTMMIO_DEVICE_ID_GPU              16
83 #define VIRTMMIO_DEVICE_ID_INPUT            18
84 
85 /* QEMU 5.2 virtio-mmio for riscv */
86 #define VIRTMMIO_BASE_ADDR                  0x10001000    /* see hw/riscv/virt.c virt_memmap[] */
87 #define VIRTMMIO_BASE_SIZE                  0x1000        /* see hw/riscv/virt.c virt_memmap[] */
88 #define VIRTMMIO_BASE_IRQ                   1             /* see hw/riscv/virt.h VIRTIO_IRQ */
89 #define NUM_VIRTIO_TRANSPORTS               8             /* see hw/riscv/virt.h VIRTIO_COUNT */
90 
91 #define VIRTMMIO_IRQ_NOTIFY_USED            (1 << 0)
92 
93 struct VirtqDesc {
94     uint64_t pAddr;
95     uint32_t len;
96 #define VIRTQ_DESC_F_NEXT                   (1 << 0)
97 #define VIRTQ_DESC_F_WRITE                  (1 << 1)
98     uint16_t flag;
99     uint16_t next;
100 };
101 
102 struct VirtqAvail {
103 #define VIRTQ_AVAIL_F_NO_INTERRUPT          (1 << 0)
104     uint16_t flag;
105     uint16_t index;
106     uint16_t ring[];
107     /* We do not use VIRTIO_F_EVENT_IDX, so no other member */
108 };
109 
110 struct VirtqUsedElem {
111     uint32_t id;    /* u32 for padding purpose */
112     uint32_t len;
113 };
114 
115 struct VirtqUsed {
116 #define VIRTQ_USED_F_NO_NOTIFY              (1 << 0)
117     uint16_t flag;
118     uint16_t index;
119     struct VirtqUsedElem ring[];
120     /* We do not use VIRTIO_F_EVENT_IDX, so no other member */
121 };
122 
123 struct Virtq {
124     uint16_t qsz;
125     uint16_t last;
126 
127     struct VirtqDesc *desc;
128     struct VirtqAvail *avail;
129     struct VirtqUsed *used;
130 };
131 
132 #define VIRTQ_NUM   2
133 
134 /* common virtio-mmio device structure, should be first member of specific device */
135 struct VirtmmioDev {
136     VADDR_T         base;   /* I/O base address */
137 #define _IRQ_MASK   0xFF    /* higher bytes as registered flag */
138     int             irq;
139     struct Virtq    vq[VIRTQ_NUM];
140 };
141 
142 
143 /* discover and fill in 'dev' if found given ID device */
144 bool VirtmmioDiscover(uint32_t devId, struct VirtmmioDev *dev);
145 
146 void VirtmmioInitBegin(const struct VirtmmioDev *dev);
147 
148 /* add 'supported'(default 0) according given 'features' */
149 typedef bool (*VirtioFeatureFn)(uint32_t features, uint32_t *supported, void *dev);
150 
151 /* negotiate 'baseDev' feature word 0 & 1 through 'f0' & 'f1'. 'dev' is passed to callbacks */
152 bool VirtmmioNegotiate(struct VirtmmioDev *baseDev, VirtioFeatureFn f0, VirtioFeatureFn f1, void *dev);
153 
154 /* calculate queue space of size 'qsz', conforming to alignment limits */
155 unsigned VirtqSize(uint16_t qsz);
156 
157 /* config pre-allocated continuous memory as two Virtq, started at 'base' with specified queue size */
158 VADDR_T VirtmmioConfigQueue(struct VirtmmioDev *dev, VADDR_T base, uint16_t qsz[], int num);
159 
160 bool VirtmmioRegisterIRQ(struct VirtmmioDev *dev, HWI_PROC_FUNC handle, void *argDev, const char *devName);
161 
162 void VritmmioInitEnd(const struct VirtmmioDev *dev);
163 
164 void VirtmmioInitFailed(const struct VirtmmioDev *dev);
165 
166 #endif
167