1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-11-11 GuEe-GUI the first version
9 */
10
11 #include <rtthread.h>
12 #include <virt.h>
13
14 #ifdef BSP_USING_VIRTIO
15
16 #include <virtio.h>
17 #ifdef BSP_USING_VIRTIO_BLK
18 #include <virtio_blk.h>
19 #endif
20 #ifdef BSP_USING_VIRTIO_NET
21 #include <virtio_net.h>
22 #endif
23 #ifdef BSP_USING_VIRTIO_CONSOLE
24 #include <virtio_console.h>
25 #endif
26 #ifdef BSP_USING_VIRTIO_GPU
27 #include <virtio_gpu.h>
28 #endif
29 #ifdef BSP_USING_VIRTIO_INPUT
30 #include <virtio_input.h>
31 #endif
32
33 #include <board.h>
34
35 static virtio_device_init_handler virtio_device_init_handlers[] =
36 {
37 #ifdef BSP_USING_VIRTIO_BLK
38 [VIRTIO_DEVICE_ID_BLOCK] = rt_virtio_blk_init,
39 #endif
40 #ifdef BSP_USING_VIRTIO_NET
41 [VIRTIO_DEVICE_ID_NET] = rt_virtio_net_init,
42 #endif
43 #ifdef BSP_USING_VIRTIO_CONSOLE
44 [VIRTIO_DEVICE_ID_CONSOLE] = rt_virtio_console_init,
45 #endif
46 #ifdef BSP_USING_VIRTIO_GPU
47 [VIRTIO_DEVICE_ID_GPU] = rt_virtio_gpu_init,
48 #endif
49 #ifdef BSP_USING_VIRTIO_INPUT
50 [VIRTIO_DEVICE_ID_INPUT] = rt_virtio_input_init,
51 #endif
52 [VIRTIO_DEVICE_TYPE_SIZE] = RT_NULL
53 };
54
rt_virtio_devices_init(void)55 int rt_virtio_devices_init(void)
56 {
57 int i;
58 rt_uint32_t irq = VIRTIO_IRQ_BASE;
59 rt_ubase_t mmio_base = VIRTIO_MMIO_BASE;
60 struct virtio_mmio_config *mmio_config;
61 virtio_device_init_handler init_handler;
62
63 if (sizeof(virtio_device_init_handlers) == 0)
64 {
65 /* The compiler will optimize the codes after here. */
66 return 0;
67 }
68
69 #ifdef RT_USING_SMART
70 mmio_base = (rt_ubase_t)rt_ioremap((void *)mmio_base, VIRTIO_MMIO_SIZE * VIRTIO_MAX_NR);
71
72 if (mmio_base == RT_NULL)
73 {
74 return -RT_ERROR;
75 }
76 #endif
77
78 for (i = 0; i < VIRTIO_MAX_NR; ++i, ++irq, mmio_base += VIRTIO_MMIO_SIZE)
79 {
80 mmio_config = (struct virtio_mmio_config *)mmio_base;
81
82 if (mmio_config->magic != VIRTIO_MAGIC_VALUE ||
83 mmio_config->version != RT_USING_VIRTIO_VERSION ||
84 mmio_config->vendor_id != VIRTIO_VENDOR_ID)
85 {
86 continue;
87 }
88
89 init_handler = virtio_device_init_handlers[mmio_config->device_id];
90
91 if (init_handler != RT_NULL)
92 {
93 init_handler((rt_ubase_t *)mmio_base, irq);
94 }
95 }
96
97 return 0;
98 }
99 INIT_DEVICE_EXPORT(rt_virtio_devices_init);
100 #endif /* BSP_USING_VIRTIO */
101