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