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