[smart/aarch64] code sync (#6750)

* [smart/aarch64] sync aarch64
This commit is contained in:
Shell
2022-12-20 17:49:37 +08:00
committed by GitHub
parent f0ef8ada33
commit e8504c7cf1
114 changed files with 6099 additions and 9092 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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"

View File

@@ -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)

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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')

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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__ */

View File

@@ -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 */

View File

@@ -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

View File

@@ -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

View File

@@ -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__ */

View File

@@ -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 */

View File

@@ -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__ */

View File

@@ -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 queues 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 queues 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 queues 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__ */

View File

@@ -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 */

View File

@@ -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__ */

View File

@@ -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__ */

View File

@@ -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

View File

@@ -3,7 +3,7 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)

View 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
}

View 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

View File

@@ -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);

View 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 */

View 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);

View 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

View File

@@ -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;

View File

@@ -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__ */

View File

@@ -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;

View 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

View File

@@ -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;
}

View File

@@ -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 = .;
}

View 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

View 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

View File

@@ -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 ^

View 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 -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
View 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

View File

@@ -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