Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76519099
rt-thread
提交
8fa16f96
R
rt-thread
项目概览
2301_76519099
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
3
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
8fa16f96
编写于
6月 18, 2022
作者:
G
GUI
提交者:
GitHub
6月 18, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[bsp/qemu-virt64-aarch64] Add more VirtIO drivers (#6091)
上级
fb941e6d
变更
22
展开全部
隐藏空白更改
内联
并排
Showing
22 changed file
with
3778 addition
and
38 deletion
+3778
-38
bsp/qemu-virt64-aarch64/.config
bsp/qemu-virt64-aarch64/.config
+102
-7
bsp/qemu-virt64-aarch64/README.md
bsp/qemu-virt64-aarch64/README.md
+4
-1
bsp/qemu-virt64-aarch64/README_zh.md
bsp/qemu-virt64-aarch64/README_zh.md
+4
-1
bsp/qemu-virt64-aarch64/applications/graphic.c
bsp/qemu-virt64-aarch64/applications/graphic.c
+198
-0
bsp/qemu-virt64-aarch64/driver/Kconfig
bsp/qemu-virt64-aarch64/driver/Kconfig
+13
-1
bsp/qemu-virt64-aarch64/driver/drv_virtio.c
bsp/qemu-virt64-aarch64/driver/drv_virtio.c
+18
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio.c
bsp/qemu-virt64-aarch64/driver/virtio/virtio.c
+30
-10
bsp/qemu-virt64-aarch64/driver/virtio/virtio.h
bsp/qemu-virt64-aarch64/driver/virtio/virtio.h
+21
-1
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c
+19
-14
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h
+45
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.c
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.c
+903
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.h
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.h
+412
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.c
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.c
+432
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.h
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.h
+145
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input_event_codes.h
...u-virt64-aarch64/driver/virtio/virtio_input_event_codes.h
+932
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.c
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.c
+308
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.h
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.h
+101
-0
bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h
bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h
+3
-0
bsp/qemu-virt64-aarch64/qemu-graphic.bat
bsp/qemu-virt64-aarch64/qemu-graphic.bat
+12
-0
bsp/qemu-virt64-aarch64/qemu-graphic.sh
bsp/qemu-virt64-aarch64/qemu-graphic.sh
+10
-0
bsp/qemu-virt64-aarch64/rtconfig.h
bsp/qemu-virt64-aarch64/rtconfig.h
+65
-2
bsp/qemu-virt64-aarch64/rtconfig.py
bsp/qemu-virt64-aarch64/rtconfig.py
+1
-1
未找到文件。
bsp/qemu-virt64-aarch64/.config
浏览文件 @
8fa16f96
...
...
@@ -8,7 +8,8 @@
#
CONFIG_RT_NAME_MAX
=
16
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_USING_SMP
=
y
CONFIG_RT_CPUS_NR
=
4
CONFIG_RT_ALIGN_SIZE
=
4
# CONFIG_RT_THREAD_PRIORITY_8 is not set
CONFIG_RT_THREAD_PRIORITY_32
=
y
...
...
@@ -21,6 +22,7 @@ CONFIG_RT_HOOK_USING_FUNC_PTR=y
CONFIG_RT_USING_IDLE_HOOK
=
y
CONFIG_RT_IDLE_HOOK_LIST_SIZE
=
4
CONFIG_IDLE_THREAD_STACK_SIZE
=
4096
CONFIG_SYSTEM_THREAD_STACK_SIZE
=
4096
CONFIG_RT_USING_TIMER_SOFT
=
y
CONFIG_RT_TIMER_THREAD_PRIO
=
4
CONFIG_RT_TIMER_THREAD_STACK_SIZE
=
4096
...
...
@@ -31,7 +33,7 @@ CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096
# CONFIG_RT_KSERVICE_USING_STDLIB is not set
# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
# CONFIG_RT_USING_TINY_FFS is not set
# CONFIG_RT_PRINTF_LONGLONG is not set
CONFIG_RT_KPRINTF_USING_LONGLONG
=
y
CONFIG_RT_DEBUG
=
y
CONFIG_RT_DEBUG_COLOR
=
y
# CONFIG_RT_DEBUG_INIT_CONFIG is not set
...
...
@@ -82,7 +84,7 @@ CONFIG_RT_USING_DEVICE_OPS=y
CONFIG_RT_USING_CONSOLE
=
y
CONFIG_RT_CONSOLEBUF_SIZE
=
128
CONFIG_RT_CONSOLE_DEVICE_NAME
=
"uart0"
CONFIG_RT_VER_NUM
=
0
x4010
0
CONFIG_RT_VER_NUM
=
0
x4010
1
CONFIG_ARCH_CPU_64BIT
=
y
# CONFIG_RT_USING_CPU_FFS is not set
CONFIG_ARCH_ARMV8
=
y
...
...
@@ -144,6 +146,7 @@ CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000
CONFIG_RT_USING_DFS_DEVFS
=
y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_NFS is not set
# CONFIG_RT_USING_FAL is not set
#
...
...
@@ -151,7 +154,7 @@ CONFIG_RT_USING_DFS_DEVFS=y
#
CONFIG_RT_USING_DEVICE_IPC
=
y
CONFIG_RT_USING_SYSTEM_WORKQUEUE
=
y
CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE
=
2048
CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE
=
4096
CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY
=
23
CONFIG_RT_USING_SERIAL
=
y
CONFIG_RT_USING_SERIAL_V1
=
y
...
...
@@ -221,9 +224,83 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# Network
#
# CONFIG_RT_USING_SAL is not set
# CONFIG_RT_USING_NETDEV is not set
# CONFIG_RT_USING_LWIP is not set
CONFIG_RT_USING_SAL
=
y
CONFIG_SAL_INTERNET_CHECK
=
y
#
# Docking with protocol stacks
#
CONFIG_SAL_USING_LWIP
=
y
# CONFIG_SAL_USING_AT is not set
# CONFIG_SAL_USING_TLS is not set
CONFIG_SAL_USING_POSIX
=
y
CONFIG_RT_USING_NETDEV
=
y
CONFIG_NETDEV_USING_IFCONFIG
=
y
CONFIG_NETDEV_USING_PING
=
y
CONFIG_NETDEV_USING_NETSTAT
=
y
CONFIG_NETDEV_USING_AUTO_DEFAULT
=
y
# CONFIG_NETDEV_USING_IPV6 is not set
CONFIG_NETDEV_IPV4
=
1
CONFIG_NETDEV_IPV6
=
0
# CONFIG_NETDEV_IPV6_SCOPES is not set
CONFIG_RT_USING_LWIP
=
y
# CONFIG_RT_USING_LWIP_LOCAL_VERSION is not set
# CONFIG_RT_USING_LWIP141 is not set
CONFIG_RT_USING_LWIP203
=
y
# CONFIG_RT_USING_LWIP212 is not set
# CONFIG_RT_USING_LWIP_LATEST is not set
CONFIG_RT_USING_LWIP_VER_NUM
=
0
x20003
# CONFIG_RT_USING_LWIP_IPV6 is not set
CONFIG_RT_LWIP_MEM_ALIGNMENT
=
4
# CONFIG_RT_LWIP_IGMP is not set
CONFIG_RT_LWIP_ICMP
=
y
# CONFIG_RT_LWIP_SNMP is not set
CONFIG_RT_LWIP_DNS
=
y
CONFIG_RT_LWIP_DHCP
=
y
CONFIG_IP_SOF_BROADCAST
=
1
CONFIG_IP_SOF_BROADCAST_RECV
=
1
#
# Static IPv4 Address
#
CONFIG_RT_LWIP_IPADDR
=
"192.168.1.30"
CONFIG_RT_LWIP_GWADDR
=
"192.168.1.1"
CONFIG_RT_LWIP_MSKADDR
=
"255.255.255.0"
CONFIG_RT_LWIP_UDP
=
y
CONFIG_RT_LWIP_TCP
=
y
CONFIG_RT_LWIP_RAW
=
y
# CONFIG_RT_LWIP_PPP is not set
CONFIG_RT_MEMP_NUM_NETCONN
=
8
CONFIG_RT_LWIP_PBUF_NUM
=
16
CONFIG_RT_LWIP_RAW_PCB_NUM
=
4
CONFIG_RT_LWIP_UDP_PCB_NUM
=
4
CONFIG_RT_LWIP_TCP_PCB_NUM
=
4
CONFIG_RT_LWIP_TCP_SEG_NUM
=
40
CONFIG_RT_LWIP_TCP_SND_BUF
=
8196
CONFIG_RT_LWIP_TCP_WND
=
8196
CONFIG_RT_LWIP_TCPTHREAD_PRIORITY
=
10
CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE
=
8
CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE
=
4096
# CONFIG_LWIP_NO_RX_THREAD is not set
# CONFIG_LWIP_NO_TX_THREAD is not set
CONFIG_RT_LWIP_ETHTHREAD_PRIORITY
=
12
CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE
=
4096
CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE
=
8
CONFIG_RT_LWIP_REASSEMBLY_FRAG
=
y
CONFIG_LWIP_NETIF_STATUS_CALLBACK
=
1
CONFIG_LWIP_NETIF_LINK_CALLBACK
=
1
CONFIG_SO_REUSE
=
1
CONFIG_LWIP_SO_RCVTIMEO
=
1
CONFIG_LWIP_SO_SNDTIMEO
=
1
CONFIG_LWIP_SO_RCVBUF
=
1
CONFIG_LWIP_SO_LINGER
=
0
# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
CONFIG_LWIP_NETIF_LOOPBACK
=
0
# CONFIG_RT_LWIP_STATS is not set
# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
CONFIG_RT_LWIP_USING_PING
=
y
# CONFIG_LWIP_USING_DHCPD is not set
# CONFIG_RT_LWIP_DEBUG is not set
# CONFIG_RT_USING_AT is not set
#
...
...
@@ -299,6 +376,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
# CONFIG_PKG_USING_EZ_IOT_OS is not set
# CONFIG_PKG_USING_IOTSHARP_SDK is not set
# CONFIG_PKG_USING_NIMBLE is not set
# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
...
...
@@ -332,12 +410,14 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_HM is not set
# CONFIG_PKG_USING_SMALL_MODBUS is not set
# CONFIG_PKG_USING_NET_SERVER is not set
# CONFIG_PKG_USING_ZFTP is not set
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_LIBSODIUM is not set
# CONFIG_PKG_USING_LIBHYDROGEN is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
# CONFIG_PKG_USING_YD_CRYPTO is not set
...
...
@@ -366,6 +446,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
# CONFIG_PKG_USING_PIKASCRIPT is not set
# CONFIG_PKG_USING_RTT_RUST is not set
#
# multimedia packages
...
...
@@ -377,6 +458,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_LVGL is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
#
# u8g2: a monochrome graphic library
...
...
@@ -451,6 +533,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_FDT is not set
# CONFIG_PKG_USING_CBOX is not set
# CONFIG_PKG_USING_SNOWFLAKE is not set
# CONFIG_PKG_USING_HASH_MATCH is not set
# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
#
# system packages
...
...
@@ -470,6 +555,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_POSIX_WCWIDTH is not set
# CONFIG_PKG_USING_POSIX_ITOA is not set
# CONFIG_PKG_USING_POSIX_STRINGS is not set
# CONFIG_PKG_USING_POSIX_CTYPES is not set
#
# acceleration: Assembly language or algorithmic acceleration packages
...
...
@@ -482,6 +568,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
#
# CONFIG_PKG_USING_CMSIS_5 is not set
# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
#
...
...
@@ -497,6 +584,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_PERF_COUNTER is not set
# CONFIG_PKG_USING_FLASHDB is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
...
...
@@ -524,6 +612,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_TINYUSB is not set
# CONFIG_PKG_USING_CHERRYUSB is not set
# CONFIG_PKG_USING_KMULTI_RTIMER is not set
# CONFIG_PKG_USING_TFDB is not set
# CONFIG_PKG_USING_QPC is not set
#
# peripheral libraries and drivers
...
...
@@ -678,6 +768,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_CONTROLLER is not set
# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
# CONFIG_PKG_USING_MFBD is not set
# CONFIG_PKG_USING_SLCAN2RTT is not set
# CONFIG_PKG_USING_SOEM is not set
CONFIG_SOC_VIRT64_AARCH64
=
y
#
...
...
@@ -688,6 +780,9 @@ CONFIG_RT_USING_UART0=y
CONFIG_BSP_USING_RTC
=
y
CONFIG_BSP_USING_ALARM
=
y
CONFIG_BSP_USING_VIRTIO_BLK
=
y
CONFIG_BSP_USING_VIRTIO_NET
=
y
CONFIG_BSP_USING_VIRTIO_GPU
=
y
CONFIG_BSP_USING_VIRTIO_INPUT
=
y
CONFIG_BSP_USING_GIC
=
y
CONFIG_BSP_USING_GICV2
=
y
# CONFIG_BSP_USING_GICV3 is not set
bsp/qemu-virt64-aarch64/README.md
浏览文件 @
8fa16f96
...
...
@@ -51,4 +51,7 @@ msh />
| ------ | --------- | ------ |
| UART | Support | UART0 |
| RTC | Support | - |
| VIRTIO BLK | Support | - |
\ No newline at end of file
| VIRTIO BLK | Support | - |
| VIRTIO NET | Support | - |
| VIRTIO GPU | Support | 2D |
| VIRTIO Input | Support | Keyboard, Mouse, Tablet |
\ No newline at end of file
bsp/qemu-virt64-aarch64/README_zh.md
浏览文件 @
8fa16f96
...
...
@@ -52,4 +52,7 @@ msh />
| ------ | ---- | :------: |
| UART | 支持 | UART0 |
| RTC | 支持 | - |
| VIRTIO BLK | 支持 | - |
\ No newline at end of file
| VIRTIO BLK | 支持 | - |
| VIRTIO NET | 支持 | - |
| VIRTIO GPU | 支持 | 2D |
| VIRTIO Input | 支持 | Keyboard, Mouse, Tablet |
\ No newline at end of file
bsp/qemu-virt64-aarch64/applications/graphic.c
0 → 100644
浏览文件 @
8fa16f96
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-11 GuEe-GUI the first version
*/
#include <rtthread.h>
#include <virtio_gpu.h>
#include <virtio_input.h>
#define GRAPHIC_THREAD_PRIORITY 25
#define GRAPHIC_THREAD_STACK_SIZE 4096
#define GRAPHIC_THREAD_TIMESLICE 5
static
rt_uint32_t
cur_min
[
2
];
static
rt_uint32_t
cur_max
[
2
];
static
rt_uint32_t
cur_range
[
2
];
static
rt_uint32_t
cur_points
[
2
];
static
rt_uint32_t
cur_last_points
[
2
];
static
rt_bool_t
cur_event_sync
;
void
tablet_event_handler
(
struct
virtio_input_event
event
)
{
if
(
event
.
type
==
EV_ABS
)
{
if
(
event
.
code
==
0
)
{
cur_points
[
0
]
=
(
cur_max
[
0
]
*
(
event
.
value
-
cur_min
[
0
])
+
cur_range
[
0
]
/
2
)
/
cur_range
[
0
];
}
else
if
(
event
.
code
==
1
)
{
cur_points
[
1
]
=
(
cur_max
[
1
]
*
(
event
.
value
-
cur_min
[
1
])
+
cur_range
[
1
]
/
2
)
/
cur_range
[
1
];
}
}
else
if
(
event
.
type
==
EV_SYN
)
{
cur_event_sync
=
RT_TRUE
;
}
}
void
graphic_thread
(
void
*
param
)
{
int
i
;
char
dev_name
[
RT_NAME_MAX
];
rt_device_t
device
=
RT_NULL
;
rt_device_t
tablet_dev
=
RT_NULL
;
struct
virtio_input_config
tablet_config
;
rt_uint32_t
red
=
0xff0000
;
rt_uint32_t
blue
=
0x0000ff
;
rt_uint32_t
white
=
0xffffff
;
rt_device_t
gpu_dev
=
RT_NULL
;
struct
rt_device_rect_info
rect_info
;
struct
rt_device_graphic_info
graphic_info
;
struct
rt_device_graphic_ops
*
virtio_gpu_graphic_ops
;
/* GPU */
device
=
rt_device_find
(
"virtio-gpu0"
);
if
(
device
!=
RT_NULL
&&
rt_device_open
(
device
,
0
)
==
RT_EOK
)
{
virtio_gpu_graphic_ops
=
rt_graphix_ops
(
device
);
rt_memset
(
&
rect_info
,
0
,
sizeof
(
rect_info
));
rt_memset
(
&
graphic_info
,
0
,
sizeof
(
graphic_info
));
rt_device_control
(
device
,
VIRTIO_DEVICE_CTRL_GPU_SET_PRIMARY
,
RT_NULL
);
rt_device_control
(
device
,
VIRTIO_DEVICE_CTRL_GPU_CREATE_2D
,
(
void
*
)
RTGRAPHIC_PIXEL_FORMAT_RGB888
);
rt_device_control
(
device
,
RTGRAPHIC_CTRL_GET_INFO
,
&
graphic_info
);
rect_info
.
x
=
0
;
rect_info
.
y
=
0
;
rect_info
.
width
=
graphic_info
.
width
;
rect_info
.
height
=
graphic_info
.
height
;
if
(
graphic_info
.
framebuffer
!=
RT_NULL
)
{
rt_memset
(
graphic_info
.
framebuffer
,
0xff
,
graphic_info
.
width
*
graphic_info
.
height
*
graphic_info
.
bits_per_pixel
);
cur_last_points
[
0
]
=
graphic_info
.
width
/
2
;
cur_last_points
[
1
]
=
graphic_info
.
height
/
2
;
virtio_gpu_graphic_ops
->
draw_hline
((
char
*
)
&
red
,
0
,
graphic_info
.
width
,
cur_last_points
[
1
]);
virtio_gpu_graphic_ops
->
draw_vline
((
char
*
)
&
blue
,
cur_last_points
[
0
],
0
,
graphic_info
.
height
);
rt_device_control
(
device
,
RTGRAPHIC_CTRL_RECT_UPDATE
,
&
rect_info
);
gpu_dev
=
device
;
}
rt_device_close
(
device
);
}
/* Keyboard, Mouse, Tablet */
for
(
i
=
0
;
i
<
3
;
++
i
)
{
rt_snprintf
(
dev_name
,
RT_NAME_MAX
,
"virtio-input%d"
,
i
);
device
=
rt_device_find
(
dev_name
);
if
(
device
!=
RT_NULL
&&
rt_device_open
(
device
,
0
)
==
RT_EOK
)
{
enum
virtio_input_type
type
;
rt_device_control
(
device
,
VIRTIO_DEVICE_CTRL_INPUT_GET_TYPE
,
&
type
);
if
(
type
==
VIRTIO_INPUT_TYPE_TABLET
)
{
tablet_dev
=
device
;
}
else
{
rt_device_close
(
device
);
}
}
}
if
(
tablet_dev
==
RT_NULL
||
gpu_dev
==
RT_NULL
)
{
goto
_graphic_fail
;
}
cur_max
[
0
]
=
graphic_info
.
width
;
cur_max
[
1
]
=
graphic_info
.
height
;
rt_device_control
(
tablet_dev
,
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_X_INFO
,
&
tablet_config
);
cur_min
[
0
]
=
tablet_config
.
abs
.
min
;
cur_range
[
0
]
=
tablet_config
.
abs
.
max
-
cur_min
[
0
];
rt_device_control
(
tablet_dev
,
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_Y_INFO
,
&
tablet_config
);
cur_min
[
1
]
=
tablet_config
.
abs
.
min
;
cur_range
[
1
]
=
tablet_config
.
abs
.
max
-
cur_min
[
1
];
cur_event_sync
=
RT_FALSE
;
rt_device_control
(
tablet_dev
,
VIRTIO_DEVICE_CTRL_INPUT_BIND_BSCT_HANDLER
,
tablet_event_handler
);
for
(;;)
{
while
(
cur_event_sync
)
{
virtio_gpu_graphic_ops
->
draw_hline
((
char
*
)
&
white
,
0
,
graphic_info
.
width
,
cur_last_points
[
1
]);
virtio_gpu_graphic_ops
->
draw_vline
((
char
*
)
&
white
,
cur_last_points
[
0
],
0
,
graphic_info
.
height
);
cur_last_points
[
0
]
=
cur_points
[
0
];
cur_last_points
[
1
]
=
cur_points
[
1
];
virtio_gpu_graphic_ops
->
draw_hline
((
char
*
)
&
red
,
0
,
graphic_info
.
width
,
cur_last_points
[
1
]);
virtio_gpu_graphic_ops
->
draw_vline
((
char
*
)
&
blue
,
cur_last_points
[
0
],
0
,
graphic_info
.
height
);
rt_device_control
(
gpu_dev
,
RTGRAPHIC_CTRL_RECT_UPDATE
,
&
rect_info
);
cur_event_sync
=
RT_FALSE
;
rt_thread_mdelay
(
1
);
}
}
_graphic_fail:
if
(
gpu_dev
!=
RT_NULL
)
{
rt_device_close
(
gpu_dev
);
}
if
(
tablet_dev
!=
RT_NULL
)
{
rt_device_close
(
tablet_dev
);
}
}
int
graphic_init
(
void
)
{
rt_thread_t
graphic_tid
=
rt_thread_create
(
"graphic work"
,
graphic_thread
,
RT_NULL
,
GRAPHIC_THREAD_STACK_SIZE
,
GRAPHIC_THREAD_PRIORITY
,
GRAPHIC_THREAD_TIMESLICE
);
if
(
graphic_tid
!=
RT_NULL
)
{
rt_thread_startup
(
graphic_tid
);
return
RT_EOK
;
}
return
-
RT_ERROR
;
}
#ifdef RT_USING_SMP
INIT_ENV_EXPORT
(
graphic_init
);
#else
MSH_CMD_EXPORT
(
graphic_init
,
Graphic
initialize
);
#endif
bsp/qemu-virt64-aarch64/driver/Kconfig
浏览文件 @
8fa16f96
...
...
@@ -24,10 +24,22 @@ menu "AARCH64 qemu virt64 configs"
default n
endif
menu
config BSP_USING_VIRTIO_BLK
config BSP_USING_VIRTIO_BLK
bool "Using VirtIO BLK"
default y
config BSP_USING_VIRTIO_NET
bool "Using VirtIO NET"
default y
config BSP_USING_VIRTIO_GPU
bool "Using VirtIO GPU"
default y
config BSP_USING_VIRTIO_INPUT
bool "Using VirtIO Input"
default y
config BSP_USING_GIC
bool
default y
...
...
bsp/qemu-virt64-aarch64/driver/drv_virtio.c
浏览文件 @
8fa16f96
...
...
@@ -14,6 +14,15 @@
#ifdef BSP_USING_VIRTIO_BLK
#include <virtio_blk.h>
#endif
#ifdef BSP_USING_VIRTIO_NET
#include <virtio_net.h>
#endif
#ifdef BSP_USING_VIRTIO_GPU
#include <virtio_gpu.h>
#endif
#ifdef BSP_USING_VIRTIO_INPUT
#include <virtio_input.h>
#endif
#include <board.h>
...
...
@@ -22,6 +31,15 @@ static virtio_device_init_handler virtio_device_init_handlers[] =
#ifdef BSP_USING_VIRTIO_BLK
[
VIRTIO_DEVICE_ID_BLOCK
]
=
rt_virtio_blk_init
,
#endif
#ifdef BSP_USING_VIRTIO_NET
[
VIRTIO_DEVICE_ID_NET
]
=
rt_virtio_net_init
,
#endif
#ifdef BSP_USING_VIRTIO_GPU
[
VIRTIO_DEVICE_ID_GPU
]
=
rt_virtio_gpu_init
,
#endif
#ifdef BSP_USING_VIRTIO_INPUT
[
VIRTIO_DEVICE_ID_INPUT
]
=
rt_virtio_input_init
,
#endif
};
int
rt_virtio_devices_init
(
void
)
...
...
bsp/qemu-virt64-aarch64/driver/virtio/virtio.c
浏览文件 @
8fa16f96
...
...
@@ -40,11 +40,18 @@ void virtio_status_driver_ok(struct virtio_device *dev)
dev
->
mmio_config
->
status
|=
VIRTIO_STATUS_FEATURES_OK
|
VIRTIO_STATUS_DRIVER_OK
;
}
void
virtio_interrupt_ack
(
struct
virtio_device
*
dev
,
rt_uint32_t
ack
)
void
virtio_interrupt_ack
(
struct
virtio_device
*
dev
)
{
rt_uint32_t
status
;
_virtio_dev_check
(
dev
);
dev
->
mmio_config
->
interrupt_ack
=
ack
;
status
=
dev
->
mmio_config
->
interrupt_status
;
if
(
status
!=
0
)
{
dev
->
mmio_config
->
interrupt_ack
=
status
;
}
}
rt_err_t
virtio_queue_init
(
struct
virtio_device
*
dev
,
rt_uint32_t
queue_index
,
rt_size_t
ring_size
)
...
...
@@ -105,6 +112,8 @@ rt_err_t virtio_queue_init(struct virtio_device *dev, rt_uint32_t queue_index, r
queue
->
free
[
i
]
=
RT_TRUE
;
}
queue
->
free_count
=
ring_size
;
return
RT_EOK
;
}
...
...
@@ -162,7 +171,6 @@ void virtio_submit_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_
rt_uint16_t
virtio_alloc_desc
(
struct
virtio_device
*
dev
,
rt_uint32_t
queue_index
)
{
int
i
;
rt_size_t
ring_size
;
struct
virtq
*
queue
;
_virtio_dev_check
(
dev
);
...
...
@@ -170,19 +178,24 @@ rt_uint16_t virtio_alloc_desc(struct virtio_device *dev, rt_uint32_t queue_index
RT_ASSERT
(
queue_index
<
RT_USING_VIRTIO_QUEUE_MAX_NR
);
queue
=
&
dev
->
queues
[
queue_index
];
ring_size
=
queue
->
num
;
for
(
i
=
0
;
i
<
ring_size
;
++
i
)
if
(
queue
->
free_count
>
0
)
{
if
(
queue
->
free
[
i
])
rt_size_t
ring_size
=
queue
->
num
;
for
(
i
=
0
;
i
<
ring_size
;
++
i
)
{
queue
->
free
[
i
]
=
RT_FALSE
;
if
(
queue
->
free
[
i
])
{
queue
->
free
[
i
]
=
RT_FALSE
;
queue
->
free_count
--
;
return
(
rt_uint16_t
)
i
;
return
(
rt_uint16_t
)
i
;
}
}
}
return
RT_UINT16_MAX
;
return
VIRTQ_INVALID_DESC_ID
;
}
void
virtio_free_desc
(
struct
virtio_device
*
dev
,
rt_uint32_t
queue_index
,
rt_uint16_t
desc_index
)
...
...
@@ -202,6 +215,8 @@ void virtio_free_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uin
queue
->
desc
[
desc_index
].
next
=
0
;
queue
->
free
[
desc_index
]
=
RT_TRUE
;
queue
->
free_count
++
;
}
rt_err_t
virtio_alloc_desc_chain
(
struct
virtio_device
*
dev
,
rt_uint32_t
queue_index
,
rt_size_t
count
,
...
...
@@ -213,11 +228,16 @@ rt_err_t virtio_alloc_desc_chain(struct virtio_device *dev, rt_uint32_t queue_in
RT_ASSERT
(
indexs
!=
RT_NULL
);
if
(
dev
->
queues
[
queue_index
].
free_count
<
count
)
{
return
-
RT_ERROR
;
}
for
(
i
=
0
;
i
<
count
;
++
i
)
{
indexs
[
i
]
=
virtio_alloc_desc
(
dev
,
queue_index
);
if
(
indexs
[
i
]
==
RT_UINT16_MAX
)
if
(
indexs
[
i
]
==
VIRTQ_INVALID_DESC_ID
)
{
for
(
j
=
0
;
j
<
i
;
++
j
)
{
...
...
bsp/qemu-virt64-aarch64/driver/virtio/virtio.h
浏览文件 @
8fa16f96
...
...
@@ -43,6 +43,7 @@
#define VIRTIO_F_RING_PACKED 34
#define VIRTIO_VA2PA(vaddr) ((rt_ubase_t)vaddr)
#define VIRTIO_PA2VA(paddr) ((rt_ubase_t)paddr)
#define VIRTIO_PAGE_SHIFT 12
#define VIRTIO_PAGE_SIZE (1 << VIRTIO_PAGE_SHIFT)
#define VIRTIO_PAGE_ALIGN(addr) (RT_ALIGN(addr, VIRTIO_PAGE_SIZE))
...
...
@@ -74,6 +75,25 @@ enum
VIRTIO_DEVICE_ID_PSTORE
=
22
,
/* Pstore device */
VIRTIO_DEVICE_ID_IOMMU
=
23
,
/* IOMMU device */
VIRTIO_DEVICE_ID_MEM
=
24
,
/* Memory device */
/* virtio 1.2 */
VIRTIO_DEVICE_ID_AUDIO
=
25
,
/* Audio device */
VIRTIO_DEVICE_ID_FS
=
26
,
/* File system device */
VIRTIO_DEVICE_ID_PMEM
=
27
,
/* PMEM device */
VIRTIO_DEVICE_ID_RPMB
=
28
,
/* RPMB device */
VIRTIO_DEVICE_ID_MAC80211_HWSIM
=
29
,
/* Mac80211 hwsim wireless simulation device */
VIRTIO_DEVICE_ID_VIDEO_ENCODER
=
30
,
/* Video encoder device */
VIRTIO_DEVICE_ID_VIDEO_DECODER
=
31
,
/* Video decoder device */
VIRTIO_DEVICE_ID_SCMI
=
32
,
/* SCMI device */
VIRTIO_DEVICE_ID_NITRO_SEC_MOD
=
33
,
/* NitroSecureModule */
VIRTIO_DEVICE_ID_I2C_ADAPTER
=
34
,
/* I2C adapter */
VIRTIO_DEVICE_ID_WATCHDOG
=
35
,
/* Watchdog */
VIRTIO_DEVICE_ID_CAN
=
36
,
/* CAN device */
VIRTIO_DEVICE_ID_DMABUF
=
37
,
/* Virtio dmabuf */
VIRTIO_DEVICE_ID_PARAM_SERV
=
38
,
/* Parameter Server */
VIRTIO_DEVICE_ID_AUDIO_POLICY
=
39
,
/* Audio policy device */
VIRTIO_DEVICE_ID_BT
=
40
,
/* Bluetooth device */
VIRTIO_DEVICE_ID_GPIO
=
41
,
/* GPIO device */
VIRTIO_DEVICE_ID_RDMA
=
42
,
/* RDMA device */
VIRTIO_DEVICE_TYPE_SIZE
};
...
...
@@ -101,7 +121,7 @@ typedef rt_err_t (*virtio_device_init_handler)(rt_ubase_t *mmio_base, rt_uint32_
void
virtio_reset_device
(
struct
virtio_device
*
dev
);
void
virtio_status_acknowledge_driver
(
struct
virtio_device
*
dev
);
void
virtio_status_driver_ok
(
struct
virtio_device
*
dev
);
void
virtio_interrupt_ack
(
struct
virtio_device
*
dev
,
rt_uint32_t
ack
);
void
virtio_interrupt_ack
(
struct
virtio_device
*
dev
);
rt_err_t
virtio_queue_init
(
struct
virtio_device
*
dev
,
rt_uint32_t
queue_index
,
rt_size_t
ring_size
);
void
virtio_queue_destroy
(
struct
virtio_device
*
dev
,
rt_uint32_t
queue_index
);
...
...
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c
浏览文件 @
8fa16f96
...
...
@@ -13,9 +13,10 @@
#include <rtthread.h>
#include <cpuport.h>
#ifdef BSP_USING_VIRTIO_BLK
#include <virtio_blk.h>
#ifdef BSP_USING_VIRTIO_BLK
static
void
virtio_blk_rw
(
struct
virtio_blk_device
*
virtio_blk_dev
,
rt_off_t
pos
,
void
*
buffer
,
int
flags
)
{
rt_uint16_t
idx
[
3
];
...
...
@@ -38,18 +39,18 @@ static void virtio_blk_rw(struct virtio_blk_device *virtio_blk_dev, rt_off_t pos
flags
=
flags
==
VIRTIO_BLK_T_OUT
?
0
:
VIRTQ_DESC_F_WRITE
;
virtio_fill_desc
(
virtio_dev
,
0
,
idx
[
0
],
virtio_fill_desc
(
virtio_dev
,
VIRTIO_BLK_QUEUE
,
idx
[
0
],
VIRTIO_VA2PA
(
&
virtio_blk_dev
->
info
[
idx
[
0
]].
req
),
sizeof
(
struct
virtio_blk_req
),
VIRTQ_DESC_F_NEXT
,
idx
[
1
]);
virtio_fill_desc
(
virtio_dev
,
0
,
idx
[
1
],
virtio_fill_desc
(
virtio_dev
,
VIRTIO_BLK_QUEUE
,
idx
[
1
],
VIRTIO_VA2PA
(
buffer
),
VIRTIO_BLK_BUF_DATA_SIZE
,
flags
|
VIRTQ_DESC_F_NEXT
,
idx
[
2
]);
virtio_fill_desc
(
virtio_dev
,
0
,
idx
[
2
],
VIRTIO_VA2PA
(
&
virtio_blk_dev
->
info
[
idx
[
0
]].
status
),
1
,
VIRTQ_DESC_F_WRITE
,
0
);
virtio_fill_desc
(
virtio_dev
,
VIRTIO_BLK_QUEUE
,
idx
[
2
],
VIRTIO_VA2PA
(
&
virtio_blk_dev
->
info
[
idx
[
0
]].
status
),
sizeof
(
rt_uint8_t
)
,
VIRTQ_DESC_F_WRITE
,
0
);
virtio_submit_chain
(
virtio_dev
,
0
,
idx
[
0
]);
virtio_submit_chain
(
virtio_dev
,
VIRTIO_BLK_QUEUE
,
idx
[
0
]);
virtio_queue_notify
(
virtio_dev
,
0
);
virtio_queue_notify
(
virtio_dev
,
VIRTIO_BLK_QUEUE
);
/* Wait for virtio_blk_isr() to done */
while
(
virtio_blk_dev
->
info
[
idx
[
0
]].
valid
)
...
...
@@ -64,7 +65,7 @@ static void virtio_blk_rw(struct virtio_blk_device *virtio_blk_dev, rt_off_t pos
#endif
}
virtio_free_desc_chain
(
virtio_dev
,
0
,
idx
[
0
]);
virtio_free_desc_chain
(
virtio_dev
,
VIRTIO_BLK_QUEUE
,
idx
[
0
]);
#ifdef RT_USING_SMP
rt_spin_unlock_irqrestore
(
&
virtio_dev
->
spinlock
,
level
);
...
...
@@ -104,10 +105,11 @@ static rt_err_t virtio_blk_control(rt_device_t dev, int cmd, void *args)
geometry
->
bytes_per_sector
=
VIRTIO_BLK_BYTES_PER_SECTOR
;
geometry
->
block_size
=
VIRTIO_BLK_BLOCK_SIZE
;
geometry
->
sector_count
=
virtio_blk_dev
->
virtio_dev
.
mmio_config
->
config
[
0
]
;
geometry
->
sector_count
=
virtio_blk_dev
->
config
->
capacity
;
}
break
;
default:
status
=
-
RT_EINVAL
;
break
;
}
...
...
@@ -129,19 +131,20 @@ static void virtio_blk_isr(int irqno, void *param)
rt_uint32_t
id
;
struct
virtio_blk_device
*
virtio_blk_dev
=
(
struct
virtio_blk_device
*
)
param
;
struct
virtio_device
*
virtio_dev
=
&
virtio_blk_dev
->
virtio_dev
;
struct
virtq
*
queue
=
&
virtio_dev
->
queues
[
VIRTIO_BLK_QUEUE
];
#ifdef RT_USING_SMP
rt_base_t
level
=
rt_spin_lock_irqsave
(
&
virtio_dev
->
spinlock
);
#endif
virtio_interrupt_ack
(
virtio_dev
,
virtio_dev
->
mmio_config
->
interrupt_status
&
0x3
);
virtio_interrupt_ack
(
virtio_dev
);
rt_hw_dsb
();
/* The device increments disk.used->idx when it adds an entry to the used ring */
while
(
virtio_dev
->
queues
[
0
].
used_idx
!=
virtio_dev
->
queues
[
0
].
used
->
idx
)
while
(
queue
->
used_idx
!=
queue
->
used
->
idx
)
{
rt_hw_dsb
();
id
=
virtio_dev
->
queues
[
0
].
used
->
ring
[
virtio_dev
->
queues
[
0
].
used_idx
%
VIRTIO_BLK_QUEUE_RING_SIZE
].
id
;
id
=
queue
->
used
->
ring
[
queue
->
used_idx
%
queue
->
num
].
id
;
RT_ASSERT
(
virtio_blk_dev
->
info
[
id
].
status
==
0
);
...
...
@@ -149,7 +152,7 @@ static void virtio_blk_isr(int irqno, void *param)
virtio_blk_dev
->
info
[
id
].
valid
=
RT_FALSE
;
rt_thread_yield
();
virtio_dev
->
queues
[
0
].
used_idx
++
;
queue
->
used_idx
++
;
}
#ifdef RT_USING_SMP
...
...
@@ -175,6 +178,8 @@ rt_err_t rt_virtio_blk_init(rt_ubase_t *mmio_base, rt_uint32_t irq)
virtio_dev
->
irq
=
irq
;
virtio_dev
->
mmio_base
=
mmio_base
;
virtio_blk_dev
->
config
=
(
struct
virtio_blk_config
*
)
virtio_dev
->
mmio_config
->
config
;
#ifdef RT_USING_SMP
rt_spin_lock_init
(
&
virtio_dev
->
spinlock
);
#endif
...
...
@@ -206,7 +211,7 @@ rt_err_t rt_virtio_blk_init(rt_ubase_t *mmio_base, rt_uint32_t irq)
virtio_blk_dev
->
parent
.
type
=
RT_Device_Class_Block
;
virtio_blk_dev
->
parent
.
ops
=
&
virtio_blk_ops
;
rt_snprintf
(
dev_name
,
RT_NAME_MAX
,
"
%s%d"
,
"virtio-blk
"
,
dev_no
++
);
rt_snprintf
(
dev_name
,
RT_NAME_MAX
,
"
virtio-blk%d
"
,
dev_no
++
);
rt_hw_interrupt_install
(
irq
,
virtio_blk_isr
,
virtio_blk_dev
,
dev_name
);
rt_hw_interrupt_umask
(
irq
);
...
...
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h
浏览文件 @
8fa16f96
...
...
@@ -16,6 +16,7 @@
#include <virtio.h>
#define VIRTIO_BLK_QUEUE 0
#define VIRTIO_BLK_BUF_DATA_SIZE 512
#define VIRTIO_BLK_BYTES_PER_SECTOR 512
#define VIRTIO_BLK_BLOCK_SIZE 512
...
...
@@ -40,12 +41,56 @@ struct virtio_blk_req
rt_uint64_t
sector
;
};
struct
virtio_blk_config
{
rt_uint64_t
capacity
;
rt_uint32_t
size_max
;
rt_uint32_t
seg_max
;
struct
virtio_blk_geometry
{
rt_uint16_t
cylinders
;
rt_uint8_t
heads
;
rt_uint8_t
sectors
;
}
geometry
;
rt_uint32_t
blk_size
;
struct
virtio_blk_topology
{
/* # Of logical blocks per physical block (log2) */
rt_uint8_t
physical_block_exp
;
/* Offset of first aligned logical block */
rt_uint8_t
alignment_offset
;
/* Suggested minimum I/O size in blocks */
rt_uint16_t
min_io_size
;
/* Optimal (suggested maximum) I/O size in blocks */
rt_uint32_t
opt_io_size
;
}
topology
;
rt_uint8_t
writeback
;
rt_uint8_t
unused0
;
rt_uint16_t
num_queues
;
rt_uint32_t
max_discard_sectors
;
rt_uint32_t
max_discard_seg
;
rt_uint32_t
discard_sector_alignment
;
rt_uint32_t
max_write_zeroes_sectors
;
rt_uint32_t
max_write_zeroes_seg
;
rt_uint8_t
write_zeroes_may_unmap
;
rt_uint8_t
unused1
[
3
];
rt_uint32_t
max_secure_erase_sectors
;
rt_uint32_t
max_secure_erase_seg
;
rt_uint32_t
secure_erase_sector_alignment
;
}
__attribute__
((
packed
));
struct
virtio_blk_device
{
struct
rt_device
parent
;
struct
virtio_device
virtio_dev
;
struct
virtio_blk_config
*
config
;
struct
{
rt_bool_t
valid
;
...
...
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.c
0 → 100644
浏览文件 @
8fa16f96
此差异已折叠。
点击以展开。
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.h
0 → 100644
浏览文件 @
8fa16f96
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-11 GuEe-GUI the first version
*/
#ifndef __VIRTIO_GPU_H__
#define __VIRTIO_GPU_H__
#include <rtdef.h>
#include <virtio.h>
#define VIRTIO_GPU_QUEUE_CTRL 0
#define VIRTIO_GPU_QUEUE_CURSOR 1
#define VIRTIO_GPU_QUEUE_SIZE 32
#define VIRTIO_GPU_F_VIRGL 0
/* VIRTIO_GPU_CMD_CTX_*, VIRTIO_GPU_CMD_*_3D */
#define VIRTIO_GPU_F_EDID 1
/* VIRTIO_GPU_CMD_GET_EDID */
#define VIRTIO_GPU_F_RESOURCE_UUID 2
/* VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID */
#define VIRTIO_GPU_F_RESOURCE_BLOB 3
/* VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB */
#define VIRTIO_GPU_F_CONTEXT_INIT 4
/* VIRTIO_GPU_CMD_CREATE_CONTEXT with context_init and multiple timelines */
#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0)
#define VIRTIO_GPU_FORMAT_BPP 32
#define VIRTIO_GPU_FORMAT_PIXEL 4
#define VIRTIO_GPU_CURSOR_WIDTH 64
#define VIRTIO_GPU_CURSOR_HEIGHT 64
#define VIRTIO_GPU_CURSOR_IMG_SIZE (VIRTIO_GPU_CURSOR_WIDTH * VIRTIO_GPU_CURSOR_HEIGHT * VIRTIO_GPU_FORMAT_PIXEL)
#define VIRTIO_GPU_INVALID_PMODE_ID RT_UINT32_MAX
/* GPU control */
struct
virtio_gpu_config
{
rt_uint32_t
events_read
;
rt_uint32_t
events_clear
;
rt_uint32_t
num_scanouts
;
/* 1 ~ 16 */
rt_uint32_t
reserved
;
};
enum
virtio_gpu_ctrl_type
{
VIRTIO_GPU_UNDEFINED
=
0
,
/* 2d commands */
VIRTIO_GPU_CMD_GET_DISPLAY_INFO
=
0x0100
,
VIRTIO_GPU_CMD_RESOURCE_CREATE_2D
,
VIRTIO_GPU_CMD_RESOURCE_UNREF
,
VIRTIO_GPU_CMD_SET_SCANOUT
,
VIRTIO_GPU_CMD_RESOURCE_FLUSH
,
VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D
,
VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING
,
VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING
,
VIRTIO_GPU_CMD_GET_CAPSET_INFO
,
VIRTIO_GPU_CMD_GET_CAPSET
,
VIRTIO_GPU_CMD_GET_EDID
,
VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID
,
VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB
,
VIRTIO_GPU_CMD_SET_SCANOUT_BLOB
,
/* 3d commands */
VIRTIO_GPU_CMD_CTX_CREATE
=
0x0200
,
VIRTIO_GPU_CMD_CTX_DESTROY
,
VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE
,
VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE
,
VIRTIO_GPU_CMD_RESOURCE_CREATE_3D
,
VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D
,
VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D
,
VIRTIO_GPU_CMD_SUBMIT_3D
,
VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB
,
VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB
,
/* cursor commands */
VIRTIO_GPU_CMD_UPDATE_CURSOR
=
0x0300
,
VIRTIO_GPU_CMD_MOVE_CURSOR
,
/* success responses */
VIRTIO_GPU_RESP_OK_NODATA
=
0x1100
,
VIRTIO_GPU_RESP_OK_DISPLAY_INFO
,
VIRTIO_GPU_RESP_OK_CAPSET_INFO
,
VIRTIO_GPU_RESP_OK_CAPSET
,
VIRTIO_GPU_RESP_OK_EDID
,
VIRTIO_GPU_RESP_OK_RESOURCE_UUID
,
VIRTIO_GPU_RESP_OK_MAP_INFO
,
/* error responses */
VIRTIO_GPU_RESP_ERR_UNSPEC
=
0x1200
,
VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY
,
VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID
,
VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID
,
VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID
,
VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER
,
};
#define VIRTIO_GPU_FLAG_FENCE (1 << 0)
struct
virtio_gpu_ctrl_hdr
{
rt_uint32_t
type
;
rt_uint32_t
flags
;
rt_uint64_t
fence_id
;
rt_uint32_t
ctx_id
;
rt_uint8_t
ring_idx
;
rt_uint8_t
padding
[
3
];
};
#define VIRTIO_GPU_MAX_SCANOUTS 16
struct
virtio_gpu_rect
{
rt_uint32_t
x
;
rt_uint32_t
y
;
rt_uint32_t
width
;
rt_uint32_t
height
;
};
struct
virtio_gpu_resp_display_info
{
struct
virtio_gpu_ctrl_hdr
hdr
;
struct
virtio_gpu_display_one
{
struct
virtio_gpu_rect
r
;
rt_uint32_t
enabled
;
rt_uint32_t
flags
;
}
pmodes
[
VIRTIO_GPU_MAX_SCANOUTS
];
};
struct
virtio_gpu_get_edid
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
scanout
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_resp_edid
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
size
;
rt_uint32_t
padding
;
rt_uint8_t
edid
[
1024
];
};
enum
virtio_gpu_formats
{
VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM
=
1
,
VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM
=
2
,
VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM
=
3
,
VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM
=
4
,
VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM
=
67
,
VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM
=
68
,
VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM
=
121
,
VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM
=
134
,
};
struct
virtio_gpu_resource_create_2d
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
format
;
rt_uint32_t
width
;
rt_uint32_t
height
;
};
struct
virtio_gpu_resource_unref
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_set_scanout
{
struct
virtio_gpu_ctrl_hdr
hdr
;
struct
virtio_gpu_rect
r
;
rt_uint32_t
scanout_id
;
rt_uint32_t
resource_id
;
};
struct
virtio_gpu_resource_flush
{
struct
virtio_gpu_ctrl_hdr
hdr
;
struct
virtio_gpu_rect
r
;
rt_uint32_t
resource_id
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_transfer_to_host_2d
{
struct
virtio_gpu_ctrl_hdr
hdr
;
struct
virtio_gpu_rect
r
;
rt_uint64_t
offset
;
rt_uint32_t
resource_id
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_resource_attach_backing
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
nr_entries
;
};
struct
virtio_gpu_mem_entry
{
rt_uint64_t
addr
;
rt_uint32_t
length
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_resource_detach_backing
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_get_capset_info
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
capset_index
;
rt_uint32_t
padding
;
};
#define VIRTIO_GPU_CAPSET_VIRGL 1
#define VIRTIO_GPU_CAPSET_VIRGL2 2
#define VIRTIO_GPU_CAPSET_GFXSTREAM 3
#define VIRTIO_GPU_CAPSET_VENUS 4
#define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5
struct
virtio_gpu_resp_capset_info
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
capset_id
;
rt_uint32_t
capset_max_version
;
rt_uint32_t
capset_max_size
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_get_capset
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
capset_id
;
rt_uint32_t
capset_version
;
};
struct
virtio_gpu_resp_capset
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint8_t
capset_data
[];
};
struct
virtio_gpu_resource_assign_uuid
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_resp_resource_uuid
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint8_t
uuid
[
16
];
};
#define VIRTIO_GPU_BLOB_MEM_GUEST 0x0001
#define VIRTIO_GPU_BLOB_MEM_HOST3D 0x0002
#define VIRTIO_GPU_BLOB_MEM_HOST3D_GUEST 0x0003
#define VIRTIO_GPU_BLOB_FLAG_USE_MAPPABLE 0x0001
#define VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE 0x0002
#define VIRTIO_GPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004
struct
virtio_gpu_resource_create_blob
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
blob_mem
;
rt_uint32_t
blob_flags
;
rt_uint32_t
nr_entries
;
rt_uint64_t
blob_id
;
rt_uint64_t
size
;
};
struct
virtio_gpu_set_scanout_blob
{
struct
virtio_gpu_ctrl_hdr
hdr
;
struct
virtio_gpu_rect
r
;
rt_uint32_t
scanout_id
;
rt_uint32_t
resource_id
;
rt_uint32_t
width
;
rt_uint32_t
height
;
rt_uint32_t
format
;
rt_uint32_t
padding
;
rt_uint32_t
strides
[
4
];
rt_uint32_t
offsets
[
4
];
};
#define VIRTIO_GPU_CONTEXT_INIT_CAPSET_ID_MASK 0x000000ff
struct
virtio_gpu_ctx_create
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
nlen
;
rt_uint32_t
context_init
;
char
debug_name
[
64
];
};
struct
virtio_gpu_resource_map_blob
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
padding
;
rt_uint64_t
offset
;
};
#define VIRTIO_GPU_MAP_CACHE_MASK 0x0f
#define VIRTIO_GPU_MAP_CACHE_NONE 0x00
#define VIRTIO_GPU_MAP_CACHE_CACHED 0x01
#define VIRTIO_GPU_MAP_CACHE_UNCACHED 0x02
#define VIRTIO_GPU_MAP_CACHE_WC 0x03
struct
virtio_gpu_resp_map_info
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
map_info
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_resource_unmap_blob
{
struct
virtio_gpu_ctrl_hdr
hdr
;
rt_uint32_t
resource_id
;
rt_uint32_t
padding
;
};
/* GPU cursor */
struct
virtio_gpu_cursor_pos
{
rt_uint32_t
scanout_id
;
rt_uint32_t
x
;
rt_uint32_t
y
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_update_cursor
{
struct
virtio_gpu_ctrl_hdr
hdr
;
struct
virtio_gpu_cursor_pos
pos
;
rt_uint32_t
resource_id
;
rt_uint32_t
hot_x
;
rt_uint32_t
hot_y
;
rt_uint32_t
padding
;
};
struct
virtio_gpu_device
{
struct
rt_device
parent
;
struct
virtio_device
virtio_dev
;
/* Current display's info */
struct
virtio_gpu_display_one
pmode
;
enum
virtio_gpu_formats
format
;
rt_uint32_t
pmode_id
;
rt_uint32_t
cursor_x
,
cursor_y
;
rt_uint32_t
display_resource_id
;
rt_uint32_t
cursor_resource_id
;
rt_uint32_t
next_resource_id
;
/* Display framebuffer */
struct
rt_mutex
rw_mutex
;
void
*
framebuffer
;
rt_uint32_t
smem_len
;
/* Cursor image info */
rt_bool_t
cursor_enable
;
struct
rt_mutex
ops_mutex
;
rt_uint8_t
cursor_img
[
VIRTIO_GPU_CURSOR_IMG_SIZE
];
/* GPU request info */
struct
virtio_gpu_resp_display_info
gpu_request
;
struct
{
rt_bool_t
ctrl_valid
;
rt_bool_t
cursor_valid
;
struct
virtio_gpu_update_cursor
cursor_cmd
;
}
info
[
VIRTIO_GPU_QUEUE_SIZE
];
};
rt_err_t
rt_virtio_gpu_init
(
rt_ubase_t
*
mmio_base
,
rt_uint32_t
irq
);
enum
{
VIRTIO_DEVICE_CTRL_GPU_SET_PRIMARY
=
0x20
,
VIRTIO_DEVICE_CTRL_GPU_CREATE_2D
,
VIRTIO_DEVICE_CTRL_CURSOR_SETUP
,
VIRTIO_DEVICE_CTRL_CURSOR_SET_IMG
,
VIRTIO_DEVICE_CTRL_CURSOR_MOVE
,
};
#endif
/* __VIRTIO_GPU_H__ */
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.c
0 → 100644
浏览文件 @
8fa16f96
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-11 GuEe-GUI the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <cpuport.h>
#ifdef BSP_USING_VIRTIO_INPUT
#include <virtio_input.h>
static
void
_set_bit
(
rt_uint32_t
nr
,
volatile
rt_ubase_t
*
addr
)
{
rt_ubase_t
mask
=
BIT_MASK
(
nr
);
rt_ubase_t
*
p
=
((
rt_ubase_t
*
)
addr
)
+
BIT_WORD
(
nr
);
*
p
|=
mask
;
}
static
rt_size_t
virtio_input_cfg_select
(
struct
virtio_input_device
*
virtio_input_dev
,
rt_uint8_t
select
,
rt_uint8_t
subsel
)
{
struct
virtio_input_config
*
config
=
virtio_input_dev
->
config
;
rt_hw_dsb
();
config
->
select
=
select
;
config
->
subsel
=
subsel
;
rt_hw_dsb
();
return
config
->
size
;
}
static
void
virtio_input_cfg_bits
(
struct
virtio_input_device
*
virtio_input_dev
,
rt_uint8_t
select
,
rt_uint8_t
subsel
,
rt_ubase_t
*
bits
,
rt_uint32_t
bitcount
)
{
int
i
;
rt_uint32_t
bit
;
rt_uint8_t
bytes
;
rt_uint8_t
*
virtio_bits
;
void
*
config_base
=
virtio_input_dev
->
config
;
rt_off_t
offset
=
(
rt_size_t
)
&
((
struct
virtio_input_config
*
)
0
)
->
bitmap
;
bytes
=
virtio_input_cfg_select
(
virtio_input_dev
,
select
,
subsel
);
if
(
bytes
==
0
)
{
return
;
}
if
(
bitcount
>
bytes
*
8
)
{
bitcount
=
bytes
*
8
;
}
/*
* Bitmap in virtio config space is a simple stream of bytes,
* with the first byte carrying bits 0-7, second bits 8-15 and
* so on.
*/
virtio_bits
=
rt_malloc
(
bytes
);
if
(
virtio_bits
==
RT_NULL
)
{
return
;
}
for
(
i
=
0
;
i
<
bytes
;
++
i
)
{
void
*
buffer
=
(
void
*
)
virtio_bits
+
i
;
if
(
virtio_input_dev
->
virtio_dev
.
mmio_config
->
version
==
1
)
{
HWREG8
(
config_base
+
offset
+
i
)
=
*
((
rt_uint8_t
*
)
buffer
);
}
else
{
rt_memcpy
(
config_base
+
offset
+
i
,
buffer
,
sizeof
(
rt_uint8_t
));
}
}
for
(
bit
=
0
;
bit
<
bitcount
;
++
bit
)
{
if
(
virtio_bits
[
bit
/
8
]
&
(
1
<<
(
bit
%
8
)))
{
_set_bit
(
bit
,
bits
);
}
}
rt_free
(
virtio_bits
);
if
(
select
==
VIRTIO_INPUT_CFG_EV_BITS
)
{
_set_bit
(
subsel
,
virtio_input_dev
->
ev_bit
);
}
}
static
rt_err_t
virtio_input_init
(
rt_device_t
dev
)
{
int
i
;
rt_uint16_t
idx
[
VIRTIO_INPUT_QUEUE_MAX_SIZE
];
struct
virtio_input_device
*
virtio_input_dev
=
(
struct
virtio_input_device
*
)
dev
;
struct
virtio_device
*
virtio_dev
=
&
virtio_input_dev
->
virtio_dev
;
struct
virtq
*
queue_event
,
*
queue_status
;
virtio_input_cfg_bits
(
virtio_input_dev
,
VIRTIO_INPUT_CFG_EV_BITS
,
EV_KEY
,
virtio_input_dev
->
key_bit
,
KEY_CNT
);
virtio_input_cfg_bits
(
virtio_input_dev
,
VIRTIO_INPUT_CFG_EV_BITS
,
EV_REL
,
virtio_input_dev
->
rel_bit
,
REL_CNT
);
virtio_input_cfg_bits
(
virtio_input_dev
,
VIRTIO_INPUT_CFG_EV_BITS
,
EV_ABS
,
virtio_input_dev
->
abs_bit
,
ABS_CNT
);
queue_event
=
&
virtio_dev
->
queues
[
VIRTIO_INPUT_QUEUE_EVENT
];
queue_status
=
&
virtio_dev
->
queues
[
VIRTIO_INPUT_QUEUE_STATUS
];
virtio_alloc_desc_chain
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
,
queue_event
->
num
,
idx
);
virtio_alloc_desc_chain
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_STATUS
,
queue_status
->
num
,
idx
);
for
(
i
=
0
;
i
<
queue_event
->
num
;
++
i
)
{
rt_uint16_t
id
=
i
;
void
*
addr
=
&
virtio_input_dev
->
recv_events
[
i
];
virtio_fill_desc
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
,
id
,
VIRTIO_VA2PA
(
addr
),
sizeof
(
struct
virtio_input_event
),
VIRTQ_DESC_F_WRITE
,
0
);
virtio_submit_chain
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
,
id
);
}
rt_hw_dsb
();
queue_event
->
avail
->
flags
=
0
;
queue_status
->
avail
->
flags
=
VIRTQ_AVAIL_F_NO_INTERRUPT
;
virtio_queue_notify
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
);
return
RT_EOK
;
}
static
rt_size_t
virtio_input_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
struct
virtio_input_device
*
virtio_input_dev
=
(
struct
virtio_input_device
*
)
dev
;
if
(
buffer
==
RT_NULL
||
pos
+
size
>=
virtio_input_dev
->
virtio_dev
.
queues
[
VIRTIO_INPUT_QUEUE_EVENT
].
num
)
{
return
0
;
}
rt_mutex_take
(
&
virtio_input_dev
->
rw_mutex
,
RT_WAITING_FOREVER
);
rt_memcpy
(
buffer
,
&
virtio_input_dev
->
bcst_events
[
pos
],
size
);
rt_mutex_release
(
&
virtio_input_dev
->
rw_mutex
);
return
size
;
}
static
rt_size_t
virtio_input_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
struct
virtio_input_device
*
virtio_input_dev
=
(
struct
virtio_input_device
*
)
dev
;
if
(
buffer
==
RT_NULL
||
pos
+
size
>=
virtio_input_dev
->
virtio_dev
.
queues
[
VIRTIO_INPUT_QUEUE_EVENT
].
num
)
{
return
0
;
}
rt_mutex_take
(
&
virtio_input_dev
->
rw_mutex
,
RT_WAITING_FOREVER
);
rt_memcpy
(
&
virtio_input_dev
->
bcst_events
[
pos
],
buffer
,
size
);
rt_mutex_release
(
&
virtio_input_dev
->
rw_mutex
);
return
size
;
}
static
rt_err_t
virtio_input_control
(
rt_device_t
dev
,
int
cmd
,
void
*
args
)
{
rt_err_t
status
=
RT_EOK
;
struct
virtio_input_device
*
virtio_input_dev
=
(
struct
virtio_input_device
*
)
dev
;
struct
virtio_device
*
virtio_dev
=
&
virtio_input_dev
->
virtio_dev
;
struct
virtio_input_config
*
config
=
virtio_input_dev
->
config
;
if
(
args
==
RT_NULL
)
{
return
-
RT_ERROR
;
}
switch
(
cmd
)
{
case
VIRTIO_DEVICE_CTRL_INPUT_GET_TYPE
:
*
(
enum
virtio_input_type
*
)
args
=
virtio_input_dev
->
type
;
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_BIND_BSCT_HANDLER
:
virtio_input_dev
->
bsct_handler
=
args
;
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_X_INFO
:
virtio_input_cfg_select
(
virtio_input_dev
,
VIRTIO_INPUT_CFG_ABS_INFO
,
VIRTIO_INPUT_ABS_AXIS_X
);
rt_memcpy
(
args
,
config
,
sizeof
(
struct
virtio_input_config
));
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_Y_INFO
:
virtio_input_cfg_select
(
virtio_input_dev
,
VIRTIO_INPUT_CFG_ABS_INFO
,
VIRTIO_INPUT_ABS_AXIS_Y
);
rt_memcpy
(
args
,
config
,
sizeof
(
struct
virtio_input_config
));
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_SET_STATUS
:
{
rt_uint16_t
id
;
void
*
addr
;
struct
virtq
*
queue_status
=
&
virtio_dev
->
queues
[
VIRTIO_INPUT_QUEUE_STATUS
];
#ifdef RT_USING_SMP
rt_base_t
level
=
rt_spin_lock_irqsave
(
&
virtio_dev
->
spinlock
);
#endif
id
=
queue_status
->
avail
->
idx
%
queue_status
->
num
;
addr
=
&
virtio_input_dev
->
xmit_events
[
id
];
rt_memcpy
(
addr
,
args
,
sizeof
(
struct
virtio_input_event
));
virtio_free_desc
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_STATUS
,
id
);
virtio_fill_desc
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_STATUS
,
id
,
VIRTIO_VA2PA
(
addr
),
sizeof
(
struct
virtio_input_event
),
0
,
0
);
virtio_submit_chain
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_STATUS
,
id
);
virtio_queue_notify
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_STATUS
);
virtio_alloc_desc
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_STATUS
);
#ifdef RT_USING_SMP
rt_spin_unlock_irqrestore
(
&
virtio_dev
->
spinlock
,
level
);
#endif
}
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_GET_EV_BIT
:
rt_memcpy
(
args
,
virtio_input_dev
->
ev_bit
,
sizeof
(
virtio_input_dev
->
ev_bit
));
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_GET_KEY_BIT
:
rt_memcpy
(
args
,
virtio_input_dev
->
key_bit
,
sizeof
(
virtio_input_dev
->
key_bit
));
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_GET_REL_BIT
:
rt_memcpy
(
args
,
virtio_input_dev
->
rel_bit
,
sizeof
(
virtio_input_dev
->
rel_bit
));
break
;
case
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_BIT
:
rt_memcpy
(
args
,
virtio_input_dev
->
abs_bit
,
sizeof
(
virtio_input_dev
->
abs_bit
));
break
;
default:
status
=
-
RT_EINVAL
;
break
;
}
return
status
;
}
const
static
struct
rt_device_ops
virtio_input_ops
=
{
virtio_input_init
,
RT_NULL
,
RT_NULL
,
virtio_input_read
,
virtio_input_write
,
virtio_input_control
};
static
void
virtio_input_isr
(
int
irqno
,
void
*
param
)
{
struct
virtio_input_device
*
virtio_input_dev
=
(
struct
virtio_input_device
*
)
param
;
struct
virtio_device
*
virtio_dev
=
&
virtio_input_dev
->
virtio_dev
;
struct
virtq
*
event_queue
=
&
virtio_dev
->
queues
[
VIRTIO_INPUT_QUEUE_EVENT
];
const
char
*
dev_name
=
virtio_input_dev
->
parent
.
parent
.
name
;
#ifdef RT_USING_SMP
rt_base_t
level
=
rt_spin_lock_irqsave
(
&
virtio_dev
->
spinlock
);
#endif
virtio_interrupt_ack
(
virtio_dev
);
rt_hw_dsb
();
while
(
event_queue
->
used_idx
!=
event_queue
->
used
->
idx
)
{
rt_uint16_t
id
=
event_queue
->
used
->
ring
[
event_queue
->
used_idx
%
event_queue
->
num
].
id
;
rt_uint32_t
len
=
event_queue
->
used
->
ring
[
event_queue
->
used_idx
%
event_queue
->
num
].
len
;
if
(
len
==
sizeof
(
struct
virtio_input_event
))
{
struct
virtio_input_event
*
recv_events
=
&
virtio_input_dev
->
recv_events
[
id
];
struct
virtio_input_event
*
bcst_events
=
&
virtio_input_dev
->
bcst_events
[
id
];
if
(
recv_events
->
type
>=
EV_SYN
&&
recv_events
->
type
<=
EV_ABS
)
{
bcst_events
->
type
=
recv_events
->
type
;
bcst_events
->
code
=
recv_events
->
code
;
bcst_events
->
value
=
recv_events
->
value
;
if
(
virtio_input_dev
->
bsct_handler
!=
RT_NULL
)
{
virtio_input_dev
->
bsct_handler
(
*
bcst_events
);
}
}
else
{
rt_kprintf
(
"%s: Unsupport event[type: %02x, code: %02x, value: %08x]!
\n
"
,
dev_name
,
recv_events
->
type
,
recv_events
->
code
,
recv_events
->
value
);
}
}
else
{
rt_kprintf
(
"%s: Invalid event!
\n
"
,
dev_name
);
}
event_queue
->
used_idx
++
;
virtio_submit_chain
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
,
id
);
virtio_queue_notify
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
);
}
#ifdef RT_USING_SMP
rt_spin_unlock_irqrestore
(
&
virtio_dev
->
spinlock
,
level
);
#endif
}
rt_err_t
rt_virtio_input_init
(
rt_ubase_t
*
mmio_base
,
rt_uint32_t
irq
)
{
rt_uint32_t
flag
;
static
int
dev_no
=
0
;
char
dev_name
[
RT_NAME_MAX
];
struct
virtio_device
*
virtio_dev
;
struct
virtio_input_device
*
virtio_input_dev
;
virtio_input_dev
=
rt_malloc
(
sizeof
(
struct
virtio_input_device
));
if
(
virtio_input_dev
==
RT_NULL
)
{
goto
_alloc_fail
;
}
virtio_dev
=
&
virtio_input_dev
->
virtio_dev
;
virtio_dev
->
irq
=
irq
;
virtio_dev
->
mmio_base
=
mmio_base
;
virtio_input_dev
->
config
=
(
struct
virtio_input_config
*
)
virtio_dev
->
mmio_config
->
config
;
virtio_input_dev
->
bsct_handler
=
RT_NULL
;
#ifdef RT_USING_SMP
rt_spin_lock_init
(
&
virtio_dev
->
spinlock
);
#endif
virtio_reset_device
(
virtio_dev
);
virtio_status_acknowledge_driver
(
virtio_dev
);
virtio_dev
->
mmio_config
->
driver_features
=
virtio_dev
->
mmio_config
->
device_features
&
~
(
(
1
<<
VIRTIO_F_RING_EVENT_IDX
)
|
(
1
<<
VIRTIO_F_RING_INDIRECT_DESC
));
virtio_status_driver_ok
(
virtio_dev
);
if
(
virtio_queue_init
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
,
VIRTIO_INPUT_EVENT_QUEUE_SIZE
)
!=
RT_EOK
)
{
goto
_alloc_fail
;
}
if
(
virtio_queue_init
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_STATUS
,
VIRTIO_INPUT_STATUS_QUEUE_SIZE
)
!=
RT_EOK
)
{
virtio_queue_destroy
(
virtio_dev
,
VIRTIO_INPUT_QUEUE_EVENT
);
goto
_alloc_fail
;
}
virtio_input_cfg_select
(
virtio_input_dev
,
VIRTIO_INPUT_CFG_ID_DEVIDS
,
0
);
if
(
virtio_input_dev
->
config
->
ids
.
product
==
EV_ABS
)
{
virtio_input_dev
->
type
=
VIRTIO_INPUT_TYPE_TABLET
;
virtio_input_dev
->
parent
.
type
=
RT_Device_Class_Touch
;
flag
=
RT_DEVICE_FLAG_STANDALONE
|
RT_DEVICE_FLAG_INT_RX
;
}
else
{
if
(
virtio_input_dev
->
config
->
ids
.
product
==
EV_KEY
)
{
virtio_input_dev
->
type
=
VIRTIO_INPUT_TYPE_KEYBOARD
;
}
else
{
virtio_input_dev
->
type
=
VIRTIO_INPUT_TYPE_MOUSE
;
}
/* Replace it to "KeyBoard" or "Mouse" if support in the future */
virtio_input_dev
->
parent
.
type
=
RT_Device_Class_Miscellaneous
;
flag
=
RT_DEVICE_FLAG_RDWR
;
}
virtio_input_dev
->
parent
.
ops
=
&
virtio_input_ops
;
rt_snprintf
(
dev_name
,
RT_NAME_MAX
,
"virtio-input%d"
,
dev_no
++
);
rt_mutex_init
(
&
virtio_input_dev
->
rw_mutex
,
dev_name
,
RT_IPC_FLAG_PRIO
);
rt_hw_interrupt_install
(
irq
,
virtio_input_isr
,
virtio_input_dev
,
dev_name
);
rt_hw_interrupt_umask
(
irq
);
return
rt_device_register
((
rt_device_t
)
virtio_input_dev
,
dev_name
,
flag
);
_alloc_fail:
if
(
virtio_input_dev
!=
RT_NULL
)
{
rt_free
(
virtio_input_dev
);
}
return
-
RT_ENOMEM
;
}
#endif
/* BSP_USING_VIRTIO_INPUT */
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.h
0 → 100644
浏览文件 @
8fa16f96
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-11 GuEe-GUI the first version
*/
#ifndef __VIRTIO_INPUT_H__
#define __VIRTIO_INPUT_H__
#include <rtdef.h>
#include <virtio.h>
#include <virtio_input_event_codes.h>
#define VIRTIO_INPUT_QUEUE_EVENT 0
#define VIRTIO_INPUT_QUEUE_STATUS 1
#define VIRTIO_INPUT_EVENT_QUEUE_SIZE 64
#define VIRTIO_INPUT_STATUS_QUEUE_SIZE 8
#define VIRTIO_INPUT_QUEUE_MAX_SIZE (VIRTIO_INPUT_EVENT_QUEUE_SIZE > VIRTIO_INPUT_STATUS_QUEUE_SIZE ? \
VIRTIO_INPUT_EVENT_QUEUE_SIZE : VIRTIO_INPUT_STATUS_QUEUE_SIZE)
#define VIRTIO_INPUT_ABS_AXIS_X 0
#define VIRTIO_INPUT_ABS_AXIS_Y 1
enum
virtio_input_type
{
VIRTIO_INPUT_TYPE_KEYBOARD
,
VIRTIO_INPUT_TYPE_MOUSE
,
VIRTIO_INPUT_TYPE_TABLET
,
VIRTIO_INPUT_TYPE_SIZE
,
};
enum
virtio_input_config_select
{
VIRTIO_INPUT_CFG_UNSET
=
0x00
,
VIRTIO_INPUT_CFG_ID_NAME
=
0x01
,
VIRTIO_INPUT_CFG_ID_SERIAL
=
0x02
,
VIRTIO_INPUT_CFG_ID_DEVIDS
=
0x03
,
VIRTIO_INPUT_CFG_PROP_BITS
=
0x10
,
VIRTIO_INPUT_CFG_EV_BITS
=
0x11
,
VIRTIO_INPUT_CFG_ABS_INFO
=
0x12
,
};
struct
virtio_input_absinfo
{
rt_uint32_t
min
;
/* Minimum value for the axis */
rt_uint32_t
max
;
/* Maximum value for the axis */
rt_uint32_t
fuzz
;
/* Fuzz value that is used to filter noise from the event stream */
rt_uint32_t
flat
;
/* Within this value will be discarded by joydev interface and reported as 0 instead */
rt_uint32_t
res
;
/* Resolution for the values reported for the axis */
};
struct
virtio_input_devids
{
rt_uint16_t
bustype
;
rt_uint16_t
vendor
;
rt_uint16_t
product
;
rt_uint16_t
version
;
};
struct
virtio_input_config
{
rt_uint8_t
select
;
rt_uint8_t
subsel
;
rt_uint8_t
size
;
rt_uint8_t
reserved
[
5
];
union
{
char
string
[
128
];
rt_uint8_t
bitmap
[
128
];
struct
virtio_input_absinfo
abs
;
struct
virtio_input_devids
ids
;
};
}
__attribute__
((
packed
));
struct
virtio_input_event
{
rt_uint16_t
type
;
rt_uint16_t
code
;
rt_uint32_t
value
;
};
#ifdef ARCH_CPU_64BIT
#define BITS_PER_LONG 64
#else
#define BITS_PER_LONG 32
#endif
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BITS_PER_BYTE 8
#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
struct
virtio_input_device
{
struct
rt_device
parent
;
struct
virtio_device
virtio_dev
;
rt_ubase_t
ev_bit
[
BITS_TO_LONGS
(
EV_CNT
)];
rt_ubase_t
key_bit
[
BITS_TO_LONGS
(
KEY_CNT
)];
rt_ubase_t
rel_bit
[
BITS_TO_LONGS
(
REL_CNT
)];
rt_ubase_t
abs_bit
[
BITS_TO_LONGS
(
ABS_CNT
)];
enum
virtio_input_type
type
;
struct
virtio_input_config
*
config
;
/* Broadcast events */
struct
rt_mutex
rw_mutex
;
void
(
*
bsct_handler
)(
struct
virtio_input_event
event
);
struct
virtio_input_event
bcst_events
[
VIRTIO_INPUT_EVENT_QUEUE_SIZE
];
/* Receive events */
struct
virtio_input_event
recv_events
[
VIRTIO_INPUT_EVENT_QUEUE_SIZE
];
/* Transmit status */
struct
virtio_input_event
xmit_events
[
VIRTIO_INPUT_STATUS_QUEUE_SIZE
];
};
enum
{
VIRTIO_DEVICE_CTRL_INPUT_GET_TYPE
=
0x20
,
VIRTIO_DEVICE_CTRL_INPUT_BIND_BSCT_HANDLER
,
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_X_INFO
,
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_Y_INFO
,
VIRTIO_DEVICE_CTRL_INPUT_SET_STATUS
,
VIRTIO_DEVICE_CTRL_INPUT_GET_EV_BIT
,
VIRTIO_DEVICE_CTRL_INPUT_GET_KEY_BIT
,
VIRTIO_DEVICE_CTRL_INPUT_GET_REL_BIT
,
VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_BIT
,
};
rt_err_t
rt_virtio_input_init
(
rt_ubase_t
*
mmio_base
,
rt_uint32_t
irq
);
#endif
/* __VIRTIO_INPUT_H__ */
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input_event_codes.h
0 → 100644
浏览文件 @
8fa16f96
此差异已折叠。
点击以展开。
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.c
0 → 100644
浏览文件 @
8fa16f96
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-11 GuEe-GUI the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <cpuport.h>
#ifdef BSP_USING_VIRTIO_NET
#include <virtio_net.h>
static
rt_err_t
virtio_net_tx
(
rt_device_t
dev
,
struct
pbuf
*
p
)
{
rt_uint16_t
id
;
struct
virtio_net_device
*
virtio_net_dev
=
(
struct
virtio_net_device
*
)
dev
;
struct
virtio_device
*
virtio_dev
=
&
virtio_net_dev
->
virtio_dev
;
struct
virtq
*
queue_tx
=
&
virtio_dev
->
queues
[
VIRTIO_NET_QUEUE_TX
];
while
(
p
!=
RT_NULL
)
{
#ifdef RT_USING_SMP
rt_base_t
level
=
rt_spin_lock_irqsave
(
&
virtio_dev
->
spinlock
);
#endif
id
=
(
queue_tx
->
avail
->
idx
*
2
)
%
queue_tx
->
num
;
virtio_net_dev
->
info
[
id
].
hdr
.
flags
=
VIRTIO_NET_HDR_F_NEEDS_CSUM
;
virtio_net_dev
->
info
[
id
].
hdr
.
gso_type
=
VIRTIO_NET_HDR_GSO_NONE
;
virtio_net_dev
->
info
[
id
].
hdr
.
hdr_len
=
0
;
virtio_net_dev
->
info
[
id
].
hdr
.
gso_size
=
0
;
virtio_net_dev
->
info
[
id
].
hdr
.
csum_start
=
0
;
virtio_net_dev
->
info
[
id
].
hdr
.
csum_offset
=
p
->
tot_len
+
sizeof
(
virtio_net_dev
->
info
[
id
].
hdr
);
virtio_free_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
,
id
);
virtio_free_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
,
id
+
1
);
virtio_fill_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
,
id
,
VIRTIO_VA2PA
(
&
virtio_net_dev
->
info
[
id
].
hdr
),
VIRTIO_NET_HDR_SIZE
,
VIRTQ_DESC_F_NEXT
,
id
+
1
);
virtio_fill_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
,
id
+
1
,
VIRTIO_VA2PA
(
p
->
payload
),
p
->
tot_len
,
0
,
0
);
virtio_submit_chain
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
,
id
);
virtio_queue_notify
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
);
virtio_alloc_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
);
virtio_alloc_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
);
#ifdef RT_USING_SMP
rt_spin_unlock_irqrestore
(
&
virtio_dev
->
spinlock
,
level
);
#endif
p
=
p
->
next
;
}
return
RT_EOK
;
}
static
struct
pbuf
*
virtio_net_rx
(
rt_device_t
dev
)
{
rt_uint16_t
id
;
rt_uint32_t
len
;
struct
pbuf
*
p
=
RT_NULL
,
*
new
,
*
ret
=
RT_NULL
;
struct
virtio_net_device
*
virtio_net_dev
=
(
struct
virtio_net_device
*
)
dev
;
struct
virtio_device
*
virtio_dev
=
&
virtio_net_dev
->
virtio_dev
;
struct
virtq
*
queue_rx
=
&
virtio_dev
->
queues
[
VIRTIO_NET_QUEUE_RX
];
while
(
queue_rx
->
used_idx
!=
queue_rx
->
used
->
idx
)
{
#ifdef RT_USING_SMP
rt_base_t
level
=
rt_spin_lock_irqsave
(
&
virtio_dev
->
spinlock
);
#endif
id
=
(
queue_rx
->
used
->
ring
[
queue_rx
->
used_idx
%
queue_rx
->
num
].
id
+
1
)
%
queue_rx
->
num
;
len
=
queue_rx
->
used
->
ring
[
queue_rx
->
used_idx
%
queue_rx
->
num
].
len
-
VIRTIO_NET_HDR_SIZE
;
#ifdef RT_USING_SMP
rt_spin_unlock_irqrestore
(
&
virtio_dev
->
spinlock
,
level
);
#endif
if
(
len
>
VIRTIO_NET_PAYLOAD_MAX_SIZE
)
{
rt_kprintf
(
"%s: Receive buffer's size = %u is too big!
\n
"
,
virtio_net_dev
->
parent
.
parent
.
parent
.
name
,
len
);
len
=
VIRTIO_NET_PAYLOAD_MAX_SIZE
;
}
new
=
pbuf_alloc
(
PBUF_RAW
,
len
,
PBUF_RAM
);
if
(
p
!=
RT_NULL
)
{
p
->
next
=
new
;
p
=
p
->
next
;
}
else
{
p
=
new
;
ret
=
p
;
}
if
(
p
!=
RT_NULL
)
{
#ifdef RT_USING_SMP
level
=
rt_spin_lock_irqsave
(
&
virtio_dev
->
spinlock
);
#endif
rt_memcpy
(
p
->
payload
,
(
void
*
)
VIRTIO_PA2VA
(
queue_rx
->
desc
[
id
].
addr
),
len
);
queue_rx
->
used_idx
++
;
virtio_submit_chain
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
,
id
-
1
);
virtio_queue_notify
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
);
#ifdef RT_USING_SMP
rt_spin_unlock_irqrestore
(
&
virtio_dev
->
spinlock
,
level
);
#endif
}
else
{
break
;
}
}
return
ret
;
}
static
rt_err_t
virtio_net_init
(
rt_device_t
dev
)
{
int
i
;
rt_uint16_t
idx
[
VIRTIO_NET_RTX_QUEUE_SIZE
];
struct
virtio_net_device
*
virtio_net_dev
=
(
struct
virtio_net_device
*
)
dev
;
struct
virtio_device
*
virtio_dev
=
&
virtio_net_dev
->
virtio_dev
;
struct
virtq
*
queue_rx
,
*
queue_tx
;
queue_rx
=
&
virtio_dev
->
queues
[
VIRTIO_NET_QUEUE_RX
];
queue_tx
=
&
virtio_dev
->
queues
[
VIRTIO_NET_QUEUE_TX
];
virtio_alloc_desc_chain
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
,
queue_rx
->
num
,
idx
);
virtio_alloc_desc_chain
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
,
queue_tx
->
num
,
idx
);
for
(
i
=
0
;
i
<
queue_rx
->
num
;
++
i
)
{
rt_uint16_t
id
=
(
i
*
2
)
%
queue_rx
->
num
;
void
*
addr
=
virtio_net_dev
->
info
[
i
].
buffer
;
/* Descriptor for net_hdr */
virtio_fill_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
,
id
,
VIRTIO_VA2PA
(
addr
),
VIRTIO_NET_HDR_SIZE
,
VIRTQ_DESC_F_NEXT
|
VIRTQ_DESC_F_WRITE
,
id
+
1
);
/* Descriptor for data */
virtio_fill_desc
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
,
id
+
1
,
VIRTIO_VA2PA
(
addr
)
+
VIRTIO_NET_HDR_SIZE
,
VIRTIO_NET_MSS
,
VIRTQ_DESC_F_WRITE
,
0
);
queue_rx
->
avail
->
ring
[
i
]
=
id
;
}
rt_hw_dsb
();
queue_rx
->
avail
->
flags
=
0
;
queue_rx
->
avail
->
idx
=
queue_rx
->
num
;
queue_rx
->
used_idx
=
queue_rx
->
used
->
idx
;
queue_tx
->
avail
->
flags
=
VIRTQ_AVAIL_F_NO_INTERRUPT
;
queue_tx
->
avail
->
idx
=
0
;
virtio_queue_notify
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
);
return
eth_device_linkchange
(
&
virtio_net_dev
->
parent
,
RT_TRUE
);
}
static
rt_err_t
virtio_net_control
(
rt_device_t
dev
,
int
cmd
,
void
*
args
)
{
rt_err_t
status
=
RT_EOK
;
struct
virtio_net_device
*
virtio_net_dev
=
(
struct
virtio_net_device
*
)
dev
;
switch
(
cmd
)
{
case
NIOCTL_GADDR
:
if
(
args
==
RT_NULL
)
{
status
=
-
RT_ERROR
;
break
;
}
rt_memcpy
(
args
,
virtio_net_dev
->
mac
,
sizeof
(
virtio_net_dev
->
mac
));
break
;
default:
status
=
-
RT_EINVAL
;
break
;
}
return
status
;
}
const
static
struct
rt_device_ops
virtio_net_ops
=
{
virtio_net_init
,
RT_NULL
,
RT_NULL
,
RT_NULL
,
RT_NULL
,
virtio_net_control
};
static
void
virtio_net_isr
(
int
irqno
,
void
*
param
)
{
struct
virtio_net_device
*
virtio_net_dev
=
(
struct
virtio_net_device
*
)
param
;
struct
virtio_device
*
virtio_dev
=
&
virtio_net_dev
->
virtio_dev
;
struct
virtq
*
queue_rx
=
&
virtio_dev
->
queues
[
VIRTIO_NET_QUEUE_RX
];
#ifdef RT_USING_SMP
rt_base_t
level
=
rt_spin_lock_irqsave
(
&
virtio_dev
->
spinlock
);
#endif
virtio_interrupt_ack
(
virtio_dev
);
rt_hw_dsb
();
if
(
queue_rx
->
used_idx
!=
queue_rx
->
used
->
idx
)
{
rt_hw_dsb
();
eth_device_ready
(
&
virtio_net_dev
->
parent
);
}
#ifdef RT_USING_SMP
rt_spin_unlock_irqrestore
(
&
virtio_dev
->
spinlock
,
level
);
#endif
}
rt_err_t
rt_virtio_net_init
(
rt_ubase_t
*
mmio_base
,
rt_uint32_t
irq
)
{
int
i
;
static
int
dev_no
=
0
;
char
dev_name
[
RT_NAME_MAX
];
struct
virtio_device
*
virtio_dev
;
struct
virtio_net_device
*
virtio_net_dev
;
virtio_net_dev
=
rt_malloc
(
sizeof
(
struct
virtio_net_device
));
if
(
virtio_net_dev
==
RT_NULL
)
{
goto
_alloc_fail
;
}
virtio_dev
=
&
virtio_net_dev
->
virtio_dev
;
virtio_dev
->
irq
=
irq
;
virtio_dev
->
mmio_base
=
mmio_base
;
#ifdef RT_USING_SMP
rt_spin_lock_init
(
&
virtio_dev
->
spinlock
);
#endif
virtio_reset_device
(
virtio_dev
);
virtio_status_acknowledge_driver
(
virtio_dev
);
virtio_dev
->
mmio_config
->
driver_features
=
virtio_dev
->
mmio_config
->
device_features
&
~
(
(
1
<<
VIRTIO_NET_F_CTRL_VQ
)
|
(
1
<<
VIRTIO_NET_F_GUEST_TSO4
)
|
(
1
<<
VIRTIO_NET_F_GUEST_TSO6
)
|
(
1
<<
VIRTIO_NET_F_GUEST_UFO
)
|
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
)
|
(
1
<<
VIRTIO_F_RING_EVENT_IDX
))
&
(
1
<<
VIRTIO_NET_F_CSUM
)
&
(
1
<<
VIRTIO_NET_F_GUEST_CSUM
)
&
(
1
<<
VIRTIO_NET_F_MAC
);
virtio_status_driver_ok
(
virtio_dev
);
if
(
virtio_queue_init
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
,
VIRTIO_NET_RTX_QUEUE_SIZE
)
!=
RT_EOK
)
{
goto
_alloc_fail
;
}
if
(
virtio_queue_init
(
virtio_dev
,
VIRTIO_NET_QUEUE_TX
,
VIRTIO_NET_RTX_QUEUE_SIZE
)
!=
RT_EOK
)
{
virtio_queue_destroy
(
virtio_dev
,
VIRTIO_NET_QUEUE_RX
);
goto
_alloc_fail
;
}
for
(
i
=
0
;
i
<
sizeof
(
virtio_net_dev
->
mac
)
/
sizeof
(
virtio_net_dev
->
mac
[
0
]);
++
i
)
{
virtio_net_dev
->
mac
[
i
]
=
virtio_dev
->
mmio_config
->
config
[
i
];
}
virtio_net_dev
->
parent
.
parent
.
type
=
RT_Device_Class_NetIf
;
virtio_net_dev
->
parent
.
parent
.
ops
=
&
virtio_net_ops
;
virtio_net_dev
->
parent
.
eth_tx
=
virtio_net_tx
;
virtio_net_dev
->
parent
.
eth_rx
=
virtio_net_rx
;
rt_snprintf
(
dev_name
,
RT_NAME_MAX
,
"virtio-net%d"
,
dev_no
++
);
rt_hw_interrupt_install
(
irq
,
virtio_net_isr
,
virtio_net_dev
,
dev_name
);
rt_hw_interrupt_umask
(
irq
);
return
eth_device_init
(
&
virtio_net_dev
->
parent
,
dev_name
);
_alloc_fail:
if
(
virtio_net_dev
!=
RT_NULL
)
{
rt_free
(
virtio_net_dev
);
}
return
-
RT_ENOMEM
;
}
#endif
/* BSP_USING_VIRTIO_NET */
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.h
0 → 100644
浏览文件 @
8fa16f96
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-11 GuEe-GUI the first version
*/
#ifndef __VIRTIO_NET_H__
#define __VIRTIO_NET_H__
#include <rtdef.h>
#include <netif/ethernetif.h>
#include <virtio.h>
#define VIRTIO_NET_QUEUE_RX 0
#define VIRTIO_NET_QUEUE_TX 1
#define VIRTIO_NET_RTX_QUEUE_SIZE 16
#define VIRTIO_NET_RTX_BUF_SIZE 2048
#define VIRTIO_NET_F_CSUM 0
/* Host handles pkts w/ partial csum */
#define VIRTIO_NET_F_GUEST_CSUM 1
/* Guest handles pkts w/ partial csum */
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2
/* Dynamic offload configuration */
#define VIRTIO_NET_F_MTU 3
/* Initial MTU advice */
#define VIRTIO_NET_F_MAC 5
/* Host has given MAC address */
#define VIRTIO_NET_F_GUEST_TSO4 7
/* Guest can handle TSOv4 in */
#define VIRTIO_NET_F_GUEST_TSO6 8
/* Guest can handle TSOv6 in */
#define VIRTIO_NET_F_GUEST_ECN 9
/* Guest can handle TSO[6] w/ ECN in */
#define VIRTIO_NET_F_GUEST_UFO 10
/* Guest can handle UFO in */
#define VIRTIO_NET_F_HOST_TSO4 11
/* Host can handle TSOv4 in */
#define VIRTIO_NET_F_HOST_TSO6 12
/* Host can handle TSOv6 in */
#define VIRTIO_NET_F_HOST_ECN 13
/* Host can handle TSO[6] w/ ECN in */
#define VIRTIO_NET_F_HOST_UFO 14
/* Host can handle UFO in */
#define VIRTIO_NET_F_MRG_RXBUF 15
/* Host can merge receive buffers. */
#define VIRTIO_NET_F_STATUS 16
/* virtio_net_config.status available */
#define VIRTIO_NET_F_CTRL_VQ 17
/* Control channel available */
#define VIRTIO_NET_F_CTRL_RX 18
/* Control channel RX mode support */
#define VIRTIO_NET_F_CTRL_VLAN 19
/* Control channel VLAN filtering */
#define VIRTIO_NET_F_CTRL_RX_EXTRA 20
/* Extra RX mode control support */
#define VIRTIO_NET_F_GUEST_ANNOUNCE 21
/* Guest can announce device on the network */
#define VIRTIO_NET_F_MQ 22
/* Device supports Receive Flow Steering */
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23
/* Set MAC address */
#define VIRTIO_NET_F_HASH_REPORT 57
/* Supports hash report */
#define VIRTIO_NET_F_RSS 60
/* Supports RSS RX steering */
#define VIRTIO_NET_F_RSC_EXT 61
/* Extended coalescing info */
#define VIRTIO_NET_F_STANDBY 62
/* Act as standby for another device with the same MAC */
#define VIRTIO_NET_F_SPEED_DUPLEX 63
/* Device set linkspeed and duplex */
#define VIRTIO_NET_S_LINK_UP (1 << 0)
#define VIRTIO_NET_S_ANNOUNCE (1 << 1)
#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1
#define VIRTIO_NET_HDR_F_DATA_VALID 2
#define VIRTIO_NET_HDR_F_RSC_INFO 4
#define VIRTIO_NET_HDR_GSO_NONE 0
#define VIRTIO_NET_HDR_GSO_TCPV4 1
#define VIRTIO_NET_HDR_GSO_UDP 3
#define VIRTIO_NET_HDR_GSO_TCPV6 4
#define VIRTIO_NET_HDR_GSO_ECN 0x80
struct
virtio_net_hdr
{
rt_uint8_t
flags
;
rt_uint8_t
gso_type
;
rt_uint16_t
hdr_len
;
rt_uint16_t
gso_size
;
rt_uint16_t
csum_start
;
rt_uint16_t
csum_offset
;
rt_uint16_t
num_buffers
;
/* Only if VIRTIO_NET_F_MRG_RXBUF */
}
__attribute__
((
packed
));
#define VIRTIO_NET_MSS 1514
/* Disable VIRTIO_NET_F_MRG_RXBUF */
#define VIRTIO_NET_HDR_SIZE (sizeof(struct virtio_net_hdr) - sizeof(rt_uint16_t))
#define VIRTIO_NET_PAYLOAD_MAX_SIZE (VIRTIO_NET_HDR_SIZE + VIRTIO_NET_MSS)
struct
virtio_net_device
{
struct
eth_device
parent
;
struct
virtio_device
virtio_dev
;
rt_uint8_t
mac
[
6
];
struct
{
/* Transmit hdr */
struct
virtio_net_hdr
hdr
;
/* Receive buffer */
rt_uint8_t
buffer
[
VIRTIO_NET_PAYLOAD_MAX_SIZE
];
}
info
[
VIRTIO_NET_RTX_QUEUE_SIZE
];
};
rt_err_t
rt_virtio_net_init
(
rt_ubase_t
*
mmio_base
,
rt_uint32_t
irq
);
#endif
/* __VIRTIO_NET_H__ */
bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h
浏览文件 @
8fa16f96
...
...
@@ -80,6 +80,7 @@ struct virtq
/* Helper of driver */
rt_uint32_t
used_idx
;
rt_bool_t
*
free
;
rt_size_t
free_count
;
};
#define VIRTQ_DESC_TOTAL_SIZE(ring_size) (sizeof(struct virtq_desc) * (ring_size))
...
...
@@ -91,4 +92,6 @@ struct virtq
#define VIRTQ_AVAIL_RES_SIZE (sizeof(rt_uint16_t))
/* used_event */
#define VIRTQ_USED_RES_SIZE (sizeof(rt_uint16_t))
/* avail_event */
#define VIRTQ_INVALID_DESC_ID RT_UINT16_MAX
#endif
/* __VIRTIO_QUEUE_H__ */
bsp/qemu-virt64-aarch64/qemu-graphic.bat
0 → 100644
浏览文件 @
8fa16f96
@echo
off
if
exist
sd
.bin
goto
run
qemu
-img
create
-f
raw
sd
.bin
64
M
:run
qemu
-system-aarch
64
-M
virt
,
gic
-version
=
2
-cpu
cortex
-a
53
-smp
4
-kernel
rtthread
.elf
-serial
stdio
^
-drive
if
=
none
,
file
=
sd
.bin
,
format
=
raw
,
id
=
blk0
-device
virtio
-blk-device
,
drive
=
blk0
,
bus
=
virtio
-mmio-bus
.0
^
-netdev
user
,
id
=
net0
-device
virtio
-net-device
,
netdev
=
net0
,
bus
=
virtio
-mmio-bus
.1
^
-device
virtio
-gpu-device
,
xres
=
800
,
yres
=
600
,
bus
=
virtio
-mmio-bus
.2
^
-device
virtio
-keyboard-device
,
bus
=
virtio
-mmio-bus
.3
^
-device
virtio
-mouse-device
,
bus
=
virtio
-mmio-bus
.4
^
-device
virtio
-tablet-device
,
bus
=
virtio
-mmio-bus
.5
bsp/qemu-virt64-aarch64/qemu-graphic.sh
0 → 100644
浏览文件 @
8fa16f96
if
[
!
-f
"sd.bin"
]
;
then
dd
if
=
/dev/zero
of
=
sd.bin
bs
=
1024
count
=
65536
fi
qemu-system-aarch64
-M
virt,gic-version
=
2
-cpu
cortex-a53
-smp
4
-kernel
rtthread.elf
-serial
stdio
\
-drive
if
=
none,file
=
sd.bin,format
=
raw,id
=
blk0
-device
virtio-blk-device,drive
=
blk0,bus
=
virtio-mmio-bus.0
\
-netdev
user,id
=
net0
-device
virtio-net-device,netdev
=
net0,bus
=
virtio-mmio-bus.1
\
-device
virtio-gpu-device,xres
=
800,yres
=
600,bus
=
virtio-mmio-bus.2
\
-device
virtio-keyboard-device,bus
=
virtio-mmio-bus.3
\
-device
virtio-mouse-device,bus
=
virtio-mmio-bus.4
\
-device
virtio-tablet-device,bus
=
virtio-mmio-bus.5
bsp/qemu-virt64-aarch64/rtconfig.h
浏览文件 @
8fa16f96
...
...
@@ -7,6 +7,8 @@
/* RT-Thread Kernel */
#define RT_NAME_MAX 16
#define RT_USING_SMP
#define RT_CPUS_NR 4
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
...
...
@@ -17,12 +19,14 @@
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 4096
#define SYSTEM_THREAD_STACK_SIZE 4096
#define RT_USING_TIMER_SOFT
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 4096
/* kservice optimization */
#define RT_KPRINTF_USING_LONGLONG
#define RT_DEBUG
#define RT_DEBUG_COLOR
...
...
@@ -51,7 +55,7 @@
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart0"
#define RT_VER_NUM 0x4010
0
#define RT_VER_NUM 0x4010
1
#define ARCH_CPU_64BIT
#define ARCH_ARMV8
...
...
@@ -101,7 +105,7 @@
#define RT_USING_DEVICE_IPC
#define RT_USING_SYSTEM_WORKQUEUE
#define RT_SYSTEM_WORKQUEUE_STACKSIZE
2048
#define RT_SYSTEM_WORKQUEUE_STACKSIZE
4096
#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V1
...
...
@@ -128,6 +132,62 @@
/* Network */
#define RT_USING_SAL
#define SAL_INTERNET_CHECK
/* Docking with protocol stacks */
#define SAL_USING_LWIP
#define SAL_USING_POSIX
#define RT_USING_NETDEV
#define NETDEV_USING_IFCONFIG
#define NETDEV_USING_PING
#define NETDEV_USING_NETSTAT
#define NETDEV_USING_AUTO_DEFAULT
#define NETDEV_IPV4 1
#define NETDEV_IPV6 0
#define RT_USING_LWIP
#define RT_USING_LWIP203
#define RT_USING_LWIP_VER_NUM 0x20003
#define RT_LWIP_MEM_ALIGNMENT 4
#define RT_LWIP_ICMP
#define RT_LWIP_DNS
#define RT_LWIP_DHCP
#define IP_SOF_BROADCAST 1
#define IP_SOF_BROADCAST_RECV 1
/* Static IPv4 Address */
#define RT_LWIP_IPADDR "192.168.1.30"
#define RT_LWIP_GWADDR "192.168.1.1"
#define RT_LWIP_MSKADDR "255.255.255.0"
#define RT_LWIP_UDP
#define RT_LWIP_TCP
#define RT_LWIP_RAW
#define RT_MEMP_NUM_NETCONN 8
#define RT_LWIP_PBUF_NUM 16
#define RT_LWIP_RAW_PCB_NUM 4
#define RT_LWIP_UDP_PCB_NUM 4
#define RT_LWIP_TCP_PCB_NUM 4
#define RT_LWIP_TCP_SEG_NUM 40
#define RT_LWIP_TCP_SND_BUF 8196
#define RT_LWIP_TCP_WND 8196
#define RT_LWIP_TCPTHREAD_PRIORITY 10
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
#define RT_LWIP_TCPTHREAD_STACKSIZE 4096
#define RT_LWIP_ETHTHREAD_PRIORITY 12
#define RT_LWIP_ETHTHREAD_STACKSIZE 4096
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
#define RT_LWIP_REASSEMBLY_FRAG
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define SO_REUSE 1
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_SNDTIMEO 1
#define LWIP_SO_RCVBUF 1
#define LWIP_SO_LINGER 0
#define LWIP_NETIF_LOOPBACK 0
#define RT_LWIP_USING_PING
/* Utilities */
...
...
@@ -217,6 +277,9 @@
#define BSP_USING_RTC
#define BSP_USING_ALARM
#define BSP_USING_VIRTIO_BLK
#define BSP_USING_VIRTIO_NET
#define BSP_USING_VIRTIO_GPU
#define BSP_USING_VIRTIO_INPUT
#define BSP_USING_GIC
#define BSP_USING_GICV2
...
...
bsp/qemu-virt64-aarch64/rtconfig.py
浏览文件 @
8fa16f96
...
...
@@ -39,7 +39,7 @@ if PLATFORM == 'gcc':
OBJCPY
=
PREFIX
+
'objcopy'
DEVICE
=
' -g -march=armv8-a -mtune=cortex-a53'
CFLAGS
=
DEVICE
+
' -Wall
-Werror
'
CFLAGS
=
DEVICE
+
' -Wall '
AFLAGS
=
' -c'
+
' -x assembler-with-cpp -D__ASSEMBLY__'
LFLAGS
=
DEVICE
+
' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
CPATH
=
''
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录