xref: /device/qemu/drivers/virtio/virtmmio.h (revision d6aed566)
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
82struct 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
91struct 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
99struct VirtqUsedElem {
100    uint32_t id;    /* u32 for padding purpose */
101    uint32_t len;
102};
103
104struct 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
112struct 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 */
124struct 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 */
133bool VirtmmioDiscover(uint32_t devId, struct VirtmmioDev *dev);
134
135void VirtmmioInitBegin(const struct VirtmmioDev *dev);
136
137/* add 'supported'(default 0) according given 'features' */
138typedef 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 */
141bool VirtmmioNegotiate(struct VirtmmioDev *baseDev, VirtioFeatureFn f0, VirtioFeatureFn f1, void *dev);
142
143/* calculate queue space of size 'qsz', conforming to alignment limits */
144unsigned VirtqSize(uint16_t qsz);
145
146/* config pre-allocated continuous memory as two Virtq, started at 'base' with specified queue size */
147VADDR_T VirtmmioConfigQueue(struct VirtmmioDev *dev, VADDR_T base, uint16_t qsz[], int len);
148
149bool VirtmmioRegisterIRQ(struct VirtmmioDev *dev, HWI_PROC_FUNC handle, void *argDev, const char *devName);
150
151void VritmmioInitEnd(const struct VirtmmioDev *dev);
152
153void VirtmmioInitFailed(const struct VirtmmioDev *dev);
154
155uint32_t VirtgpuGetXres(void);
156uint32_t VirtgpuGetYres(void);
157
158#endif
159