mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-26 17:00:00 +08:00
File diff suppressed because it is too large
Load Diff
@@ -21,10 +21,14 @@ source "$PKGS_DIR/Kconfig"
|
||||
config SOC_VIRT64_AARCH64
|
||||
bool
|
||||
select ARCH_ARMV8
|
||||
select RT_USING_CACHE
|
||||
select ARCH_CPU_64BIT
|
||||
select ARCH_ARM_MMU
|
||||
select RT_USING_CACHE
|
||||
select RT_USING_COMPONENTS_INIT
|
||||
select RT_USING_USER_MAIN
|
||||
select RT_USING_GIC
|
||||
select BSP_USING_GIC
|
||||
select ARCH_MM_MMU
|
||||
default y
|
||||
|
||||
source "$BSP_DIR/driver/Kconfig"
|
||||
source "$BSP_DIR/drivers/Kconfig"
|
||||
|
||||
@@ -1,19 +1,33 @@
|
||||
import os
|
||||
import sys
|
||||
import rtconfig
|
||||
import re
|
||||
|
||||
if os.getenv('RTT_ROOT'):
|
||||
RTT_ROOT = os.getenv('RTT_ROOT')
|
||||
else:
|
||||
RTT_ROOT = os.path.join(os.getcwd(), '..', '..')
|
||||
|
||||
from rtconfig import RTT_ROOT
|
||||
|
||||
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
|
||||
from building import *
|
||||
|
||||
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
|
||||
TRACE_CONFIG = ""
|
||||
|
||||
content = ""
|
||||
with open("rtconfig.h") as f:
|
||||
for line in f.readlines():
|
||||
if line.find("RT_BACKTRACE_FUNCTION_NAME") != -1:
|
||||
for token in line.split(" "):
|
||||
if re.match(r'RT_BACKTRACE_FUNCTION_NAME$', token, flags=0):
|
||||
TRACE_CONFIG = " "
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
env = Environment(tools = ['mingw'],
|
||||
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
|
||||
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
|
||||
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
|
||||
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS + TRACE_CONFIG,
|
||||
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS + TRACE_CONFIG,
|
||||
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS + TRACE_CONFIG,
|
||||
AR = rtconfig.AR, ARFLAGS = '-rc',
|
||||
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
|
||||
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
|
||||
|
||||
@@ -10,9 +10,13 @@
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#if defined(RT_USING_POSIX_DEVIO) && defined(RT_USING_SMART)
|
||||
#include <console.h>
|
||||
#endif
|
||||
|
||||
#include <virtio_console.h>
|
||||
|
||||
int console_init()
|
||||
static int console_init()
|
||||
{
|
||||
rt_err_t status = RT_EOK;
|
||||
rt_device_t device = rt_device_find("virtio-console0");
|
||||
@@ -44,7 +48,23 @@ static int console(int argc, char **argv)
|
||||
{
|
||||
rt_kprintf("console change to %s\n", argv[2]);
|
||||
rt_console_set_device(argv[2]);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
{
|
||||
rt_device_t dev = rt_device_find(argv[2]);
|
||||
|
||||
if (dev != RT_NULL)
|
||||
{
|
||||
#ifdef RT_USING_SMART
|
||||
console_set_iodev(dev);
|
||||
#else
|
||||
rt_kprintf("TODO not supported\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
finsh_set_device(argv[2]);
|
||||
#endif /* RT_USING_POSIX_DEVIO */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -114,7 +114,7 @@ void graphic_thread(void *param)
|
||||
|
||||
rt_device_control(device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
|
||||
|
||||
while (i < sizeof(cursor) / sizeof(rt_uint32_t))
|
||||
while (i < sizeof(cursor) / 4)
|
||||
{
|
||||
/* R: 0x4c G: 0xaf B: 0x50 A: 0.8 */
|
||||
((rt_uint32_t *)cursor)[i] = 0xcc4caf50;
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-5-30 Bernard the first version
|
||||
* 2020/10/7 bernard the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main(void)
|
||||
{
|
||||
rt_kprintf("Hi, this is RT-Thread!!\n");
|
||||
printf("hello rt-thread\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-5-30 bernard the first version
|
||||
* 2021/08/19 bernard the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
int mnt_init(void)
|
||||
{
|
||||
if(rt_device_find("virtio-blk0"))
|
||||
if (rt_device_find("virtio-blk0"))
|
||||
{
|
||||
/* mount virtio-blk as root directory */
|
||||
if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0)
|
||||
|
||||
@@ -21,7 +21,7 @@ void qemu_gpio3_key_poweroff(void *args)
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
int pin_init()
|
||||
static int pin_init()
|
||||
{
|
||||
rt_pin_attach_irq(3, PIN_IRQ_MODE_FALLING, qemu_gpio3_key_poweroff, RT_NULL);
|
||||
rt_pin_irq_enable(3, RT_TRUE);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
list = os.listdir(cwd)
|
||||
CPPPATH = [cwd]
|
||||
objs = []
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
for d in list:
|
||||
path = os.path.join(cwd, d)
|
||||
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||
objs = objs + group
|
||||
|
||||
Return('objs')
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-07-29 zdzn first version
|
||||
* 2021-07-31 GuEe-GUI config the memory/io address map
|
||||
* 2021-09-11 GuEe-GUI remove do-while in rt_hw_timer_isr
|
||||
* 2021-12-28 GuEe-GUI add smp support
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "board.h"
|
||||
#include <mmu.h>
|
||||
#include <gic.h>
|
||||
#include <gicv3.h>
|
||||
#include <psci.h>
|
||||
#include <gtimer.h>
|
||||
#include <cpuport.h>
|
||||
#include <interrupt.h>
|
||||
|
||||
#include "drv_uart.h"
|
||||
|
||||
struct mem_desc platform_mem_desc[] =
|
||||
{
|
||||
{0x40000000, 0x80000000, 0x40000000, NORMAL_MEM},
|
||||
{PL031_RTC_BASE, PL031_RTC_BASE + 0x1000, PL031_RTC_BASE, DEVICE_MEM},
|
||||
{PL061_GPIO_BASE, PL061_GPIO_BASE + 0x1000, PL061_GPIO_BASE, DEVICE_MEM},
|
||||
{PL011_UART0_BASE, PL011_UART0_BASE + 0x1000, PL011_UART0_BASE, DEVICE_MEM},
|
||||
{VIRTIO_MMIO_BASE, VIRTIO_MMIO_BASE + VIRTIO_MAX_NR * VIRTIO_MMIO_SIZE, VIRTIO_MMIO_BASE, DEVICE_MEM},
|
||||
#ifdef BSP_USING_GICV2
|
||||
{GIC_PL390_DISTRIBUTOR_PPTR, GIC_PL390_DISTRIBUTOR_PPTR + 0x1000, GIC_PL390_DISTRIBUTOR_PPTR, DEVICE_MEM},
|
||||
#endif
|
||||
#ifdef BSP_USING_GICV3
|
||||
{GIC_PL500_DISTRIBUTOR_PPTR, GIC_PL500_DISTRIBUTOR_PPTR + 0x1000, GIC_PL500_DISTRIBUTOR_PPTR, DEVICE_MEM},
|
||||
{GIC_PL500_REDISTRIBUTOR_PPTR, GIC_PL500_REDISTRIBUTOR_PPTR + 0xf60000, GIC_PL500_REDISTRIBUTOR_PPTR, DEVICE_MEM},
|
||||
#endif
|
||||
};
|
||||
|
||||
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
|
||||
|
||||
void idle_wfi(void)
|
||||
{
|
||||
asm volatile ("wfi");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Hardware related stuffs. Called from rtthread_startup()
|
||||
* after interrupt disabled.
|
||||
*/
|
||||
void rt_hw_board_init(void)
|
||||
{
|
||||
rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size);
|
||||
rt_hw_mmu_init();
|
||||
|
||||
/* initialize hardware interrupt */
|
||||
rt_hw_interrupt_init();
|
||||
|
||||
/* initialize uart */
|
||||
rt_hw_uart_init();
|
||||
/* initialize timer for os tick */
|
||||
rt_hw_gtimer_init();
|
||||
rt_thread_idle_sethook(idle_wfi);
|
||||
|
||||
arm_psci_init(PSCI_METHOD_HVC, RT_NULL, RT_NULL);
|
||||
|
||||
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
|
||||
/* set console device */
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
/* initialize memory system */
|
||||
rt_kprintf("heap: [0x%08x - 0x%08x]\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
|
||||
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_COMPONENTS_INIT
|
||||
rt_components_board_init();
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
/* install IPI handle */
|
||||
rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
|
||||
arm_gic_umask(0, IRQ_ARM_IPI_KICK);
|
||||
#endif
|
||||
}
|
||||
|
||||
void poweroff(void)
|
||||
{
|
||||
arm_psci_system_off();
|
||||
}
|
||||
MSH_CMD_EXPORT(poweroff, poweroff...);
|
||||
|
||||
void rt_hw_cpu_shutdown()
|
||||
{
|
||||
rt_kprintf("shutdown...\n");
|
||||
|
||||
poweroff();
|
||||
}
|
||||
|
||||
void reboot(void)
|
||||
{
|
||||
arm_psci_system_reboot();
|
||||
}
|
||||
MSH_CMD_EXPORT(reboot, reboot...);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
void rt_hw_secondary_cpu_up(void)
|
||||
{
|
||||
int i;
|
||||
extern void secondary_cpu_start(void);
|
||||
extern rt_uint64_t rt_cpu_mpidr_early[];
|
||||
|
||||
for (i = 1; i < RT_CPUS_NR; ++i)
|
||||
{
|
||||
arm_psci_cpu_on(rt_cpu_mpidr_early[i], (uint64_t)(secondary_cpu_start));
|
||||
}
|
||||
}
|
||||
|
||||
void secondary_cpu_c_start(void)
|
||||
{
|
||||
rt_hw_mmu_init();
|
||||
rt_hw_spin_lock(&_cpus_lock);
|
||||
|
||||
arm_gic_cpu_init(0, platform_get_gic_cpu_base());
|
||||
#ifdef BSP_USING_GICV3
|
||||
arm_gic_redist_init(0, platform_get_gic_redist_base());
|
||||
#endif
|
||||
rt_hw_vector_init();
|
||||
rt_hw_gtimer_local_enable();
|
||||
arm_gic_umask(0, IRQ_ARM_IPI_KICK);
|
||||
|
||||
rt_kprintf("\rcall cpu %d on success\n", rt_hw_cpu_id());
|
||||
|
||||
rt_system_scheduler_start();
|
||||
}
|
||||
|
||||
void rt_hw_secondary_cpu_idle_exec(void)
|
||||
{
|
||||
__WFE();
|
||||
}
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-5-30 Bernard the first version
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H__
|
||||
#define BOARD_H__
|
||||
|
||||
#include <virt.h>
|
||||
|
||||
extern unsigned char __bss_start;
|
||||
extern unsigned char __bss_end;
|
||||
|
||||
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
|
||||
#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024)
|
||||
|
||||
void rt_hw_board_init(void);
|
||||
|
||||
#endif
|
||||
@@ -1,206 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-11-4 GuEe-GUI first version
|
||||
* 2022-07-15 GuEe-GUI add alarm ops support
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <sys/time.h>
|
||||
#include <board.h>
|
||||
|
||||
#include "drv_rtc.h"
|
||||
|
||||
#ifdef BSP_USING_RTC
|
||||
|
||||
#define RTC_DR 0x00 /* data read register */
|
||||
#define RTC_MR 0x04 /* match register */
|
||||
#define RTC_LR 0x08 /* data load register */
|
||||
#define RTC_CR 0x0c /* control register */
|
||||
#define RTC_IMSC 0x10 /* interrupt mask and set register */
|
||||
#define RTC_RIS 0x14 /* raw interrupt status register */
|
||||
#define RTC_MIS 0x18 /* masked interrupt status register */
|
||||
#define RTC_ICR 0x1c /* interrupt clear register */
|
||||
|
||||
#define RTC_CR_OPEN 1
|
||||
#define RTC_CR_CLOSE 0
|
||||
#define RTC_BIT_AI (1 << 0) /* Alarm interrupt bit */
|
||||
#define RTC_BIT_PI (1 << 1) /* Periodic interrupt bit. ST variants only. */
|
||||
|
||||
static rt_rtc_dev_t _rtc_device;
|
||||
#ifdef RT_USING_ALARM
|
||||
static struct rt_rtc_wkalarm _wkalarm;
|
||||
#endif
|
||||
|
||||
rt_inline rt_uint32_t pl031_read32(rt_ubase_t offset)
|
||||
{
|
||||
return (*((volatile unsigned int *)(PL031_RTC_BASE + offset)));
|
||||
}
|
||||
|
||||
rt_inline void pl031_write32(rt_ubase_t offset, rt_uint32_t value)
|
||||
{
|
||||
(*((volatile unsigned int *)(PL031_RTC_BASE + offset))) = value;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_rtc_init(void)
|
||||
{
|
||||
pl031_write32(RTC_CR, RTC_CR_OPEN);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_get_secs(time_t *sec)
|
||||
{
|
||||
if (sec != RT_NULL)
|
||||
{
|
||||
*(rt_uint32_t *)sec = pl031_read32(RTC_DR);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_set_secs(time_t *sec)
|
||||
{
|
||||
if (sec != RT_NULL)
|
||||
{
|
||||
pl031_write32(RTC_LR, *(rt_uint32_t *)sec);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_ALARM
|
||||
static rt_err_t pl031_set_alarm(struct rt_rtc_wkalarm *alarm)
|
||||
{
|
||||
if (alarm != RT_NULL)
|
||||
{
|
||||
rt_uint32_t imsc, time;
|
||||
|
||||
_wkalarm.enable = alarm->enable;
|
||||
_wkalarm.tm_hour = alarm->tm_hour;
|
||||
_wkalarm.tm_min = alarm->tm_min;
|
||||
_wkalarm.tm_sec = alarm->tm_sec;
|
||||
|
||||
time = pl031_read32(RTC_DR);
|
||||
|
||||
/* Back to 08:00 today */
|
||||
time = time / (3600 * 24) * (3600 * 24);
|
||||
|
||||
/* Get alarm time */
|
||||
time += alarm->tm_hour * 3600 + alarm->tm_min * 60 + alarm->tm_sec;
|
||||
|
||||
pl031_write32(RTC_MR, time);
|
||||
|
||||
/* Clear any pending alarm interrupts. */
|
||||
pl031_write32(RTC_ICR, RTC_BIT_AI);
|
||||
|
||||
imsc = pl031_read32(RTC_IMSC);
|
||||
|
||||
if (alarm->enable)
|
||||
{
|
||||
pl031_write32(RTC_IMSC, imsc | RTC_BIT_AI);
|
||||
}
|
||||
else
|
||||
{
|
||||
pl031_write32(RTC_IMSC, imsc & ~RTC_BIT_AI);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_get_alarm(struct rt_rtc_wkalarm *alarm)
|
||||
{
|
||||
if (alarm != RT_NULL)
|
||||
{
|
||||
*alarm = _wkalarm;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
#endif /* RT_USING_ALARM */
|
||||
|
||||
static rt_err_t pl031_get_timeval(struct timeval *tv)
|
||||
{
|
||||
if (tv != RT_NULL)
|
||||
{
|
||||
tv->tv_sec = pl031_read32(RTC_DR);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_set_timeval(struct timeval *tv)
|
||||
{
|
||||
if (tv != RT_NULL)
|
||||
{
|
||||
pl031_write32(RTC_LR, *(rt_uint32_t *)tv->tv_sec);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
static const struct rt_rtc_ops rtc_ops =
|
||||
{
|
||||
.init = pl031_rtc_init,
|
||||
.get_secs = pl031_get_secs,
|
||||
.set_secs = pl031_set_secs,
|
||||
#ifdef RT_USING_ALARM
|
||||
.get_alarm = pl031_get_alarm,
|
||||
.set_alarm = pl031_set_alarm,
|
||||
#else
|
||||
.get_alarm = RT_NULL,
|
||||
.set_alarm = RT_NULL,
|
||||
#endif
|
||||
.get_timeval = pl031_get_timeval,
|
||||
.set_timeval = pl031_set_timeval,
|
||||
};
|
||||
|
||||
#ifdef RT_USING_ALARM
|
||||
static void rt_hw_rtc_isr(int irqno, void *param)
|
||||
{
|
||||
rt_uint32_t rtcmis = pl031_read32(RTC_MIS);
|
||||
|
||||
if (rtcmis & RTC_BIT_AI)
|
||||
{
|
||||
pl031_write32(RTC_ICR, RTC_BIT_AI);
|
||||
|
||||
rt_alarm_update(&_rtc_device.parent, 1);
|
||||
}
|
||||
}
|
||||
#endif /* RT_USING_ALARM */
|
||||
|
||||
int rt_hw_rtc_init(void)
|
||||
{
|
||||
_rtc_device.ops = &rtc_ops;
|
||||
|
||||
/* register a rtc device */
|
||||
rt_hw_rtc_register(&_rtc_device, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
|
||||
|
||||
#ifdef RT_USING_ALARM
|
||||
rt_hw_interrupt_install(PL031_RTC_IRQNUM, rt_hw_rtc_isr, RT_NULL, "rtc");
|
||||
rt_hw_interrupt_umask(PL031_RTC_IRQNUM);
|
||||
#endif /* RT_USING_ALARM */
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
|
||||
#endif /* BSP_USING_RTC */
|
||||
@@ -1,324 +0,0 @@
|
||||
/*
|
||||
* 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 <cpuport.h>
|
||||
|
||||
#include <virtio.h>
|
||||
|
||||
rt_inline void _virtio_dev_check(struct virtio_device *dev)
|
||||
{
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
RT_ASSERT(dev->mmio_config != RT_NULL);
|
||||
}
|
||||
|
||||
void virtio_reset_device(struct virtio_device *dev)
|
||||
{
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
dev->mmio_config->status = 0;
|
||||
}
|
||||
|
||||
void virtio_status_acknowledge_driver(struct virtio_device *dev)
|
||||
{
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
dev->mmio_config->status |= VIRTIO_STATUS_ACKNOWLEDGE | VIRTIO_STATUS_DRIVER;
|
||||
}
|
||||
|
||||
void virtio_status_driver_ok(struct virtio_device *dev)
|
||||
{
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
dev->mmio_config->status |= VIRTIO_STATUS_FEATURES_OK | VIRTIO_STATUS_DRIVER_OK;
|
||||
}
|
||||
|
||||
void virtio_interrupt_ack(struct virtio_device *dev)
|
||||
{
|
||||
rt_uint32_t status;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
status = dev->mmio_config->interrupt_status;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
dev->mmio_config->interrupt_ack = status;
|
||||
}
|
||||
}
|
||||
|
||||
rt_bool_t virtio_has_feature(struct virtio_device *dev, rt_uint32_t feature_bit)
|
||||
{
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
return !!(dev->mmio_config->device_features & (1UL << feature_bit));
|
||||
}
|
||||
|
||||
rt_err_t virtio_queues_alloc(struct virtio_device *dev, rt_size_t queues_num)
|
||||
{
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
dev->queues = rt_malloc(sizeof(struct virtq) * queues_num);
|
||||
|
||||
if (dev->queues != RT_NULL)
|
||||
{
|
||||
dev->queues_num = queues_num;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
void virtio_queues_free(struct virtio_device *dev)
|
||||
{
|
||||
if (dev->queues != RT_NULL)
|
||||
{
|
||||
dev->queues_num = 0;
|
||||
rt_free(dev->queues);
|
||||
}
|
||||
}
|
||||
|
||||
rt_err_t virtio_queue_init(struct virtio_device *dev, rt_uint32_t queue_index, rt_size_t ring_size)
|
||||
{
|
||||
int i;
|
||||
void *pages;
|
||||
rt_size_t pages_total_size;
|
||||
struct virtq *queue;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
RT_ASSERT(dev->mmio_config->queue_num_max > 0);
|
||||
RT_ASSERT(dev->mmio_config->queue_num_max > queue_index);
|
||||
/* ring_size is power of 2 */
|
||||
RT_ASSERT(ring_size > 0);
|
||||
RT_ASSERT(((ring_size - 1) & ring_size) == 0);
|
||||
|
||||
queue = &dev->queues[queue_index];
|
||||
pages_total_size = VIRTIO_PAGE_ALIGN(
|
||||
VIRTQ_DESC_TOTAL_SIZE(ring_size) + VIRTQ_AVAIL_TOTAL_SIZE(ring_size)) + VIRTQ_USED_TOTAL_SIZE(ring_size);
|
||||
|
||||
pages = rt_malloc_align(pages_total_size, VIRTIO_PAGE_SIZE);
|
||||
|
||||
if (pages == RT_NULL)
|
||||
{
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
queue->free = rt_malloc(sizeof(rt_bool_t) * ring_size);
|
||||
|
||||
if (queue->free == RT_NULL)
|
||||
{
|
||||
rt_free_align(pages);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_memset(pages, 0, pages_total_size);
|
||||
|
||||
dev->mmio_config->guest_page_size = VIRTIO_PAGE_SIZE;
|
||||
dev->mmio_config->queue_sel = queue_index;
|
||||
dev->mmio_config->queue_num = ring_size;
|
||||
dev->mmio_config->queue_align = VIRTIO_PAGE_SIZE;
|
||||
dev->mmio_config->queue_pfn = VIRTIO_VA2PA(pages) >> VIRTIO_PAGE_SHIFT;
|
||||
|
||||
queue->num = ring_size;
|
||||
queue->desc = (struct virtq_desc *)((rt_ubase_t)pages);
|
||||
queue->avail = (struct virtq_avail *)(((rt_ubase_t)pages) + VIRTQ_DESC_TOTAL_SIZE(ring_size));
|
||||
queue->used = (struct virtq_used *)VIRTIO_PAGE_ALIGN(
|
||||
(rt_ubase_t)&queue->avail->ring[ring_size] + VIRTQ_AVAIL_RES_SIZE);
|
||||
|
||||
queue->used_idx = 0;
|
||||
|
||||
/* All descriptors start out unused */
|
||||
for (i = 0; i < ring_size; ++i)
|
||||
{
|
||||
queue->free[i] = RT_TRUE;
|
||||
}
|
||||
|
||||
queue->free_count = ring_size;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
void virtio_queue_destroy(struct virtio_device *dev, rt_uint32_t queue_index)
|
||||
{
|
||||
struct virtq *queue;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
RT_ASSERT(dev->mmio_config->queue_num_max > 0);
|
||||
RT_ASSERT(dev->mmio_config->queue_num_max > queue_index);
|
||||
|
||||
queue = &dev->queues[queue_index];
|
||||
|
||||
RT_ASSERT(queue->num > 0);
|
||||
|
||||
rt_free(queue->free);
|
||||
rt_free_align((void *)queue->desc);
|
||||
|
||||
dev->mmio_config->queue_sel = queue_index;
|
||||
dev->mmio_config->queue_pfn = RT_NULL;
|
||||
|
||||
queue->num = 0;
|
||||
queue->desc = RT_NULL;
|
||||
queue->avail = RT_NULL;
|
||||
queue->used = RT_NULL;
|
||||
}
|
||||
|
||||
void virtio_queue_notify(struct virtio_device *dev, rt_uint32_t queue_index)
|
||||
{
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
dev->mmio_config->queue_notify = queue_index;
|
||||
}
|
||||
|
||||
void virtio_submit_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index)
|
||||
{
|
||||
rt_size_t ring_size;
|
||||
struct virtq *queue;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
queue = &dev->queues[queue_index];
|
||||
ring_size = queue->num;
|
||||
|
||||
/* Tell the device the first index in our chain of descriptors */
|
||||
queue->avail->ring[queue->avail->idx % ring_size] = desc_index;
|
||||
rt_hw_dsb();
|
||||
|
||||
/* Tell the device another avail ring entry is available */
|
||||
queue->avail->idx++;
|
||||
rt_hw_dsb();
|
||||
}
|
||||
|
||||
rt_uint16_t virtio_alloc_desc(struct virtio_device *dev, rt_uint32_t queue_index)
|
||||
{
|
||||
int i;
|
||||
struct virtq *queue;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
RT_ASSERT(queue_index < dev->queues_num);
|
||||
|
||||
queue = &dev->queues[queue_index];
|
||||
|
||||
if (queue->free_count > 0)
|
||||
{
|
||||
rt_size_t ring_size = queue->num;
|
||||
|
||||
for (i = 0; i < ring_size; ++i)
|
||||
{
|
||||
if (queue->free[i])
|
||||
{
|
||||
queue->free[i] = RT_FALSE;
|
||||
queue->free_count--;
|
||||
|
||||
return (rt_uint16_t)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VIRTQ_INVALID_DESC_ID;
|
||||
}
|
||||
|
||||
void virtio_free_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index)
|
||||
{
|
||||
struct virtq *queue;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
queue = &dev->queues[queue_index];
|
||||
|
||||
RT_ASSERT(queue_index < dev->queues_num);
|
||||
RT_ASSERT(!queue->free[desc_index]);
|
||||
|
||||
queue->desc[desc_index].addr = 0;
|
||||
queue->desc[desc_index].len = 0;
|
||||
queue->desc[desc_index].flags = 0;
|
||||
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,
|
||||
rt_uint16_t *indexs)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
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] == VIRTQ_INVALID_DESC_ID)
|
||||
{
|
||||
for (j = 0; j < i; ++j)
|
||||
{
|
||||
virtio_free_desc(dev, queue_index, indexs[j]);
|
||||
}
|
||||
|
||||
return -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
void virtio_free_desc_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index)
|
||||
{
|
||||
rt_uint16_t flags, next;
|
||||
struct virtq_desc *desc;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
desc = &dev->queues[queue_index].desc[0];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
flags = desc[desc_index].flags;
|
||||
next = desc[desc_index].next;
|
||||
|
||||
virtio_free_desc(dev, queue_index, desc_index);
|
||||
|
||||
if (flags & VIRTQ_DESC_F_NEXT)
|
||||
{
|
||||
desc_index = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_fill_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index,
|
||||
rt_uint64_t addr, rt_uint32_t len, rt_uint16_t flags, rt_uint16_t next)
|
||||
{
|
||||
struct virtq_desc *desc;
|
||||
|
||||
_virtio_dev_check(dev);
|
||||
|
||||
desc = &dev->queues[queue_index].desc[desc_index];
|
||||
|
||||
desc->addr = addr;
|
||||
desc->len = len;
|
||||
desc->flags = flags;
|
||||
desc->next = next;
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-9-16 GuEe-GUI the first version
|
||||
* 2021-11-11 GuEe-GUI modify to virtio common interface
|
||||
*/
|
||||
|
||||
#ifndef __VIRTIO_H__
|
||||
#define __VIRTIO_H__
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifndef RT_USING_VIRTIO_VERSION
|
||||
#define RT_USING_VIRTIO_VERSION 0x1
|
||||
#endif
|
||||
|
||||
#include <virtio_mmio.h>
|
||||
#include <virtio_queue.h>
|
||||
|
||||
#define VIRTIO_MAGIC_VALUE 0x74726976 /* "virt" */
|
||||
|
||||
#define VIRTIO_STATUS_ACKNOWLEDGE (1 << 0)
|
||||
#define VIRTIO_STATUS_DRIVER (1 << 1)
|
||||
#define VIRTIO_STATUS_DRIVER_OK (1 << 2)
|
||||
#define VIRTIO_STATUS_FEATURES_OK (1 << 3)
|
||||
#define VIRTIO_STATUS_NEEDS_RESET (1 << 6)
|
||||
#define VIRTIO_STATUS_FAILED (1 << 7)
|
||||
|
||||
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
|
||||
#define VIRTIO_F_ANY_LAYOUT 27
|
||||
#define VIRTIO_F_RING_INDIRECT_DESC 28
|
||||
#define VIRTIO_F_RING_EVENT_IDX 29
|
||||
#define VIRTIO_F_VERSION_1 32
|
||||
#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))
|
||||
|
||||
enum
|
||||
{
|
||||
/* virtio 1.0 */
|
||||
VIRTIO_DEVICE_ID_INVALID = 0, /* Invalid device */
|
||||
VIRTIO_DEVICE_ID_NET = 1, /* Net */
|
||||
VIRTIO_DEVICE_ID_BLOCK = 2, /* Block */
|
||||
VIRTIO_DEVICE_ID_CONSOLE = 3, /* Console */
|
||||
VIRTIO_DEVICE_ID_RNG = 4, /* Rng */
|
||||
VIRTIO_DEVICE_ID_BALLOON = 5, /* Balloon */
|
||||
VIRTIO_DEVICE_ID_IOMEM = 6, /* IO memory */
|
||||
VIRTIO_DEVICE_ID_RPMSG = 7, /* Remote processor messaging */
|
||||
VIRTIO_DEVICE_ID_SCSI = 8, /* SCSI */
|
||||
VIRTIO_DEVICE_ID_9P = 9, /* 9p console */
|
||||
VIRTIO_DEVICE_ID_MAC80211_WLAN = 10, /* Mac80211 wlan */
|
||||
VIRTIO_DEVICE_ID_RPROC_SERIAL = 11, /* Remoteproc serial link */
|
||||
VIRTIO_DEVICE_ID_CAIF = 12, /* CAIF */
|
||||
VIRTIO_DEVICE_ID_MEM_BALLOON = 13, /* Memory balloon */
|
||||
VIRTIO_DEVICE_ID_GPU = 16, /* GPU */
|
||||
VIRTIO_DEVICE_ID_TIME = 17, /* Timer/clock device */
|
||||
VIRTIO_DEVICE_ID_INPUT = 18, /* Input */
|
||||
/* virtio 1.1 */
|
||||
VIRTIO_DEVICE_ID_SOCKET = 19, /* Socket device */
|
||||
VIRTIO_DEVICE_ID_CRYPTO = 20, /* Crypto device */
|
||||
VIRTIO_DEVICE_ID_SIG_DIS_MOD = 21, /* Signal Distribution Module */
|
||||
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
|
||||
};
|
||||
|
||||
struct virtio_device
|
||||
{
|
||||
rt_uint32_t irq;
|
||||
|
||||
struct virtq *queues;
|
||||
rt_size_t queues_num;
|
||||
|
||||
union
|
||||
{
|
||||
rt_ubase_t *mmio_base;
|
||||
struct virtio_mmio_config *mmio_config;
|
||||
};
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
struct rt_spinlock spinlock;
|
||||
#endif
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
||||
typedef rt_err_t (*virtio_device_init_handler)(rt_ubase_t *mmio_base, rt_uint32_t irq);
|
||||
|
||||
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_bool_t virtio_has_feature(struct virtio_device *dev, rt_uint32_t feature_bit);
|
||||
|
||||
rt_err_t virtio_queues_alloc(struct virtio_device *dev, rt_size_t queues_num);
|
||||
void virtio_queues_free(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);
|
||||
void virtio_queue_notify(struct virtio_device *dev, rt_uint32_t queue_index);
|
||||
|
||||
void virtio_submit_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index);
|
||||
|
||||
rt_uint16_t virtio_alloc_desc(struct virtio_device *dev, rt_uint32_t queue_index);
|
||||
void virtio_free_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index);
|
||||
rt_err_t virtio_alloc_desc_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_size_t count,
|
||||
rt_uint16_t *indexs);
|
||||
void virtio_free_desc_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index);
|
||||
void virtio_fill_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index,
|
||||
rt_uint64_t addr, rt_uint32_t len, rt_uint16_t flags, rt_uint16_t next);
|
||||
|
||||
#endif /* __VIRTIO_H__ */
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-9-16 GuEe-GUI the first version
|
||||
* 2021-11-11 GuEe-GUI using virtio common interface
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <cpuport.h>
|
||||
|
||||
#ifdef BSP_USING_VIRTIO_BLK
|
||||
|
||||
#include <virtio_blk.h>
|
||||
|
||||
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];
|
||||
struct virtio_device *virtio_dev = &virtio_blk_dev->virtio_dev;
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
|
||||
#endif
|
||||
|
||||
/* Allocate 3 descriptors */
|
||||
while (virtio_alloc_desc_chain(virtio_dev, 0, 3, idx))
|
||||
{
|
||||
#ifdef RT_USING_SMP
|
||||
rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
|
||||
#endif
|
||||
rt_thread_yield();
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtio_blk_dev->info[idx[0]].status = 0xff;
|
||||
virtio_blk_dev->info[idx[0]].valid = RT_TRUE;
|
||||
virtio_blk_dev->info[idx[0]].req.type = flags;
|
||||
virtio_blk_dev->info[idx[0]].req.ioprio = 0;
|
||||
virtio_blk_dev->info[idx[0]].req.sector = pos * (VIRTIO_BLK_BUF_DATA_SIZE / 512);
|
||||
|
||||
flags = flags == VIRTIO_BLK_T_OUT ? 0 : VIRTQ_DESC_F_WRITE;
|
||||
|
||||
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, 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, 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, VIRTIO_BLK_QUEUE, idx[0]);
|
||||
|
||||
virtio_queue_notify(virtio_dev, VIRTIO_BLK_QUEUE);
|
||||
|
||||
/* Wait for virtio_blk_isr() to done */
|
||||
while (virtio_blk_dev->info[idx[0]].valid)
|
||||
{
|
||||
#ifdef RT_USING_SMP
|
||||
rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
|
||||
#endif
|
||||
rt_thread_yield();
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtio_free_desc_chain(virtio_dev, VIRTIO_BLK_QUEUE, idx[0]);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
|
||||
#endif
|
||||
}
|
||||
|
||||
static rt_size_t virtio_blk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
|
||||
{
|
||||
virtio_blk_rw((struct virtio_blk_device *)dev, pos, buffer, VIRTIO_BLK_T_IN);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static rt_size_t virtio_blk_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
|
||||
{
|
||||
virtio_blk_rw((struct virtio_blk_device *)dev, pos, (void *)buffer, VIRTIO_BLK_T_OUT);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static rt_err_t virtio_blk_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
rt_err_t status = RT_EOK;
|
||||
struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_BLK_GETGEOME:
|
||||
{
|
||||
struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *)args;
|
||||
|
||||
if (geometry == RT_NULL)
|
||||
{
|
||||
status = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
geometry->bytes_per_sector = VIRTIO_BLK_BYTES_PER_SECTOR;
|
||||
geometry->block_size = VIRTIO_BLK_BLOCK_SIZE;
|
||||
geometry->sector_count = virtio_blk_dev->config->capacity;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = -RT_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
const static struct rt_device_ops virtio_blk_ops =
|
||||
{
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
virtio_blk_read,
|
||||
virtio_blk_write,
|
||||
virtio_blk_control
|
||||
};
|
||||
|
||||
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);
|
||||
rt_hw_dsb();
|
||||
|
||||
/* The device increments disk.used->idx when it adds an entry to the used ring */
|
||||
while (queue->used_idx != queue->used->idx)
|
||||
{
|
||||
rt_hw_dsb();
|
||||
id = queue->used->ring[queue->used_idx % queue->num].id;
|
||||
|
||||
RT_ASSERT(virtio_blk_dev->info[id].status == 0);
|
||||
|
||||
/* Done with buffer */
|
||||
virtio_blk_dev->info[id].valid = RT_FALSE;
|
||||
|
||||
queue->used_idx++;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
|
||||
#endif
|
||||
}
|
||||
|
||||
rt_err_t rt_virtio_blk_init(rt_ubase_t *mmio_base, rt_uint32_t irq)
|
||||
{
|
||||
static int dev_no = 0;
|
||||
char dev_name[RT_NAME_MAX];
|
||||
struct virtio_device *virtio_dev;
|
||||
struct virtio_blk_device *virtio_blk_dev;
|
||||
|
||||
virtio_blk_dev = rt_malloc(sizeof(struct virtio_blk_device));
|
||||
|
||||
if (virtio_blk_dev == RT_NULL)
|
||||
{
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
virtio_dev = &virtio_blk_dev->virtio_dev;
|
||||
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
|
||||
|
||||
virtio_reset_device(virtio_dev);
|
||||
virtio_status_acknowledge_driver(virtio_dev);
|
||||
|
||||
/* Negotiate features */
|
||||
virtio_dev->mmio_config->driver_features = virtio_dev->mmio_config->device_features & ~(
|
||||
(1 << VIRTIO_BLK_F_RO) |
|
||||
(1 << VIRTIO_BLK_F_MQ) |
|
||||
(1 << VIRTIO_BLK_F_SCSI) |
|
||||
(1 << VIRTIO_BLK_F_CONFIG_WCE) |
|
||||
(1 << VIRTIO_F_ANY_LAYOUT) |
|
||||
(1 << VIRTIO_F_RING_EVENT_IDX) |
|
||||
(1 << VIRTIO_F_RING_INDIRECT_DESC));
|
||||
|
||||
/* Tell device that feature negotiation is complete and we're completely ready */
|
||||
virtio_status_driver_ok(virtio_dev);
|
||||
|
||||
if (virtio_queues_alloc(virtio_dev, 1) != RT_EOK)
|
||||
{
|
||||
goto _alloc_fail;
|
||||
}
|
||||
|
||||
/* Initialize queue 0 */
|
||||
if (virtio_queue_init(virtio_dev, 0, VIRTIO_BLK_QUEUE_RING_SIZE) != RT_EOK)
|
||||
{
|
||||
goto _alloc_fail;
|
||||
}
|
||||
|
||||
virtio_blk_dev->parent.type = RT_Device_Class_Block;
|
||||
virtio_blk_dev->parent.ops = &virtio_blk_ops;
|
||||
|
||||
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);
|
||||
|
||||
return rt_device_register((rt_device_t)virtio_blk_dev, dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
_alloc_fail:
|
||||
|
||||
if (virtio_blk_dev != RT_NULL)
|
||||
{
|
||||
virtio_queues_free(virtio_dev);
|
||||
rt_free(virtio_blk_dev);
|
||||
}
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
#endif /* BSP_USING_VIRTIO_BLK */
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-9-16 GuEe-GUI the first version
|
||||
* 2021-11-11 GuEe-GUI using virtio common interface
|
||||
*/
|
||||
|
||||
#ifndef __VIRTIO_BLK_H__
|
||||
#define __VIRTIO_BLK_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#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
|
||||
#define VIRTIO_BLK_QUEUE_RING_SIZE 4
|
||||
|
||||
#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
|
||||
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
|
||||
#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
|
||||
#define VIRTIO_BLK_F_MQ 12 /* Support more than one vq */
|
||||
|
||||
#define VIRTIO_BLK_T_IN 0 /* Read the blk */
|
||||
#define VIRTIO_BLK_T_OUT 1 /* Write the blk */
|
||||
#define VIRTIO_BLK_T_SCSI_CMD 2
|
||||
#define VIRTIO_BLK_T_SCSI_CMD_OUT 3
|
||||
#define VIRTIO_BLK_T_FLUSH 4
|
||||
#define VIRTIO_BLK_T_FLUSH_OUT 5
|
||||
|
||||
struct virtio_blk_req
|
||||
{
|
||||
rt_uint32_t type;
|
||||
rt_uint32_t ioprio;
|
||||
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;
|
||||
rt_uint8_t status;
|
||||
|
||||
struct virtio_blk_req req;
|
||||
|
||||
} info[VIRTIO_BLK_QUEUE_RING_SIZE];
|
||||
};
|
||||
|
||||
rt_err_t rt_virtio_blk_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
|
||||
|
||||
#endif /* __VIRTIO_BLK_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* 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_CONSOLE_H__
|
||||
#define __VIRTIO_CONSOLE_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#include <virtio.h>
|
||||
|
||||
#ifndef RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR
|
||||
#define RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR 4
|
||||
#endif
|
||||
|
||||
#define VIRTIO_CONSOLE_QUEUE_DATA_RX 0
|
||||
#define VIRTIO_CONSOLE_QUEUE_DATA_TX 1
|
||||
#define VIRTIO_CONSOLE_QUEUE_CTRL_RX 2
|
||||
#define VIRTIO_CONSOLE_QUEUE_CTRL_TX 3
|
||||
#define VIRTIO_CONSOLE_QUEUE_SIZE 64
|
||||
|
||||
/* Every port has data rx & tx, and port0 has ctrl rx & tx in multiport */
|
||||
#define VIRTIO_CONSOLE_PORT_QUEUE_INDEX(id, queue) ((id) * 2 + (!!(id)) * 2 + (queue))
|
||||
|
||||
#define VIRTIO_CONSOLE_PORT_BAD_ID (~(rt_uint32_t)0)
|
||||
|
||||
#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */
|
||||
#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
|
||||
#define VIRTIO_CONSOLE_F_EMERG_WRITE 2 /* Does host support emergency write? */
|
||||
|
||||
struct virtio_console_config
|
||||
{
|
||||
rt_uint16_t cols;
|
||||
rt_uint16_t rows;
|
||||
rt_uint32_t max_nr_ports;
|
||||
rt_uint32_t emerg_wr;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct virtio_console_control
|
||||
{
|
||||
rt_uint32_t id; /* Port number */
|
||||
rt_uint16_t event; /* The kind of control event */
|
||||
rt_uint16_t value; /* Extra information for the event */
|
||||
};
|
||||
|
||||
enum virtio_console_control_event
|
||||
{
|
||||
VIRTIO_CONSOLE_DEVICE_READY = 0,
|
||||
VIRTIO_CONSOLE_PORT_ADD,
|
||||
VIRTIO_CONSOLE_PORT_REMOVE,
|
||||
VIRTIO_CONSOLE_PORT_READY,
|
||||
VIRTIO_CONSOLE_CONSOLE_PORT,
|
||||
VIRTIO_CONSOLE_RESIZE,
|
||||
VIRTIO_CONSOLE_PORT_OPEN,
|
||||
VIRTIO_CONSOLE_PORT_NAME,
|
||||
};
|
||||
|
||||
struct virtio_console_resize
|
||||
{
|
||||
rt_uint16_t cols;
|
||||
rt_uint16_t rows;
|
||||
};
|
||||
|
||||
struct virtio_console_device
|
||||
{
|
||||
struct rt_device parent;
|
||||
|
||||
struct virtio_device virtio_dev;
|
||||
|
||||
rt_uint32_t console_id;
|
||||
rt_size_t port_nr;
|
||||
rt_size_t max_port_nr;
|
||||
rt_list_t port_head;
|
||||
struct virtio_console_config *config;
|
||||
|
||||
struct
|
||||
{
|
||||
struct virtio_console_control rx_ctrl, tx_ctrl;
|
||||
} info[VIRTIO_CONSOLE_QUEUE_SIZE];
|
||||
};
|
||||
|
||||
rt_err_t rt_virtio_console_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
|
||||
|
||||
enum
|
||||
{
|
||||
VIRTIO_DEVICE_CTRL_CONSOLE_PORT_CREATE = 0x20,
|
||||
VIRTIO_DEVICE_CTRL_CONSOLE_PORT_DESTROY,
|
||||
};
|
||||
|
||||
#endif /* __VIRTIO_CONSOLE_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,412 +0,0 @@
|
||||
/*
|
||||
* 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__ */
|
||||
@@ -1,438 +0,0 @@
|
||||
/*
|
||||
* 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_queues_alloc(virtio_dev, 2) != RT_EOK)
|
||||
{
|
||||
goto _alloc_fail;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
virtio_queues_free(virtio_dev);
|
||||
rt_free(virtio_input_dev);
|
||||
}
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
#endif /* BSP_USING_VIRTIO_INPUT */
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* 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__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-9-16 GuEe-GUI the first version
|
||||
* 2021-11-11 GuEe-GUI modify to virtio common interface
|
||||
*/
|
||||
|
||||
#ifndef __VIRTIO_MMIO_H__
|
||||
#define __VIRTIO_MMIO_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
struct virtio_mmio_config
|
||||
{
|
||||
rt_uint32_t magic; /* [0x00]<RO> Magic value */
|
||||
rt_uint32_t version; /* [0x04]<RO> Device version number */
|
||||
rt_uint32_t device_id; /* [0x08]<RO> Virtio Subsystem Device ID */
|
||||
rt_uint32_t vendor_id; /* [0x0c]<RO> Virtio Subsystem Vendor ID */
|
||||
rt_uint32_t device_features; /* [0x10]<RO> Flags representing features the device supports */
|
||||
rt_uint32_t device_features_sel; /* [0x14]<WO> Device (host) features word selection. */
|
||||
rt_uint32_t res0[2]; /* [0x18] */
|
||||
rt_uint32_t driver_features; /* [0x20]<WO> Device features understood and activated by the driver */
|
||||
rt_uint32_t driver_features_sel; /* [0x24]<WO> Activated (guest) features word selection */
|
||||
rt_uint32_t guest_page_size; /* [0x28]<WO> Guest page size, this value should be a power of 2 */
|
||||
rt_uint32_t res1[1]; /* [0x2c] */
|
||||
rt_uint32_t queue_sel; /* [0x30]<WO> Virtual queue index */
|
||||
rt_uint32_t queue_num_max; /* [0x34]<RO> Maximum virtual queue size */
|
||||
rt_uint32_t queue_num; /* [0x38]<WO> Virtual queue size */
|
||||
rt_uint32_t queue_align; /* [0x3c]<WO> Used Ring alignment in the virtual queue */
|
||||
rt_uint32_t queue_pfn; /* [0x40]<RW> Guest physical page number of the virtual queue */
|
||||
rt_uint32_t queue_ready; /* [0x44]<RW> Virtual queue ready bit */
|
||||
rt_uint32_t res2[2]; /* [0x48] */
|
||||
rt_uint32_t queue_notify; /* [0x50]<WO> Queue notifier */
|
||||
rt_uint32_t res3[3]; /* [0x54] */
|
||||
rt_uint32_t interrupt_status; /* [0x60]<RO> Interrupt status */
|
||||
rt_uint32_t interrupt_ack; /* [0x64]<WO> Interrupt acknowledge */
|
||||
rt_uint32_t res4[2]; /* [0x68] */
|
||||
rt_uint32_t status; /* [0x70]<RW> Device status */
|
||||
rt_uint32_t res5[3]; /* [0x74] */
|
||||
rt_uint32_t queue_desc_low; /* [0x80]<WO> Virtual queue’s Descriptor Area 64 bit long physical address */
|
||||
rt_uint32_t queue_desc_high; /* [0x84]<WO> */
|
||||
rt_uint32_t res6[2]; /* [0x88] */
|
||||
rt_uint32_t queue_driver_low; /* [0x90]<WO> Virtual queue’s Driver Area 64 bit long physical address */
|
||||
rt_uint32_t queue_driver_high; /* [0x94]<WO> */
|
||||
rt_uint32_t res7[2]; /* [0x98] */
|
||||
rt_uint32_t queue_device_low; /* [0xa0]<WO> Virtual queue’s Device Area 64 bit long physical address */
|
||||
rt_uint32_t queue_device_high; /* [0xa4]<WO> */
|
||||
rt_uint32_t res8[21]; /* [0xa8] */
|
||||
rt_uint32_t config_generation; /* [0xfc]<RO> Configuration atomicity value */
|
||||
rt_uint32_t config[]; /* [0x100+]<RO> Configuration space */
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* __VIRTIO_MMIO_H__ */
|
||||
@@ -1,303 +0,0 @@
|
||||
/*
|
||||
* 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];
|
||||
|
||||
#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 = 0;
|
||||
virtio_net_dev->info[id].hdr.gso_type = 0;
|
||||
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 = 0;
|
||||
virtio_net_dev->info[id].hdr.num_buffers = 0;
|
||||
|
||||
pbuf_copy_partial(p, virtio_net_dev->info[id].rx_buffer, p->tot_len, 0);
|
||||
|
||||
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(virtio_net_dev->info[id].rx_buffer), 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
|
||||
|
||||
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].tx_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->config->mac, sizeof(virtio_net_dev->config->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)
|
||||
{
|
||||
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;
|
||||
|
||||
virtio_net_dev->config = (struct virtio_net_config *)virtio_dev->mmio_config->config;
|
||||
|
||||
#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_F_RING_EVENT_IDX));
|
||||
|
||||
virtio_status_driver_ok(virtio_dev);
|
||||
|
||||
if (virtio_queues_alloc(virtio_dev, 2) != RT_EOK)
|
||||
{
|
||||
goto _alloc_fail;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
virtio_queues_free(virtio_dev);
|
||||
rt_free(virtio_net_dev);
|
||||
}
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
#endif /* BSP_USING_VIRTIO_NET */
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define VIRTIO_NET_MSS 1514
|
||||
#define VIRTIO_NET_HDR_SIZE (sizeof(struct virtio_net_hdr))
|
||||
#define VIRTIO_NET_PAYLOAD_MAX_SIZE (VIRTIO_NET_HDR_SIZE + VIRTIO_NET_MSS)
|
||||
|
||||
struct virtio_net_config
|
||||
{
|
||||
rt_uint8_t mac[6];
|
||||
rt_uint16_t status;
|
||||
rt_uint16_t max_virtqueue_pairs;
|
||||
rt_uint16_t mtu;
|
||||
rt_uint32_t speed;
|
||||
rt_uint8_t duplex;
|
||||
rt_uint8_t rss_max_key_size;
|
||||
rt_uint16_t rss_max_indirection_table_length;
|
||||
rt_uint32_t supported_hash_types;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct virtio_net_device
|
||||
{
|
||||
struct eth_device parent;
|
||||
|
||||
struct virtio_device virtio_dev;
|
||||
|
||||
struct virtio_net_config *config;
|
||||
|
||||
struct
|
||||
{
|
||||
/* Transmit hdr */
|
||||
struct virtio_net_hdr hdr;
|
||||
/* Transmit buffer */
|
||||
rt_uint8_t tx_buffer[VIRTIO_NET_PAYLOAD_MAX_SIZE];
|
||||
/* Receive buffer */
|
||||
rt_uint8_t rx_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__ */
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* 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_QUEUE_H__
|
||||
#define __VIRTIO_QUEUE_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#define VIRTQ_DESC_F_NEXT 1 /* This marks a buffer as continuing via the next field. */
|
||||
#define VIRTQ_DESC_F_WRITE 2 /* This marks a buffer as write-only (otherwise read-only). */
|
||||
#define VIRTQ_DESC_F_INDIRECT 4 /* This means the buffer contains a list of buffer descriptors. */
|
||||
|
||||
/*
|
||||
* The device uses this in used->flags to advise the driver: don't kick me
|
||||
* when you add a buffer. It's unreliable, so it's simply an optimization.
|
||||
*/
|
||||
#define VIRTQ_USED_F_NO_NOTIFY 1
|
||||
|
||||
/*
|
||||
* The driver uses this in avail->flags to advise the device: don't
|
||||
* interrupt me when you consume a buffer. It's unreliable, so it's
|
||||
* simply an optimization.
|
||||
*/
|
||||
#define VIRTQ_AVAIL_F_NO_INTERRUPT 1
|
||||
|
||||
/* Virtqueue descriptors: 16 bytes. These can chain together via "next". */
|
||||
struct virtq_desc
|
||||
{
|
||||
rt_uint64_t addr; /* Address (guest-physical). */
|
||||
rt_uint32_t len; /* Length. */
|
||||
rt_uint16_t flags; /* The flags as indicated above. */
|
||||
rt_uint16_t next; /* We chain unused descriptors via this, too */
|
||||
};
|
||||
|
||||
struct virtq_avail
|
||||
{
|
||||
rt_uint16_t flags; /* Notifications */
|
||||
rt_uint16_t idx; /* Where the driver would put the next descriptor entry in the ring (modulo the queue size) */
|
||||
rt_uint16_t ring[];
|
||||
|
||||
/*
|
||||
* Only if VIRTIO_F_RING_EVENT_IDX
|
||||
* rt_uint16_t used_event;
|
||||
*/
|
||||
};
|
||||
|
||||
struct virtq_used_elem
|
||||
{
|
||||
rt_uint32_t id; /* Index of start of used descriptor chain. */
|
||||
rt_uint32_t len; /* Total length of the descriptor chain which was written to. */
|
||||
};
|
||||
|
||||
struct virtq_used
|
||||
{
|
||||
rt_uint16_t flags;
|
||||
rt_uint16_t idx;
|
||||
struct virtq_used_elem ring[];
|
||||
|
||||
/*
|
||||
* Only if VIRTIO_F_RING_EVENT_IDX
|
||||
* rt_uint16_t avail_event;
|
||||
*/
|
||||
};
|
||||
|
||||
struct virtq
|
||||
{
|
||||
rt_uint32_t num;
|
||||
|
||||
struct virtq_desc *desc;
|
||||
struct virtq_avail *avail;
|
||||
struct virtq_used *used;
|
||||
|
||||
/* 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))
|
||||
/* flags, idx, used_event + ring * ring_size */
|
||||
#define VIRTQ_AVAIL_TOTAL_SIZE(ring_size) (sizeof(rt_uint16_t) * 3 + sizeof(rt_uint16_t) * (ring_size))
|
||||
/* flags, idx, avail_event + ring * ring_size */
|
||||
#define VIRTQ_USED_TOTAL_SIZE(ring_size) (sizeof(rt_uint16_t) * 3 + sizeof(struct virtq_used_elem) * (ring_size))
|
||||
|
||||
#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__ */
|
||||
@@ -1,4 +1,8 @@
|
||||
|
||||
menu "AARCH64 qemu virt64 configs"
|
||||
menuconfig BSP_SUPPORT_FPU
|
||||
bool "Using Float"
|
||||
default y
|
||||
|
||||
menuconfig BSP_USING_UART
|
||||
bool "Using UART"
|
||||
@@ -11,7 +15,6 @@ menu "AARCH64 qemu virt64 configs"
|
||||
default y
|
||||
endif
|
||||
|
||||
|
||||
menuconfig BSP_USING_RTC
|
||||
bool "Using RTC"
|
||||
select RT_USING_RTC
|
||||
@@ -31,22 +34,32 @@ menu "AARCH64 qemu virt64 configs"
|
||||
|
||||
config BSP_USING_VIRTIO_BLK
|
||||
bool "Using VirtIO BLK"
|
||||
select RT_USING_VIRTIO
|
||||
select RT_USING_VIRTIO_BLK
|
||||
default y
|
||||
|
||||
config BSP_USING_VIRTIO_NET
|
||||
bool "Using VirtIO NET"
|
||||
select RT_USING_VIRTIO
|
||||
select RT_USING_VIRTIO_NET
|
||||
default y
|
||||
|
||||
config BSP_USING_VIRTIO_CONSOLE
|
||||
bool "Using VirtIO Console"
|
||||
select RT_USING_VIRTIO
|
||||
select RT_USING_VIRTIO_CONSOLE
|
||||
default y
|
||||
|
||||
config BSP_USING_VIRTIO_GPU
|
||||
bool "Using VirtIO GPU"
|
||||
select RT_USING_VIRTIO
|
||||
select RT_USING_VIRTIO_GPU
|
||||
default y
|
||||
|
||||
config BSP_USING_VIRTIO_INPUT
|
||||
bool "Using VirtIO Input"
|
||||
select RT_USING_VIRTIO
|
||||
select RT_USING_VIRTIO_INPUT
|
||||
default y
|
||||
|
||||
config BSP_USING_GIC
|
||||
@@ -3,7 +3,7 @@
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
src = Glob('*.c')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
120
bsp/qemu-virt64-aarch64/drivers/board.c
Normal file
120
bsp/qemu-virt64-aarch64/drivers/board.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2012-11-20 Bernard the first version
|
||||
* 2018-11-22 Jesven add rt_hw_spin_lock
|
||||
* add rt_hw_spin_unlock
|
||||
* add smp ipi init
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <mmu.h>
|
||||
#ifdef RT_USING_SMART
|
||||
#include <page.h>
|
||||
#include <lwp_arch.h>
|
||||
#endif
|
||||
#include "board.h"
|
||||
|
||||
#ifdef RT_USING_FDT
|
||||
#include "interrupt.h"
|
||||
#include "dtb_node.h"
|
||||
#include <psci_api.h>
|
||||
#include <cpu.h>
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
struct mem_desc platform_mem_desc[] = {
|
||||
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM}
|
||||
};
|
||||
#else
|
||||
struct mem_desc platform_mem_desc[] =
|
||||
{
|
||||
{0x40000000, 0x80000000 - 1, 0x40000000, NORMAL_MEM},
|
||||
// {PL031_RTC_BASE, PL031_RTC_BASE + 0x1000 - 1, PL031_RTC_BASE, DEVICE_MEM},
|
||||
// {PL061_GPIO_BASE, PL061_GPIO_BASE + 0x1000 - 1, PL061_GPIO_BASE, DEVICE_MEM},
|
||||
{PL011_UART0_BASE, PL011_UART0_BASE + ARCH_SECTION_SIZE - 1, PL011_UART0_BASE, DEVICE_MEM},
|
||||
{VIRTIO_MMIO_BASE, RT_ALIGN(VIRTIO_MMIO_BASE + VIRTIO_MAX_NR * VIRTIO_MMIO_SIZE, ARCH_SECTION_SIZE) - 1, VIRTIO_MMIO_BASE, DEVICE_MEM},
|
||||
#ifdef BSP_USING_GICV2
|
||||
{GIC_PL390_DISTRIBUTOR_PPTR, GIC_PL390_DISTRIBUTOR_PPTR + ARCH_SECTION_SIZE - 1, GIC_PL390_DISTRIBUTOR_PPTR, DEVICE_MEM},
|
||||
#endif
|
||||
#ifdef BSP_USING_GICV3
|
||||
{GIC_PL500_DISTRIBUTOR_PPTR, GIC_PL500_DISTRIBUTOR_PPTR + 0x1000 - 1, GIC_PL500_DISTRIBUTOR_PPTR, DEVICE_MEM},
|
||||
{GIC_PL500_REDISTRIBUTOR_PPTR, GIC_PL500_REDISTRIBUTOR_PPTR + 0xf60000 - 1, GIC_PL500_REDISTRIBUTOR_PPTR, DEVICE_MEM},
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
|
||||
|
||||
void idle_wfi(void)
|
||||
{
|
||||
asm volatile ("wfi");
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will initialize board
|
||||
*/
|
||||
|
||||
rt_mmu_info mmu_info;
|
||||
|
||||
extern size_t MMUTable[];
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
rt_region_t init_page_region = {
|
||||
PAGE_START,
|
||||
PAGE_END,
|
||||
};
|
||||
#endif
|
||||
|
||||
void rt_hw_board_init(void)
|
||||
{
|
||||
#ifdef RT_USING_SMART
|
||||
rt_page_init(init_page_region);
|
||||
|
||||
rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
|
||||
|
||||
rt_hw_mmu_map_init(&mmu_info, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
|
||||
|
||||
arch_kuser_init(&mmu_info, (void*)0xffffffffffff0000);
|
||||
#else
|
||||
rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
|
||||
rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0);
|
||||
rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000);
|
||||
#endif
|
||||
|
||||
/* initialize hardware interrupt */
|
||||
rt_hw_interrupt_init();
|
||||
|
||||
/* initialize system heap */
|
||||
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
|
||||
|
||||
/* support debug feature before components init */
|
||||
rt_hw_uart_init();
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
|
||||
#ifdef RT_USING_FDT
|
||||
// TODO 0x44000000 should be replace by a variable
|
||||
void * fdt_start = (void *)0x44000000 - PV_OFFSET;
|
||||
device_tree_setup(fdt_start);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
rt_hw_cpu_init();
|
||||
#else
|
||||
psci_init();
|
||||
#endif /* RT_USING_SMP */
|
||||
#endif
|
||||
|
||||
rt_components_board_init();
|
||||
|
||||
rt_thread_idle_sethook(idle_wfi);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
/* install IPI handle */
|
||||
rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
|
||||
#endif
|
||||
}
|
||||
36
bsp/qemu-virt64-aarch64/drivers/board.h
Normal file
36
bsp/qemu-virt64-aarch64/drivers/board.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* File : board.h
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2013-07-06 Bernard the first version
|
||||
*/
|
||||
|
||||
#ifndef __BOARD_H__
|
||||
#define __BOARD_H__
|
||||
|
||||
#include <virt.h>
|
||||
|
||||
extern unsigned char __bss_start;
|
||||
extern unsigned char __bss_end;
|
||||
|
||||
#define HEAP_BEGIN (void *)&__bss_end
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#define HEAP_END (rt_size_t)(KERNEL_VADDR_START + 64 * 1024 * 1024)
|
||||
#define PAGE_START HEAP_END + 1 * 1024 * 1024
|
||||
#define PAGE_END ((rt_size_t)KERNEL_VADDR_START + 128 * 1024 * 1024)
|
||||
#else
|
||||
#define HEAP_END ((void *)HEAP_BEGIN + 64 * 1024 * 1024)
|
||||
#define KERNEL_VADDR_START 0x40000000
|
||||
#define PV_OFFSET 0
|
||||
#endif
|
||||
|
||||
void rt_hw_board_init(void);
|
||||
|
||||
int rt_hw_uart_init(void);
|
||||
|
||||
#endif
|
||||
@@ -39,14 +39,16 @@ static struct pl061
|
||||
void *args[PL061_GPIO_NR];
|
||||
} _pl061;
|
||||
|
||||
static rt_ubase_t pl061_gpio_base = PL061_GPIO_BASE;
|
||||
|
||||
rt_inline rt_uint8_t pl061_read8(rt_ubase_t offset)
|
||||
{
|
||||
return HWREG8(PL061_GPIO_BASE + offset);
|
||||
return HWREG8(pl061_gpio_base + offset);
|
||||
}
|
||||
|
||||
rt_inline void pl061_write8(rt_ubase_t offset, rt_uint8_t value)
|
||||
{
|
||||
HWREG8(PL061_GPIO_BASE + offset) = value;
|
||||
HWREG8(pl061_gpio_base + offset) = value;
|
||||
}
|
||||
|
||||
static void pl061_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
|
||||
@@ -303,6 +305,10 @@ int rt_hw_gpio_init(void)
|
||||
rt_spin_lock_init(&_pl061.spinlock);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_LWP
|
||||
pl061_gpio_base = (rt_size_t)rt_ioremap((void *)pl061_gpio_base, PL061_GPIO_SIZE);
|
||||
#endif
|
||||
|
||||
rt_device_pin_register("gpio", &ops, RT_NULL);
|
||||
rt_hw_interrupt_install(PL061_GPIO_IRQNUM, rt_hw_gpio_isr, RT_NULL, "gpio");
|
||||
rt_hw_interrupt_umask(PL061_GPIO_IRQNUM);
|
||||
123
bsp/qemu-virt64-aarch64/drivers/drv_rtc.c
Normal file
123
bsp/qemu-virt64-aarch64/drivers/drv_rtc.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-11-4 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <sys/time.h>
|
||||
#include <board.h>
|
||||
|
||||
#include "drv_rtc.h"
|
||||
|
||||
#ifdef BSP_USING_RTC
|
||||
|
||||
#define RTC_DR 0x00 /* data read register */
|
||||
#define RTC_MR 0x04 /* match register */
|
||||
#define RTC_LR 0x08 /* data load register */
|
||||
#define RTC_CR 0x0c /* control register */
|
||||
#define RTC_IMSC 0x10 /* interrupt mask and set register */
|
||||
#define RTC_RIS 0x14 /* raw interrupt status register */
|
||||
#define RTC_MIS 0x18 /* masked interrupt status register */
|
||||
#define RTC_ICR 0x1c /* interrupt clear register */
|
||||
|
||||
#define RTC_CR_OPEN 1
|
||||
#define RTC_CR_CLOSE 0
|
||||
|
||||
static struct hw_rtc_device rtc_device;
|
||||
static rt_ubase_t pl031_rtc_base = PL031_RTC_BASE;
|
||||
|
||||
rt_inline rt_uint32_t pl031_read32(rt_ubase_t offset)
|
||||
{
|
||||
return (*((volatile unsigned int *)(pl031_rtc_base + offset)));
|
||||
}
|
||||
|
||||
rt_inline void pl031_write32(rt_ubase_t offset, rt_uint32_t value)
|
||||
{
|
||||
(*((volatile unsigned int *)(pl031_rtc_base + offset))) = value;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_rtc_init(rt_device_t dev)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_rtc_open(rt_device_t dev, rt_uint16_t oflag)
|
||||
{
|
||||
pl031_write32(RTC_CR, RTC_CR_OPEN);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_rtc_close(rt_device_t dev)
|
||||
{
|
||||
pl031_write32(RTC_CR, RTC_CR_CLOSE);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t pl031_rtc_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_RTC_GET_TIME:
|
||||
*(rt_uint32_t *)args = pl031_read32(RTC_DR);
|
||||
break;
|
||||
case RT_DEVICE_CTRL_RTC_SET_TIME:
|
||||
pl031_write32(RTC_LR, *(time_t *)args);
|
||||
break;
|
||||
default:
|
||||
return RT_EINVAL;
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_size_t pl031_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
|
||||
{
|
||||
pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
|
||||
return size;
|
||||
}
|
||||
|
||||
static rt_size_t pl031_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
|
||||
{
|
||||
pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
|
||||
return size;
|
||||
}
|
||||
|
||||
const static struct rt_device_ops pl031_rtc_ops =
|
||||
{
|
||||
.init = pl031_rtc_init,
|
||||
.open = pl031_rtc_open,
|
||||
.close = pl031_rtc_close,
|
||||
.read = pl031_rtc_read,
|
||||
.write = pl031_rtc_write,
|
||||
.control = pl031_rtc_control
|
||||
};
|
||||
|
||||
int rt_hw_rtc_init(void)
|
||||
{
|
||||
#ifdef RT_USING_LWP
|
||||
pl031_rtc_base = (rt_size_t)rt_ioremap((void *)pl031_rtc_base, PL031_RTC_SIZE);
|
||||
#endif
|
||||
|
||||
rt_memset(&rtc_device, 0, sizeof(rtc_device));
|
||||
|
||||
rtc_device.device.type = RT_Device_Class_RTC;
|
||||
rtc_device.device.rx_indicate = RT_NULL;
|
||||
rtc_device.device.tx_complete = RT_NULL;
|
||||
rtc_device.device.ops = &pl031_rtc_ops;
|
||||
rtc_device.device.user_data = RT_NULL;
|
||||
|
||||
/* register a rtc device */
|
||||
rt_device_register(&rtc_device.device, "rtc", RT_DEVICE_FLAG_RDWR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
|
||||
#endif /* BSP_USING_RTC */
|
||||
46
bsp/qemu-virt64-aarch64/drivers/drv_timer.c
Normal file
46
bsp/qemu-virt64-aarch64/drivers/drv_timer.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-22 Jesven first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <stdint.h>
|
||||
#include "cp15.h"
|
||||
#include "board.h"
|
||||
#include "gtimer.h"
|
||||
|
||||
#define TIMER_IRQ 30
|
||||
|
||||
static rt_uint64_t timerStep = 0;
|
||||
|
||||
static void rt_hw_timer_isr(int vector, void *param)
|
||||
{
|
||||
rt_hw_set_gtimer_val(timerStep);
|
||||
rt_tick_increase();
|
||||
}
|
||||
|
||||
void rt_hw_timer_enable(void)
|
||||
{
|
||||
rt_hw_set_gtimer_val(timerStep);
|
||||
rt_hw_interrupt_umask(TIMER_IRQ);
|
||||
rt_hw_gtimer_enable();
|
||||
}
|
||||
|
||||
int rt_hw_timer_init(void)
|
||||
{
|
||||
rt_hw_interrupt_install(TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
|
||||
__ISB();
|
||||
timerStep = rt_hw_get_gtimer_frq();
|
||||
__DSB();
|
||||
timerStep /= RT_TICK_PER_SECOND;
|
||||
rt_hw_timer_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_timer_init);
|
||||
16
bsp/qemu-virt64-aarch64/drivers/drv_timer.h
Normal file
16
bsp/qemu-virt64-aarch64/drivers/drv_timer.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-22 Jesven first version
|
||||
*/
|
||||
|
||||
#ifndef DRV_TIMER_H__
|
||||
#define DRV_TIMER_H__
|
||||
|
||||
void timer_init(int timer, unsigned int preload);
|
||||
|
||||
#endif
|
||||
@@ -1,39 +1,46 @@
|
||||
/*
|
||||
* serial.c UART driver
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018/5/5 Bernard The first version
|
||||
* 2013-03-30 Bernard the first verion
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define PL011_UARTDR 0x000
|
||||
#define PL011_UARTFR 0x018
|
||||
#define PL011_UARTFR_TXFF_BIT 5
|
||||
|
||||
unsigned int readl(volatile void *addr)
|
||||
{
|
||||
return *(volatile unsigned int *)addr;
|
||||
}
|
||||
|
||||
void writel(unsigned int v, volatile void *addr)
|
||||
{
|
||||
*(volatile unsigned int *)addr = v;
|
||||
}
|
||||
#include "mmu.h"
|
||||
|
||||
struct hw_uart_device
|
||||
{
|
||||
rt_ubase_t hw_base;
|
||||
rt_uint32_t irqno;
|
||||
rt_size_t hw_base;
|
||||
rt_size_t irqno;
|
||||
};
|
||||
|
||||
#define UART_DR(base) __REG32(base + 0x00)
|
||||
#define UART_FR(base) __REG32(base + 0x18)
|
||||
#define UART_CR(base) __REG32(base + 0x30)
|
||||
#define UART_IMSC(base) __REG32(base + 0x38)
|
||||
#define UART_ICR(base) __REG32(base + 0x44)
|
||||
|
||||
#define UARTFR_RXFE 0x10
|
||||
#define UARTFR_TXFF 0x20
|
||||
#define UARTIMSC_RXIM 0x10
|
||||
#define UARTIMSC_TXIM 0x20
|
||||
#define UARTICR_RXIC 0x10
|
||||
#define UARTICR_TXIC 0x20
|
||||
|
||||
static void rt_hw_uart_isr(int irqno, void *param)
|
||||
{
|
||||
struct rt_serial_device *serial = (struct rt_serial_device *)param;
|
||||
|
||||
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
|
||||
}
|
||||
|
||||
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
||||
{
|
||||
return RT_EOK;
|
||||
@@ -42,28 +49,22 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
|
||||
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
||||
{
|
||||
struct hw_uart_device *uart;
|
||||
uint32_t val;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
uart = (struct hw_uart_device *)serial->parent.user_data;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* disable rx irq */
|
||||
val = readl((volatile void *)(uart->hw_base + 0x38));
|
||||
val &= ~0x10;
|
||||
writel(val, (volatile void *)(uart->hw_base + 0x38));
|
||||
rt_hw_interrupt_mask(uart->irqno);
|
||||
break;
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* disable rx irq */
|
||||
UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM;
|
||||
break;
|
||||
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* enable rx irq */
|
||||
val = readl((volatile void *)(uart->hw_base + 0x38));
|
||||
val |= 0x10;
|
||||
writel(val, (volatile void *)(uart->hw_base + 0x38));
|
||||
rt_hw_interrupt_umask(uart->irqno);
|
||||
break;
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* enable rx irq */
|
||||
UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM;
|
||||
rt_hw_interrupt_umask(uart->irqno);
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
@@ -76,26 +77,24 @@ static int uart_putc(struct rt_serial_device *serial, char c)
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
uart = (struct hw_uart_device *)serial->parent.user_data;
|
||||
|
||||
while (readl((volatile void *)(uart->hw_base + PL011_UARTFR)) & (1 << PL011_UARTFR_TXFF_BIT))
|
||||
{
|
||||
}
|
||||
|
||||
writel(c, (volatile void *)( uart->hw_base + PL011_UARTDR));
|
||||
while (UART_FR(uart->hw_base) & UARTFR_TXFF);
|
||||
UART_DR(uart->hw_base) = c;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int uart_getc(struct rt_serial_device *serial)
|
||||
{
|
||||
int ch = -1;
|
||||
int ch;
|
||||
struct hw_uart_device *uart;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
uart = (struct hw_uart_device *)serial->parent.user_data;
|
||||
|
||||
if (!(readl((volatile void *)(uart->hw_base + 0x18)) & (1 << 4)))
|
||||
ch = -1;
|
||||
if (!(UART_FR(uart->hw_base) & UARTFR_RXFE))
|
||||
{
|
||||
ch = readl((volatile void *)(uart->hw_base));
|
||||
ch = UART_DR(uart->hw_base) & 0xff;
|
||||
}
|
||||
|
||||
return ch;
|
||||
@@ -109,12 +108,6 @@ static const struct rt_uart_ops _uart_ops =
|
||||
uart_getc,
|
||||
};
|
||||
|
||||
static void rt_hw_uart_isr(int irqno, void *param)
|
||||
{
|
||||
struct rt_serial_device *serial = (struct rt_serial_device*)param;
|
||||
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
|
||||
}
|
||||
|
||||
#ifdef RT_USING_UART0
|
||||
/* UART device driver structure */
|
||||
static struct hw_uart_device _uart0_device =
|
||||
@@ -131,6 +124,7 @@ int rt_hw_uart_init(void)
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
|
||||
#ifdef RT_USING_UART0
|
||||
_uart0_device.hw_base = (rt_size_t)rt_ioremap((void*)_uart0_device.hw_base, PL011_UART0_SIZE);
|
||||
uart = &_uart0_device;
|
||||
|
||||
_serial0.ops = &_uart_ops;
|
||||
@@ -138,9 +132,11 @@ int rt_hw_uart_init(void)
|
||||
|
||||
/* register UART1 device */
|
||||
rt_hw_serial_register(&_serial0, "uart0",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0");
|
||||
/* enable Rx and Tx of UART */
|
||||
UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -5,12 +5,12 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-5-30 Bernard the first version
|
||||
* 2013-03-30 Bernard the first verion
|
||||
*/
|
||||
|
||||
#ifndef DRV_UART_H__
|
||||
#define DRV_UART_H__
|
||||
#ifndef __DRV_UART_H__
|
||||
#define __DRV_UART_H__
|
||||
|
||||
int rt_hw_uart_init(void);
|
||||
|
||||
#endif /* DRV_UART_H__ */
|
||||
#endif /* __DRV_UART_H__ */
|
||||
@@ -62,6 +62,15 @@ int rt_virtio_devices_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_LWP
|
||||
mmio_base = (rt_ubase_t)rt_ioremap((void *)mmio_base, VIRTIO_MMIO_SIZE * VIRTIO_MAX_NR);
|
||||
|
||||
if (mmio_base == RT_NULL)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < VIRTIO_MAX_NR; ++i, ++irq, mmio_base += VIRTIO_MMIO_SIZE)
|
||||
{
|
||||
mmio_config = (struct virtio_mmio_config *)mmio_base;
|
||||
36
bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c
Normal file
36
bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <cpu.h>
|
||||
#include "gic.h"
|
||||
#include "interrupt.h"
|
||||
#include "mmu.h"
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
|
||||
extern unsigned long MMUTable[];
|
||||
|
||||
void rt_hw_secondary_cpu_bsp_start(void)
|
||||
{
|
||||
rt_hw_spin_lock(&_cpus_lock);
|
||||
|
||||
rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
|
||||
|
||||
// interrupt init
|
||||
rt_hw_vector_init();
|
||||
|
||||
arm_gic_cpu_init(0, 0);
|
||||
|
||||
// local timer init
|
||||
|
||||
rt_system_scheduler_start();
|
||||
}
|
||||
|
||||
#endif // SMP
|
||||
@@ -13,6 +13,18 @@
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#include <mmu.h>
|
||||
#include <ioremap.h>
|
||||
|
||||
extern rt_mmu_info mmu_info;
|
||||
#else
|
||||
#define rt_ioremap(x, ...) (x)
|
||||
#endif
|
||||
|
||||
#define __REG32(x) (*((volatile unsigned int *)(x)))
|
||||
#define __REG16(x) (*((volatile unsigned short *)(x)))
|
||||
|
||||
/* UART */
|
||||
#define PL011_UART0_BASE 0x09000000
|
||||
#define PL011_UART0_SIZE 0x00001000
|
||||
@@ -47,6 +59,8 @@
|
||||
/* GICv2 */
|
||||
#define GIC_PL390_DISTRIBUTOR_PPTR 0x08000000
|
||||
#define GIC_PL390_CONTROLLER_PPTR 0x08010000
|
||||
#define GIC_PL390_HYPERVISOR_BASE 0x08030000
|
||||
#define GIC_PL390_VIRTUAL_CPU_BASE 0x08040000
|
||||
|
||||
/* GICv3 */
|
||||
#define GIC_PL500_DISTRIBUTOR_PPTR GIC_PL390_DISTRIBUTOR_PPTR
|
||||
@@ -55,7 +69,7 @@
|
||||
#define GIC_PL500_ITS_PPTR 0x08080000
|
||||
|
||||
/* the basic constants and interfaces needed by gic */
|
||||
rt_inline rt_uint32_t platform_get_gic_dist_base(void)
|
||||
rt_inline rt_ubase_t platform_get_gic_dist_base(void)
|
||||
{
|
||||
#ifdef BSP_USING_GICV2
|
||||
return GIC_PL390_DISTRIBUTOR_PPTR;
|
||||
@@ -64,12 +78,12 @@ rt_inline rt_uint32_t platform_get_gic_dist_base(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
rt_inline rt_uint32_t platform_get_gic_redist_base(void)
|
||||
rt_inline rt_ubase_t platform_get_gic_redist_base(void)
|
||||
{
|
||||
return GIC_PL500_REDISTRIBUTOR_PPTR;
|
||||
}
|
||||
|
||||
rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
|
||||
rt_inline rt_ubase_t platform_get_gic_cpu_base(void)
|
||||
{
|
||||
#ifdef BSP_USING_GICV2
|
||||
return GIC_PL390_CONTROLLER_PPTR;
|
||||
@@ -78,7 +92,7 @@ rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
rt_inline rt_uint32_t platform_get_gic_its_base(void)
|
||||
rt_inline rt_ubase_t platform_get_gic_its_base(void)
|
||||
{
|
||||
return GIC_PL500_ITS_PPTR;
|
||||
}
|
||||
@@ -1,94 +1,65 @@
|
||||
/*
|
||||
* File : link.lds
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* 2017-5-30 bernard first version
|
||||
*/
|
||||
|
||||
/* _EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 0x20000; */
|
||||
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40008000;
|
||||
. = ALIGN(4096);
|
||||
/*. = 0x60080000; */
|
||||
. = 0x40080000;
|
||||
/* . = 0xffff000000080000; */
|
||||
|
||||
__text_start = .;
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.text.entrypoint)) /* The entry point */
|
||||
*(.vectors)
|
||||
*(.text) /* remaining code */
|
||||
*(.text.*) /* remaining code */
|
||||
KEEP(*(.text.entrypoint))
|
||||
KEEP(*(.vectors))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
*(.rodata) /* read-only data (constants) */
|
||||
*(.rodata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gnu.linkonce.t*)
|
||||
/* section information for utest */
|
||||
. = ALIGN(8);
|
||||
__rt_utest_tc_tab_start = .;
|
||||
KEEP(*(UtestTcTab))
|
||||
__rt_utest_tc_tab_end = .;
|
||||
|
||||
/* section information for finsh shell */
|
||||
. = ALIGN(16);
|
||||
. = ALIGN(8);
|
||||
__fsymtab_start = .;
|
||||
KEEP(*(FSymTab))
|
||||
__fsymtab_end = .;
|
||||
. = ALIGN(16);
|
||||
. = ALIGN(8);
|
||||
__vsymtab_start = .;
|
||||
KEEP(*(VSymTab))
|
||||
__vsymtab_end = .;
|
||||
. = ALIGN(16);
|
||||
. = ALIGN(8);
|
||||
|
||||
/* section information for initial. */
|
||||
. = ALIGN(16);
|
||||
/* section information for modules */
|
||||
. = ALIGN(8);
|
||||
__rtmsymtab_start = .;
|
||||
KEEP(*(RTMSymTab))
|
||||
__rtmsymtab_end = .;
|
||||
|
||||
/* section information for initialization */
|
||||
. = ALIGN(8);
|
||||
__rt_init_start = .;
|
||||
KEEP(*(SORT(.rti_fn*)))
|
||||
__rt_init_end = .;
|
||||
. = ALIGN(16);
|
||||
} =0
|
||||
__text_end = .;
|
||||
|
||||
. = ALIGN(16);
|
||||
_etext = .;
|
||||
}
|
||||
|
||||
.eh_frame_hdr :
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame_entry)
|
||||
}
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
|
||||
. = ALIGN(16);
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
|
||||
*(.data1)
|
||||
*(.data1.*)
|
||||
|
||||
. = ALIGN(16);
|
||||
_gp = ABSOLUTE(.); /* Base of small data */
|
||||
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
__exidx_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(16);
|
||||
__rodata_start = .;
|
||||
.rodata : { *(.rodata) *(.rodata.*) }
|
||||
__rodata_end = .;
|
||||
|
||||
. = ALIGN(8);
|
||||
.ctors :
|
||||
{
|
||||
PROVIDE(__ctors_start__ = .);
|
||||
/* new GCC version uses .init_array */
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE(__ctors_end__ = .);
|
||||
@@ -97,56 +68,43 @@ SECTIONS
|
||||
.dtors :
|
||||
{
|
||||
PROVIDE(__dtors_start__ = .);
|
||||
KEEP(*(SORT(.dtors.*)))
|
||||
KEEP(*(.dtors))
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE(__dtors_end__ = .);
|
||||
}
|
||||
|
||||
. = ALIGN(16);
|
||||
.bss :
|
||||
. = ALIGN(8);
|
||||
__data_start = .;
|
||||
.data :
|
||||
{
|
||||
PROVIDE(__bss_start = .);
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.dynbss)
|
||||
*(COMMON)
|
||||
PROVIDE(__bss_end = .);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
}
|
||||
_end = .;
|
||||
__data_end = .;
|
||||
|
||||
. = ALIGN(8);
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(8);
|
||||
}
|
||||
. = ALIGN(8);
|
||||
__bss_end = .;
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
* Symbols in the DWARF debugging sections are relative to the beginning
|
||||
* of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
|
||||
__bss_size = SIZEOF(.bss);
|
||||
__data_size = SIZEOF(.data);
|
||||
__bss_size = SIZEOF(.bss);
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
||||
9
bsp/qemu-virt64-aarch64/qemu-debug.bat
Normal file
9
bsp/qemu-virt64-aarch64/qemu-debug.bat
Normal file
@@ -0,0 +1,9 @@
|
||||
@echo off
|
||||
if exist sd.bin goto run
|
||||
qemu-img create -f raw sd.bin 64M
|
||||
|
||||
:run
|
||||
qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -nographic ^
|
||||
-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 -s -S ^
|
||||
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
|
||||
7
bsp/qemu-virt64-aarch64/qemu-debug.sh
Normal file
7
bsp/qemu-virt64-aarch64/qemu-debug.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
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.bin -nographic \
|
||||
-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 -s -S \
|
||||
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
|
||||
@@ -3,7 +3,7 @@ if exist sd.bin goto run
|
||||
qemu-img create -f raw sd.bin 64M
|
||||
|
||||
:run
|
||||
qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.elf -serial stdio ^
|
||||
qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -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 ^
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 \
|
||||
qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -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 \
|
||||
|
||||
2
bsp/qemu-virt64-aarch64/qemu.sh
Normal file → Executable file
2
bsp/qemu-virt64-aarch64/qemu.sh
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
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 -nographic \
|
||||
qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -nographic \
|
||||
-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-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define RT_NAME_MAX 16
|
||||
#define RT_USING_SMP
|
||||
#define RT_CPUS_NR 4
|
||||
#define RT_ALIGN_SIZE 4
|
||||
#define RT_ALIGN_SIZE 8
|
||||
#define RT_THREAD_PRIORITY_32
|
||||
#define RT_THREAD_PRIORITY_MAX 32
|
||||
#define RT_TICK_PER_SECOND 100
|
||||
@@ -18,14 +18,15 @@
|
||||
#define RT_HOOK_USING_FUNC_PTR
|
||||
#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 IDLE_THREAD_STACK_SIZE 8192
|
||||
#define SYSTEM_THREAD_STACK_SIZE 8192
|
||||
#define RT_USING_TIMER_SOFT
|
||||
#define RT_TIMER_THREAD_PRIO 4
|
||||
#define RT_TIMER_THREAD_STACK_SIZE 4096
|
||||
#define RT_TIMER_THREAD_STACK_SIZE 8192
|
||||
|
||||
/* kservice optimization */
|
||||
|
||||
#define RT_KSERVICE_USING_STDLIB
|
||||
#define RT_KPRINTF_USING_LONGLONG
|
||||
#define RT_DEBUG
|
||||
#define RT_DEBUG_COLOR
|
||||
@@ -44,7 +45,8 @@
|
||||
#define RT_USING_SMALL_MEM
|
||||
#define RT_USING_MEMHEAP
|
||||
#define RT_MEMHEAP_FAST_MODE
|
||||
#define RT_USING_SMALL_MEM_AS_HEAP
|
||||
#define RT_USING_MEMHEAP_AS_HEAP
|
||||
#define RT_USING_MEMHEAP_AUTO_BINDING
|
||||
#define RT_USING_MEMTRACE
|
||||
#define RT_USING_HEAP
|
||||
|
||||
@@ -52,13 +54,16 @@
|
||||
|
||||
#define RT_USING_DEVICE
|
||||
#define RT_USING_DEVICE_OPS
|
||||
#define RT_USING_INTERRUPT_INFO
|
||||
#define RT_USING_CONSOLE
|
||||
#define RT_CONSOLEBUF_SIZE 128
|
||||
#define RT_CONSOLEBUF_SIZE 256
|
||||
#define RT_CONSOLE_DEVICE_NAME "uart0"
|
||||
#define RT_VER_NUM 0x50000
|
||||
#define ARCH_CPU_64BIT
|
||||
#define RT_USING_CACHE
|
||||
#define ARCH_MM_MMU
|
||||
#define ARCH_ARM
|
||||
#define ARCH_ARM_MMU
|
||||
#define ARCH_ARMV8
|
||||
|
||||
/* RT-Thread Components */
|
||||
@@ -74,18 +79,18 @@
|
||||
#define FINSH_THREAD_PRIORITY 20
|
||||
#define FINSH_THREAD_STACK_SIZE 4096
|
||||
#define FINSH_USING_HISTORY
|
||||
#define FINSH_HISTORY_LINES 5
|
||||
#define FINSH_HISTORY_LINES 10
|
||||
#define FINSH_USING_SYMTAB
|
||||
#define FINSH_CMD_SIZE 80
|
||||
#define FINSH_CMD_SIZE 256
|
||||
#define MSH_USING_BUILT_IN_COMMANDS
|
||||
#define FINSH_USING_DESCRIPTION
|
||||
#define FINSH_ARG_MAX 10
|
||||
#define RT_USING_DFS
|
||||
#define DFS_USING_POSIX
|
||||
#define DFS_USING_WORKDIR
|
||||
#define DFS_FILESYSTEMS_MAX 2
|
||||
#define DFS_FILESYSTEM_TYPES_MAX 2
|
||||
#define DFS_FD_MAX 16
|
||||
#define DFS_FILESYSTEMS_MAX 4
|
||||
#define DFS_FILESYSTEM_TYPES_MAX 8
|
||||
#define DFS_FD_MAX 32
|
||||
#define RT_USING_DFS_ELMFAT
|
||||
|
||||
/* elm-chan's FatFs, Generic FAT Filesystem Module */
|
||||
@@ -102,20 +107,33 @@
|
||||
#define RT_DFS_ELM_REENTRANT
|
||||
#define RT_DFS_ELM_MUTEX_TIMEOUT 3000
|
||||
#define RT_USING_DFS_DEVFS
|
||||
#define RT_USING_DFS_ROMFS
|
||||
|
||||
/* Device Drivers */
|
||||
|
||||
#define RT_USING_DEVICE_IPC
|
||||
#define RT_UNAMED_PIPE_NUMBER 64
|
||||
#define RT_USING_SYSTEM_WORKQUEUE
|
||||
#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096
|
||||
#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192
|
||||
#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
|
||||
#define RT_USING_SERIAL
|
||||
#define RT_USING_SERIAL_V1
|
||||
#define RT_SERIAL_RB_BUFSZ 64
|
||||
#define RT_SERIAL_USING_DMA
|
||||
#define RT_SERIAL_RB_BUFSZ 256
|
||||
#define RT_USING_PIN
|
||||
#define RT_USING_NULL
|
||||
#define RT_USING_ZERO
|
||||
#define RT_USING_RANDOM
|
||||
#define RT_USING_RTC
|
||||
#define RT_USING_ALARM
|
||||
#define RT_USING_DEV_BUS
|
||||
#define RT_USING_VIRTIO
|
||||
#define RT_USING_VIRTIO10
|
||||
#define RT_USING_VIRTIO_MMIO_ALIGN
|
||||
#define RT_USING_VIRTIO_BLK
|
||||
#define RT_USING_VIRTIO_CONSOLE
|
||||
#define RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR 4
|
||||
#define RT_USING_VIRTIO_GPU
|
||||
#define RT_USING_VIRTIO_INPUT
|
||||
|
||||
/* Using USB */
|
||||
|
||||
@@ -126,71 +144,25 @@
|
||||
|
||||
/* POSIX (Portable Operating System Interface) layer */
|
||||
|
||||
#define RT_USING_POSIX_FS
|
||||
#define RT_USING_POSIX_DEVIO
|
||||
#define RT_USING_POSIX_STDIO
|
||||
#define RT_USING_POSIX_POLL
|
||||
#define RT_USING_POSIX_SELECT
|
||||
#define RT_USING_POSIX_TERMIOS
|
||||
#define RT_USING_POSIX_DELAY
|
||||
#define RT_USING_POSIX_CLOCK
|
||||
|
||||
/* Interprocess Communication (IPC) */
|
||||
|
||||
#define RT_USING_POSIX_PIPE
|
||||
#define RT_USING_POSIX_PIPE_SIZE 512
|
||||
|
||||
/* Socket is in the 'Network' category */
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
@@ -255,11 +227,6 @@
|
||||
|
||||
/* peripheral libraries and drivers */
|
||||
|
||||
/* sensors drivers */
|
||||
|
||||
|
||||
/* touch drivers */
|
||||
|
||||
|
||||
/* Kendryte SDK */
|
||||
|
||||
@@ -267,9 +234,6 @@
|
||||
/* AI packages */
|
||||
|
||||
|
||||
/* Signal Processing and Control Algorithm Packages */
|
||||
|
||||
|
||||
/* miscellaneous packages */
|
||||
|
||||
/* project laboratory */
|
||||
@@ -313,25 +277,16 @@
|
||||
|
||||
/* Uncategorized */
|
||||
|
||||
/* Privated Packages of RealThread */
|
||||
|
||||
|
||||
/* Network Utilities */
|
||||
|
||||
|
||||
/* RT-Thread Smart */
|
||||
|
||||
#define SOC_VIRT64_AARCH64
|
||||
|
||||
/* AARCH64 qemu virt64 configs */
|
||||
|
||||
#define BSP_SUPPORT_FPU
|
||||
#define BSP_USING_UART
|
||||
#define RT_USING_UART0
|
||||
#define BSP_USING_RTC
|
||||
#define BSP_USING_ALARM
|
||||
#define BSP_USING_PIN
|
||||
#define BSP_USING_VIRTIO_BLK
|
||||
#define BSP_USING_VIRTIO_NET
|
||||
#define BSP_USING_VIRTIO_CONSOLE
|
||||
#define BSP_USING_VIRTIO_GPU
|
||||
#define BSP_USING_VIRTIO_INPUT
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user