diff --git a/bsp/qemu-virt64-aarch64/.config b/bsp/qemu-virt64-aarch64/.config index 724c6cce8eec..6a5bc3420188 100644 --- a/bsp/qemu-virt64-aarch64/.config +++ b/bsp/qemu-virt64-aarch64/.config @@ -6,9 +6,9 @@ # # RT-Thread Kernel # -CONFIG_RT_NAME_MAX=16 +CONFIG_RT_NAME_MAX=24 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set -# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMART=y CONFIG_RT_USING_SMP=y CONFIG_RT_CPUS_NR=4 CONFIG_RT_ALIGN_SIZE=8 @@ -106,11 +106,12 @@ CONFIG_RT_USING_HW_ATOMIC=y CONFIG_ARCH_MM_MMU=y CONFIG_ARCH_ARM=y CONFIG_ARCH_ARM_MMU=y +CONFIG_KERNEL_VADDR_START=0xffff000000000000 CONFIG_ARCH_ARMV8=y CONFIG_ARCH_ARMV8_EXTENSIONS=0 -CONFIG_ARCH_SUPPORT_FPU=y -CONFIG_ARCH_TEXT_OFFSET=0x80000 +CONFIG_ARCH_TEXT_OFFSET=0x200000 CONFIG_ARCH_RAM_OFFSET=0x40000000 +CONFIG_ARCH_ASPACE_SIZE=0xffffffff CONFIG_ARCH_SECONDARY_CPU_STACK_SIZE=4096 CONFIG_ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -127,7 +128,7 @@ CONFIG_RT_USING_FINSH=y CONFIG_FINSH_USING_MSH=y CONFIG_FINSH_THREAD_NAME="tshell" CONFIG_FINSH_THREAD_PRIORITY=20 -CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_THREAD_STACK_SIZE=8192 CONFIG_FINSH_USING_HISTORY=y CONFIG_FINSH_HISTORY_LINES=10 CONFIG_FINSH_USING_SYMTAB=y @@ -174,15 +175,38 @@ CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512 CONFIG_RT_DFS_ELM_REENTRANT=y CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 CONFIG_RT_USING_DFS_DEVFS=y +CONFIG_RT_USING_DFS_DIRECTFS=y CONFIG_RT_USING_DFS_ROMFS=y # CONFIG_RT_USING_DFS_CROMFS is not set # CONFIG_RT_USING_DFS_RAMFS is not set # CONFIG_RT_USING_DFS_TMPFS is not set # CONFIG_RT_USING_FAL is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_RT_LWP_SHM_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set # # Device Drivers # +CONFIG_RT_USING_TTY=y +# CONFIG_RT_TTY_DEBUG is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_DAC is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +CONFIG_RT_USING_DEV_BUS=y +# CONFIG_RT_USING_WIFI is not set CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_UNAMED_PIPE_NUMBER=64 CONFIG_RT_USING_SYSTEM_WORKQUEUE=y @@ -194,16 +218,49 @@ CONFIG_RT_USING_SERIAL_V1=y CONFIG_RT_SERIAL_USING_DMA=y CONFIG_RT_SERIAL_RB_BUFSZ=256 # CONFIG_RT_USING_CAN is not set -# CONFIG_RT_USING_HWTIMER is not set +CONFIG_RT_USING_CLK=y # CONFIG_RT_USING_CPUTIME is not set +CONFIG_RT_USING_FIRMWARE=y +CONFIG_RT_FIRMWARE_PSCI=y +CONFIG_RT_FIRMWARE_QEMU_FW_CFG=y +CONFIG_RT_USING_HWTIMER=y +CONFIG_RT_HWTIMER_ARM_ARCH=y # CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_OFW=y +# CONFIG_RT_USING_BUILTIN_FDT is not set +CONFIG_RT_FDT_EARLYCON_MSG_SIZE=128 +CONFIG_RT_USING_OFW_DIRECTFS=y +CONFIG_RT_USING_OFW_BUS_RANGES_NUMBER=8 +CONFIG_RT_USING_PCI=y +CONFIG_RT_PCI_MSI=y +CONFIG_RT_PCI_ENDPOINT=y +CONFIG_RT_PCI_SYS_64BIT=y +CONFIG_RT_PCI_CACHE_LINE_SIZE=8 +# CONFIG_RT_PCI_LOCKLESS is not set + +# +# PCI Device Drivers +# +CONFIG_RT_PCI_ECAM=y +CONFIG_RT_PCI_HOST_COMMON=y +CONFIG_RT_PCI_HOST_GENERIC=y # CONFIG_RT_USING_PHY is not set +CONFIG_RT_USING_PIC=y +CONFIG_MAX_HANDLERS=512 +CONFIG_RT_PIC_ARM_GIC=y +CONFIG_RT_PIC_ARM_GIC_V2M=y +CONFIG_RT_PIC_ARM_GIC_V3=y +CONFIG_RT_PIC_ARM_GIC_V3_ITS=y +CONFIG_RT_PIC_ARM_GIC_MAX_NR=1 +# CONFIG_RT_USING_PINCTRL is not set CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_ADC is not set -# CONFIG_RT_USING_DAC is not set +CONFIG_RT_PIN_PL061=y CONFIG_RT_USING_NULL=y -CONFIG_RT_USING_ZERO=y -CONFIG_RT_USING_RANDOM=y + +# +# Power Management (PM) Domains device drivers +# # CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set @@ -212,21 +269,41 @@ CONFIG_RT_USING_FDT=y CONFIG_RT_USING_FDTLIB=y # CONFIG_FDT_USING_DEBUG is not set CONFIG_RT_USING_RTC=y -# CONFIG_RT_USING_ALARM is not set +CONFIG_RT_USING_ALARM=y # CONFIG_RT_USING_SOFT_RTC is not set # CONFIG_RT_USING_SDIO is not set +CONFIG_RT_RTC_PL031=y +# CONFIG_RT_RTC_RK_TIMER is not set +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=256 + +# +# Serial Device Drivers +# +CONFIG_RT_SERIAL_PL011=y # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set -# CONFIG_RT_USING_TOUCH is not set -# CONFIG_RT_USING_LCD is not set +CONFIG_RT_USING_LCD=y +CONFIG_RT_USING_VIDEO=y # CONFIG_RT_USING_HWCRYPTO is not set -# CONFIG_RT_USING_PULSE_ENCODER is not set +CONFIG_RT_VIDEO_FB=y # CONFIG_RT_USING_INPUT_CAPTURE is not set -CONFIG_RT_USING_DEV_BUS=y -# CONFIG_RT_USING_WIFI is not set -CONFIG_RT_USING_VIRTIO=y +CONFIG_RT_VIDEO_LOGO=y +CONFIG_RT_VIDEO_LOGO_FBDEV="fb0" +CONFIG_RT_VIDEO_LOGO_RENDERING_STAGE_DRIVER_EARLY=y +# CONFIG_RT_VIDEO_LOGO_RENDERING_STAGE_DRIVER is not set +# CONFIG_RT_VIDEO_LOGO_RENDERING_STAGE_DRIVER_LATER is not set +# CONFIG_RT_VIDEO_LOGO_RENDERING_STAGE_COMPONENT is not set +# CONFIG_RT_VIDEO_LOGO_RENDERING_STAGE_ENV is not set +# CONFIG_RT_VIDEO_LOGO_RENDERING_STAGE_APP is not set +CONFIG_RT_VIDEO_LOGO_RT_THREAD_CLUT224=y +# CONFIG_RT_VIDEO_LOGO_RT_THREAD_WHITE_CLUT224 is not set +# CONFIG_RT_USING_VIRTIO is not set CONFIG_RT_USING_VIRTIO10=y CONFIG_RT_USING_VIRTIO_MMIO_ALIGN=y CONFIG_RT_USING_VIRTIO_BLK=y @@ -262,7 +339,7 @@ CONFIG_RT_USING_POSIX_TERMIOS=y # CONFIG_RT_USING_POSIX_MMAN is not set CONFIG_RT_USING_POSIX_DELAY=y CONFIG_RT_USING_POSIX_CLOCK=y -# CONFIG_RT_USING_POSIX_TIMER is not set +CONFIG_RT_USING_POSIX_TIMER=y # CONFIG_RT_USING_PTHREADS is not set # CONFIG_RT_USING_MODULE is not set @@ -294,7 +371,12 @@ CONFIG_RT_USING_POSIX_PIPE_SIZE=512 # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set +CONFIG_RT_USING_CRASH_CORE=y CONFIG_RT_USING_ADT=y +CONFIG_RT_USING_ADT_AVL=y +CONFIG_RT_USING_ADT_BITMAP=y +CONFIG_RT_USING_ADT_HASHMAP=y +CONFIG_RT_USING_ADT_REF=y # CONFIG_RT_USING_RT_LINK is not set # CONFIG_RT_USING_VBUS is not set @@ -1053,21 +1135,3 @@ CONFIG_RT_USING_ADT=y # Uncategorized # CONFIG_SOC_VIRT64_AARCH64=y - -# -# AARCH64 qemu virt64 configs -# -CONFIG_BSP_SUPPORT_FPU=y -CONFIG_BSP_USING_UART=y -CONFIG_RT_USING_UART0=y -CONFIG_BSP_USING_RTC=y -# CONFIG_BSP_USING_ALARM is not set -CONFIG_BSP_USING_PIN=y -CONFIG_BSP_USING_VIRTIO_BLK=y -# CONFIG_BSP_USING_VIRTIO_NET is not set -CONFIG_BSP_USING_VIRTIO_CONSOLE=y -CONFIG_BSP_USING_VIRTIO_GPU=y -CONFIG_BSP_USING_VIRTIO_INPUT=y -CONFIG_BSP_USING_GIC=y -CONFIG_BSP_USING_GICV2=y -# CONFIG_BSP_USING_GICV3 is not set diff --git a/bsp/qemu-virt64-aarch64/.gitignore b/bsp/qemu-virt64-aarch64/.gitignore new file mode 100644 index 000000000000..b511ae114b5a --- /dev/null +++ b/bsp/qemu-virt64-aarch64/.gitignore @@ -0,0 +1 @@ +*.qcow2 diff --git a/bsp/qemu-virt64-aarch64/Kconfig b/bsp/qemu-virt64-aarch64/Kconfig index 2f53613bd976..6ab4bf98774a 100644 --- a/bsp/qemu-virt64-aarch64/Kconfig +++ b/bsp/qemu-virt64-aarch64/Kconfig @@ -26,9 +26,4 @@ config SOC_VIRT64_AARCH64 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/drivers/Kconfig" diff --git a/bsp/qemu-virt64-aarch64/applications/console.c b/bsp/qemu-virt64-aarch64/applications/console.c index 19a3d2d6f415..93220ce06582 100644 --- a/bsp/qemu-virt64-aarch64/applications/console.c +++ b/bsp/qemu-virt64-aarch64/applications/console.c @@ -14,28 +14,6 @@ #include #endif -#include - -static int console_init() -{ - rt_err_t status = RT_EOK; - rt_device_t device = rt_device_find("virtio-console0"); - - if (device != RT_NULL && rt_device_open(device, 0) == RT_EOK) - { - /* Create vport0p1 */ - // status = rt_device_control(device, VIRTIO_DEVICE_CTRL_CONSOLE_PORT_CREATE, RT_NULL); - } - - if (device != RT_NULL) - { - rt_device_close(device); - } - - return status; -} -INIT_ENV_EXPORT(console_init); - #ifdef FINSH_USING_MSH static int console(int argc, char **argv) @@ -55,11 +33,11 @@ static int console(int argc, char **argv) if (dev != RT_NULL) { - #ifdef RT_USING_SMART - console_set_iodev(dev); - #else - rt_kprintf("TODO not supported\n"); - #endif + #ifdef RT_USING_SMART + console_set_iodev(dev); + #else + rt_kprintf("TODO not supported\n"); + #endif } } #else diff --git a/bsp/qemu-virt64-aarch64/applications/main.c b/bsp/qemu-virt64-aarch64/applications/main.c index 7e30fab14f2d..a6ef3bc9f0ba 100644 --- a/bsp/qemu-virt64-aarch64/applications/main.c +++ b/bsp/qemu-virt64-aarch64/applications/main.c @@ -8,38 +8,24 @@ * 2020/10/7 bernard the first version */ -#include +#include #include -#include "drivers/core/bus.h" -#ifdef RT_USING_FDT -#include "dtb_node.h" -#endif - -struct rt_device timer_device = { - .name = "timer_virt64", -}; - -// static void timer_init(void) -// { -// rt_device_attach(&timer_device); -// } - -int main(void) +int main(int argc, char** argv) { - /* example: init timer device statically */ - // timer_init(); + const char *oem; + +#ifdef RT_USING_SMART + oem = "Smart"; +#else + oem = "Thread"; +#endif - rt_uint8_t times = 0; + rt_ubase_t level = rt_hw_interrupt_disable(); - printf("hello rt-thread\n"); + rt_kprintf("Hi, this is RT-%s!!\n", oem); - /*test timer*/ - while (times++ < 2) - { - rt_thread_mdelay(500); - printf("hello rt-thread\n"); - } + rt_hw_interrupt_enable(level); return 0; } diff --git a/bsp/qemu-virt64-aarch64/applications/mnt.c b/bsp/qemu-virt64-aarch64/applications/mnt.c deleted file mode 100644 index 6a226db6d806..000000000000 --- a/bsp/qemu-virt64-aarch64/applications/mnt.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021/08/19 bernard the first version - */ - -#include - -#ifdef RT_USING_DFS -#include - -int mnt_init(void) -{ - if (rt_device_find("virtio-blk0")) - { - /* mount virtio-blk as root directory */ - if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0) - { - rt_kprintf("file system initialization done!\n"); - } - } - - return 0; -} -INIT_ENV_EXPORT(mnt_init); -#endif diff --git a/bsp/qemu-virt64-aarch64/applications/pin.c b/bsp/qemu-virt64-aarch64/applications/pin.c deleted file mode 100644 index 37d1927b0033..000000000000 --- a/bsp/qemu-virt64-aarch64/applications/pin.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-6-30 GuEe-GUI first version - */ - -#include -#include -#include - -#ifdef RT_USING_PIN - -void qemu_gpio3_key_poweroff(void *args) -{ - rt_kprintf("\nYou power off the machine.\n"); - - rt_hw_cpu_shutdown(); -} - -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); - - return 0; -} -INIT_ENV_EXPORT(pin_init); - -#endif /* RT_USING_PIN */ diff --git a/bsp/qemu-virt64-aarch64/drivers/Kconfig b/bsp/qemu-virt64-aarch64/drivers/Kconfig deleted file mode 100644 index f14fc73fc183..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/Kconfig +++ /dev/null @@ -1,80 +0,0 @@ - -menu "AARCH64 qemu virt64 configs" - menuconfig BSP_SUPPORT_FPU - bool "Using Float" - default y - - menuconfig BSP_USING_UART - bool "Using UART" - select RT_USING_SERIAL - default y - - if BSP_USING_UART - config RT_USING_UART0 - bool "Enabel UART 0" - default y - endif - - menuconfig BSP_USING_RTC - bool "Using RTC" - select RT_USING_RTC - default y - - if BSP_USING_RTC - config BSP_USING_ALARM - bool "Enable Alarm" - select RT_USING_ALARM - default n - endif - - config BSP_USING_PIN - bool "Using PIN" - select RT_USING_PIN - default y - - 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 - bool - default y - - choice - prompt "GIC Version" - default BSP_USING_GICV2 - - config BSP_USING_GICV2 - bool "GICv2" - - config BSP_USING_GICV3 - bool "GICv3" - endchoice - -endmenu diff --git a/bsp/qemu-virt64-aarch64/drivers/SConscript b/bsp/qemu-virt64-aarch64/drivers/SConscript index fb730944e47a..6afaddd429fc 100644 --- a/bsp/qemu-virt64-aarch64/drivers/SConscript +++ b/bsp/qemu-virt64-aarch64/drivers/SConscript @@ -4,12 +4,11 @@ from building import * cwd = GetCurrentDir() src = Glob('*.c') -src += Glob('expired/*.c') -src += Glob('virtio/*.c') CPPPATH = [cwd] -CPPPATH += [cwd + '/expired'] -CPPPATH += [cwd + '/virtio'] + +if not GetDepend(['RT_FIRMWARE_QEMU_FW_CFG', 'RT_VIDEO_FB']): + SrcRemove(src, ['drv_romfb.c']) group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/qemu-virt64-aarch64/drivers/amba-pl011.c b/bsp/qemu-virt64-aarch64/drivers/amba-pl011.c deleted file mode 100644 index 968876f72180..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/amba-pl011.c +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include -#include - -#include "board.h" -#include "drivers/amba_bus.h" - -#ifdef RT_USING_FDT -#include "dtb_node.h" -#endif - -struct hw_uart_device -{ - rt_ubase_t hw_base; - rt_uint32_t irqno; -}; - -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; -} - -static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) -{ - struct hw_uart_device *uart; - - 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 */ - UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM; - 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; -} - -static int uart_putc(struct rt_serial_device *serial, char c) -{ - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - 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; - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - ch = -1; - if (!(UART_FR(uart->hw_base) & UARTFR_RXFE)) - { - ch = UART_DR(uart->hw_base) & 0xff; - } - - return ch; -} - -struct rt_serial_device *pl011_device_create(struct rt_device *dev) -{ - struct rt_serial_device *serial; - - serial = rt_malloc(sizeof(struct rt_serial_device)); - if (serial == RT_NULL) - { - rt_kprintf("malloc serial failed...\n"); - return serial; - } - serial->parent = *dev; - - struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - serial->config = config; - - return serial; -} - -static struct rt_uart_ops pl011_uart_ops = - { - .device_create = pl011_device_create, - .configure = uart_configure, - .control = uart_control, - .putc = uart_putc, - .getc = uart_getc, -}; - -int pl011_probe(struct rt_device *dev) -{ - size_t uart_reg_range = 0; - void *uart_reg_addr = RT_NULL; - - struct dtb_node *node = (struct dtb_node *)(dev->dtb_node); - - struct hw_uart_device *uart_priv = (struct hw_uart_device *)(rt_calloc(1, sizeof(struct hw_uart_device))); - if (node) - { - uart_reg_addr = (void *)dtb_node_get_addr_size(node, "reg", &uart_reg_range); - if ((uart_reg_addr) && (uart_reg_range != 0)) - { - uart_priv->hw_base = (rt_base_t)rt_ioremap(uart_reg_addr, uart_reg_range); - } - - uart_priv->irqno = dtb_node_irq_get(node, 0) + IRQ_SPI_OFFSET; - - struct rt_uart_ops *uart_ops = ((struct rt_uart_driver *)(dev->drv))->ops; - struct rt_serial_device *serial = uart_ops->device_create(dev); - - const char *uart_name = dev->drv->name; - dev->priv = serial; - rt_hw_serial_register(serial, uart_name, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DEACTIVATE, - uart_priv); - rt_hw_interrupt_install(uart_priv->irqno, rt_hw_uart_isr, serial, uart_name); - UART_CR(uart_priv->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); - } - - return RT_EOK; -} - -struct rt_device_id pl011_ids[] = - { - {.compatible = "arm,pl011"}, - {/* sentinel */}}; - -struct rt_uart_driver pl011_drv = { - .parent = { - .name = RT_CONSOLE_DEVICE_NAME, - .probe = pl011_probe, - .ids = pl011_ids, - }, - .ops = &pl011_uart_ops, -}; - -AMBA_DRIVER_EXPORT(pl011_drv); diff --git a/bsp/qemu-virt64-aarch64/drivers/amba-pl031.c b/bsp/qemu-virt64-aarch64/drivers/amba-pl031.c deleted file mode 100644 index df9e9af4f16b..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/amba-pl031.c +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#include -#include - -#include "drivers/amba_bus.h" - -#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 - -struct hw_rtc_device -{ - struct rt_device device; - rt_ubase_t hw_base; -}; - -static struct hw_rtc_device rtc_device; - -rt_inline rt_uint32_t pl031_read32(rt_ubase_t offset) -{ - return (*((volatile unsigned int *)(rtc_device.hw_base + offset))); -} - -rt_inline void pl031_write32(rt_ubase_t offset, rt_uint32_t value) -{ - (*((volatile unsigned int *)(rtc_device.hw_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_ssize_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_ssize_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; -} - -static struct rt_device_ops pl031_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 pl031_probe(struct rt_device *dev) -{ - size_t reg_range = 0; - void *reg_addr = RT_NULL; - - struct dtb_node *node = (struct dtb_node *)(dev->dtb_node); - - if (node) - { - reg_addr = (void *)dtb_node_get_addr_size(node, "reg", ®_range); - if ((reg_addr) && (reg_range != 0)) - { - rtc_device.hw_base = (rt_base_t)rt_ioremap(reg_addr, reg_range); - } - - rt_memset(&rtc_device, 0, sizeof(rtc_device)); - struct rt_device_ops *ops = ((struct rt_rtc_driver *)(dev->drv))->ops; - - 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 = ops; - rtc_device.device.user_data = RT_NULL; - - /* register a rtc device */ - rt_device_register(&rtc_device.device, dev->drv->name, RT_DEVICE_FLAG_RDWR); - } - - return 0; -} - -struct rt_device_id pl031_ids[] = - { - {.compatible = "arm,pl031"}, - {/* sentinel */}}; - -struct rt_rtc_driver pl031_drv = { - .parent = { - .name = "pl031_rtc", - .probe = pl031_probe, - .ids = pl031_ids, - }, - .ops = &pl031_ops, -}; - -AMBA_DRIVER_EXPORT(pl031_drv); - diff --git a/bsp/qemu-virt64-aarch64/drivers/amba-pl061.c b/bsp/qemu-virt64-aarch64/drivers/amba-pl061.c deleted file mode 100644 index 3dc27a7c9de0..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/amba-pl061.c +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include -#include -#include - -#include "board.h" -#include "drivers/amba_bus.h" - -#ifdef RT_USING_FDT -#include "dtb_node.h" -#endif - -#define GPIODIR 0x400 -#define GPIOIS 0x404 -#define GPIOIBE 0x408 -#define GPIOIEV 0x40c -#define GPIOIE 0x410 -#define GPIORIS 0x414 -#define GPIOMIS 0x418 -#define GPIOIC 0x41c - -#define BIT(x) (1 << (x)) - -#define PL061_GPIO_NR 8 - -static struct pl061 -{ -#ifdef RT_USING_SMP - struct rt_spinlock spinlock; -#endif - void (*(hdr[PL061_GPIO_NR]))(void *args); - void *args[PL061_GPIO_NR]; - rt_ubase_t hw_base; - rt_uint32_t irqno; -} _pl061; - -rt_inline rt_uint8_t pl061_read8(rt_ubase_t offset) -{ - return HWREG8(_pl061.hw_base + offset); -} - -rt_inline void pl061_write8(rt_ubase_t offset, rt_uint8_t value) -{ - HWREG8(_pl061.hw_base + offset) = value; -} - -static void pl061_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode) -{ - int value; - rt_uint8_t gpiodir; - -#ifdef RT_USING_SMP - rt_base_t level; -#endif - - if (pin < 0 || pin >= PL061_GPIO_NR) - { - return; - } - -#ifdef RT_USING_SMP - level = rt_spin_lock_irqsave(&_pl061.spinlock); -#endif - - switch (mode) - { - case PIN_MODE_OUTPUT: - - value = !!pl061_read8((BIT(pin + 2))); - - pl061_write8(BIT(pin + 2), 0 << pin); - gpiodir = pl061_read8(GPIODIR); - gpiodir |= BIT(pin); - pl061_write8(GPIODIR, gpiodir); - - /* - * gpio value is set again, because pl061 doesn't allow to set value of - * a gpio pin before configuring it in OUT mode. - */ - pl061_write8((BIT(pin + 2)), value << pin); - - break; - case PIN_MODE_INPUT: - - gpiodir = pl061_read8(GPIODIR); - gpiodir &= ~(BIT(pin)); - pl061_write8(GPIODIR, gpiodir); - - break; - } - -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&_pl061.spinlock, level); -#endif -} - -static void pl061_pin_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value) -{ - pl061_write8(BIT(pin + 2), !!value << pin); -} - -static rt_int8_t pl061_pin_read(struct rt_device *device, rt_base_t pin) -{ - return !!pl061_read8((BIT(pin + 2))); -} - -static rt_err_t pl061_pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_uint8_t mode, void (*hdr)(void *args), void *args) -{ - rt_uint8_t gpiois, gpioibe, gpioiev; - rt_uint8_t bit = BIT(mode); -#ifdef RT_USING_SMP - rt_base_t level; -#endif - - if (pin < 0 || pin >= PL061_GPIO_NR) - { - return -RT_EINVAL; - } - -#ifdef RT_USING_SMP - level = rt_spin_lock_irqsave(&_pl061.spinlock); -#endif - - gpioiev = pl061_read8(GPIOIEV); - gpiois = pl061_read8(GPIOIS); - gpioibe = pl061_read8(GPIOIBE); - - if (mode == PIN_IRQ_MODE_HIGH_LEVEL || pin == PIN_IRQ_MODE_LOW_LEVEL) - { - rt_bool_t polarity = (mode == PIN_IRQ_MODE_HIGH_LEVEL); - - /* Disable edge detection */ - gpioibe &= ~bit; - /* Enable level detection */ - gpiois |= bit; - - /* Select polarity */ - if (polarity) - { - gpioiev |= bit; - } - else - { - gpioiev &= ~bit; - } - } - else if (mode == PIN_IRQ_MODE_RISING_FALLING) - { - /* Disable level detection */ - gpiois &= ~bit; - /* Select both edges, setting this makes GPIOEV be ignored */ - gpioibe |= bit; - } - else if (mode == PIN_IRQ_MODE_RISING || mode == PIN_IRQ_MODE_FALLING) - { - rt_bool_t rising = (mode == PIN_IRQ_MODE_RISING); - - /* Disable level detection */ - gpiois &= ~bit; - /* Clear detection on both edges */ - gpioibe &= ~bit; - - /* Select edge */ - if (rising) - { - gpioiev |= bit; - } - else - { - gpioiev &= ~bit; - } - } - else - { - /* No trigger: disable everything */ - gpiois &= ~bit; - gpioibe &= ~bit; - gpioiev &= ~bit; - } - - pl061_write8(GPIOIS, gpiois); - pl061_write8(GPIOIBE, gpioibe); - pl061_write8(GPIOIEV, gpioiev); - - _pl061.hdr[pin] = hdr; - _pl061.args[pin] = args; - -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&_pl061.spinlock, level); -#endif - - return RT_EOK; -} - -static rt_err_t pl061_pin_detach_irq(struct rt_device *device, rt_base_t pin) -{ - if (pin < 0 || pin >= PL061_GPIO_NR) - { - return -RT_EINVAL; - } - - _pl061.hdr[pin] = RT_NULL; - _pl061.args[pin] = RT_NULL; - - return RT_EOK; -} - -static rt_err_t pl061_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled) -{ - rt_uint8_t mask = BIT(pin); - rt_uint8_t gpioie; - -#ifdef RT_USING_SMP - rt_base_t level; -#endif - - if (pin < 0 || pin >= PL061_GPIO_NR) - { - return -RT_EINVAL; - } - -#ifdef RT_USING_SMP - level = rt_spin_lock_irqsave(&_pl061.spinlock); -#endif - - if (enabled) - { - gpioie = pl061_read8(GPIOIE) | mask; - } - else - { - gpioie = pl061_read8(GPIOIE) & ~mask; - } - - pl061_write8(GPIOIE, gpioie); - -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&_pl061.spinlock, level); -#endif - - return RT_EOK; -} - -static struct rt_pin_ops pl061_ops = -{ - pl061_pin_mode, - pl061_pin_write, - pl061_pin_read, - pl061_pin_attach_irq, - pl061_pin_detach_irq, - pl061_pin_irq_enable, - RT_NULL, -}; - -static void rt_hw_gpio_isr(int irqno, void *param) -{ - rt_uint8_t mask; - unsigned long pending; - -#ifdef RT_USING_SMP - rt_base_t level; -#endif - - pending = pl061_read8(GPIOMIS); - - if (pending) - { - rt_base_t pin; - - for (pin = 0; pin < PL061_GPIO_NR; ++pin) - { - if (pending & BIT(pin)) - { - mask |= BIT(pin); - - if (_pl061.hdr[pin] != RT_NULL) - { - _pl061.hdr[pin](_pl061.args[pin]); - } - } - } - } - -#ifdef RT_USING_SMP - level = rt_spin_lock_irqsave(&_pl061.spinlock); -#endif - - pl061_write8(GPIOIC, mask); - -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&_pl061.spinlock, level); -#endif -} - -int pl061_probe(struct rt_device *dev) -{ - size_t reg_range = 0; - void *reg_addr = RT_NULL; - - struct dtb_node *node = (struct dtb_node *)(dev->dtb_node); - -#ifdef RT_USING_SMP - rt_spin_lock_init(&_pl061.spinlock); -#endif - - if (node) - { - reg_addr = (void *)dtb_node_get_addr_size(node, "reg", ®_range); - if ((reg_addr) && (reg_range != 0)) - { - _pl061.hw_base = (rt_base_t)rt_ioremap(reg_addr, reg_range); - } - - _pl061.irqno = dtb_node_irq_get(node, 0) + IRQ_SPI_OFFSET; - - struct rt_pin_ops *ops = ((struct rt_pin_driver *)(dev->drv))->ops; - - rt_device_pin_register(dev->drv->name, ops, RT_NULL); - rt_hw_interrupt_install(_pl061.irqno, rt_hw_gpio_isr, RT_NULL, dev->drv->name); - rt_hw_interrupt_umask(_pl061.irqno); - } - - return RT_EOK; -} - -struct rt_device_id pl061_ids[] = - { - {.compatible = "arm,pl061"}, - {/* sentinel */}}; - -struct rt_pin_driver pl061_drv = { - .parent = { - .name = "pl061_gpio", - .probe = pl061_probe, - .ids = pl061_ids, - }, - .ops = &pl061_ops, -}; - -AMBA_DRIVER_EXPORT(pl061_drv); diff --git a/bsp/qemu-virt64-aarch64/drivers/board.c b/bsp/qemu-virt64-aarch64/drivers/board.c index 42e8a015e669..2696e6b83460 100644 --- a/bsp/qemu-virt64-aarch64/drivers/board.c +++ b/bsp/qemu-virt64-aarch64/drivers/board.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -9,121 +9,20 @@ * 2018-11-22 Jesven add rt_hw_spin_lock * add rt_hw_spin_unlock * add smp ipi init + * 2023-02-21 GuEe-GUI move common init to setup */ -#include -#include -#include - -#ifdef RT_USING_SMART -#include -#endif - -#include "board.h" -#include -#include -#include - -#ifdef RT_USING_FDT -#include "interrupt.h" -#include "dtb_node.h" -#include -#include -#endif - -#ifdef RT_USING_SMART -struct mem_desc platform_mem_desc[] = { - {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM} -}; -#else - -#define PAGE_POOL_SIZE (2ul << 20) -#define PHYMEM_END (0x48000000ul) - -struct mem_desc platform_mem_desc[] = -{ - {0x40000000, PHYMEM_END - 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 - */ - -extern size_t MMUTable[]; - -#ifdef RT_USING_SMART -rt_region_t init_page_region = { - PAGE_START, - PAGE_END, -}; -#else -rt_region_t init_page_region = { - PHYMEM_END - PAGE_POOL_SIZE, - PHYMEM_END, -}; -#endif +#include +#include void rt_hw_board_init(void) { -#ifdef RT_USING_SMART - rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET); -#else - rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0); -#endif - rt_page_init(init_page_region); - rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size); - - /* initialize system heap */ - rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); - - /* initialize hardware interrupt */ - rt_hw_interrupt_init(); - - rt_components_board_init(); - -#ifdef RT_USING_FDT -#ifdef RT_USING_SMP - rt_hw_cpu_init(); -#else - psci_init(); -#endif /* RT_USING_SMP */ -#endif - - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); - - 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 -} - -void rt_hw_console_output(const char *str) -{ - /* empty console output */ - while (*str) + rt_fdt_commit_memregion_early(&(rt_region_t) { - while (UART_FR(UART_BASE_ADDR) & UARTFR_TXFF); - UART_DR(UART_BASE_ADDR) = *str++; - } + .name = "memheap", + .start = (rt_size_t)rt_kmem_v2p(HEAP_BEGIN), + .end = (rt_size_t)rt_kmem_v2p(HEAP_END), + }, RT_TRUE); + + rt_hw_common_setup(); } diff --git a/bsp/qemu-virt64-aarch64/drivers/board.h b/bsp/qemu-virt64-aarch64/drivers/board.h index 6e004a7295b9..8538debd8aa6 100644 --- a/bsp/qemu-virt64-aarch64/drivers/board.h +++ b/bsp/qemu-virt64-aarch64/drivers/board.h @@ -12,42 +12,14 @@ #ifndef __BOARD_H__ #define __BOARD_H__ -#include -#include #include - -extern unsigned char __bss_start; -extern unsigned char __bss_end; +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 -#endif - -#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) HWREG32(base + 0x38) - -#define UARTFR_RXFE 0x10 -#define UARTFR_TXFF 0x20 - -#define UARTIMSC_RXIM 0x10 - -#define UART_BASE_ADDR 0x09000000 - -#define IRQ_SPI_OFFSET 32 -#define IRQ_PPI_OFFSET 16 void rt_hw_board_init(void); -int rt_hw_uart_init(void); - #endif diff --git a/bsp/qemu-virt64-aarch64/drivers/drv_romfb.c b/bsp/qemu-virt64-aarch64/drivers/drv_romfb.c new file mode 100644 index 000000000000..4ed54307ae7d --- /dev/null +++ b/bsp/qemu-virt64-aarch64/drivers/drv_romfb.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-02-25 GuEe-GUI the first version + */ + +#include +#include + +static int romfb_init(void) +{ + rt_err_t err; + struct fb_info *info; + struct fb_var_screeninfo var = {}; + struct fb_fix_screeninfo fix = {}; + rt_device_t rom_fbdev = rt_device_find("fb0"); + + if (!rom_fbdev || rt_device_open(rom_fbdev, 0)) + { + return -RT_EIO; + } + + var.xres = 800; + var.yres = 600; + var.xres_virtual = var.xres; + var.yres_virtual = var.yres; + var.bits_per_pixel = 32; + var.red.offset = 16; + var.red.length = 8; + var.green.offset = 8; + var.green.length = 8; + var.blue.offset = 0; + var.blue.length = 8; + var.transp.offset = 24; + var.transp.length = 8; + + if (!(err = rt_device_control(rom_fbdev, FBIOPUT_VSCREENINFO, &var))) + { + if (!(err = rt_device_control(rom_fbdev, FBIOGET_FSCREENINFO, &fix))) + { + info = rom_fbdev->user_data; + + rt_memset((void *)info->screen_base, 0, fix.smem_len); + } + } + + rt_device_close(rom_fbdev); + + return err; +} +INIT_SUBSYS_LATER_EXPORT(romfb_init); diff --git a/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c b/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c deleted file mode 100644 index 844f73ce8d4e..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include -#include -#include -#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 \ No newline at end of file diff --git a/bsp/qemu-virt64-aarch64/drivers/timer.c b/bsp/qemu-virt64-aarch64/drivers/timer.c deleted file mode 100644 index 791fc2b35277..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/timer.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include - -#include "cp15.h" -#include "board.h" -#include "gtimer.h" -#include "drivers/core/rtdm.h" - -#ifdef RT_USING_FDT -#include "dtb_node.h" -#endif - -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(rt_uint32_t irqno) -{ - rt_hw_set_gtimer_val(timerStep); - rt_hw_interrupt_umask(irqno); - rt_hw_gtimer_enable(); -} - -int timer_probe(struct rt_device *dev) -{ - struct dtb_node *node = (struct dtb_node *)(dev->dtb_node); - if (node) - { - rt_uint32_t irqno = dtb_node_irq_get(node, 1) + IRQ_PPI_OFFSET; - const char *name = dev->drv->name; - rt_device_register(dev, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_DEACTIVATE); - rt_hw_interrupt_install(irqno, rt_hw_timer_isr, RT_NULL, name); - __ISB(); - timerStep = rt_hw_get_gtimer_frq(); - __DSB(); - timerStep /= RT_TICK_PER_SECOND; - rt_hw_timer_enable(irqno); - } - return 0; -} - -struct rt_device_id timer_ids[] = - { - {.compatible = "arm,armv7-timer"}, - {/* sentinel */} - }; - -struct rt_driver timer_drv = { - .ids = timer_ids, - .name = "timer_virt64", - .dev_type = RT_Device_Class_Timer, - .device_size = sizeof(struct rt_device), - .probe = timer_probe, -}; - -TIMER_DRIVER_EXPORT(timer_drv); diff --git a/bsp/qemu-virt64-aarch64/drivers/virt.h b/bsp/qemu-virt64-aarch64/drivers/virt.h deleted file mode 100644 index 10ea7a49c6bc..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/virt.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-02-17 GuEe-GUI the first version - */ - -#ifndef VIRT_H__ -#define VIRT_H__ - -#include - -#ifdef RT_USING_SMART -#include -#include - -#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 -#define PL011_UART0_IRQNUM (32 + 1) - -/* RTC */ -#define PL031_RTC_BASE 0x9010000 -#define PL031_RTC_SIZE 0x00001000 -#define PL031_RTC_IRQNUM (32 + 2) - -/* GPIO */ -#define PL061_GPIO_BASE 0x09030000 -#define PL061_GPIO_SIZE 0x00001000 -#define PL061_GPIO_IRQNUM (32 + 7) - -/* VirtIO */ -#define VIRTIO_MMIO_BASE 0x0a000000 -#define VIRTIO_MMIO_SIZE 0x00000200 -#define VIRTIO_MAX_NR 32 -#define VIRTIO_IRQ_BASE (32 + 16) -#define VIRTIO_VENDOR_ID 0x554d4551 /* "QEMU" */ - -/* GIC */ -#define MAX_HANDLERS 96 -#define GIC_IRQ_START 0 -#define ARM_GIC_NR_IRQS 96 -#define ARM_GIC_MAX_NR 1 - -#define IRQ_ARM_IPI_KICK 0 -#define IRQ_ARM_IPI_CALL 1 - -/* 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 -#define GIC_PL500_REDISTRIBUTOR_PPTR 0x080a0000 -#define GIC_PL500_CONTROLLER_PPTR GIC_PL390_CONTROLLER_PPTR -#define GIC_PL500_ITS_PPTR 0x08080000 - -/* the basic constants and interfaces needed by gic */ -rt_inline rt_ubase_t platform_get_gic_dist_base(void) -{ -#ifdef BSP_USING_GICV2 - return GIC_PL390_DISTRIBUTOR_PPTR; -#else - return GIC_PL500_DISTRIBUTOR_PPTR; -#endif -} - -rt_inline rt_ubase_t platform_get_gic_redist_base(void) -{ - return GIC_PL500_REDISTRIBUTOR_PPTR; -} - -rt_inline rt_ubase_t platform_get_gic_cpu_base(void) -{ -#ifdef BSP_USING_GICV2 - return GIC_PL390_CONTROLLER_PPTR; -#else - return GIC_PL500_CONTROLLER_PPTR; -#endif -} - -rt_inline rt_ubase_t platform_get_gic_its_base(void) -{ - return GIC_PL500_ITS_PPTR; -} - -#endif diff --git a/bsp/qemu-virt64-aarch64/drivers/virtio_mmio.c b/bsp/qemu-virt64-aarch64/drivers/virtio_mmio.c deleted file mode 100644 index 11945634f43a..000000000000 --- a/bsp/qemu-virt64-aarch64/drivers/virtio_mmio.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-04-13 ErikChan the first version - */ - -#include -#include -#include -#include - -#ifdef RT_USING_FDT -#include "dtb_node.h" -#endif - -int virtio_mmio_probe(struct rt_device *dev) -{ - struct virtio_mmio_config *mmio_config; - - struct dtb_node *node = (struct dtb_node *)(dev->dtb_node); - if (node) - { - size_t uart_reg_range = 0; - void *uart_reg_addr = (void *)dtb_node_get_addr_size(node, "reg", &uart_reg_range); - - rt_ubase_t hw_base; - if ((uart_reg_addr) && (uart_reg_range != 0)) - { - hw_base = (rt_base_t)rt_ioremap(uart_reg_addr, uart_reg_range); - } - - mmio_config = (struct virtio_mmio_config *)hw_base; - - if (mmio_config->magic != VIRTIO_MAGIC_VALUE || - mmio_config->version != RT_USING_VIRTIO_VERSION || - mmio_config->vendor_id != VIRTIO_VENDOR_ID) - { - return 0; - } - - struct hw_virtio_device *virtio_device_priv = (struct hw_virtio_device *)(dev->user_data); - rt_uint32_t device_id = virtio_device_priv->id; - - switch (device_id) - { - case VIRTIO_DEVICE_ID_CONSOLE: - { - /* Create vport0p1 */ - struct virtio_console_device *virtio_console_dev = (struct virtio_console_device *)(dev); - virtio_console_port_create(virtio_console_dev); - } - break; - default: - break; - } - } - - return 0; -} - -struct rt_device_id virtio_mmio_ids[] = - { - {.compatible = "virtio,mmio"}, - {/* sentinel */}}; - -static struct rt_virtio_driver virtio_mmio_drv = { - .parent = { - .name = "virtio_mmio", - .probe = virtio_mmio_probe, - .ids = virtio_mmio_ids, - }, -}; - -int virtio_drv_init(void) -{ - struct rt_bus *virtio_bus = rt_bus_find_by_name("virtio"); - virtio_mmio_drv.parent.bus = virtio_bus; - - rt_virtio_driver_register(&virtio_mmio_drv); - return 0; -} - -INIT_ENV_EXPORT(virtio_drv_init); diff --git a/bsp/qemu-virt64-aarch64/qemu-debug.bat b/bsp/qemu-virt64-aarch64/qemu-debug.bat deleted file mode 100644 index 8d47286bd238..000000000000 --- a/bsp/qemu-virt64-aarch64/qemu-debug.bat +++ /dev/null @@ -1,9 +0,0 @@ -@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 diff --git a/bsp/qemu-virt64-aarch64/qemu-debug.sh b/bsp/qemu-virt64-aarch64/qemu-debug.sh deleted file mode 100644 index 91f0cf752675..000000000000 --- a/bsp/qemu-virt64-aarch64/qemu-debug.sh +++ /dev/null @@ -1,7 +0,0 @@ -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 -m 128M -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 diff --git a/bsp/qemu-virt64-aarch64/qemu-graphic.bat b/bsp/qemu-virt64-aarch64/qemu-graphic.bat deleted file mode 100644 index 74332bb5eea0..000000000000 --- a/bsp/qemu-virt64-aarch64/qemu-graphic.bat +++ /dev/null @@ -1,13 +0,0 @@ -@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 -serial stdio ^ --drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 ^ --netdev user,id=net0 -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1 ^ --device virtio-gpu-device,xres=800,yres=600,bus=virtio-mmio-bus.2 ^ --device virtio-keyboard-device,bus=virtio-mmio-bus.3 ^ --device virtio-mouse-device,bus=virtio-mmio-bus.4 ^ --device virtio-tablet-device,bus=virtio-mmio-bus.5 ^ --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 diff --git a/bsp/qemu-virt64-aarch64/qemu-graphic.sh b/bsp/qemu-virt64-aarch64/qemu-graphic.sh deleted file mode 100644 index 09d4371cabbe..000000000000 --- a/bsp/qemu-virt64-aarch64/qemu-graphic.sh +++ /dev/null @@ -1,11 +0,0 @@ -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 -serial stdio \ --drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \ --netdev user,id=net0 -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1 \ --device virtio-gpu-device,xres=800,yres=600,bus=virtio-mmio-bus.2 \ --device virtio-keyboard-device,bus=virtio-mmio-bus.3 \ --device virtio-mouse-device,bus=virtio-mmio-bus.4 \ --device virtio-tablet-device,bus=virtio-mmio-bus.5 \ --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 diff --git a/bsp/qemu-virt64-aarch64/qemu.bat b/bsp/qemu-virt64-aarch64/qemu.bat deleted file mode 100644 index de958844932d..000000000000 --- a/bsp/qemu-virt64-aarch64/qemu.bat +++ /dev/null @@ -1,9 +0,0 @@ -@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 ^ --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 diff --git a/bsp/qemu-virt64-aarch64/qemu.py b/bsp/qemu-virt64-aarch64/qemu.py new file mode 100755 index 000000000000..9ee88ef01055 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/qemu.py @@ -0,0 +1,342 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import os, sys + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.join(os.getcwd(), '..', '..') + +sys.path.append(RTT_ROOT + '/tools') + +from building import * +import dtc + +# WSL? +is_windows = sys.platform.startswith('win') or \ + os.popen('which qemu-system-aarch64 | xargs file').read().find('PE') >= 0 or \ + (os.system("readlink `which qemu-system-aarch64` > /dev/null") == 0 and \ + os.popen('readlink `which qemu-system-aarch64` | xargs file').read().find('PE') >= 0) + +class QEMU_VERSION: + def __init__(self): + cmd = os.popen("qemu-system-aarch64 --version").readlines()[0] + version = cmd[cmd.find("version ") + 8: -1].split('.') + + self.major = version[0] + self.minor = version[1] + self.revision = version[2] + # == + def __eq__(self, version_in): + version = version_in.split('.') + return self.major == version[0] and self.minor == version[1] and self.revision == version[2] + # >= + def __ge__(self, version_in): + return self.__gt__(version_in) or self.__eq__(version_in) + # > + def __gt__(self, version_in): + version = version_in.split('.') + return self.major > version[0] or \ + (self.major == version[0] and self.minor > version[1]) or \ + (self.major == version[0] and self.minor == version[1] and self.revision > version[2]) + # <= + def __le__(self, version_in): + return self.__lt__(version_in) or self.__eq__(version_in) + # < + def __lt__(self, version_in): + return not self.__ge__(version_in) + # != + def __ne__(self, version_in): + return not self.__eq__(version_in) + +qemu_version = QEMU_VERSION() + +opt = sys.argv + +graphic_cfg = """ \ + -serial stdio -device ramfb \ + -device virtio-gpu-device \ + -device virtio-keyboard-device \ + -device virtio-mouse-device \ + -device virtio-tablet-device \ +""" + +smmu_cfg = "" +iommu_cfg = "" +plugged_mem_cfg = "" +virtfs_cfg = "" +ufs_cfg = "" + +q_gic = 2 +q_dumpdtb = "" +q_el = 1 +q_smp = 4 +q_mem = 128 +q_graphic = "-nographic" +q_debug = "" +q_bootargs = "console=ttyAMA0 earlycon cma=8M coherent_pool=2M root=vda0 rootfstype=elm rootwait rw" +q_initrd = "" +q_block = "block" +q_net = "user" +q_ssh = 12055 +q_scsi = "scsi" +q_flash = "flash" +q_emmc = "emmc" +q_nvme = "nvme" +q_plugged_mem = "" +q_iommu = "smmu" +q_sound = "hda" +q_gl = None +q_9p = "" +q_ufs = "ufs" +q_dtbo = [] +q_dtb = "" + +def is_opt(key, inkey): + if str("-" + key) == inkey: + return True + return False + +for i in range(len(opt)): + if i == 0: + continue + inkey = opt[i] + + if is_opt("gic", inkey): q_gic = int(opt[i + 1]) + if is_opt("dumpdtb", inkey): q_dumpdtb = str(",dumpdtb=" + opt[i + 1]) + if is_opt("el", inkey): q_el = int(opt[i + 1]) + if is_opt("smp", inkey): q_smp = int(opt[i + 1]) + if is_opt("mem", inkey): q_mem = int(opt[i + 1]) + if is_opt("debug", inkey): q_debug = "-S -s" + if is_opt("bootargs", inkey): q_bootargs = opt[i + 1] + if is_opt("initrd", inkey): q_initrd = str("-initrd " + opt[i + 1]) + if is_opt("graphic", inkey): q_graphic = graphic_cfg + if is_opt("block", inkey): q_block = opt[i + 1] + if is_opt("tap", inkey): q_net = "tap,ifname=tap0" + if is_opt("ssh", inkey): q_ssh = int(opt[i + 1]) + if is_opt("flash", inkey): q_flash = opt[i + 1] + if is_opt("emmc", inkey): q_emmc = opt[i + 1] + if is_opt("nvme", inkey): q_nvme = opt[i + 1] + if is_opt("plugged-mem", inkey): q_plugged_mem = opt[i + 1] + if is_opt("iommu", inkey): q_iommu = opt[i + 1] + if is_opt("sound", inkey): q_sound = opt[i + 1] + if is_opt("gl", inkey): q_gl = "-device virtio-gpu-gl-device -display gtk,gl=on " + if is_opt("9p", inkey): q_9p = opt[i + 1] + if is_opt("ufs", inkey): q_ufs = opt[i + 1] + if is_opt("dtb", inkey): q_dtb = "-dtb " + opt[i + 1] + if is_opt("dtbo", inkey): q_dtbo += [opt[i + 1]] + +# SMP +if q_smp > 8: + q_gic = 3 + +# Exception Level +if q_el == 1: + q_el = "" +elif q_el == 2: + q_el = ",virtualization=on" + if q_gic == 3: + q_gic = "max" +elif q_el == 3: + q_el = ",secure=on" +else: + print("Error: Invalid -el {}".format(q_el)) + exit(-1) + +# IOMMU +if q_iommu == "smmu": + smmu_cfg = "iommu=smmuv3," +elif q_iommu == "virtio": + iommu_cfg = "-device virtio-iommu-device,disable-legacy=on,primary-bus=pcie.0 " +else: + print("Error: Invalid -iommu {}".format(q_iommu)) + exit(-1) + +# Display +# --enable-opengl --enable-virglrenderer +if q_graphic != "-nographic": + if is_windows: + q_bootargs += " ramfb.buffer_size=1" +elif q_gl != None: + print("Error: GL should in graphic mode") + exit(-1) + +# Sound +if q_sound == "hda": + q_sound = "-device intel-hda -device hda-duplex " +elif q_sound == "virtio": + if qemu_version < '8.2.0': + print("Error: VirtIO Sound is not in this version: {}".format(qemu_version)) + exit(-1) + q_sound = "-device virtio-sound-pci,audiodev=vsnd -audiodev alsa,id=vsnd " +else: + print("Error: Invalid -sound {}".format(q_sound)) + exit(-1) + +# Net +# --enable-slirp +# Enable TAP in example (not support in Windows, Maybe WSL2): +# ETH0=`/sbin/route -n | awk '$1 == "0.0.0.0" {print $NF}'` +# ip link add br0 type bridge +# ip link set br0 up +# echo 1 | tee /proc/sys/net/ipv4/ip_forward > /dev/null +# ip link set ${ETH0} up +# ip link set ${ETH0} master br0 +# dhclient br0 +# ip tuntap add dev tap0 mode tap +# ip link set dev tap0 up +# ip link set tap0 master br0 +# +# Disable TAP in example (not support in Windows, Maybe WSL2): +# ip link set tap0 down +# ip tuntap del dev tap0 mod tap +# echo 0 | tee /proc/sys/net/ipv4/ip_forward > /dev/null +# ip link set br0 down +# ip link del br0 type bridge +if q_net.find("user") >= 0: + q_net += ",hostfwd=tcp::{}-:22".format(q_ssh) +else: + if not is_windows: + q_net += ",script=no,downscript=no" + print("Warning: SSH not set in TAP") + +# Storage +# pflash have pflash0 and pflash1, pflash0 is used for BootROMs such as UEFI +# if we load file to pflash0, QEMU will boot from it, so we only use pflash1. +# Well, we can R/W in pflash0 by CFI driver, but the data will lost after QEMU exits. +# +# partitions (not support in Windows, Maybe WSL2): +# modprobe nbd max_part=12 +# qemu-nbd --connect=/dev/nbdX ABC.qcow2 +# fdisk /dev/nbdX +# ... +# qemu-nbd --disconnect /dev/nbdX +disk_list = [q_block, q_scsi, q_flash, q_emmc, q_nvme] + +if qemu_version >= '8.2.0': + disk_list += [q_ufs] + ufs_cfg = """ \ + -drive if=none,file={}.qcow2,format=qcow2,id=ufs \ + -device ufs,serial=deadbeef \ + -device ufs-lu,drive=ufs \ + """.format(q_ufs) + +for disk in disk_list: + disk += ".qcow2" + if not os.path.exists(disk): + os.system("qemu-img create -f qcow2 {} 64M".format(disk)) + +# Share File System +# --enable-virtfs +if len(q_9p) > 0: + p9_tag = "hostshare" + virtfs_cfg = """ \ + -fsdev local,security_model=passthrough,id=fsdev0,path={} \ + -device virtio-9p-device,fsdev=fsdev0,mount_tag={} \ + """.format(q_9p, p9_tag) + q_bootargs += " 9p.tag={} 9p.mount=host".format(p9_tag) + +# Plugged Memory +if len(q_plugged_mem) > 0: + if is_windows: + print("Warning: virtio-mem is not supported in MS Windows") + else: + plugged_mem_cfg = """ \ + -device virtio-mem,id=plugged-mem0,memdev=plugged-mem-pool0,node=0,requested-size={} \ + -object memory-backend-ram,id=plugged-mem-pool0,size={} \ + """.format(q_plugged_mem, q_plugged_mem) + +# Note +# Hot-plug / Hot-unplug in QEMU monitor: +# (qemu) chardev-add socket,host=127.0.0.1,port=4323,server=on,wait=off,telnet=on,id=console2 +# (qemu) device_add virtserialport,chardev=console2,name=org.rt-thread.port,id=port2 +# (qemu) device_del port2 +# (qemu) chardev-remove console2 +# +# VirtIO version disable legacy to set version >= 1.0: +# -global virtio-mmio.force-legacy=false +# +# VirtIO used virtqueue packed (version >= 1.0) +# -device virtio-XYZ-device,packed=on +# +# VirtIO used PCI/PCIe bus (version >= 1.0) +# -device virtio-XYZ-pci,disable-legacy=on + +cmd_base = """ +qemu-system-aarch64 \ + -M virt,acpi=on,{}its=on,gic-version={}{}{} \ + -cpu max \ + -smp {} \ + -m {} \ + -kernel rtthread.bin \ + -append "{}" \ + {} \ + {} \ + -device vmcoreinfo \ + {} \ + {} \ + -drive if=none,file={}.qcow2,format=qcow2,id=blk0 \ + -device virtio-blk-device,drive=blk0 \ + -netdev {},id=net0 \ + -device virtio-net-device,netdev=net0,speed=800000 \ + -device virtio-rng-device \ + -device virtio-balloon-device \ + -device virtio-scsi-pci,disable-legacy=on \ + -device scsi-hd,channel=0,scsi-id=0,lun=2,drive=scsi0 \ + -drive file={}.qcow2,format=qcow2,if=none,id=scsi0 \ + {} \ + {} \ + -device virtio-crypto-device,cryptodev=vcrypto0 \ + -object cryptodev-backend-builtin,id=vcrypto0 \ + -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,name=org.rt-thread.console \ + {} \ + {} \ + -drive if=pflash,file={}.qcow2,format=qcow2,index=1 \ + -device pci-serial,chardev=console1 \ + -chardev socket,host=127.0.0.1,port=4322,server=on,wait=off,telnet=on,id=console1 \ + -device sdhci-pci -device sd-card,drive=emmc0 \ + -drive if=none,file={}.qcow2,format=qcow2,id=emmc0 \ + -device nvme,id=nvme-ctrl-0,serial=deadbeef \ + -drive if=none,file={}.qcow2,format=qcow2,id=nvme0 \ + -device nvme-ns,drive=nvme0 \ + -device i6300esb -watchdog-action reset \ + {} \ + -device edu,dma_mask=0xffffffff +""" +def cmd(): + return cmd_base.format(smmu_cfg, q_gic, q_dumpdtb, q_el, q_smp, q_mem, q_bootargs, q_dtb, q_initrd, + q_graphic, q_debug, q_block, q_net, q_scsi, virtfs_cfg, plugged_mem_cfg, + iommu_cfg, q_sound, q_flash, q_emmc, q_nvme, ufs_cfg) + +def dumpdtb(): + dtb = q_dumpdtb.split('=')[-1] + os.system("dtc -I dtb -O dts -@ -A {} -o {}".format(dtb, dtb.replace(".dtb", ".dts"))) + +if len(q_dtbo) > 0: + # Dump raw QEMU dts + q_dumpdtb = ",dumpdtb=qemu.tmp.dtb" + os.system(cmd()) + dumpdtb(); + os.remove("qemu.tmp.dtb") + q_dumpdtb = "" + # Merge all dts + q_dtbo = ["qemu.tmp.dts"] + q_dtbo + with open("qemu.run.dts", 'w') as run_dts: + for dts in q_dtbo: + with open(dts) as dts: + run_dts.write(dts.read()) + os.remove("qemu.tmp.dts") + # Build runtime dtb + dtc.dts_to_dtb(RTT_ROOT, ["qemu.run.dts"]) + os.remove("qemu.run.dts") + # Run QEMU + q_dtb = "-dtb qemu.run.dtb" + os.system(cmd()) + os.remove("qemu.run.dtb") +else: + os.system(cmd()) + + if len(q_dumpdtb) != 0: + dumpdtb() diff --git a/bsp/qemu-virt64-aarch64/qemu.sh b/bsp/qemu-virt64-aarch64/qemu.sh deleted file mode 100755 index f025e2c94788..000000000000 --- a/bsp/qemu-virt64-aarch64/qemu.sh +++ /dev/null @@ -1,7 +0,0 @@ -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 -m 128M -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 diff --git a/bsp/qemu-virt64-aarch64/rtconfig.h b/bsp/qemu-virt64-aarch64/rtconfig.h index 68ad479a4474..ad186102b5f8 100644 --- a/bsp/qemu-virt64-aarch64/rtconfig.h +++ b/bsp/qemu-virt64-aarch64/rtconfig.h @@ -6,7 +6,8 @@ /* RT-Thread Kernel */ -#define RT_NAME_MAX 16 +#define RT_NAME_MAX 24 +#define RT_USING_SMART #define RT_USING_SMP #define RT_CPUS_NR 4 #define RT_ALIGN_SIZE 8 @@ -71,11 +72,12 @@ #define ARCH_MM_MMU #define ARCH_ARM #define ARCH_ARM_MMU +#define KERNEL_VADDR_START 0xffff000000000000 #define ARCH_ARMV8 #define ARCH_ARMV8_EXTENSIONS 0 -#define ARCH_SUPPORT_FPU -#define ARCH_TEXT_OFFSET 0x80000 +#define ARCH_TEXT_OFFSET 0x200000 #define ARCH_RAM_OFFSET 0x40000000 +#define ARCH_ASPACE_SIZE 0xffffffff #define ARCH_SECONDARY_CPU_STACK_SIZE 4096 #define ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS @@ -90,7 +92,7 @@ #define FINSH_USING_MSH #define FINSH_THREAD_NAME "tshell" #define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_THREAD_STACK_SIZE 8192 #define FINSH_USING_HISTORY #define FINSH_HISTORY_LINES 10 #define FINSH_USING_SYMTAB @@ -124,20 +126,72 @@ #define RT_DFS_ELM_REENTRANT #define RT_DFS_ELM_MUTEX_TIMEOUT 3000 #define RT_USING_DFS_DEVFS +#define RT_USING_DFS_DIRECTFS #define RT_USING_DFS_ROMFS +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 +#define RT_LWP_SHM_MAX_NR 64 /* Device Drivers */ +#define RT_USING_TTY +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_DEV_BUS #define RT_USING_DEVICE_IPC #define RT_UNAMED_PIPE_NUMBER 64 #define RT_USING_SYSTEM_WORKQUEUE #define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 #define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_CLK +#define RT_USING_FIRMWARE +#define RT_FIRMWARE_PSCI +#define RT_FIRMWARE_QEMU_FW_CFG +#define RT_USING_HWTIMER +#define RT_HWTIMER_ARM_ARCH +#define RT_USING_OFW +#define RT_FDT_EARLYCON_MSG_SIZE 128 +#define RT_USING_OFW_DIRECTFS +#define RT_USING_OFW_BUS_RANGES_NUMBER 8 +#define RT_USING_PCI +#define RT_PCI_MSI +#define RT_PCI_ENDPOINT +#define RT_PCI_SYS_64BIT +#define RT_PCI_CACHE_LINE_SIZE 8 + +/* PCI Device Drivers */ + +#define RT_PCI_ECAM +#define RT_PCI_HOST_COMMON +#define RT_PCI_HOST_GENERIC +#define RT_USING_PIC +#define MAX_HANDLERS 512 +#define RT_PIC_ARM_GIC +#define RT_PIC_ARM_GIC_V2M +#define RT_PIC_ARM_GIC_V3 +#define RT_PIC_ARM_GIC_V3_ITS +#define RT_PIC_ARM_GIC_MAX_NR 1 +#define RT_USING_PIN +#define RT_PIN_PL061 + +/* Power Management (PM) Domains device drivers */ + +#define RT_USING_RTC +#define RT_USING_ALARM +#define RT_RTC_PL031 #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 256 -#define RT_USING_PIN + +/* Serial Device Drivers */ + +#define RT_SERIAL_PL011 #define RT_USING_NULL #define RT_USING_ZERO #define RT_USING_RANDOM @@ -145,7 +199,14 @@ #define RT_USING_FDTLIB #define RT_USING_RTC #define RT_USING_DEV_BUS -#define RT_USING_VIRTIO +#define RT_USING_LCD +#define RT_USING_VIDEO +#define RT_VIDEO_FB +#define RT_VIDEO_LOGO +#define RT_VIDEO_LOGO_FBDEV "fb0" +#define RT_VIDEO_LOGO_RENDERING_STAGE_DRIVER_EARLY +#define RT_VIDEO_LOGO_RT_THREAD_CLUT224 + #define RT_USING_VIRTIO10 #define RT_USING_VIRTIO_MMIO_ALIGN #define RT_USING_VIRTIO_BLK @@ -171,6 +232,7 @@ #define RT_USING_POSIX_TERMIOS #define RT_USING_POSIX_DELAY #define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER /* Interprocess Communication (IPC) */ @@ -185,7 +247,12 @@ /* Utilities */ +#define RT_USING_CRASH_CORE #define RT_USING_ADT +#define RT_USING_ADT_AVL +#define RT_USING_ADT_BITMAP +#define RT_USING_ADT_HASHMAP +#define RT_USING_ADT_REF /* RT-Thread Utestcases */ @@ -305,18 +372,4 @@ #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_PIN -#define BSP_USING_VIRTIO_BLK -#define BSP_USING_VIRTIO_CONSOLE -#define BSP_USING_VIRTIO_GPU -#define BSP_USING_VIRTIO_INPUT -#define BSP_USING_GIC -#define BSP_USING_GICV2 - #endif diff --git a/bsp/qemu-virt64-aarch64/rtconfig.py b/bsp/qemu-virt64-aarch64/rtconfig.py index c363513a185a..7f76fe77d312 100644 --- a/bsp/qemu-virt64-aarch64/rtconfig.py +++ b/bsp/qemu-virt64-aarch64/rtconfig.py @@ -30,7 +30,7 @@ CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always' CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always' AFLAGS = ' -c' + AFPFLAGS + ' -x assembler-with-cpp' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc -static' + LFLAGS = DEVICE + ' -nostartfiles -Wl,--no-warn-rwx-segments -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc -static' CPATH = '' LPATH = '' diff --git a/components/mm/ioremap.c b/components/mm/ioremap.c index 5d31185e5785..9b062adf2bc5 100644 --- a/components/mm/ioremap.c +++ b/components/mm/ioremap.c @@ -18,8 +18,9 @@ void *rt_ioremap_start; size_t rt_ioremap_size; #ifdef RT_USING_SMART - #include +#endif + #define DBG_TAG "mm.ioremap" #define DBG_LVL DBG_LOG #include @@ -110,24 +111,3 @@ void rt_iounmap(volatile void *vaddr) { rt_aspace_unmap(&rt_kernel_space, (void *)vaddr); } - -#else -void *rt_ioremap(void *paddr, size_t size) -{ - return paddr; -} - -void *rt_ioremap_nocache(void *paddr, size_t size) -{ - return paddr; -} - -void *rt_ioremap_cached(void *paddr, size_t size) -{ - return paddr; -} - -void rt_iounmap(volatile void *vaddr) -{ -} -#endif diff --git a/libcpu/aarch64/Kconfig b/libcpu/aarch64/Kconfig index 58af5bd08bb2..5d78a891d83d 100644 --- a/libcpu/aarch64/Kconfig +++ b/libcpu/aarch64/Kconfig @@ -13,6 +13,10 @@ config ARCH_RAM_OFFSET hex "RAM offset" default 0 +config ARCH_ASPACE_SIZE + hex "Address space size" + default 0xffffffff + config ARCH_SECONDARY_CPU_STACK_SIZE int "Secondary CPU stack size" default 4096 diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S index 12741988ea74..5e2040262ca4 100644 --- a/libcpu/aarch64/common/context_gcc.S +++ b/libcpu/aarch64/common/context_gcc.S @@ -13,13 +13,6 @@ #include "asm_fpu.h" .text -.weak rt_hw_cpu_id_set -.type rt_hw_cpu_id_set, @function -rt_hw_cpu_id_set: - mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */ - and x0, x0, #15 - msr tpidr_el1, x0 - ret /* int rt_hw_cpu_id(void) @@ -38,45 +31,6 @@ rt_hw_set_process_id: msr CONTEXTIDR_EL1, x0 ret - /* - *enable gtimer - */ -.globl rt_hw_gtimer_enable -rt_hw_gtimer_enable: - MOV X0,#1 - MSR CNTP_CTL_EL0,X0 - RET - -/* - *set gtimer CNTP_TVAL_EL0 value - */ -.globl rt_hw_set_gtimer_val -rt_hw_set_gtimer_val: - MSR CNTP_TVAL_EL0,X0 - RET - -/* - *get gtimer CNTP_TVAL_EL0 value - */ -.globl rt_hw_get_gtimer_val -rt_hw_get_gtimer_val: - MRS X0,CNTP_TVAL_EL0 - RET - - -.globl rt_hw_get_cntpct_val -rt_hw_get_cntpct_val: - MRS X0, CNTPCT_EL0 - RET - -/* - *get gtimer frq value - */ -.globl rt_hw_get_gtimer_frq -rt_hw_get_gtimer_frq: - MRS X0,CNTFRQ_EL0 - RET - .macro SAVE_CONTEXT /* Save the entire context. */ SAVE_FPU SP diff --git a/libcpu/aarch64/common/cp15.h b/libcpu/aarch64/common/cp15.h deleted file mode 100644 index cb1458ceec6e..000000000000 --- a/libcpu/aarch64/common/cp15.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-09-15 Bernard first version - */ - -#ifndef __CP15_H__ -#define __CP15_H__ - -#ifndef __STATIC_FORCEINLINE -#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline -#endif - -#define __WFI() __asm__ volatile ("wfi":::"memory") - -#define __WFE() __asm__ volatile ("wfe":::"memory") - -#define __SEV() __asm__ volatile ("sev") - -__STATIC_FORCEINLINE void __ISB(void) -{ - __asm__ volatile ("isb 0xF":::"memory"); -} - -/** - \brief Data Synchronization Barrier - \details Acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__STATIC_FORCEINLINE void __DSB(void) -{ - __asm__ volatile ("dsb 0xF":::"memory"); -} - -/** - \brief Data Memory Barrier - \details Ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ - -__STATIC_FORCEINLINE void __DMB(void) -{ - __asm__ volatile ("dmb 0xF":::"memory"); -} - -unsigned long rt_cpu_get_smp_id(void); - -void rt_cpu_mmu_disable(void); -void rt_cpu_mmu_enable(void); -void rt_cpu_tlb_set(volatile unsigned long*); - -void rt_cpu_dcache_clean_flush(void); -void rt_cpu_icache_flush(void); - -void rt_cpu_vector_set_base(rt_ubase_t addr); -void rt_hw_mmu_init(void); -void rt_hw_vector_init(void); - -void set_timer_counter(unsigned int counter); -void set_timer_control(unsigned int control); -#endif diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 8f7f2843a9a3..d7d10427c332 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -7,58 +7,14 @@ * Date Author Notes * 2011-09-15 Bernard first version * 2019-07-28 zdzn add smp support + * 2023-02-21 GuEe-GUI mov cpu ofw init to setup */ #include #include -#include -#include "cp15.h" - -#define DBG_TAG "libcpu.aarch64.cpu" -#define DBG_LVL DBG_INFO -#include -#include -#include "cpu.h" -#include "psci_api.h" - -void (*system_off)(void); +#include #ifdef RT_USING_SMP - -#ifdef RT_USING_FDT -#include "dtb_node.h" -struct dtb_node *_cpu_node[RT_CPUS_NR]; -#endif /* RT_USING_FDT */ - -#define MPIDR_AFF_MASK 0x000000FF00FFFFFFul -#define REPORT_ERR(retval) LOG_E("got error code %d in %s(), %s:%d", (retval), __func__, __FILE__, __LINE__) -#define CHECK_RETVAL(retval) if (retval) {REPORT_ERR(retval);} - -/** - * cpu_ops_tbl contains cpu_ops_t for each cpu kernel observed, - * given cpu logical id 'i', its cpu_ops_t is 'cpu_ops_tbl[i]' - */ -struct cpu_ops_t *cpu_ops_tbl[RT_CPUS_NR]; - -#ifdef RT_USING_SMART -// _id_to_mpidr is a table translate logical id to mpid, which is a 64-bit value -rt_uint64_t rt_cpu_mpidr_early[RT_CPUS_NR] rt_weak = {[0 ... RT_CPUS_NR - 1] = ID_ERROR}; -#else -/* The more common mpidr_el1 table, redefine it in BSP if it is in other cases */ -rt_weak rt_uint64_t rt_cpu_mpidr_early[] = -{ - [0] = 0x80000000, - [1] = 0x80000001, - [2] = 0x80000002, - [3] = 0x80000003, - [4] = 0x80000004, - [5] = 0x80000005, - [6] = 0x80000006, - [7] = 0x80000007, - [RT_CPUS_NR] = 0 -}; -#endif /* RT_USING_SMART */ - void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) { lock->slock = 0; @@ -106,244 +62,6 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) : "r"(lock->tickets.owner + 1) : "memory"); } - -static int _cpus_init_data_hardcoded(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]) -{ - // load in cpu_hw_ids in cpuid_to_hwid, - // cpu_ops to cpu_ops_tbl - if (num_cpus > RT_CPUS_NR) - { - LOG_W("num_cpus (%d) greater than RT_CPUS_NR (%d)\n", num_cpus, RT_CPUS_NR); - num_cpus = RT_CPUS_NR; - } - - for (int i = 0; i < num_cpus; i++) - { - set_hwid(i, cpu_hw_ids[i]); - cpu_ops_tbl[i] = cpu_ops[i]; - } - return 0; -} - -#ifdef RT_USING_FDT - -/** read ('size' * 4) bytes number from start, big-endian format */ -static rt_uint64_t _read_be_number(void *start, int size) -{ - rt_uint64_t buf = 0; - for (; size > 0; size--) - { - buf = (buf << 32) | fdt32_to_cpu(*(uint32_t *)start); - start = (uint32_t *)start + 1; - } - return buf; -} - -/** check device-type of the node, */ -static bool _node_is_cpu(struct dtb_node *node) -{ - char *device_type = dtb_node_get_dtb_node_property_value(node, "device_type", NULL); - if (device_type) - { - return !strcmp(device_type, "cpu"); - } - return false; -} - -static int _read_and_set_hwid(struct dtb_node *cpu, int *id_pool, int *pcpuid) -{ - // size/address_cells is number of elements in reg array - int size; - static int address_cells, size_cells; - if (!address_cells && !size_cells) - dtb_node_get_dtb_node_cells(cpu, &address_cells, &size_cells); - - void *id_start = dtb_node_get_dtb_node_property_value(cpu, "reg", &size); - rt_uint64_t mpid = _read_be_number(id_start, address_cells); - - *pcpuid = *id_pool; - *id_pool = *id_pool + 1; - set_hwid(*pcpuid, mpid); - - LOG_I("Using MPID 0x%lx as cpu %d", mpid, *pcpuid); - - // setting _cpu_node for cpu_init use - _cpu_node[*pcpuid] = cpu; - - return 0; -} - -static int _read_and_set_cpuops(struct dtb_node *cpu, int cpuid) -{ - char *method = dtb_node_get_dtb_node_property_value(cpu, "enable-method", NULL); - if (!method) - { - LOG_E("Cannot read method from cpu node"); - return -1; - } - - struct cpu_ops_t *cpu_ops; - if (!strcmp(method, cpu_ops_psci.method)) - { - cpu_ops = &cpu_ops_psci; - } - else if (!strcmp(method, cpu_ops_spin_tbl.method)) - { - cpu_ops = &cpu_ops_spin_tbl; - } - else - { - cpu_ops = RT_NULL; - LOG_E("Not supported cpu_ops: %s", method); - } - cpu_ops_tbl[cpuid] = cpu_ops; - - LOG_D("Using boot method [%s] for cpu %d", cpu_ops->method, cpuid); - return 0; -} - -static int _cpus_init_data_fdt() -{ - // cpuid_to_hwid and cpu_ops_tbl with fdt - void *root = get_dtb_node_head(); - int id_pool = 0; - int cpuid; - struct dtb_node *cpus = dtb_node_get_dtb_node_by_path(root, "/cpus"); - - // for each cpu node (device-type is cpu), read its mpid and set its cpuid_to_hwid - for_each_node_child(cpus) - { - if (!_node_is_cpu(cpus)) - { - continue; - } - - if (id_pool > RT_CPUS_NR) - { - LOG_W("Reading more cpus from FDT than RT_CPUS_NR" - "\n Parsing will not continue and only %d cpus will be used.", RT_CPUS_NR); - break; - } - - _read_and_set_hwid(cpus, &id_pool, &cpuid); - - _read_and_set_cpuops(cpus, cpuid); - } - return 0; -} - -#endif /* RT_USING_FDT */ - -/** init cpu with hardcoded infomation or parsing from FDT */ -static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]) -{ - int retval; - - // first setup cpu_ops_tbl and cpuid_to_hwid - if (num_cpus > 0) - retval = _cpus_init_data_hardcoded(num_cpus, cpu_hw_ids, cpu_ops); - else - { - retval = -1; -#ifdef RT_USING_FDT - retval = _cpus_init_data_fdt(); -#endif - } - - if (retval) - return retval; - - // using cpuid_to_hwid and cpu_ops_tbl to call method_init and cpu_init - // assuming that cpuid 0 has already init - for (int i = 1; i < RT_CPUS_NR; i++) - { - if (cpuid_to_hwid(i) == ID_ERROR) - { - LOG_E("Failed to find hardware id of CPU %d", i); - continue; - } - - if (cpu_ops_tbl[i] && cpu_ops_tbl[i]->cpu_init) - { - retval = cpu_ops_tbl[i]->cpu_init(i); - CHECK_RETVAL(retval); - } - else - { - LOG_E("Failed to find cpu_init for cpu %d with cpu_ops[%p], cpu_ops->cpu_init[%p]" - , cpuid_to_hwid(i), cpu_ops_tbl[i], cpu_ops_tbl[i] ? cpu_ops_tbl[i]->cpu_init : NULL); - } - } - return 0; -} - -static void _boot_secondary(void) -{ - for (int i = 1; i < RT_CPUS_NR; i++) - { - int retval = -0xbad0; // mark no support operation - if (cpu_ops_tbl[i] && cpu_ops_tbl[i]->cpu_boot) - retval = cpu_ops_tbl[i]->cpu_boot(i); - if (retval) - { - if (retval == -0xbad0) - LOG_E("No cpu_ops was probed for CPU %d. Try to configure it or use fdt", i); - else - LOG_E("Failed to boot secondary CPU %d, error code %d", i, retval); - } else { - LOG_I("Secondary CPU %d booted", i); - } - } -} - -rt_weak void rt_hw_secondary_cpu_up(void) -{ - _boot_secondary(); -} - -/** - * @brief boot cpu with hardcoded data - * - * @param num_cpus number of cpus - * @param cpu_hw_ids each element represents a hwid of cpu[i] - * @param cpu_ops each element represents a pointer to cpu_ops of cpu[i] - * @return int 0 on success, - */ -int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]) -{ - int retval = 0; - if (num_cpus < 1 || !cpu_hw_ids || !cpu_ops) - return -1; - - retval = _cpus_init(num_cpus, cpu_hw_ids, cpu_ops); - CHECK_RETVAL(retval); - - return retval; -} - -#define CPU_INIT_USING_FDT 0,0,0 - -/** - * @brief Initialize cpu infomation from fdt - * - * @return int - */ -int rt_hw_cpu_init() -{ -#ifdef RT_USING_FDT - return _cpus_init(CPU_INIT_USING_FDT); -#else - LOG_E("CPU init failed since RT_USING_FDT was not defined"); - return -0xa; /* no fdt support */ -#endif /* RT_USING_FDT */ -} - -rt_weak void rt_hw_secondary_cpu_idle_exec(void) -{ - asm volatile("wfe" :: - : "memory", "cc"); -} - #endif /*RT_USING_SMP*/ /** @@ -356,22 +74,4 @@ const char *rt_hw_cpu_arch(void) return "aarch64"; } -/** shutdown CPU */ -rt_weak void rt_hw_cpu_shutdown() -{ - rt_uint32_t level; - rt_kprintf("shutdown...\n"); - - if (system_off) - system_off(); - LOG_E("system shutdown failed"); - - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } -} -MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_shutdown, shutdown, shutdown machine); - /*@}*/ diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h index 28044bb18535..bc380870170f 100644 --- a/libcpu/aarch64/common/cpu.h +++ b/libcpu/aarch64/common/cpu.h @@ -1,63 +1,248 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes + * 2022-08-24 GuEe-GUI add arch time registers + * 2023-02-21 GuEe-GUI add ICC registers and affinity info */ #ifndef __RT_HW_CPU_H__ #define __RT_HW_CPU_H__ -#include -#include -#include +#include +#include -#ifndef RT_CPUS_NR -#define RT_CPUS_NR 1 -#endif /* RT_CPUS_NR */ +#include +#include -#ifdef RT_USING_SMP struct cpu_ops_t { const char *method; - int (*cpu_init)(rt_uint32_t id); - int (*cpu_boot)(rt_uint32_t id); + int (*cpu_init)(rt_uint32_t id, void *param); + int (*cpu_boot)(rt_uint32_t id, rt_uint64_t entry); void (*cpu_shutdown)(void); }; -/** - * Identifier to mark a wrong CPU MPID. - * All elements in rt_cpu_mpidr_early[] should be initialized with this value - */ -#define ID_ERROR __INT64_MAX__ +#define sysreg_32(op1, crn, crm, op2) s3_##op1 ##_##crn ##_##crm ##_##op2 +#define sysreg_64(op1, crn, crm, op2) sysreg_32(op1, crn, crm, op2) + +#define MPIDR_AFFINITY_MASK 0x000000ff00ffffffUL + +#define MPIDR_LEVEL_BITS_SHIFT 3 +#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT) +#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) +#define MPIDR_LEVEL_SHIFT(level) (((1 << (level)) >> 1) << MPIDR_LEVEL_BITS_SHIFT) + +#define MPIDR_AFFINITY_LEVEL(mpidr, level) (((mpidr) >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK) + +#define MIDR_REVISION_SHIFT 0 +#define MIDR_REVISION_MASK (0xf << MIDR_REVISION_SHIFT) +#define MIDR_PARTNUM_SHIFT 4 +#define MIDR_PARTNUM_MASK (0xfff << MIDR_PARTNUM_SHIFT) +#define MIDR_VARIANT_SHIFT 20 +#define MIDR_VARIANT_MASK (0xf << MIDR_VARIANT_SHIFT) +#define MIDR_ARCHITECTURE_SHIFT 16 +#define MIDR_ARCHITECTURE_MASK (0xf << MIDR_ARCHITECTURE_SHIFT) +#define MIDR_IMPLEMENTOR_SHIFT 24 +#define MIDR_IMPLEMENTOR_MASK (0xffU << MIDR_IMPLEMENTOR_SHIFT) + +#define MIDR_CPU_MODEL(imp, partnum) \ + (((rt_uint32_t)imp << MIDR_IMPLEMENTOR_SHIFT) | \ + (0xf << MIDR_ARCHITECTURE_SHIFT) | \ + ((partnum) << MIDR_PARTNUM_SHIFT)) + +#define ARM_CPU_IMP_ARM 0x41 +#define ARM_CPU_IMP_APM 0x50 +#define ARM_CPU_IMP_CAVIUM 0x43 +#define ARM_CPU_IMP_BRCM 0x42 +#define ARM_CPU_IMP_QCOM 0x51 +#define ARM_CPU_IMP_NVIDIA 0x4e +#define ARM_CPU_IMP_FUJITSU 0x46 +#define ARM_CPU_IMP_HISI 0x48 +#define ARM_CPU_IMP_APPLE 0x61 +#define ARM_CPU_IMP_AMPERE 0xc0 + +#define ARM_CPU_PART_AEM_V8 0xd0f +#define ARM_CPU_PART_FOUNDATION 0xd00 +#define ARM_CPU_PART_CORTEX_A57 0xd07 +#define ARM_CPU_PART_CORTEX_A72 0xd08 +#define ARM_CPU_PART_CORTEX_A53 0xd03 +#define ARM_CPU_PART_CORTEX_A73 0xd09 +#define ARM_CPU_PART_CORTEX_A75 0xd0a +#define ARM_CPU_PART_CORTEX_A35 0xd04 +#define ARM_CPU_PART_CORTEX_A55 0xd05 +#define ARM_CPU_PART_CORTEX_A76 0xd0b +#define ARM_CPU_PART_NEOVERSE_N1 0xd0c +#define ARM_CPU_PART_CORTEX_A77 0xd0d +#define ARM_CPU_PART_NEOVERSE_V1 0xd40 +#define ARM_CPU_PART_CORTEX_A78 0xd41 +#define ARM_CPU_PART_CORTEX_A78AE 0xd42 +#define ARM_CPU_PART_CORTEX_X1 0xd44 +#define ARM_CPU_PART_CORTEX_A510 0xd46 +#define ARM_CPU_PART_CORTEX_A710 0xd47 +#define ARM_CPU_PART_CORTEX_A715 0xd4d +#define ARM_CPU_PART_CORTEX_X2 0xd48 +#define ARM_CPU_PART_NEOVERSE_N2 0xd49 +#define ARM_CPU_PART_CORTEX_A78C 0xd4b + +#define APM_CPU_PART_POTENZA 0x000 + +#define CAVIUM_CPU_PART_THUNDERX 0x0a1 +#define CAVIUM_CPU_PART_THUNDERX_81XX 0x0a2 +#define CAVIUM_CPU_PART_THUNDERX_83XX 0x0a3 +#define CAVIUM_CPU_PART_THUNDERX2 0x0af +/* OcteonTx2 series */ +#define CAVIUM_CPU_PART_OCTX2_98XX 0x0b1 +#define CAVIUM_CPU_PART_OCTX2_96XX 0x0b2 +#define CAVIUM_CPU_PART_OCTX2_95XX 0x0b3 +#define CAVIUM_CPU_PART_OCTX2_95XXN 0x0b4 +#define CAVIUM_CPU_PART_OCTX2_95XXMM 0x0b5 +#define CAVIUM_CPU_PART_OCTX2_95XXO 0x0b6 + +#define BRCM_CPU_PART_BRAHMA_B53 0x100 +#define BRCM_CPU_PART_VULCAN 0x516 + +#define QCOM_CPU_PART_FALKOR_V1 0x800 +#define QCOM_CPU_PART_FALKOR 0xc00 +#define QCOM_CPU_PART_KRYO 0x200 +#define QCOM_CPU_PART_KRYO_2XX_GOLD 0x800 +#define QCOM_CPU_PART_KRYO_2XX_SILVER 0x801 +#define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803 +#define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804 +#define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805 + +#define NVIDIA_CPU_PART_DENVER 0x003 +#define NVIDIA_CPU_PART_CARMEL 0x004 + +#define FUJITSU_CPU_PART_A64FX 0x001 -extern rt_uint64_t rt_cpu_mpidr_early[]; -extern struct dtb_node *_cpu_node[]; +#define HISI_CPU_PART_TSV110 0xd01 -#define cpuid_to_hwid(cpuid) \ - ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? rt_cpu_mpidr_early[cpuid] : ID_ERROR) -#define set_hwid(cpuid, hwid) \ - ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? (rt_cpu_mpidr_early[cpuid] = (hwid)) : ID_ERROR) -#define get_cpu_node(cpuid) \ - ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? _cpu_node[cpuid] : NULL) -#define set_cpu_node(cpuid, node) \ - ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? (_cpu_node[cpuid] = node) : NULL) +#define APPLE_CPU_PART_M1_ICESTORM 0x022 +#define APPLE_CPU_PART_M1_FIRESTORM 0x023 +#define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024 +#define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025 +#define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028 +#define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029 +#define APPLE_CPU_PART_M2_BLIZZARD 0x032 +#define APPLE_CPU_PART_M2_AVALANCHE 0x033 +#define APPLE_CPU_PART_M2_BLIZZARD_PRO 0x034 +#define APPLE_CPU_PART_M2_AVALANCHE_PRO 0x035 +#define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038 +#define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 -extern int rt_hw_cpu_init(); +#define AMPERE_CPU_PART_AMPERE1 0xac3 -extern int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]); +#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) +#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) +#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) +#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73) +#define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A75) +#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35) +#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55) +#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) +#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) +#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) +#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1) +#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78) +#define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) +#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) +#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) +#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) +#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) +#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) +#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) +#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) +#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) +#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) +#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) +#define MIDR_OCTX2_98XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_98XX) +#define MIDR_OCTX2_96XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_96XX) +#define MIDR_OCTX2_95XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XX) +#define MIDR_OCTX2_95XXN MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXN) +#define MIDR_OCTX2_95XXMM MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXMM) +#define MIDR_OCTX2_95XXO MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXO) +#define MIDR_CAVIUM_THUNDERX2 MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX2) +#define MIDR_BRAHMA_B53 MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_BRAHMA_B53) +#define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN) +#define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) +#define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) +#define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) +#define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD) +#define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER) +#define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER) +#define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD) +#define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER) +#define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER) +#define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) +#define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX) +#define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) +#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) +#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) +#define MIDR_APPLE_M1_ICESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO) +#define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) +#define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX) +#define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX) +#define MIDR_APPLE_M2_BLIZZARD MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD) +#define MIDR_APPLE_M2_AVALANCHE MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE) +#define MIDR_APPLE_M2_BLIZZARD_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_PRO) +#define MIDR_APPLE_M2_AVALANCHE_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_PRO) +#define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX) +#define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX) +#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) +#define MIDR_QEMU MIDR_CPU_MODEL(0, 'Q') -extern void rt_hw_secondary_cpu_idle_exec(void); +/* GIC registers */ +#define ICC_IAR0_SYS sysreg_64(0, c12, c8, 0) +#define ICC_IAR1_SYS sysreg_64(0, c12, c12, 0) +#define ICC_EOIR0_SYS sysreg_64(0, c12, c8, 1) +#define ICC_EOIR1_SYS sysreg_64(0, c12, c12, 1) +#define ICC_HPPIR0_SYS sysreg_64(0, c12, c8, 2) +#define ICC_HPPIR1_SYS sysreg_64(0, c12, c12, 2) +#define ICC_BPR0_SYS sysreg_64(0, c12, c8, 3) +#define ICC_BPR1_SYS sysreg_64(0, c12, c12, 3) +#define ICC_DIR_SYS sysreg_64(0, c12, c11, 1) +#define ICC_PMR_SYS sysreg_64(0, c4, c6, 0) +#define ICC_RPR_SYS sysreg_64(0, c12, c11, 3) +#define ICC_CTLR_SYS sysreg_64(0, c12, c12, 4) +#define ICC_SRE_SYS sysreg_64(0, c12, c12, 5) +#define ICC_IGRPEN0_SYS sysreg_64(0, c12, c12, 6) +#define ICC_IGRPEN1_SYS sysreg_64(0, c12, c12, 7) +#define ICC_SGI0R_SYS sysreg_64(0, c12, c11, 7) +#define ICC_SGI1R_SYS sysreg_64(0, c12, c11, 5) +#define ICC_ASGI1R_SYS sysreg_64(0, c12, c11, 6) -extern struct cpu_ops_t cpu_ops_psci; +/* Arch timer registers */ +#define CNTP_CTL CNTP_CTL_EL0 /* EL1 Physical Timer */ +#define CNTHP_CTL CNTHP_CTL_EL2 /* EL2 Non-secure Physical Timer */ +#define CNTHPS_CTL CNTHPS_CTL_EL2 /* EL2 Secure Physical Timer */ +#define CNTPS_CTL CNTPS_CTL_EL1 /* EL3 Physical Timer */ +#define CNTV_CTL CNTV_CTL_EL0 /* EL1 Virtual Timer */ +#define CNTHV_CTL CNTHV_CTL_EL2 /* EL2 Non-secure Virtual Timer */ +#define CNTHVS_CTL CNTHVS_CTL_EL2 /* EL2 Secure Virtual Timer */ -extern struct cpu_ops_t cpu_ops_spin_tbl; +#define CNTP_CVAL CNTP_CVAL_EL0 +#define CNTHP_CVAL CNTHP_CVAL_EL2 +#define CNTHPS_CVAL CNTHPS_CVAL_EL2 +#define CNTPS_CVAL CNTPS_CVAL_EL1 +#define CNTV_CVAL CNTV_CVAL_EL0 +#define CNTHV_CVAL CNTHV_CVAL_EL2 +#define CNTHVS_CVAL CNTHVS_CVAL_EL2 -#endif /* RT_USING_SMP */ +#define CNTP_TVAL CNTP_TVAL_EL0 +#define CNTHP_TVAL CNTHP_TVAL_EL2 +#define CNTHPS_TVAL CNTHPS_TVAL_EL2 +#define CNTPS_TVAL CNTPS_TVAL_EL1 +#define CNTV_TVAL CNTV_TVAL_EL0 +#define CNTHV_TVAL CNTHV_TVAL_EL2 +#define CNTHVS_TVAL CNTHVS_TVAL_EL2 -extern void rt_hw_cpu_shutdown(void); +#define CNTPCT CNTPCT_EL0 +#define CNTVCT CNTVCT_EL0 +#define CNTFRQ CNTFRQ_EL0 -extern void (*system_off)(void); +extern rt_uint64_t rt_cpu_mpidr_table[]; #endif /* __RT_HW_CPU_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/cpu_ops_common.h b/libcpu/aarch64/common/cpu_ops_common.h deleted file mode 100644 index 5e47584c7bc6..000000000000 --- a/libcpu/aarch64/common/cpu_ops_common.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __CPU_OPS_COMMON_H__ -#define __CPU_OPS_COMMON_H__ - -#include -#include -#include -#include "entry_point.h" - -static inline rt_uint64_t get_secondary_entry_pa(void) -{ - rt_uint64_t secondary_entry_pa = (rt_uint64_t)rt_kmem_v2p(_secondary_cpu_entry); - - if (!secondary_entry_pa) - { - LOG_E("Failed to translate 'secondary_entry_pa' to physical address"); - return 0; - } - return secondary_entry_pa; -} - -#endif /* __CPU_OPS_COMMON_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/cpu_psci.c b/libcpu/aarch64/common/cpu_psci.c index ddb8ae4a477f..3087dc76dd7e 100644 --- a/libcpu/aarch64/common/cpu_psci.c +++ b/libcpu/aarch64/common/cpu_psci.c @@ -1,70 +1,45 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes + * 2023-02-21 GuEe-GUI replace with drivers/psci */ #include #include -#include -#ifdef RT_USING_SMP - -#define DBG_TAG "libcpu.aarch64.cpu_psci" +#define DBG_TAG "cpu.aa64" #define DBG_LVL DBG_INFO #include -#include "cpu_ops_common.h" -#include "cpu.h" -#include "errno.h" -#include "psci.h" -#include "psci_api.h" +#include +#include -static int (*_psci_init)(void) = psci_init; +#ifdef RT_FIRMWARE_PSCI +#include -static int __call_method_init() +static int psci_cpu_boot(rt_uint32_t cpuid, rt_uint64_t entry) { - int (*init)(void) = _psci_init; - _psci_init = RT_NULL; - - return init(); + return rt_psci_cpu_on(cpuid, entry); } -/** return 0 on success, otherwise failed */ -#define _call_method_init() ((_psci_init) ? __call_method_init() : 0); - -static int cpu_psci_cpu_init(rt_uint32_t cpuid) +static void psci_cpu_shutdown(void) { - // init psci only once - return _call_method_init(); -} + rt_uint32_t state, state_id = PSCI_POWER_STATE_ID(0, 0, 0, PSCI_POWER_STATE_ID_POWERDOWN); -static int cpu_psci_cpu_boot(rt_uint32_t cpuid) -{ - rt_uint64_t secondary_entry_pa = get_secondary_entry_pa(); + state = PSCI_POWER_STATE(PSCI_POWER_STATE_LEVEL_CORES, PSCI_POWER_STATE_TYPE_STANDBY, state_id); - if (!secondary_entry_pa) - return -1; - - if (!psci_ops.cpu_on) { - LOG_E("Uninitialized psci operation"); - return -1; - } - return psci_ops.cpu_on(cpuid_to_hwid(cpuid), secondary_entry_pa); + rt_psci_cpu_off(state); } +#endif /* RT_FIRMWARE_PSCI */ -static void cpu_psci_cpu_shutdown() +struct cpu_ops_t cpu_psci_ops = { - psci_ops.cpu_off(cpuid_to_hwid(rt_hw_cpu_id())); -} - -struct cpu_ops_t cpu_ops_psci = { +#ifdef RT_FIRMWARE_PSCI .method = "psci", - .cpu_boot = cpu_psci_cpu_boot, - .cpu_init = cpu_psci_cpu_init, - .cpu_shutdown = cpu_psci_cpu_shutdown, + .cpu_boot = psci_cpu_boot, + .cpu_shutdown = psci_cpu_shutdown, +#endif /* RT_FIRMWARE_PSCI */ }; - -#endif /* RT_USING_SMP */ \ No newline at end of file diff --git a/libcpu/aarch64/common/cpu_spin_table.c b/libcpu/aarch64/common/cpu_spin_table.c index 67e788225fb1..4b8cf9775119 100644 --- a/libcpu/aarch64/common/cpu_spin_table.c +++ b/libcpu/aarch64/common/cpu_spin_table.c @@ -1,80 +1,62 @@ /* - * Copyright (c) 2006-2022, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes + * 2023-02-21 GuEe-GUI replace with ofw */ #include #include -#include "cpu.h" - -#ifdef RT_USING_SMART -#include -#else -#define rt_ioremap(x, ...) (x) -#define rt_iounmap(x) -#endif - -#define DBG_TAG "libcpu.aarch64.cpu_spin_table" +#define DBG_TAG "cpu.aa64" #define DBG_LVL DBG_INFO #include -#include "cpu_ops_common.h" -#ifdef RT_USING_SMP -#ifdef RT_USING_FDT -#include +#include +#include + +#include +#include static rt_uint64_t cpu_release_addr[RT_CPUS_NR]; -static int spin_table_cpu_init(rt_uint32_t cpuid) +static int spin_table_cpu_init(rt_uint32_t cpuid, void *param) { - struct dtb_node *cpu = get_cpu_node(cpuid); - if (!cpu) - return -1; /* uninitialized cpu node in fdt */ + struct rt_ofw_node *cpu_np = param; - int size; - rt_uint64_t *phead = (rt_uint64_t*)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size); - cpu_release_addr[cpuid] = fdt64_to_cpu(*phead); + rt_ofw_prop_read_u64(cpu_np, "cpu-release-addr", &cpu_release_addr[cpuid]); LOG_D("Using release address 0x%p for CPU %d", cpu_release_addr[cpuid], cpuid); + return 0; } -static int spin_table_cpu_boot(rt_uint32_t cpuid) +static int spin_table_cpu_boot(rt_uint32_t cpuid, rt_uint64_t entry) { - rt_uint64_t secondary_entry_pa = get_secondary_entry_pa(); - if (!secondary_entry_pa) - return -1; + void *cpu_release_vaddr; - // map release_addr to addressable place - void *rel_va = (void *)cpu_release_addr[cpuid]; + cpu_release_vaddr = rt_ioremap((void *)cpu_release_addr[cpuid], sizeof(cpu_release_addr[0])); -#ifdef RT_USING_SMART - rel_va = rt_ioremap(rel_va, sizeof(cpu_release_addr[0])); -#endif - if (!rel_va) + if (!cpu_release_vaddr) { LOG_E("IO remap failing"); return -1; } - __asm__ volatile("str %0, [%1]" ::"rZ"(secondary_entry_pa), "r"(rel_va)); - __asm__ volatile("dsb sy"); - __asm__ volatile("sev"); - rt_iounmap(rel_va); + __asm__ volatile ("str %0, [%1]" ::"rZ"(entry), "r"(cpu_release_vaddr)); + rt_hw_barrier(dsb, sy); + rt_hw_sev(); + + rt_iounmap(cpu_release_vaddr); + return 0; } -#endif /* RT_USING_FDT */ -struct cpu_ops_t cpu_ops_spin_tbl = { +struct cpu_ops_t cpu_spin_table_ops = +{ .method = "spin-table", -#ifdef RT_USING_FDT .cpu_init = spin_table_cpu_init, .cpu_boot = spin_table_cpu_boot, -#endif }; - -#endif /* RT_USING_SMP */ \ No newline at end of file diff --git a/libcpu/aarch64/common/cpuport.h b/libcpu/aarch64/common/cpuport.h index d20c1d50080e..282114f93d03 100644 --- a/libcpu/aarch64/common/cpuport.h +++ b/libcpu/aarch64/common/cpuport.h @@ -1,10 +1,11 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes + * 2023-02-21 GuEe-GUI rename barrier and add cpu relax */ #ifndef CPUPORT_H__ @@ -23,29 +24,55 @@ typedef union { } rt_hw_spinlock_t; #endif -rt_inline void rt_hw_isb(void) -{ - __asm__ volatile ("isb":::"memory"); -} +#define rt_hw_barrier(cmd, ...) asm volatile (RT_STRINGIFY(cmd) " "RT_STRINGIFY(__VA_ARGS__):::"memory") -rt_inline void rt_hw_dmb(void) -{ - __asm__ volatile ("dmb ish":::"memory"); -} +#define rt_hw_isb() rt_hw_barrier(isb) +#define rt_hw_dmb() rt_hw_barrier(dmb, ish) +#define rt_hw_wmb() rt_hw_barrier(dmb, ishst) +#define rt_hw_rmb() rt_hw_barrier(dmb, ishld) +#define rt_hw_dsb() rt_hw_barrier(dsb, ish) -rt_inline void rt_hw_wmb(void) -{ - __asm__ volatile ("dmb ishst":::"memory"); -} +#define rt_hw_wfi() rt_hw_barrier(wfi) +#define rt_hw_wfe() rt_hw_barrier(wfe) +#define rt_hw_sev() rt_hw_barrier(sev) + +#define rt_hw_cpu_relax() rt_hw_barrier(yield) + +#define sysreg_write(sysreg, val) \ + __asm__ volatile ("msr "RT_STRINGIFY(sysreg)", %0"::"r"((rt_uint64_t)(val))) -rt_inline void rt_hw_rmb(void) +#define sysreg_read(sysreg, val) \ + __asm__ volatile ("mrs %0, "RT_STRINGIFY(sysreg)"":"=r"((val))) + +rt_inline unsigned long __rt_clz(unsigned long word) { - __asm__ volatile ("dmb ishld":::"memory"); +#ifdef __GNUC__ + return __builtin_clz(word); +#else + unsigned long val; + + __asm__ volatile ("clz %0, %1" + :"=r"(val) + :"r"(word)); + + return val; +#endif } -rt_inline void rt_hw_dsb(void) +rt_inline unsigned long __rt_ffsl(unsigned long word) { - __asm__ volatile ("dsb ish":::"memory"); +#ifdef __GNUC__ + return __builtin_ffsl(word); +#else + if (!word) + { + return 0; + } + + __asm__ volatile ("rbit %0, %0" : "+r" (word)); + + return __rt_clz(word); +#endif } #endif /*CPUPORT_H__*/ diff --git a/libcpu/aarch64/common/entry_point.h b/libcpu/aarch64/common/entry_point.h deleted file mode 100644 index fc3e6c061f12..000000000000 --- a/libcpu/aarch64/common/entry_point.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __ENTRY_POINT_H__ -#define __ENTRY_POINT_H__ - -extern void _secondary_cpu_entry(void); -#endif /* __ENTRY_POINT_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/gic.c b/libcpu/aarch64/common/gic.c deleted file mode 100644 index 498cc9ea0071..000000000000 --- a/libcpu/aarch64/common/gic.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - * 2014-04-03 Grissiom many enhancements - * 2018-11-22 Jesven add rt_hw_ipi_send() - * add rt_hw_ipi_handler_install() - */ - -#include -#include - -#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) - -#include "gic.h" -#include "cp15.h" - -struct arm_gic -{ - rt_uint64_t offset; /* the first interrupt index in the vector table */ - - rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ - rt_uint64_t cpu_hw_base; /* the base addrees of the gic cpu interface */ -}; - -/* 'ARM_GIC_MAX_NR' is the number of cores */ -static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; - -/** Macro to access the Generic Interrupt Controller Interface (GICC) -*/ -#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00U) -#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04U) -#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08U) -#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0cU) -#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10U) -#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14U) -#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18U) -#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFCU) - -/** Macro to access the Generic Interrupt Controller Distributor (GICD) -*/ -#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) -#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004U) -#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080U + ((n)/32U) * 4U) -#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100U + ((n)/32U) * 4U) -#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180U + ((n)/32U) * 4U) -#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200U + ((n)/32U) * 4U) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280U + ((n)/32U) * 4U) -#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300U + ((n)/32U) * 4U) -#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380U + ((n)/32U) * 4U) -#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400U + ((n)/4U) * 4U) -#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800U + ((n)/4U) * 4U) -#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U) -#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00U) -#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U) -#define GIC_DIST_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U) -#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8U) - -static unsigned int _gic_max_irq; - -int arm_gic_get_active_irq(rt_uint64_t index) -{ - int irq; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base); - irq += _gic_table[index].offset; - return irq; -} - -void arm_gic_ack(rt_uint64_t index, int irq) -{ - rt_uint64_t mask = 1U << (irq % 32U); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; - GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; -} - -void arm_gic_mask(rt_uint64_t index, int irq) -{ - rt_uint64_t mask = 1U << (irq % 32U); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; -} - -void arm_gic_umask(rt_uint64_t index, int irq) -{ - rt_uint64_t mask = 1U << (irq % 32U); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; -} - -rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq) -{ - rt_uint64_t pend; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - if (irq >= 16U) - { - pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; - } - else - { - /* INTID 0-15 Software Generated Interrupt */ - pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; - /* No CPU identification offered */ - if (pend != 0U) - { - pend = 1U; - } - else - { - pend = 0U; - } - } - - return (pend); -} - -void arm_gic_set_pending_irq(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - if (irq >= 16U) - { - GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1U << (irq % 32U); - } - else - { - /* INTID 0-15 Software Generated Interrupt */ - /* Forward the interrupt to the CPU interface that requested it */ - GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000U); - } -} - -void arm_gic_clear_pending_irq(rt_uint64_t index, int irq) -{ - rt_uint64_t mask; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - if (irq >= 16U) - { - mask = 1U << (irq % 32U); - GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; - } - else - { - mask = 1U << ((irq % 4U) * 8U); - GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask; - } -} - -void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config) -{ - rt_uint64_t icfgr; - rt_uint64_t shift; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq); - shift = (irq % 16U) << 1U; - - icfgr &= (~(3U << shift)); - icfgr |= (config << (shift + 1)); - - GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr; -} - -rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> ((irq % 16U) >> 1U)); -} - -void arm_gic_clear_active(rt_uint64_t index, int irq) -{ - rt_uint64_t mask = 1U << (irq % 32U); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; -} - -/* Set up the cpu mask for the specific interrupt */ -void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask) -{ - rt_uint64_t old_tgt; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); - - old_tgt &= ~(0x0FFUL << ((irq % 4U)*8U)); - old_tgt |= cpumask << ((irq % 4U)*8U); - - GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; -} - -rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - return (GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; -} - -void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority) -{ - rt_uint64_t mask; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq); - mask &= ~(0xFFUL << ((irq % 4U) * 8U)); - mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U)); - GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask; -} - -rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; -} - -void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - /* set priority mask */ - GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base) = priority & 0xFFUL; -} - -rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - return GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base); -} - -void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point) -{ - GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base) = binary_point & 0x7U; -} - -rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index) -{ - return GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base); -} - -rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq) -{ - rt_uint64_t pending; - rt_uint64_t active; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; - pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; - - return ((active << 1U) | pending); -} - -void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_uint64_t filter_list) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = - ((filter_list & 0x3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (irq & 0x0FUL); -} - -rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - return GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); -} - -rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - return GIC_CPU_IIDR(_gic_table[index].cpu_hw_base); -} - -void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group) -{ - uint32_t igroupr; - uint32_t shift; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - RT_ASSERT(group <= 1U); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq); - shift = (irq % 32U); - igroupr &= (~(1U << shift)); - igroupr |= ((group & 0x1U) << shift); - - GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr; -} - -rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0U); - - return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; -} - -int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start) -{ - unsigned int gic_type, i; - rt_uint64_t cpumask = 1U << 0U; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - _gic_table[index].dist_hw_base = dist_base; - _gic_table[index].offset = irq_start; - - /* Find out how many interrupts are supported. */ - gic_type = GIC_DIST_TYPE(dist_base); - _gic_max_irq = ((gic_type & 0x1fU) + 1U) * 32U; - - /* - * The GIC only supports up to 1020 interrupt sources. - * Limit this to either the architected maximum, or the - * platform maximum. - */ - if (_gic_max_irq > 1020U) - { - _gic_max_irq = 1020U; - } - if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ - { - _gic_max_irq = ARM_GIC_NR_IRQS; - } - - cpumask |= cpumask << 8U; - cpumask |= cpumask << 16U; - cpumask |= cpumask << 24U; - - GIC_DIST_CTRL(dist_base) = 0x0U; - - /* Set all global interrupts to be level triggered, active low. */ - for (i = 32U; i < _gic_max_irq; i += 16U) - { - GIC_DIST_CONFIG(dist_base, i) = 0x0U; - } - - /* Set all global interrupts to this CPU only. */ - for (i = 32U; i < _gic_max_irq; i += 4U) - { - GIC_DIST_TARGET(dist_base, i) = cpumask; - } - - /* Set priority on all interrupts. */ - for (i = 0U; i < _gic_max_irq; i += 4U) - { - GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0U; - } - - /* Disable all interrupts. */ - for (i = 0U; i < _gic_max_irq; i += 32U) - { - GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffffU; - } - - /* All interrupts defaults to IGROUP1(IRQ). */ - /* - for (i = 0; i < _gic_max_irq; i += 32) - { - GIC_DIST_IGROUP(dist_base, i) = 0xffffffffU; - } - */ - for (i = 0U; i < _gic_max_irq; i += 32U) - { - GIC_DIST_IGROUP(dist_base, i) = 0U; - } - - /* Enable group0 and group1 interrupt forwarding. */ - GIC_DIST_CTRL(dist_base) = 0x01U; - - return 0; -} - -int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - if (!_gic_table[index].cpu_hw_base) - { - _gic_table[index].cpu_hw_base = cpu_base; - } - cpu_base = _gic_table[index].cpu_hw_base; - - GIC_CPU_PRIMASK(cpu_base) = 0xf0U; - GIC_CPU_BINPOINT(cpu_base) = 0x7U; - /* Enable CPU interrupt */ - GIC_CPU_CTRL(cpu_base) = 0x01U; - - return 0; -} - -void arm_gic_dump_type(rt_uint64_t index) -{ - unsigned int gic_type; - - gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); - rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", - (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4U) & 0xfUL, - _gic_table[index].dist_hw_base, - _gic_max_irq, - gic_type & (1U << 10U) ? "has" : "no", - gic_type); -} - -void arm_gic_dump(rt_uint64_t index) -{ - unsigned int i, k; - - k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); - rt_kprintf("--- high pending priority: %d(%08x)\n", k, k); - rt_kprintf("--- hw mask ---\n"); - for (i = 0U; i < _gic_max_irq / 32U; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, - i * 32U)); - } - rt_kprintf("\n--- hw pending ---\n"); - for (i = 0U; i < _gic_max_irq / 32U; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, - i * 32U)); - } - rt_kprintf("\n--- hw active ---\n"); - for (i = 0U; i < _gic_max_irq / 32U; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, - i * 32U)); - } - rt_kprintf("\n"); -} - -long gic_dump(void) -{ - arm_gic_dump_type(0); - arm_gic_dump(0); - - return 0; -} -MSH_CMD_EXPORT(gic_dump, show gic status); - -#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) */ diff --git a/libcpu/aarch64/common/gic.h b/libcpu/aarch64/common/gic.h deleted file mode 100644 index 4cdcb4402888..000000000000 --- a/libcpu/aarch64/common/gic.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - */ - -#ifndef __GIC_H__ -#define __GIC_H__ - -#include -#include - -int arm_gic_get_active_irq(rt_uint64_t index); -void arm_gic_ack(rt_uint64_t index, int irq); - -void arm_gic_mask(rt_uint64_t index, int irq); -void arm_gic_umask(rt_uint64_t index, int irq); - -rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); -void arm_gic_set_pending_irq(rt_uint64_t index, int irq); -void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); - -void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config); -rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); - -void arm_gic_clear_active(rt_uint64_t index, int irq); - -void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask); -rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq); - -void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority); -rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq); - -void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority); -rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index); - -void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point); -rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index); - -rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq); - -void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_uint64_t filter_list); - -rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index); - -rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index); - -void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group); -rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq); - -int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start); -int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); - -void arm_gic_dump_type(rt_uint64_t index); -void arm_gic_dump(rt_uint64_t index); - -#endif - diff --git a/libcpu/aarch64/common/gicv3.c b/libcpu/aarch64/common/gicv3.c deleted file mode 100644 index 35864fea2fbb..000000000000 --- a/libcpu/aarch64/common/gicv3.c +++ /dev/null @@ -1,862 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - * 2014-04-03 Grissiom many enhancements - * 2018-11-22 Jesven add rt_hw_ipi_send() - * add rt_hw_ipi_handler_install() - * 2022-03-08 GuEe-GUI add BSP bind SPI CPU self support - * add GICv3 AArch64 system register interface - * modify arm_gic_redist_init() args - * modify arm_gic_cpu_init() args - * modify arm_gic_send_affinity_sgi() args - * remove arm_gic_redist_address_set() - * remove arm_gic_cpu_interface_address_set() - * remove arm_gic_secondary_cpu_init() - * remove get_main_cpu_affval() - * remove arm_gic_cpumask_to_affval() - */ - -#include -#include - -#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) - -#include -#include - -#include - -#ifndef ARM_SPI_BIND_CPU_ID -#define ARM_SPI_BIND_CPU_ID 0 -#endif - -#ifndef RT_USING_SMP -#define RT_CPUS_NR 1 -extern int rt_hw_cpu_id(void); -#else -extern rt_uint64_t rt_cpu_mpidr_early[]; -#endif /* RT_USING_SMP */ - -struct arm_gic -{ - rt_uint64_t offset; /* the first interrupt index in the vector table */ - rt_uint64_t redist_hw_base[ARM_GIC_CPU_NUM]; /* the pointer of the gic redistributor */ - rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ - rt_uint64_t cpu_hw_base[ARM_GIC_CPU_NUM]; /* the base address of the gic cpu interface */ -}; - -/* 'ARM_GIC_MAX_NR' is the number of cores */ -static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; -static unsigned int _gic_max_irq; - -#define GET_GICV3_REG(reg, out) __asm__ volatile ("mrs %0, " reg:"=r"(out)::"memory"); -#define SET_GICV3_REG(reg, in) __asm__ volatile ("msr " reg ", %0"::"r"(in):"memory"); - -/* AArch64 System register interface to GICv3 */ -#define ICC_IAR0_EL1 "S3_0_C12_C8_0" -#define ICC_IAR1_EL1 "S3_0_C12_C12_0" -#define ICC_EOIR0_EL1 "S3_0_C12_C8_1" -#define ICC_EOIR1_EL1 "S3_0_C12_C12_1" -#define ICC_HPPIR0_EL1 "S3_0_C12_C8_2" -#define ICC_HPPIR1_EL1 "S3_0_C12_C12_2" -#define ICC_BPR0_EL1 "S3_0_C12_C8_3" -#define ICC_BPR1_EL1 "S3_0_C12_C12_3" -#define ICC_DIR_EL1 "S3_0_C12_C11_1" -#define ICC_PMR_EL1 "S3_0_C4_C6_0" -#define ICC_RPR_EL1 "S3_0_C12_C11_3" -#define ICC_CTLR_EL1 "S3_0_C12_C12_4" -#define ICC_CTLR_EL3 "S3_6_C12_C12_4" -#define ICC_SRE_EL1 "S3_0_C12_C12_5" -#define ICC_SRE_EL2 "S3_4_C12_C9_5" -#define ICC_SRE_EL3 "S3_6_C12_C12_5" -#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6" -#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7" -#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7" -#define ICC_SGI0R_EL1 "S3_0_C12_C11_7" -#define ICC_SGI1R_EL1 "S3_0_C12_C11_5" -#define ICC_ASGI1R_EL1 "S3_0_C12_C11_6" - -/* Macro to access the Distributor Control Register (GICD_CTLR) */ -#define GICD_CTLR_RWP (1 << 31) -#define GICD_CTLR_E1NWF (1 << 7) -#define GICD_CTLR_DS (1 << 6) -#define GICD_CTLR_ARE_NS (1 << 5) -#define GICD_CTLR_ARE_S (1 << 4) -#define GICD_CTLR_ENGRP1S (1 << 2) -#define GICD_CTLR_ENGRP1NS (1 << 1) -#define GICD_CTLR_ENGRP0 (1 << 0) - -/* Macro to access the Redistributor Control Register (GICR_CTLR) */ -#define GICR_CTLR_UWP (1 << 31) -#define GICR_CTLR_DPG1S (1 << 26) -#define GICR_CTLR_DPG1NS (1 << 25) -#define GICR_CTLR_DPG0 (1 << 24) -#define GICR_CTLR_RWP (1 << 3) -#define GICR_CTLR_IR (1 << 2) -#define GICR_CTLR_CES (1 << 1) -#define GICR_CTLR_EnableLPI (1 << 0) - -/* Macro to access the Generic Interrupt Controller Interface (GICC) */ -#define GIC_CPU_CTRL(hw_base) HWREG32((hw_base) + 0x00U) -#define GIC_CPU_PRIMASK(hw_base) HWREG32((hw_base) + 0x04U) -#define GIC_CPU_BINPOINT(hw_base) HWREG32((hw_base) + 0x08U) -#define GIC_CPU_INTACK(hw_base) HWREG32((hw_base) + 0x0cU) -#define GIC_CPU_EOI(hw_base) HWREG32((hw_base) + 0x10U) -#define GIC_CPU_RUNNINGPRI(hw_base) HWREG32((hw_base) + 0x14U) -#define GIC_CPU_HIGHPRI(hw_base) HWREG32((hw_base) + 0x18U) -#define GIC_CPU_IIDR(hw_base) HWREG32((hw_base) + 0xFCU) - -/* Macro to access the Generic Interrupt Controller Distributor (GICD) */ -#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) -#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U) -#define GIC_DIST_IGROUP(hw_base, n) HWREG32((hw_base) + 0x080U + ((n) / 32U) * 4U) -#define GIC_DIST_ENABLE_SET(hw_base, n) HWREG32((hw_base) + 0x100U + ((n) / 32U) * 4U) -#define GIC_DIST_ENABLE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x180U + ((n) / 32U) * 4U) -#define GIC_DIST_PENDING_SET(hw_base, n) HWREG32((hw_base) + 0x200U + ((n) / 32U) * 4U) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) HWREG32((hw_base) + 0x280U + ((n) / 32U) * 4U) -#define GIC_DIST_ACTIVE_SET(hw_base, n) HWREG32((hw_base) + 0x300U + ((n) / 32U) * 4U) -#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x380U + ((n) / 32U) * 4U) -#define GIC_DIST_PRI(hw_base, n) HWREG32((hw_base) + 0x400U + ((n) / 4U) * 4U) -#define GIC_DIST_TARGET(hw_base, n) HWREG32((hw_base) + 0x800U + ((n) / 4U) * 4U) -#define GIC_DIST_CONFIG(hw_base, n) HWREG32((hw_base) + 0xc00U + ((n) / 16U) * 4U) -#define GIC_DIST_SOFTINT(hw_base) HWREG32((hw_base) + 0xf00U) -#define GIC_DIST_CPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf10U + ((n) / 4U) * 4U) -#define GIC_DIST_SPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf20U + ((n) / 4U) * 4U) -#define GIC_DIST_ICPIDR2(hw_base) HWREG32((hw_base) + 0xfe8U) -#define GIC_DIST_IROUTER(hw_base, n) HWREG64((hw_base) + 0x6000U + (n) * 8U) - -/* SGI base address is at 64K offset from Redistributor base address */ -#define GIC_RSGI_OFFSET 0x10000 - -/* Macro to access the Generic Interrupt Controller Redistributor (GICR) */ -#define GIC_RDIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) -#define GIC_RDIST_IIDR(hw_base) HWREG32((hw_base) + 0x004U) -#define GIC_RDIST_TYPER(hw_base) HWREG64((hw_base) + 0x008U) -#define GIC_RDIST_TSTATUSR(hw_base) HWREG32((hw_base) + 0x010U) -#define GIC_RDIST_WAKER(hw_base) HWREG32((hw_base) + 0x014U) -#define GIC_RDIST_SETLPIR(hw_base) HWREG32((hw_base) + 0x040U) -#define GIC_RDIST_CLRLPIR(hw_base) HWREG32((hw_base) + 0x048U) -#define GIC_RDIST_PROPBASER(hw_base) HWREG32((hw_base) + 0x070U) -#define GIC_RDIST_PENDBASER(hw_base) HWREG32((hw_base) + 0x078U) -#define GIC_RDIST_INVLPIR(hw_base) HWREG32((hw_base) + 0x0A0U) -#define GIC_RDIST_INVALLR(hw_base) HWREG32((hw_base) + 0x0B0U) -#define GIC_RDIST_SYNCR(hw_base) HWREG32((hw_base) + 0x0C0U) - -#define GIC_RDISTSGI_IGROUPR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n) * 4U) -#define GIC_RDISTSGI_ISENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x100U) -#define GIC_RDISTSGI_ICENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x180U) -#define GIC_RDISTSGI_ISPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x200U) -#define GIC_RDISTSGI_ICPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x280U) -#define GIC_RDISTSGI_ISACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x300U) -#define GIC_RDISTSGI_ICACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x380U) -#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U) -#define GIC_RDISTSGI_ICFGR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) -#define GIC_RDISTSGI_ICFGR1(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) -#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n) * 4) -#define GIC_RDISTSGI_NSACR(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) - -int arm_gic_get_active_irq(rt_uint64_t index) -{ - int irq; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - GET_GICV3_REG(ICC_IAR1_EL1, irq); - - irq = (irq & 0x1ffffff) + _gic_table[index].offset; - return irq; -} - -void arm_gic_ack(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - RT_ASSERT(irq >= 0); - - __DSB(); - SET_GICV3_REG(ICC_EOIR1_EL1, irq); -} - -void arm_gic_mask(rt_uint64_t index, int irq) -{ - rt_uint64_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - if (irq < 32) - { - rt_int32_t cpu_id = rt_hw_cpu_id(); - - GIC_RDISTSGI_ICENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; - } - else - { - GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; - } -} - -void arm_gic_umask(rt_uint64_t index, int irq) -{ - rt_uint64_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - if (irq < 32) - { - rt_int32_t cpu_id = rt_hw_cpu_id(); - - GIC_RDISTSGI_ISENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; - } - else - { - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; - } -} - -rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq) -{ - rt_uint64_t pend; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - if (irq >= 16) - { - pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1; - } - else - { - /* INTID 0-15 Software Generated Interrupt */ - pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4) * 8)) & 0xff; - /* No CPU identification offered */ - if (pend != 0) - { - pend = 1; - } - else - { - pend = 0; - } - } - - return pend; -} - -void arm_gic_set_pending_irq(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - if (irq >= 16) - { - GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1 << (irq % 32); - } - else - { - /* INTID 0-15 Software Generated Interrupt */ - /* Forward the interrupt to the CPU interface that requested it */ - GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000); - } -} - -void arm_gic_clear_pending_irq(rt_uint64_t index, int irq) -{ - rt_uint64_t mask; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - if (irq >= 16) - { - mask = 1 << (irq % 32); - GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; - } - else - { - mask = 1 << ((irq % 4) * 8); - GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask; - } -} - -void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config) -{ - rt_uint64_t icfgr; - rt_uint64_t shift; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq); - shift = (irq % 16) << 1; - - icfgr &= (~(3 << shift)); - icfgr |= (config << (shift + 1)); - - GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr; -} - -rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> ((irq % 16) >> 1)); -} - -void arm_gic_clear_active(rt_uint64_t index, int irq) -{ - rt_uint64_t mask = 1 << (irq % 32); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; -} - -/* Set up the cpu mask for the specific interrupt */ -void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask) -{ - rt_uint64_t old_tgt; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); - - old_tgt &= ~(0x0ff << ((irq % 4) * 8)); - old_tgt |= cpumask << ((irq % 4) * 8); - - GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; -} - -rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - return (GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) >> ((irq % 4) * 8)) & 0xff; -} - -void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority) -{ - rt_uint64_t mask; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - if (irq < 32) - { - rt_int32_t cpu_id = rt_hw_cpu_id(); - - mask = GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq); - mask &= ~(0xff << ((irq % 4) * 8)); - mask |= ((priority & 0xff) << ((irq % 4) * 8)); - GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) = mask; - } - else - { - mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq); - mask &= ~(0xff << ((irq % 4) * 8)); - mask |= ((priority & 0xff) << ((irq % 4) * 8)); - GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask; - } -} - -rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - if (irq < 32) - { - rt_int32_t cpu_id = rt_hw_cpu_id(); - - return (GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) >> ((irq % 4) * 8)) & 0xff; - } - else - { - return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4) * 8)) & 0xff; - } -} - -void arm_gic_set_system_register_enable_mask(rt_uint64_t index, rt_uint64_t value) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - value &= 0xff; - /* set priority mask */ - SET_GICV3_REG(ICC_SRE_EL1, value); - __ISB(); -} - -rt_uint64_t arm_gic_get_system_register_enable_mask(rt_uint64_t index) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - rt_uint64_t value; - - GET_GICV3_REG(ICC_SRE_EL1, value); - return value; -} - -void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - priority &= 0xff; - /* set priority mask */ - SET_GICV3_REG(ICC_PMR_EL1, priority); -} - -rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - rt_uint64_t priority; - - GET_GICV3_REG(ICC_PMR_EL1, priority); - return priority; -} - -void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point) -{ - index = index; - binary_point &= 0x7; - - SET_GICV3_REG(ICC_BPR1_EL1, binary_point); -} - -rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index) -{ - rt_uint64_t binary_point; - - index = index; - GET_GICV3_REG(ICC_BPR1_EL1, binary_point); - return binary_point; -} - -rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq) -{ - rt_uint64_t pending, active; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1; - pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1; - - return ((active << 1) | pending); -} - -#ifdef RT_USING_SMP -void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint32_t cpu_masks[], rt_uint64_t routing_mode) -{ - const int cpu_mask_cpu_max_nr = sizeof(cpu_masks[0]) * 8; - rt_uint64_t int_id = (irq & 0xf) << 24; - rt_uint64_t irm = routing_mode << 40; /* Interrupt Routing Mode */ - - if (routing_mode == GICV3_ROUTED_TO_SPEC) - { - int cpu_id, cpu_mask_bit, i, cpu_masks_nr = RT_CPUS_NR / cpu_mask_cpu_max_nr; - rt_uint16_t target_list; - rt_uint64_t rs = 0; /* Range Selector */ - rt_uint64_t affinity_val, next_affinity_val; - - if (cpu_masks_nr * cpu_mask_cpu_max_nr != RT_CPUS_NR) - { - ++cpu_masks_nr; - } - - for (i = cpu_id = 0; i < cpu_masks_nr;) - { - /* No cpu in this mask */ - if (cpu_masks[i] == 0) - { - ++i; - cpu_id += cpu_mask_cpu_max_nr; - continue; - } - - /* Get last cpu affinity value */ - affinity_val = rt_cpu_mpidr_early[cpu_id] & 0xff00ffff00ULL; - - /* Read 16 cpus information */ - for (cpu_mask_bit = 0; cpu_mask_bit < 16; ++cpu_mask_bit, ++cpu_id) - { - /* MPIDR_EL1: aff3[39:32], aff2[23:16], aff1[15:8] */ - next_affinity_val = rt_cpu_mpidr_early[cpu_id] & 0xff00ffff00ULL; - - /* Affinity value is different, read end */ - if (affinity_val != next_affinity_val) - { - break; - } - } - - /* Get all valid cpu mask */ - target_list = (0xffff >> (16 - cpu_mask_bit)) & cpu_masks[i]; - /* Clear read mask */ - cpu_masks[i] >>= cpu_mask_bit; - /* ICC_SGI1R_EL1: aff3[55:48], aff2[39:32], aff1[23:16] */ - affinity_val <<= 8; - - __DSB(); - /* Interrupts routed to the PEs specified by Aff3.Aff2.Aff1.. */ - SET_GICV3_REG(ICC_SGI1R_EL1, affinity_val | (rs << 44) | irm | int_id | target_list); - __ISB(); - - /* Check if reset the range selector */ - rs = affinity_val != next_affinity_val ? 0 : rs + 1; - } - } - else - { - __DSB(); - /* Interrupts routed to all PEs in the system, excluding "self". */ - SET_GICV3_REG(ICC_SGI1R_EL1, irm | int_id); - __ISB(); - } -} -#endif /* RT_USING_SMP */ - -rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index) -{ - rt_uint64_t irq; - RT_ASSERT(index < ARM_GIC_MAX_NR); - - index = index; - GET_GICV3_REG(ICC_HPPIR1_EL1, irq); - - return irq; -} - -rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index) -{ - rt_uint64_t ret = 0; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - if (_gic_table[index].cpu_hw_base != RT_NULL) - { - ret = GIC_CPU_IIDR(_gic_table[index].cpu_hw_base); - } - - return ret; -} - -void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group) -{ - rt_uint64_t igroupr; - rt_uint64_t shift; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - RT_ASSERT(group <= 1); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq); - shift = (irq % 32); - igroupr &= (~(1U << shift)); - igroupr |= ((group & 0x1U) << shift); - - GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr; -} - -rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq) -{ - RT_ASSERT(index < ARM_GIC_MAX_NR); - - irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); - - return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1UL; -} - -static int arm_gicv3_wait_rwp(rt_uint64_t index, rt_uint64_t irq) -{ - rt_uint64_t rwp_bit; - rt_uint64_t base; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - if (irq < 32) - { - rt_int32_t cpu_id = rt_hw_cpu_id(); - - base = _gic_table[index].redist_hw_base[cpu_id]; - rwp_bit = GICR_CTLR_RWP; - } - else - { - base = _gic_table[index].dist_hw_base; - rwp_bit = GICD_CTLR_RWP; - } - - while (HWREG32(base) & rwp_bit) - { - } - - return 0; -} - -int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start) -{ - int i; - unsigned int gic_type; - rt_uint64_t main_cpu_affinity_val; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - _gic_table[index].dist_hw_base = dist_base; - _gic_table[index].offset = irq_start; - - - /* Find out how many interrupts are supported. */ - gic_type = GIC_DIST_TYPE(dist_base); - _gic_max_irq = ((gic_type & 0x1f) + 1) * 32; - - /* - * The GIC only supports up to 1020 interrupt sources. - * Limit this to either the architected maximum, or the - * platform maximum. - */ - if (_gic_max_irq > 1020) - { - _gic_max_irq = 1020; - } - if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ - { - _gic_max_irq = ARM_GIC_NR_IRQS; - } - - GIC_DIST_CTRL(dist_base) = 0; - /* Wait for register write pending */ - arm_gicv3_wait_rwp(0, 32); - - /* Set all global interrupts to be level triggered, active low. */ - for (i = 32; i < _gic_max_irq; i += 16) - { - GIC_DIST_CONFIG(dist_base, i) = 0; - } - - arm_gicv3_wait_rwp(0, 32); - -#ifdef RT_USING_SMP - main_cpu_affinity_val = rt_cpu_mpidr_early[ARM_SPI_BIND_CPU_ID]; -#else - __asm__ volatile ("mrs %0, mpidr_el1":"=r"(main_cpu_affinity_val)); -#endif - - /* aff3[39:32], aff2[23:16], aff1[15:8], aff0[7:0] */ - main_cpu_affinity_val &= 0xff00ffffffULL; - - /* Set all global interrupts to this CPU only. */ - for (i = 32; i < _gic_max_irq; i++) - { - GIC_DIST_IROUTER(dist_base, i) = main_cpu_affinity_val | (GICV3_ROUTED_TO_SPEC << 31); - } - - arm_gicv3_wait_rwp(0, 32); - - /* Set priority on spi interrupts. */ - for (i = 32; i < _gic_max_irq; i += 4) - { - GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0; - } - - arm_gicv3_wait_rwp(0, 32); - /* Disable all interrupts. */ - for (i = 0; i < _gic_max_irq; i += 32) - { - GIC_DIST_PENDING_CLEAR(dist_base, i) = 0xffffffff; - GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff; - } - - arm_gicv3_wait_rwp(0, 32); - /* All interrupts defaults to IGROUP1(IRQ). */ - for (i = 0; i < _gic_max_irq; i += 32) - { - GIC_DIST_IGROUP(dist_base, i) = 0xffffffff; - } - - arm_gicv3_wait_rwp(0, 32); - - /* - * The Distributor control register (GICD_CTLR) must be configured to enable the interrupt groups and to set the routing mode. - * Enable Affinity routing (ARE bits) The ARE bits in GICD_CTLR control whether affinity routing is enabled. - * If affinity routing is not enabled, GICv3 can be configured for legacy operation. - * Whether affinity routing is enabled or not can be controlled separately for Secure and Non-secure state. - * Enables GICD_CTLR contains separate enable bits for Group 0, Secure Group 1 and Non-secure Group 1: - * GICD_CTLR.EnableGrp1S enables distribution of Secure Group 1 interrupts. - * GICD_CTLR.EnableGrp1NS enables distribution of Non-secure Group 1 interrupts. - * GICD_CTLR.EnableGrp0 enables distribution of Group 0 interrupts. - */ - GIC_DIST_CTRL(dist_base) = GICD_CTLR_ARE_NS | GICD_CTLR_ENGRP1NS; - - return 0; -} - -int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base) -{ - int i; - int cpu_id = rt_hw_cpu_id(); - static int master_cpu_id = -1; - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - if (master_cpu_id < 0) - { - master_cpu_id = 0; - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, &master_cpu_id, sizeof(master_cpu_id)); - } - - if (!_gic_table[index].redist_hw_base[master_cpu_id]) - { - _gic_table[index].redist_hw_base[master_cpu_id] = redist_base; - } - redist_base = _gic_table[index].redist_hw_base[master_cpu_id]; - - redist_base += cpu_id * (2 << 16); - _gic_table[index].redist_hw_base[cpu_id] = redist_base; - - /* redistributor enable */ - GIC_RDIST_WAKER(redist_base) &= ~(1 << 1); - while (GIC_RDIST_WAKER(redist_base) & (1 << 2)) - { - } - - /* Disable all sgi and ppi interrupt */ - GIC_RDISTSGI_ICENABLER0(redist_base) = 0xffffffff; - arm_gicv3_wait_rwp(0, 0); - - /* Clear all inetrrupt pending */ - GIC_RDISTSGI_ICPENDR0(redist_base) = 0xffffffff; - - /* the corresponding interrupt is Group 1 or Non-secure Group 1. */ - GIC_RDISTSGI_IGROUPR0(redist_base, 0) = 0xffffffff; - GIC_RDISTSGI_IGRPMODR0(redist_base, 0) = 0xffffffff; - - /* Configure default priorities for SGI 0:15 and PPI 16:31. */ - for (i = 0; i < 32; i += 4) - { - GIC_RDISTSGI_IPRIORITYR(redist_base, i) = 0xa0a0a0a0U; - } - - /* Trigger level for PPI interrupts*/ - GIC_RDISTSGI_ICFGR1(redist_base) = 0; - return 0; -} - -int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base) -{ - rt_uint64_t value; - int cpu_id = rt_hw_cpu_id(); - - RT_ASSERT(index < ARM_GIC_MAX_NR); - - _gic_table[index].cpu_hw_base[cpu_id] = cpu_base; - - value = arm_gic_get_system_register_enable_mask(index); - value |= (1 << 0); - arm_gic_set_system_register_enable_mask(index, value); - SET_GICV3_REG(ICC_CTLR_EL1, 0); - - arm_gic_set_interface_prior_mask(index, 0xff); - - /* Enable group1 interrupt */ - value = 1; - SET_GICV3_REG(ICC_IGRPEN1_EL1, value); - - arm_gic_set_binary_point(0, 0); - - /* ICC_BPR0_EL1 determines the preemption group for both Group 0 and Group 1 interrupts. */ - value = 1; /* ICC_BPR0_EL1 determines the preemption group for both Group 0 and Group 1 interrupts.*/ - value |= 1 << 18; /* Targeted SGIs with affinity level 0 values of 0 - 255 are supported. */ - SET_GICV3_REG(ICC_CTLR_EL1, value); - - return 0; -} - -void arm_gic_dump_type(rt_uint64_t index) -{ - unsigned int gic_type; - - gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); - rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", - (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf, - _gic_table[index].dist_hw_base, - _gic_max_irq, - gic_type & (1 << 10) ? "has" : "no", - gic_type); -} - -void arm_gic_dump(rt_uint64_t index) -{ - int i; - unsigned int val; - - val = arm_gic_get_high_pending_irq(0); - rt_kprintf("--- high pending priority: %d(%08x)\n", val, val); - - rt_kprintf("--- hw mask ---\n"); - for (i = 0; i < _gic_max_irq / 32; ++i) - { - rt_kprintf("0x%08x, ", GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, i * 32)); - } - - rt_kprintf("\b\b\n--- hw pending ---\n"); - for (i = 0; i < _gic_max_irq / 32; ++i) - { - rt_kprintf("0x%08x, ", GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, i * 32)); - } - - rt_kprintf("\b\b\n--- hw active ---\n"); - for (i = 0; i < _gic_max_irq / 32; ++i) - { - rt_kprintf("0x%08x, ", GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, i * 32)); - } - - rt_kprintf("\b\b\n"); -} - -long gic_dump(void) -{ - arm_gic_dump_type(0); - arm_gic_dump(0); - - return 0; -} -MSH_CMD_EXPORT(gic_dump, show gic status); - -#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) */ diff --git a/libcpu/aarch64/common/gicv3.h b/libcpu/aarch64/common/gicv3.h deleted file mode 100644 index fbcf3fb4d92c..000000000000 --- a/libcpu/aarch64/common/gicv3.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - * 2014-04-03 Grissiom many enhancements - * 2018-11-22 Jesven add rt_hw_ipi_send() - * add rt_hw_ipi_handler_install() - */ - -#ifndef __GICV3_H__ -#define __GICV3_H__ - -#include - -#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) - - -#ifndef ARM_GIC_CPU_NUM -#define ARM_GIC_CPU_NUM RT_CPUS_NR -#endif - -#define GICV3_ROUTED_TO_ALL 1UL -#define GICV3_ROUTED_TO_SPEC 0UL - -int arm_gic_get_active_irq(rt_uint64_t index); -void arm_gic_ack(rt_uint64_t index, int irq); - -void arm_gic_mask(rt_uint64_t index, int irq); -void arm_gic_umask(rt_uint64_t index, int irq); - -rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); -void arm_gic_set_pending_irq(rt_uint64_t index, int irq); -void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); - -void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config); -rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); - -void arm_gic_clear_active(rt_uint64_t index, int irq); - -void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask); -rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq); - -void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority); -rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq); - -void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority); -rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index); - -void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point); -rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index); - -rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq); - -#ifdef RT_USING_SMP -void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint32_t cpu_masks[], rt_uint64_t routing_mode); -#endif - -rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index); - -rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index); - -void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group); -rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq); - -int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id); -int arm_gic_cpu_interface_address_set(rt_uint64_t index, rt_uint64_t interface_addr, int cpu_id); - -int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start); -int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base); -int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); - -void arm_gic_dump_type(rt_uint64_t index); -void arm_gic_dump(rt_uint64_t index); - -#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) */ - -#endif - diff --git a/libcpu/aarch64/common/gtimer.c b/libcpu/aarch64/common/gtimer.c deleted file mode 100644 index 881655c2cfe0..000000000000 --- a/libcpu/aarch64/common/gtimer.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-20 GuEe-GUI first version - */ - -#include -#include -#include -#include - -#define EL1_PHY_TIMER_IRQ_NUM 30 - -static volatile rt_uint64_t timer_step; - -static void rt_hw_timer_isr(int vector, void *parameter) -{ - rt_hw_set_gtimer_val(timer_step); - rt_tick_increase(); -} - -void rt_hw_gtimer_init(void) -{ - rt_hw_interrupt_install(EL1_PHY_TIMER_IRQ_NUM, rt_hw_timer_isr, RT_NULL, "tick"); - rt_hw_isb(); - timer_step = rt_hw_get_gtimer_frq(); - rt_hw_dsb(); - timer_step /= RT_TICK_PER_SECOND; - rt_hw_gtimer_local_enable(); -} - -void rt_hw_gtimer_local_enable(void) -{ - rt_hw_gtimer_disable(); - rt_hw_set_gtimer_val(timer_step); - rt_hw_interrupt_umask(EL1_PHY_TIMER_IRQ_NUM); - rt_hw_gtimer_enable(); -} - -void rt_hw_gtimer_local_disable(void) -{ - rt_hw_gtimer_disable(); - rt_hw_interrupt_mask(EL1_PHY_TIMER_IRQ_NUM); -} diff --git a/libcpu/aarch64/common/gtimer.h b/libcpu/aarch64/common/gtimer.h deleted file mode 100644 index 83a0d53165d4..000000000000 --- a/libcpu/aarch64/common/gtimer.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-20 GuEe-GUI first version - */ - -#ifndef __GTIMER_H__ -#define __GTIMER_H__ - -#include - -void rt_hw_gtimer_init(void); -void rt_hw_gtimer_local_enable(void); -void rt_hw_gtimer_local_disable(void); - -void rt_hw_gtimer_enable(); - -rt_inline void rt_hw_gtimer_disable(void) -{ - __asm__ volatile ("msr CNTP_CTL_EL0, xzr":::"memory"); -} - -void rt_hw_set_gtimer_val(rt_uint64_t value); -rt_uint64_t rt_hw_get_gtimer_val(); -rt_uint64_t rt_hw_get_cntpct_val(); -rt_uint64_t rt_hw_get_gtimer_frq(); -rt_uint64_t rt_hw_set_gtimer_frq(rt_uint64_t value); - -#endif /* __GTIMER_H__ */ diff --git a/libcpu/aarch64/common/interrupt.c b/libcpu/aarch64/common/interrupt.c index dc142dd9e83c..c6a28b6dc52c 100644 --- a/libcpu/aarch64/common/interrupt.c +++ b/libcpu/aarch64/common/interrupt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2022, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -7,22 +7,17 @@ * Date Author Notes * 2013-07-06 Bernard first version * 2018-11-22 Jesven add smp support + * 2023-02-21 GuEe-GUI replace with pic */ #include #include -#include "interrupt.h" -#include "gic.h" -#include "gicv3.h" +#include -#ifdef RT_USING_SMART -#include "ioremap.h" -#else -#define rt_ioremap(x, ...) (x) -#endif +#include +#include -/* exception and interrupt handler table */ -struct rt_irq_desc isr_table[MAX_HANDLERS]; +#include #ifndef RT_USING_SMP /* Those variables will be accessed in ISR, so we need to share them. */ @@ -31,106 +26,19 @@ rt_ubase_t rt_interrupt_to_thread = 0; rt_ubase_t rt_thread_switch_interrupt_flag = 0; #endif -#ifndef RT_CPUS_NR -#define RT_CPUS_NR 1 -#endif - -const unsigned int VECTOR_BASE = 0x00; -extern void rt_cpu_vector_set_base(void *addr); -extern void *system_vectors; - #ifdef RT_USING_SMP #define rt_interrupt_nest rt_cpu_self()->irq_nest #else extern volatile rt_uint8_t rt_interrupt_nest; #endif -#ifdef SOC_BCM283x -static void default_isr_handler(int vector, void *param) -{ -#ifdef RT_USING_SMP - rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector); -#else - rt_kprintf("unhandled irq: %d\n",vector); -#endif -} -#endif - -void rt_hw_vector_init(void) -{ - rt_cpu_vector_set_base(&system_vectors); -} - /** * This function will initialize hardware interrupt */ void rt_hw_interrupt_init(void) { -#ifdef SOC_BCM283x - rt_uint32_t index; - /* initialize vector table */ - rt_hw_vector_init(); - - /* initialize exceptions table */ - rt_memset(isr_table, 0x00, sizeof(isr_table)); - - /* mask all of interrupts */ - IRQ_DISABLE_BASIC = 0x000000ff; - IRQ_DISABLE1 = 0xffffffff; - IRQ_DISABLE2 = 0xffffffff; - for (index = 0; index < MAX_HANDLERS; index ++) - { - isr_table[index].handler = default_isr_handler; - isr_table[index].param = RT_NULL; -#ifdef RT_USING_INTERRUPT_INFO - rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX); - isr_table[index].counter = 0; -#endif - } - - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; -#else - rt_uint64_t gic_cpu_base; - rt_uint64_t gic_dist_base; -#ifdef BSP_USING_GICV3 - rt_uint64_t gic_rdist_base; -#endif - rt_uint64_t gic_irq_start; - - /* initialize vector table */ - rt_hw_vector_init(); - - /* initialize exceptions table */ - rt_memset(isr_table, 0x00, sizeof(isr_table)); - - /* initialize ARM GIC */ -#ifdef RT_USING_SMART - gic_dist_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x40000); - gic_cpu_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000); -#ifdef BSP_USING_GICV3 - gic_rdist_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_redist_base(), - ARM_GIC_CPU_NUM * (2 << 16)); -#endif -#else - gic_dist_base = platform_get_gic_dist_base(); - gic_cpu_base = platform_get_gic_cpu_base(); -#ifdef BSP_USING_GICV3 - gic_rdist_base = platform_get_gic_redist_base(); -#endif -#endif - - gic_irq_start = GIC_IRQ_START; - - arm_gic_dist_init(0, gic_dist_base, gic_irq_start); - arm_gic_cpu_init(0, gic_cpu_base); -#ifdef BSP_USING_GICV3 - arm_gic_redist_init(0, gic_rdist_base); -#endif -#endif + /* initialize pic */ + rt_pic_irq_init(); } /** @@ -139,24 +47,7 @@ void rt_hw_interrupt_init(void) */ void rt_hw_interrupt_mask(int vector) { -#ifdef SOC_BCM283x - if (vector < 32) - { - IRQ_DISABLE1 = (1 << vector); - } - else if (vector < 64) - { - vector = vector % 32; - IRQ_DISABLE2 = (1 << vector); - } - else - { - vector = vector - 64; - IRQ_DISABLE_BASIC = (1 << vector); - } -#else - arm_gic_mask(0, vector); -#endif + rt_pic_irq_mask(vector); } /** @@ -165,195 +56,9 @@ void rt_hw_interrupt_mask(int vector) */ void rt_hw_interrupt_umask(int vector) { -#ifdef SOC_BCM283x -if (vector < 32) - { - IRQ_ENABLE1 = (1 << vector); - } - else if (vector < 64) - { - vector = vector % 32; - IRQ_ENABLE2 = (1 << vector); - } - else - { - vector = vector - 64; - IRQ_ENABLE_BASIC = (1 << vector); - } -#else - arm_gic_umask(0, vector); -#endif -} - -/** - * This function returns the active interrupt number. - * @param none - */ -int rt_hw_interrupt_get_irq(void) -{ -#ifndef SOC_BCM283x - return arm_gic_get_active_irq(0); -#else - return 0; -#endif + rt_pic_irq_unmask(vector); } -/** - * This function acknowledges the interrupt. - * @param vector the interrupt number - */ -void rt_hw_interrupt_ack(int vector) -{ -#ifndef SOC_BCM283x - arm_gic_ack(0, vector); -#endif -} - -#ifndef SOC_BCM283x -/** - * This function set interrupt CPU targets. - * @param vector: the interrupt number - * cpu_mask: target cpus mask, one bit for one core - */ -void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask) -{ - arm_gic_set_cpu(0, vector, cpu_mask); -} - -/** - * This function get interrupt CPU targets. - * @param vector: the interrupt number - * @return target cpus mask, one bit for one core - */ -unsigned int rt_hw_interrupt_get_target_cpus(int vector) -{ - return arm_gic_get_target_cpu(0, vector); -} - -/** - * This function set interrupt triger mode. - * @param vector: the interrupt number - * mode: interrupt triger mode; 0: level triger, 1: edge triger - */ -void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode) -{ - arm_gic_set_configuration(0, vector, mode & IRQ_MODE_MASK); -} - -/** - * This function get interrupt triger mode. - * @param vector: the interrupt number - * @return interrupt triger mode; 0: level triger, 1: edge triger - */ -unsigned int rt_hw_interrupt_get_triger_mode(int vector) -{ - return arm_gic_get_configuration(0, vector); -} - -/** - * This function set interrupt pending flag. - * @param vector: the interrupt number - */ -void rt_hw_interrupt_set_pending(int vector) -{ - arm_gic_set_pending_irq(0, vector); -} - -/** - * This function get interrupt pending flag. - * @param vector: the interrupt number - * @return interrupt pending flag, 0: not pending; 1: pending - */ -unsigned int rt_hw_interrupt_get_pending(int vector) -{ - return arm_gic_get_pending_irq(0, vector); -} - -/** - * This function clear interrupt pending flag. - * @param vector: the interrupt number - */ -void rt_hw_interrupt_clear_pending(int vector) -{ - arm_gic_clear_pending_irq(0, vector); -} - -/** - * This function set interrupt priority value. - * @param vector: the interrupt number - * priority: the priority of interrupt to set - */ -void rt_hw_interrupt_set_priority(int vector, unsigned int priority) -{ - arm_gic_set_priority(0, vector, priority); -} - -/** - * This function get interrupt priority. - * @param vector: the interrupt number - * @return interrupt priority value - */ -unsigned int rt_hw_interrupt_get_priority(int vector) -{ - return arm_gic_get_priority(0, vector); -} - -/** - * This function set priority masking threshold. - * @param priority: priority masking threshold - */ -void rt_hw_interrupt_set_priority_mask(unsigned int priority) -{ - arm_gic_set_interface_prior_mask(0, priority); -} - -/** - * This function get priority masking threshold. - * @param none - * @return priority masking threshold - */ -unsigned int rt_hw_interrupt_get_priority_mask(void) -{ - return arm_gic_get_interface_prior_mask(0); -} - -/** - * This function set priority grouping field split point. - * @param bits: priority grouping field split point - * @return 0: success; -1: failed - */ -int rt_hw_interrupt_set_prior_group_bits(unsigned int bits) -{ - int status; - - if (bits < 8) - { - arm_gic_set_binary_point(0, (7 - bits)); - status = 0; - } - else - { - status = -1; - } - - return (status); -} - -/** - * This function get priority grouping field split point. - * @param none - * @return priority grouping field split point - */ -unsigned int rt_hw_interrupt_get_prior_group_bits(void) -{ - unsigned int bp; - - bp = arm_gic_get_binary_point(0) & 0x07; - - return (7 - bp); -} -#endif /* SOC_BCM283x */ - /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number @@ -363,33 +68,17 @@ unsigned int rt_hw_interrupt_get_prior_group_bits(void) rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name) { - rt_isr_handler_t old_handler = RT_NULL; - - if (vector < MAX_HANDLERS) - { - old_handler = isr_table[vector].handler; + rt_pic_attach_irq(vector, handler, param, name, RT_IRQ_F_NONE); - if (handler != RT_NULL) - { -#ifdef RT_USING_INTERRUPT_INFO - rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); -#endif /* RT_USING_INTERRUPT_INFO */ - isr_table[vector].handler = handler; - isr_table[vector].param = param; - } - } - - return old_handler; + return RT_NULL; } #ifdef RT_USING_SMP void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) { -#ifdef BSP_USING_GICV2 - arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0); -#elif defined(BSP_USING_GICV3) - arm_gic_send_affinity_sgi(0, ipi_vector, (unsigned int *)&cpu_mask, GICV3_ROUTED_TO_SPEC); -#endif + DECLARE_BITMAP(cpu_masks, RT_CPUS_NR) = { cpu_mask }; + + rt_pic_irq_send_ipi(ipi_vector, cpu_masks); } void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) diff --git a/libcpu/aarch64/common/interrupt.h b/libcpu/aarch64/common/interrupt.h index 4ff642a87432..f0a01cb0fb41 100644 --- a/libcpu/aarch64/common/interrupt.h +++ b/libcpu/aarch64/common/interrupt.h @@ -1,56 +1,26 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2013-07-06 Bernard first version + * 2023-02-21 GuEe-GUI replace with pic */ #ifndef __INTERRUPT_H__ #define __INTERRUPT_H__ #include -#include - -#define INT_IRQ 0x00 -#define INT_FIQ 0x01 - -#define IRQ_MODE_TRIG_LEVEL (0x00) /* Trigger: level triggered interrupt */ -#define IRQ_MODE_TRIG_EDGE (0x01) /* Trigger: edge triggered interrupt */ -#define IRQ_MODE_MASK (0x01) - -void rt_hw_vector_init(void); void rt_hw_interrupt_init(void); void rt_hw_interrupt_mask(int vector); void rt_hw_interrupt_umask(int vector); -int rt_hw_interrupt_get_irq(void); -void rt_hw_interrupt_ack(int vector); - -void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask); -unsigned int rt_hw_interrupt_get_target_cpus(int vector); - -void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode); -unsigned int rt_hw_interrupt_get_triger_mode(int vector); - -void rt_hw_interrupt_set_pending(int vector); -unsigned int rt_hw_interrupt_get_pending(int vector); -void rt_hw_interrupt_clear_pending(int vector); - -void rt_hw_interrupt_set_priority(int vector, unsigned int priority); -unsigned int rt_hw_interrupt_get_priority(int vector); - -void rt_hw_interrupt_set_priority_mask(unsigned int priority); -unsigned int rt_hw_interrupt_get_priority_mask(void); - -int rt_hw_interrupt_set_prior_group_bits(unsigned int bits); -unsigned int rt_hw_interrupt_get_prior_group_bits(void); - rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name); +void rt_hw_interrupt_uninstall(int vector, rt_isr_handler_t handler, void *param); #ifdef RT_USING_SMP void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask); diff --git a/libcpu/aarch64/common/mmu.c b/libcpu/aarch64/common/mmu.c index 2bbb97591fcc..ceff4f799a31 100644 --- a/libcpu/aarch64/common/mmu.c +++ b/libcpu/aarch64/common/mmu.c @@ -23,8 +23,8 @@ #include "mmu.h" #include "tlb.h" -#ifdef RT_USING_SMART #include "ioremap.h" +#ifdef RT_USING_SMART #include #endif @@ -48,6 +48,10 @@ #define MMU_TBL_PAGE_4k_LEVEL 3 #define MMU_TBL_LEVEL_NR 4 +#ifndef KERNEL_VADDR_START +#define KERNEL_VADDR_START ARCH_RAM_OFFSET +#endif + volatile unsigned long MMUTable[512] __attribute__((aligned(4 * 1024))); struct mmu_level_info @@ -425,21 +429,12 @@ void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr) rt_page_cleanup(); } -#ifdef RT_USING_SMART static void _init_region(void *vaddr, size_t size) { rt_ioremap_start = vaddr; rt_ioremap_size = size; rt_mpr_start = (char *)rt_ioremap_start - rt_mpr_size; } -#else - -#define RTOS_VEND (0xfffffffff000UL) -static inline void _init_region(void *vaddr, size_t size) -{ - rt_mpr_start = (void *)(RTOS_VEND - rt_mpr_size); -} -#endif /** * This function will initialize rt_mmu_info structure. @@ -448,12 +443,11 @@ static inline void _init_region(void *vaddr, size_t size) * @param v_address virtual address * @param size map size * @param vtable mmu table - * @param pv_off pv offset in kernel space * * @return 0 on successful and -1 for fail */ int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, size_t size, - size_t *vtable, size_t pv_off) + size_t *vtable) { size_t va_s, va_e; @@ -478,12 +472,8 @@ int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, size_t size, return -1; } -#ifdef RT_USING_SMART rt_aspace_init(aspace, (void *)KERNEL_VADDR_START, 0 - KERNEL_VADDR_START, vtable); -#else - rt_aspace_init(aspace, (void *)0x1000, RTOS_VEND - 0x1000ul, vtable); -#endif _init_region(v_address, size); @@ -499,10 +489,14 @@ int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, size_t size, void mmu_tcr_init(void) { unsigned long val64; + unsigned long pa_range; val64 = 0x00447fUL; __asm__ volatile("msr MAIR_EL1, %0\n dsb sy\n" ::"r"(val64)); + __asm__ volatile ("mrs %0, ID_AA64MMFR0_EL1":"=r"(val64)); + pa_range = val64 & 0xf; /* PARange */ + /* TCR_EL1 */ val64 = (16UL << 0) /* t0sz 48bit */ | (0x0UL << 6) /* reserved */ @@ -518,7 +512,7 @@ void mmu_tcr_init(void) | (0x3UL << 26) /* t1 outer wb cacheable */ | (0x2UL << 28) /* t1 outer shareable */ | (0x2UL << 30) /* t1 4k */ - | (0x1UL << 32) /* 001b 64GB PA */ + | (pa_range << 32) /* PA range */ | (0x0UL << 35) /* reserved */ | (0x1UL << 36) /* as: 0:8bit 1:16bit */ | (0x0UL << 37) /* tbi0 */ diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c deleted file mode 100644 index 5c6ac82b258d..000000000000 --- a/libcpu/aarch64/common/psci.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include -#include -#include -#include -#include -#include "cpu.h" -#include "psci.h" -#include "psci_api.h" -#include "smccc.h" - -#define DBG_TAG "libcpu.aarch64.psci" -#define DBG_LVL DBG_INFO -#include - -/** template for creating 4 PSCI ops: SUSPEND, OFF, ON, MIGRATE */ -#define COMMON_PSCI_OPS_TEMPLATE(VER, SUSPEND, OFF, ON, MIGRATE) \ - static int psci_##VER##_cpu_suspend(uint32_t state, unsigned long entry_point) \ - { \ - return psci_call((SUSPEND), state, entry_point, 0); \ - } \ - static int psci_##VER##_cpu_off(uint32_t state) \ - { \ - return psci_call((OFF), state, 0, 0); \ - } \ - static int psci_##VER##_cpu_on(unsigned long cpuid, unsigned long entry_point) \ - { \ - return psci_call((ON), cpuid, entry_point, 0); \ - } \ - static int psci_##VER##_migrate(unsigned long cpuid) \ - { \ - return psci_call((MIGRATE), cpuid, 0, 0); \ - } - -struct psci_ops_t psci_ops; - -#ifdef RT_USING_FDT -#include "dtb_node.h" - -#if __SIZE_WIDTH__ == 64 -#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name -#else -#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN_##name -#endif - -/** - * SMCCC can use either smc or hvc method - * smccc_call will be init to proper interface when psci_init() was executed - */ -static void (*smccc_call)(unsigned long a0, unsigned long a1, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, - struct arm_smccc_quirk_t *quirk); - -static rt_uint32_t psci_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) -{ - struct arm_smccc_res_t res; - smccc_call(a0, a1, a2, a3, 0, 0, 0, 0, &res, (void *)0); - return res.a0; -} - -static int _psci_probe_version(char *version, int *major, int *minor); -static int _psci_init_with_version(int major, int minor); - -static struct dtb_node *psci_node; - -static int psci_ver_major; -static int psci_ver_minor; - -/** - * @brief init psci operations. - * using device tree to probe version and psci-method, - * setup psci ops for future use - * - * @return int 0 on success - */ -int psci_init() -{ - void *root = get_dtb_node_head(); - psci_node = dtb_node_get_dtb_node_by_path(root, "/psci"); - if (!psci_node) - { - LOG_E("No PSCI node found"); - return -1; - } - char *compatible = dtb_node_get_dtb_node_property_value(psci_node, "compatible", NULL); - char *method = dtb_node_get_dtb_node_property_value(psci_node, "method", NULL); - - int retval = 0; - - // setup psci-method - if (!strcmp("hvc", method)) - { - smccc_call = arm_smccc_hvc; - } - else if (!strcmp("smc", method)) - { - smccc_call = arm_smccc_smc; - } - else - { - LOG_E("Unknown PSCI method: %s", method); - return -1; - } - LOG_D("Using psci method %s", method); - - retval = _psci_probe_version(compatible, &psci_ver_major, &psci_ver_minor); - if (retval != 0) - return retval; - - // init psci_ops with specified psci version - retval = _psci_init_with_version(psci_ver_major, psci_ver_minor); - - return retval; -} - -/* function id of PSCI v0.1 should be probed in FDT, they are implementation defined value */ -static rt_uint32_t cpu_suspend_0_1; -static rt_uint32_t cpu_off_0_1; -static rt_uint32_t cpu_on_0_1; -static rt_uint32_t migrate_0_1; - -/* basic operations TEMPLATE for API since 0.1 version */ -COMMON_PSCI_OPS_TEMPLATE(0_1, cpu_suspend_0_1, cpu_off_0_1, cpu_on_0_1, migrate_0_1); - -/* used for v0.1 only, rely on FDT to probe function id */ -#define PROBE_AND_SET(FUNC_NAME) \ - do \ - { \ - int num_of_elem; \ - funcid = \ - dtb_node_get_dtb_node_property_value(psci_node, #FUNC_NAME, &num_of_elem); \ - if (num_of_elem != 4 || funcid == 0 || *funcid == 0) \ - { \ - LOG_E("Failed to probe " #FUNC_NAME " in FDT"); \ - } \ - else \ - { \ - FUNC_NAME##_0_1 = (rt_uint32_t)fdt32_to_cpu(*funcid); \ - psci_ops.FUNC_NAME = psci_0_1_##FUNC_NAME; \ - } \ - } while (0) - -static int psci_0_1_init() -{ - // reading function id from fdt - rt_uint32_t *funcid; - PROBE_AND_SET(cpu_suspend); - PROBE_AND_SET(cpu_off); - PROBE_AND_SET(cpu_on); - PROBE_AND_SET(migrate); - return 0; -} - -COMMON_PSCI_OPS_TEMPLATE(0_2, PSCI_FN_NATIVE(0_2, CPU_SUSPEND), PSCI_0_2_FN_CPU_OFF, PSCI_FN_NATIVE(0_2, CPU_ON), PSCI_FN_NATIVE(0_2, MIGRATE)); - -static rt_uint32_t psci_0_2_get_version(void) -{ - return psci_call(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); -} - -static void psci_0_2_set_basic_ops() -{ - psci_ops = (struct psci_ops_t){ - .get_version = psci_0_2_get_version, - - // followings API are v0.1 compatible - .cpu_suspend = psci_0_2_cpu_suspend, - .cpu_off = psci_0_2_cpu_off, - .cpu_on = psci_0_2_cpu_on, - .migrate = psci_0_2_migrate, - }; -} - -static void psci_0_2_system_off(void) -{ - psci_call(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); -} - -static void psci_0_2_system_reset(void) -{ - psci_call(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); -} - -static int psci_0_2_init() -{ - psci_0_2_set_basic_ops(); - - // TODO init other version 0.2 features... - // psci system off and reset which controlling machine - psci_ops.system_off = psci_0_2_system_off; - psci_ops.system_reset = psci_0_2_system_reset; - - system_off = psci_0_2_system_off; - return 0; -} - -/* PSCI v1.0 & after */ -static int psci_1_0_features(uint32_t psci_func_id) -{ - return psci_call(PSCI_1_0_FN_PSCI_FEATURES, - psci_func_id, 0, 0); -} - -static int psci_1_0_init() -{ - psci_0_2_init(); - - // TODO init other version 1.0 features... - // remove unsupported features - if (psci_1_0_features(PSCI_0_2_FN_SYSTEM_OFF) == PSCI_RET_NOT_SUPPORTED) - { - psci_ops.system_off = RT_NULL; - system_off = RT_NULL; - } - else - LOG_D("Using SYSTEM OFF feature"); - if (psci_1_0_features(PSCI_0_2_FN_SYSTEM_RESET) == PSCI_RET_NOT_SUPPORTED) - psci_ops.system_reset = RT_NULL; - else - LOG_D("Using SYSTEM RESET feature"); - - return 0; -} - -/* probe psci version from fdt or SMC call */ -static int _psci_probe_version(char *version, int *major, int *minor) -{ - int retval = 0; - // if strcmp compatible 'arm,psci-0.1' - if (!strcmp(version, "arm,psci")) - { - *major = 0; - *minor = 1; - } - else if (!strncmp(version, "arm,psci-", 8)) - { - // since psci-0.2, using psci call to probe version - rt_uint32_t ret = psci_0_2_get_version(); - *major = PSCI_VERSION_MAJOR(ret); - *minor = PSCI_VERSION_MINOR(ret); - } - else - { - LOG_E("[%s] was not a proper PSCI version", version); - retval = -1; - } - LOG_D("Using PSCI v%d.%d", *major, *minor); - return retval; -} - -/* init psci ops with version info */ -static int _psci_init_with_version(int major, int minor) -{ - int retval = -0xbeef; // mark unsupported - if (major == 0) - { - // for v0.1, psci function id was provided fdt - if (minor == 1) - { - retval = psci_0_1_init(); - } - else if (minor == 2) - { - retval = psci_0_2_init(); - } - } - else if (major == 1) - { - // psci_1_0_init is a base setup for version after v1.0 - retval = psci_1_0_init(); - } - - if (retval == -0xbeef) - { - LOG_E("PSCI init with incompatible version %d.%d", major, minor); - } - return retval; -} - -#endif /* RT_USING_FDT */ \ No newline at end of file diff --git a/libcpu/aarch64/common/psci.h b/libcpu/aarch64/common/psci.h deleted file mode 100644 index 3cce66211f0a..000000000000 --- a/libcpu/aarch64/common/psci.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __PSCI_H__ -#define __PSCI_H__ - -/** - * PSCI protocol content - * For PSCI v0.1, only return values below are protocol defined - */ - -/* PSCI v0.2 interface */ -#define PSCI_0_2_FN_BASE 0x84000000 -#define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n)) -#define PSCI_0_2_64BIT 0x40000000 -#define PSCI_0_2_FN64_BASE (PSCI_0_2_FN_BASE + PSCI_0_2_64BIT) -#define PSCI_0_2_FN64(n) (PSCI_0_2_FN64_BASE + (n)) - -#define PSCI_0_2_FN_PSCI_VERSION PSCI_0_2_FN(0) -#define PSCI_0_2_FN_CPU_SUSPEND PSCI_0_2_FN(1) -#define PSCI_0_2_FN_CPU_OFF PSCI_0_2_FN(2) -#define PSCI_0_2_FN_CPU_ON PSCI_0_2_FN(3) -#define PSCI_0_2_FN_AFFINITY_INFO PSCI_0_2_FN(4) -#define PSCI_0_2_FN_MIGRATE PSCI_0_2_FN(5) -#define PSCI_0_2_FN_MIGRATE_INFO_TYPE PSCI_0_2_FN(6) -#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU PSCI_0_2_FN(7) -#define PSCI_0_2_FN_SYSTEM_OFF PSCI_0_2_FN(8) -#define PSCI_0_2_FN_SYSTEM_RESET PSCI_0_2_FN(9) - -#define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) -#define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) -#define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) -#define PSCI_0_2_FN64_MIGRATE (5) -#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) - -#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) -#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) -#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) -#define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) - -#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) -#define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) - -/* PSCI v0.2 power state encoding for CPU_SUSPEND function */ -#define PSCI_0_2_POWER_STATE_ID_MASK 0xffff -#define PSCI_0_2_POWER_STATE_ID_SHIFT 0 -#define PSCI_0_2_POWER_STATE_TYPE_SHIFT 16 -#define PSCI_0_2_POWER_STATE_TYPE_MASK (0x1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT) -#define PSCI_0_2_POWER_STATE_AFFL_SHIFT 24 -#define PSCI_0_2_POWER_STATE_AFFL_MASK (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) - -/* PSCI extended power state encoding for CPU_SUSPEND function */ -#define PSCI_1_0_EXT_POWER_STATE_ID_MASK 0xfffffff -#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT 0 -#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT 30 -#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT) - -/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ -#define PSCI_0_2_AFFINITY_LEVEL_ON 0 -#define PSCI_0_2_AFFINITY_LEVEL_OFF 1 -#define PSCI_0_2_AFFINITY_LEVEL_ON_PENDING 2 - -/* PSCI v0.2 multicore support in Trusted OS returned by MIGRATE_INFO_TYPE */ -#define PSCI_0_2_TOS_UP_MIGRATE 0 -#define PSCI_0_2_TOS_UP_NO_MIGRATE 1 -#define PSCI_0_2_TOS_MP 2 - -/* PSCI version decoding (independent of PSCI version) */ -#define PSCI_VERSION_MAJOR_SHIFT 16 -#define PSCI_VERSION_MINOR_MASK ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) -#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK -#define PSCI_VERSION_MAJOR(ver) (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) -#define PSCI_VERSION_MINOR(ver) ((ver) & PSCI_VERSION_MINOR_MASK) -#define PSCI_VERSION(maj, min) \ - ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ - ((min) & PSCI_VERSION_MINOR_MASK)) - -/* PSCI features decoding (>=1.0) */ -#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1 -#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT) - -#define PSCI_1_0_OS_INITIATED BIT(0) -#define PSCI_1_0_SUSPEND_MODE_PC 0 -#define PSCI_1_0_SUSPEND_MODE_OSI 1 - -/* PSCI return values (inclusive of all PSCI versions) */ -#define PSCI_RET_SUCCESS 0 -#define PSCI_RET_NOT_SUPPORTED -1 -#define PSCI_RET_INVALID_PARAMS -2 -#define PSCI_RET_DENIED -3 -#define PSCI_RET_ALREADY_ON -4 -#define PSCI_RET_ON_PENDING -5 -#define PSCI_RET_INTERNAL_FAILURE -6 -#define PSCI_RET_NOT_PRESENT -7 -#define PSCI_RET_DISABLED -8 -#define PSCI_RET_INVALID_ADDRESS -9 - -#endif /*__PSCI_H__*/ diff --git a/libcpu/aarch64/common/psci_api.h b/libcpu/aarch64/common/psci_api.h deleted file mode 100644 index 36566c3e6fce..000000000000 --- a/libcpu/aarch64/common/psci_api.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __PSCI_API_H__ -#define __PSCI_API_H__ - -#include -#include -#include -#include "psci_api.h" - -/** generic psci ops supported v0.1 v0.2 v1.0 v1.1 */ -struct psci_ops_t -{ - uint32_t (*get_version)(void); - int32_t (*cpu_suspend)(uint32_t state, unsigned long entry_point); - int32_t (*cpu_off)(uint32_t state); - int32_t (*cpu_on)(unsigned long cpuid, unsigned long entry_point); - int32_t (*migrate)(unsigned long cpuid); - - void (*system_off)(void); - void (*system_reset)(void); -}; - -extern struct psci_ops_t psci_ops; - -extern int psci_init(void); - -#endif // __PSCI_API_H__ diff --git a/libcpu/aarch64/common/setup.c b/libcpu/aarch64/common/setup.c new file mode 100644 index 000000000000..672516bb555b --- /dev/null +++ b/libcpu/aarch64/common/setup.c @@ -0,0 +1,817 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-02-21 GuEe-GUI first version + */ + +#include + +#define DBG_TAG "cpu.aa64" +#define DBG_LVL DBG_INFO +#include + +#include +#include +#include +#include + +#ifdef RT_USING_DFS +#include +#ifdef RT_USING_DFS_DIRECTFS +#include +#endif +#ifdef RT_USING_FINSH +#include +#endif +#endif +#ifdef RT_USING_SMART +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define phys_to_virt(pa) ((pa) - PV_OFFSET) + +extern void _secondary_cpu_entry(void); +extern void rt_hw_builtin_fdt(); + +/* symbol in entry_point.S and link.ld */ +extern rt_ubase_t _start, _end; + +extern void *system_vectors; + +static void *fdt_ptr = RT_NULL; +static rt_size_t fdt_size = 0; +static rt_uint64_t initrd_ranges[3] = { }; + +#ifdef RT_USING_SMP +extern struct cpu_ops_t cpu_psci_ops; +extern struct cpu_ops_t cpu_spin_table_ops; +#else +extern int rt_hw_cpu_id(void); +#endif + +rt_uint64_t rt_cpu_mpidr_table[] = +{ + [RT_CPUS_NR] = 0, +}; + +static struct cpu_ops_t *cpu_ops[] = +{ +#ifdef RT_USING_SMP + &cpu_psci_ops, + &cpu_spin_table_ops, +#endif +}; + +static struct rt_ofw_node *cpu_np[RT_CPUS_NR] = { }; + +void rt_hw_fdt_install_early(void *fdt) +{ + if (fdt != RT_NULL && !fdt_check_header(fdt)) + { + fdt_ptr = fdt; + fdt_size = fdt_totalsize(fdt_ptr); + } +} + +static void read_cpuid(char *ids, rt_uint64_t midr) +{ + const char *id; +#define IS_CPU(ID, NAME) case MIDR_##ID: id = NAME; break + switch (midr & ~(MIDR_VARIANT_MASK | MIDR_REVISION_MASK)) + { + IS_CPU(CORTEX_A53, "Cortex-A53"); + IS_CPU(CORTEX_A57, "Cortex-A57"); + IS_CPU(CORTEX_A72, "Cortex-A72"); + IS_CPU(CORTEX_A73, "Cortex-A73"); + IS_CPU(CORTEX_A75, "Cortex-A75"); + IS_CPU(CORTEX_A35, "Cortex-A35"); + IS_CPU(CORTEX_A55, "Cortex-A55"); + IS_CPU(CORTEX_A76, "Cortex-A76"); + IS_CPU(NEOVERSE_N1, "Neoverse-N1"); + IS_CPU(CORTEX_A77, "Cortex-A77"); + IS_CPU(NEOVERSE_V1, "Neoverse-V1"); + IS_CPU(CORTEX_A78, "Cortex-A78"); + IS_CPU(CORTEX_A78AE, "Cortex-A78AE"); + IS_CPU(CORTEX_X1, "Cortex-X1"); + IS_CPU(CORTEX_A510, "Cortex-A510"); + IS_CPU(CORTEX_A710, "Cortex-A710"); + IS_CPU(CORTEX_A715, "Cortex-A715"); + IS_CPU(CORTEX_X2, "Cortex-X2"); + IS_CPU(NEOVERSE_N2, "Neoverse-N2"); + IS_CPU(CORTEX_A78C, "Cortex-A78C"); + IS_CPU(THUNDERX, "Thunderx"); + IS_CPU(THUNDERX_81XX, "Thunderx-81XX"); + IS_CPU(THUNDERX_83XX, "Thunderx-83XX"); + IS_CPU(OCTX2_98XX, "Octx2-98XX"); + IS_CPU(OCTX2_96XX, "Octx2-96XX"); + IS_CPU(OCTX2_95XX, "Octx2-95XX"); + IS_CPU(OCTX2_95XXN, "Octx2-95XXN"); + IS_CPU(OCTX2_95XXMM, "Octx2-95XXMM"); + IS_CPU(OCTX2_95XXO, "Octx2-95XXO"); + IS_CPU(CAVIUM_THUNDERX2, "Cavium-Thunderx2"); + IS_CPU(BRAHMA_B53, "Brahma-B53"); + IS_CPU(BRCM_VULCAN, "Brcm-Vulcan"); + IS_CPU(QCOM_FALKOR, "Qcom-Falkor"); + IS_CPU(QCOM_KRYO, "Qcom-Kryo"); + IS_CPU(QCOM_KRYO_2XX_GOLD, "Qcom-Kryo-2XX-Gold"); + IS_CPU(QCOM_KRYO_2XX_SILVER, "Qcom-Kryo-2XX-Silver"); + IS_CPU(QCOM_KRYO_3XX_SILVER, "qcom-Kryo-3XX-Silver"); + IS_CPU(QCOM_KRYO_4XX_GOLD, "Qcom-Kryo-4XX-Gold"); + IS_CPU(QCOM_KRYO_4XX_SILVER, "Qcom-Kryo-4XX-Silver"); + IS_CPU(NVIDIA_DENVER, "Nvidia_Denver"); + IS_CPU(NVIDIA_CARMEL, "Nvidia_Carmel"); + IS_CPU(FUJITSU_A64FX, "Fujitsu_A64FX"); + IS_CPU(HISI_TSV110, "Hisi_Tsv110"); + IS_CPU(APPLE_M1_ICESTORM, "Apple-M1-Icestorm"); + IS_CPU(APPLE_M1_FIRESTORM, "Apple-M1-Firestorm"); + IS_CPU(APPLE_M1_ICESTORM_PRO, "Apple-M1-Icestorm-Pro"); + IS_CPU(APPLE_M1_FIRESTORM_PRO, "Apple-M1-Firestorm-Pro"); + IS_CPU(APPLE_M1_ICESTORM_MAX, "Apple-M1-Icestorm-Max"); + IS_CPU(APPLE_M1_FIRESTORM_MAX, "Apple-M1-Firestorm-Max"); + IS_CPU(APPLE_M2_BLIZZARD, "Apple-M2-Blizzard"); + IS_CPU(APPLE_M2_AVALANCHE, "Apple-M2-Avalanche"); + IS_CPU(APPLE_M2_BLIZZARD_PRO, "Apple-M2-Blizzard-Pro"); + IS_CPU(APPLE_M2_AVALANCHE_PRO, "Apple-M2-Avalanche-Pro"); + IS_CPU(APPLE_M2_BLIZZARD_MAX, "Apple-M2-Blizzard-Max"); + IS_CPU(APPLE_M2_AVALANCHE_MAX, "Apple-M2-Avalanche-Max"); + IS_CPU(AMPERE1, "Ampere1"); + IS_CPU(QEMU, "Qemu"); + default: + id = "ARMv8"; + break; + } + + if (midr & (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)) + { + rt_sprintf(ids, "%s v%dr%d", id, + (midr & MIDR_VARIANT_MASK) >> MIDR_VARIANT_SHIFT, + (midr & MIDR_REVISION_MASK) >> MIDR_REVISION_SHIFT); + } + else + { + rt_sprintf(ids, "%s", id); + } +#undef IS_CPU +} + +rt_err_t rt_fdt_boot_dump(void) +{ + rt_uint64_t mpidr, midr; + + sysreg_read(mpidr_el1, mpidr); + sysreg_read(midr_el1, midr); + + LOG_I("Booting RT-Thread on physical CPU 0x%010x [0x%08x]", mpidr & MPIDR_AFFINITY_MASK, midr); + + return RT_EOK; +} + +void rt_hw_console_output(const char *str) +{ + rt_fdt_earlycon_output(str); +} + +#ifdef RT_USING_HWTIMER +static rt_ubase_t loops_per_tick[RT_CPUS_NR]; + +static rt_ubase_t cpu_get_cycles(void) +{ + rt_ubase_t cycles; + + sysreg_read(cntpct_el0, cycles); + + return cycles; +} + +static void cpu_loops_per_tick_init(void) +{ + rt_ubase_t offset; + volatile rt_ubase_t freq, step, cycles_end1, cycles_end2; + volatile rt_uint32_t cycles_count1 = 0, cycles_count2 = 0; + + sysreg_read(cntfrq_el0, freq); + step = freq / RT_TICK_PER_SECOND; + + cycles_end1 = cpu_get_cycles() + step; + + while (cpu_get_cycles() < cycles_end1) + { + __asm__ volatile ("nop"); + __asm__ volatile ("add %0, %0, #1":"=r"(cycles_count1)); + } + + cycles_end2 = cpu_get_cycles() + step; + + while (cpu_get_cycles() < cycles_end2) + { + __asm__ volatile ("add %0, %0, #1":"=r"(cycles_count2)); + } + + if ((rt_int32_t)(cycles_count2 - cycles_count1) > 0) + { + offset = cycles_count2 - cycles_count1; + } + else + { + /* Impossible, but prepared for any eventualities */ + offset = cycles_count2 / 4; + } + + loops_per_tick[rt_hw_cpu_id()] = offset; +} + +static void cpu_us_delay(rt_uint32_t us) +{ + volatile rt_base_t start = cpu_get_cycles(), cycles; + + cycles = ((us * 0x10c7UL) * loops_per_tick[rt_hw_cpu_id()] * RT_TICK_PER_SECOND) >> 32; + + while ((cpu_get_cycles() - start) < cycles) + { + rt_hw_cpu_relax(); + } +} +#endif /* RT_USING_HWTIMER */ + +rt_weak void rt_hw_idle_wfi(void) +{ + __asm__ volatile ("wfi"); +} + +static void system_vectors_init(void) +{ + rt_hw_set_current_vbar((rt_ubase_t)&system_vectors); +} + +rt_inline void cpu_info_init(void) +{ + int i = 0; + char cpuid[32]; + rt_uint64_t mpidr, midr; + struct rt_ofw_node *np; + + /* get boot cpu info */ + sysreg_read(mpidr_el1, mpidr); + sysreg_read(midr_el1, midr); + + read_cpuid(cpuid, midr); + LOG_I("Boot Processor ID: %s", cpuid); + + rt_ofw_foreach_cpu_node(np) + { + rt_uint64_t hwid = rt_ofw_get_cpu_hwid(np, 0); + + if ((mpidr & MPIDR_AFFINITY_MASK) != hwid) + { + /* Only save affinity and res make smp boot can check */ + hwid |= 1ULL << 31; + } + else + { + hwid = mpidr; + + sysreg_write(tpidr_el1, i); + } + + cpu_np[i] = np; + rt_cpu_mpidr_table[i] = hwid; + + rt_ofw_data(np) = (void *)hwid; + + for (int idx = 0; idx < RT_ARRAY_SIZE(cpu_ops); ++idx) + { + struct cpu_ops_t *ops = cpu_ops[idx]; + + if (ops->cpu_init) + { + ops->cpu_init(i, np); + } + } + + if (++i >= RT_CPUS_NR) + { + break; + } + } + + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, rt_cpu_mpidr_table, sizeof(rt_cpu_mpidr_table)); + +#ifdef RT_USING_HWTIMER + cpu_loops_per_tick_init(); + + if (!rt_device_hwtimer_us_delay) + { + rt_device_hwtimer_us_delay = &cpu_us_delay; + } +#endif /* RT_USING_HWTIMER */ +} + +rt_inline void directfs_init(void) +{ +#ifdef RT_USING_DFS_DIRECTFS + static char *directfs_root[] = + { + "bus", + "firmware", + }; + static struct rt_object objs[RT_ARRAY_SIZE(directfs_root)]; + + for (int i = 0; i < RT_ARRAY_SIZE(directfs_root); ++i) + { + dfs_directfs_create_link(RT_NULL, &objs[i], directfs_root[i]); + } +#endif +} + +rt_inline rt_bool_t is_kernel_aspace(const char *name) +{ + static char * const names[] = + { + "kernel", + "memheap", + }; + + if (!name) + { + return RT_FALSE; + } + + for (int i = 0; i < RT_ARRAY_SIZE(names); ++i) + { + if (!rt_strcmp(names[i], name)) + { + return RT_TRUE; + } + } + + return RT_FALSE; +} + +void rt_hw_common_setup(void) +{ + const char *bootargs; + rt_ubase_t aspace_base; + rt_size_t mem_region_nr; + rt_region_t *mem_region; + rt_size_t page_best_start; + rt_region_t platform_mem_region; + struct rt_ofw_node *ofw_chosen_node; + static struct mem_desc platform_mem_desc; + void *kernel_start, *kernel_end, *memheap_start = RT_NULL, *memheap_end = RT_NULL; + + system_vectors_init(); + +#ifdef RT_USING_SMART + aspace_base = 0 - ((rt_ubase_t)ARCH_ASPACE_SIZE + 1); +#else + aspace_base = 0xffffd0000000; +#endif + + /* Init kernel address space */ + rt_hw_mmu_map_init(&rt_kernel_space, (void *)aspace_base, (rt_ubase_t)ARCH_ASPACE_SIZE + 1, MMUTable); + + /* Image ARM64 header is 64 bytes */ + kernel_start = rt_kmem_v2p((void *)&_start) - 64; + kernel_end = rt_kmem_v2p((void *)&_end); + + if (!rt_fdt_commit_memregion_request(&mem_region, &mem_region_nr, RT_TRUE)) + { + const char *name = "memheap"; + + while (mem_region_nr --> 0) + { + if (mem_region->name == name || !rt_strcmp(mem_region->name, name)) + { + memheap_start = (void *)mem_region->start; + memheap_end = (void *)mem_region->end; + + break; + } + + ++mem_region; + } + } + + /* We maybe use the area in end of memheap as page pool */ + page_best_start = (rt_size_t)(memheap_end ? : kernel_end); + +#ifdef RT_USING_BUILTIN_FDT + fdt_ptr = &rt_hw_builtin_fdt; + fdt_size = fdt_totalsize(fdt_ptr); +#else + /* + * The bootloader doesn't know the region of our memheap so maybe load the + * device tree to the memheap, it's safety to move to the end of the memheap + */ + if (memheap_end && fdt_ptr > kernel_start) + { + rt_memmove(phys_to_virt(memheap_end), phys_to_virt(fdt_ptr), fdt_size); + + fdt_ptr = memheap_end; + + /* Now, we use the page in the end of the fdt */ + page_best_start = (rt_size_t)fdt_ptr + fdt_size; + } + + /* Reserved the fdt region */ + rt_fdt_commit_memregion_early(&(rt_region_t) + { + .name = "fdt", + .start = (rt_size_t)fdt_ptr, + .end = (rt_size_t)(fdt_ptr + fdt_size), + }, RT_TRUE); + + /* Fixup the fdt pointer to kernel address space */ + fdt_ptr = phys_to_virt(fdt_ptr); +#endif /* !RT_USING_BUILTIN_FDT */ + + /* Reserved the kernel image region */ + rt_fdt_commit_memregion_early(&(rt_region_t) + { + .name = "kernel", + .start = (rt_size_t)kernel_start, + .end = (rt_size_t)kernel_end, + }, RT_TRUE); + + if (rt_fdt_prefetch(fdt_ptr)) + { + /* Platform cannot be initialized */ + RT_ASSERT(0); + } + + /* Setup earlycon */ + rt_fdt_scan_chosen_stdout(); + + rt_fdt_scan_initrd(initrd_ranges); + + /* Reserved your memory block before here */ + rt_fdt_scan_memory(); + + /* Init the system memheap */ + if (memheap_start && memheap_end) + { + rt_system_heap_init(phys_to_virt(memheap_start), phys_to_virt(memheap_end)); + } + + /* Find the SoC memory limit */ + platform_mem_region.start = ~0UL; + platform_mem_region.end = 0; + + if (!rt_fdt_commit_memregion_request(&mem_region, &mem_region_nr, RT_TRUE)) + { + LOG_I("Reserved memory:"); + + while (mem_region_nr --> 0) + { + if (is_kernel_aspace(mem_region->name)) + { + if (platform_mem_region.start > mem_region->start) + { + platform_mem_region.start = mem_region->start; + } + + if (platform_mem_region.end < mem_region->end) + { + platform_mem_region.end = mem_region->end; + } + } + + LOG_I(" %-*.s [%p, %p]", RT_NAME_MAX, mem_region->name, mem_region->start, mem_region->end); + + ++mem_region; + } + } + + if (!rt_fdt_commit_memregion_request(&mem_region, &mem_region_nr, RT_FALSE)) + { + rt_ubase_t best_offset = ~0UL; + rt_region_t *usable_mem_region = mem_region, *page_region = RT_NULL, init_page_region = { 0 }; + + LOG_I("Usable memory:"); + + /* Now, we will find the best page region by for each the usable memory */ + for (int i = 0; i < mem_region_nr; ++i, ++mem_region) + { + if (!mem_region->name) + { + continue; + } + + if (platform_mem_region.start > mem_region->start) + { + platform_mem_region.start = mem_region->start; + } + + if (platform_mem_region.end < mem_region->end) + { + platform_mem_region.end = mem_region->end; + } + + if (mem_region->start >= page_best_start && + mem_region->start - page_best_start < best_offset && + /* MUST >= 1MB */ + mem_region->end - mem_region->start >= SIZE_MB) + { + page_region = mem_region; + + best_offset = page_region->start - page_best_start; + } + + LOG_I(" %-*.s [%p, %p]", RT_NAME_MAX, mem_region->name, mem_region->start, mem_region->end); + } + + /* Init the kernel page pool */ + RT_ASSERT(page_region != RT_NULL); + + + init_page_region.start = phys_to_virt(page_region->start); + init_page_region.end = phys_to_virt(page_region->end); + rt_page_init(init_page_region); + + /* Init the mmu address space config */ + platform_mem_region.start = RT_ALIGN(platform_mem_region.start, ARCH_PAGE_SIZE); + platform_mem_region.end = RT_ALIGN_DOWN(platform_mem_region.end, ARCH_PAGE_SIZE); + RT_ASSERT(platform_mem_region.end - platform_mem_region.start != 0); + + platform_mem_desc.paddr_start = platform_mem_region.start; + platform_mem_desc.vaddr_start = phys_to_virt(platform_mem_region.start); + platform_mem_desc.vaddr_end = phys_to_virt(platform_mem_region.end) - 1; + platform_mem_desc.attr = NORMAL_MEM; + + rt_hw_mmu_setup(&rt_kernel_space, &platform_mem_desc, 1); + + /* MMU config was changed, update the mmio map in earlycon */ + rt_fdt_earlycon_kick(FDT_EARLYCON_KICK_UPDATE); + + /* Install all usable memory into memory system */ + mem_region = usable_mem_region; + + for (int i = 0; i < mem_region_nr; ++i, ++mem_region) + { + if (mem_region != page_region && mem_region->name) + { + rt_page_install(*mem_region); + } + } + } + + directfs_init(); + + rt_fdt_unflatten(); + + cpu_info_init(); + + /* Init the hardware interrupt */ + rt_pic_init(); + rt_hw_interrupt_init(); + + ofw_chosen_node = rt_ofw_find_node_by_path("/chosen"); + + if (!rt_ofw_prop_read_string(ofw_chosen_node, "bootargs", &bootargs)) + { + LOG_I("Command line: %s", bootargs); + } + + rt_ofw_node_put(ofw_chosen_node); + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE) + rt_ofw_console_setup(); +#endif + + rt_thread_idle_sethook(rt_hw_idle_wfi); + +#ifdef RT_USING_SMP + /* Install the IPI handle */ + rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler); + rt_hw_ipi_handler_install(RT_STOP_IPI, rt_scheduler_ipi_handler); + rt_hw_interrupt_umask(RT_SCHEDULE_IPI); + rt_hw_interrupt_umask(RT_STOP_IPI); +#endif +} + +#ifdef RT_USING_DFS +static int rootfs_mnt_init(void) +{ + rt_err_t err = -RT_ERROR; + void *fsdata = RT_NULL; + const char *cpio_type = "cpio"; + const char *dev = rt_ofw_bootargs_select("root=", 0); + const char *fstype = rt_ofw_bootargs_select("rootfstype=", 0); + const char *rw = rt_ofw_bootargs_select("rw", 0); + + if ((!dev || !fstype) && initrd_ranges[0] && initrd_ranges[1]) + { + void *base = (void *)initrd_ranges[0]; + size_t size = (void *)initrd_ranges[1] - base; + + fsdata = rt_ioremap(base, size); + + if (fsdata) + { + fstype = cpio_type; + initrd_ranges[2] = (rt_uint64_t)fsdata; + } + } + + if (fstype != cpio_type && dev) + { + rt_tick_t timeout = 0; + const char *rootwait, *rootdelay = RT_NULL; + + rootwait = rt_ofw_bootargs_select("rootwait", 0); + + /* Maybe it is undefined or 'rootwaitABC' */ + if (!rootwait || *rootwait) + { + rootdelay = rt_ofw_bootargs_select("rootdelay=", 0); + + if (rootdelay) + { + timeout = rt_tick_from_millisecond(atoi(rootdelay)); + } + + rootwait = RT_NULL; + } + + /* + * Delays in boot flow is a terrible behavior in RTOS, but the RT-Thread + * SDIO framework init the devices in a task that we need to wait for + * SDIO devices to init complete... + * + * WHAT THE F*CK PROBLEMS WILL HAPPENED? + * + * Your main PE, applications, services that depend on the root FS and + * the multi cores setup, init will delay, too... + * + * So, you can try to link this function to `INIT_APP_EXPORT` even later + * and remove the delays if you want to optimize the boot time and mount + * the FS auto. + */ + for (; rootdelay || rootwait; --timeout) + { + if (!rootwait && timeout == 0) + { + LOG_E("Wait for /dev/%s init time out", dev); + + /* + * We don't return at once because the device driver may init OK + * when we break from this point, might as well give it another + * try. + */ + break; + } + + if (rt_device_find(dev)) + { + break; + } + + rt_thread_mdelay(1); + } + } + + if (fstype) + { + if (!(err = dfs_mount(dev, "/", fstype, rw ? 0 : ~0, fsdata))) + { + LOG_I("Mount root %s%s type=%s %s", + (dev && *dev) ? "on /dev/" : "", + (dev && *dev) ? dev : "\b", + fstype, "done"); + } + else + { + LOG_W("Mount root %s%s type=%s %s", + (dev && *dev) ? "on /dev/" : "", + (dev && *dev) ? dev : "\b", + fstype, "fail"); + } + } + + return 0; +} +INIT_ENV_EXPORT(rootfs_mnt_init); + +static int fstab_mnt_init(void) +{ +#ifdef RT_USING_DFS_DIRECTFS + mkdir("/direct", 0755); + + if (!dfs_mount(RT_NULL, "/direct", "direct", 0, RT_NULL)) + { + LOG_I("Mount %s %s%s type=%s %s", "direct", "/", "direct", "direct", "done"); + } +#endif + + mkdir("/mnt", 0755); + +#ifdef RT_USING_FINSH + /* Try mount by table */ + msh_exec_script("fstab.sh", 16); +#endif + + return 0; +} +INIT_FS_EXPORT(fstab_mnt_init); +#endif /* RT_USING_DFS */ + +#ifdef RT_USING_SMP +rt_weak void rt_hw_secondary_cpu_up(void) +{ + int cpu_id = rt_hw_cpu_id(); + rt_uint64_t entry = (rt_uint64_t)rt_kmem_v2p(_secondary_cpu_entry); + + if (!entry) + { + LOG_E("Failed to translate '_secondary_cpu_entry' to physical address"); + RT_ASSERT(0); + } + + /* Maybe we are no in the first cpu */ + for (int i = 0; i < RT_ARRAY_SIZE(cpu_np); ++i) + { + int err; + const char *enable_method; + + if (!cpu_np[i] || i == cpu_id) + { + continue; + } + + err = rt_ofw_prop_read_string(cpu_np[i], "enable-method", &enable_method); + + for (int idx = 0; !err && idx < RT_ARRAY_SIZE(cpu_ops); ++idx) + { + struct cpu_ops_t *ops = cpu_ops[idx]; + + if (ops->method && !rt_strcmp(ops->method, enable_method) && ops->cpu_boot) + { + err = ops->cpu_boot(i, entry); + + break; + } + } + + if (err) + { + LOG_W("Call CPU%d on failed", i); + } + } +} + +rt_weak void secondary_cpu_c_start(void) +{ + char cpuid[32]; + rt_uint64_t midr; + int cpu_id = rt_hw_cpu_id(); + + system_vectors_init(); + + rt_hw_spin_lock(&_cpus_lock); + + /* Save all mpidr */ + sysreg_read(mpidr_el1, rt_cpu_mpidr_table[cpu_id]); + sysreg_read(midr_el1, midr); + + rt_hw_mmu_ktbl_set((unsigned long)MMUTable); + +#ifdef RT_USING_HWTIMER + if (rt_device_hwtimer_us_delay == &cpu_us_delay) + { + cpu_loops_per_tick_init(); + } +#endif + + rt_hw_interrupt_init(); + + rt_dm_secondary_cpu_init(); + rt_hw_interrupt_umask(RT_SCHEDULE_IPI); + rt_hw_interrupt_umask(RT_STOP_IPI); + + read_cpuid(cpuid, midr); + LOG_I("Call CPU%d [%s] on success", cpu_id, cpuid); + + rt_system_scheduler_start(); +} + +rt_weak void rt_hw_secondary_cpu_idle_exec(void) +{ + rt_hw_wfe(); +} +#endif /* RT_USING_SMP */ diff --git a/libcpu/aarch64/common/setup.h b/libcpu/aarch64/common/setup.h new file mode 100644 index 000000000000..57c3f63965e8 --- /dev/null +++ b/libcpu/aarch64/common/setup.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-02-21 GuEe-GUI first version + */ + +#ifndef __SETUP_H__ +#define __SETUP_H__ + +#include +#include +#include + +void rt_hw_common_setup(void); + +#endif /* __SETUP_H__ */ diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c index dd5468daf1d1..752f60e6fa7f 100644 --- a/libcpu/aarch64/common/trap.c +++ b/libcpu/aarch64/common/trap.c @@ -18,6 +18,8 @@ #include +#include + void rt_unwind(struct rt_hw_exp_stack *regs, int pc_adj) { } @@ -139,124 +141,12 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs) void rt_hw_trap_irq(void) { -#ifdef SOC_BCM283x - extern rt_uint8_t core_timer_flag; - void *param; - uint32_t irq; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - uint32_t value = 0; - value = IRQ_PEND_BASIC & 0x3ff; - - if(core_timer_flag != 0) - { - uint32_t cpu_id = rt_hw_cpu_id(); - uint32_t int_source = CORE_IRQSOURCE(cpu_id); - if (int_source & 0x0f) - { - if (int_source & 0x08) - { - isr_func = isr_table[IRQ_ARM_TIMER].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[IRQ_ARM_TIMER].counter++; -#endif - if (isr_func) - { - param = isr_table[IRQ_ARM_TIMER].param; - isr_func(IRQ_ARM_TIMER, param); - } - } - } - } - - /* local interrupt*/ - if (value) - { - if (value & (1 << 8)) - { - value = IRQ_PEND1; - irq = __rt_ffs(value) - 1; - } - else if (value & (1 << 9)) - { - value = IRQ_PEND2; - irq = __rt_ffs(value) + 31; - } - else - { - value &= 0x0f; - irq = __rt_ffs(value) + 63; - } - - /* get interrupt service routine */ - isr_func = isr_table[irq].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[irq].counter++; -#endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[irq].param; - /* turn to interrupt service routine */ - isr_func(irq, param); - } - } -#else - void *param; - int ir, ir_self; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - ir = rt_hw_interrupt_get_irq(); - - if (ir == 1023) - { - /* Spurious interrupt */ - return; - } - - /* bit 10~12 is cpuid, bit 0~9 is interrupt id */ - ir_self = ir & 0x3ffUL; - - /* get interrupt service routine */ - isr_func = isr_table[ir_self].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[ir_self].counter++; -#endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[ir_self].param; - /* turn to interrupt service routine */ - isr_func(ir_self, param); - } - - /* end of interrupt */ - rt_hw_interrupt_ack(ir); -#endif + rt_pic_do_traps(); } void rt_hw_trap_fiq(void) { - void *param; - int ir, ir_self; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - ir = rt_hw_interrupt_get_irq(); - - /* bit 10~12 is cpuid, bit 0~9 is interrup id */ - ir_self = ir & 0x3ffUL; - - /* get interrupt service routine */ - isr_func = isr_table[ir_self].handler; - param = isr_table[ir_self].param; - - /* turn to interrupt service routine */ - isr_func(ir_self, param); - - /* end of interrupt */ - rt_hw_interrupt_ack(ir); + rt_pic_do_traps(); } void process_exception(unsigned long esr, unsigned long epc); @@ -297,7 +187,12 @@ void rt_hw_trap_exception(struct rt_hw_exp_stack *regs) list_thread(); #endif backtrace((unsigned long)regs->pc, (unsigned long)regs->x30, (unsigned long)regs->x29); - rt_hw_cpu_shutdown(); + + rt_hw_interrupt_disable(); + + while (RT_TRUE) + { + } } void rt_hw_trap_serror(struct rt_hw_exp_stack *regs) @@ -308,5 +203,10 @@ void rt_hw_trap_serror(struct rt_hw_exp_stack *regs) #ifdef RT_USING_FINSH list_thread(); #endif - rt_hw_cpu_shutdown(); + + rt_hw_interrupt_disable(); + + while (RT_TRUE) + { + } } diff --git a/libcpu/aarch64/cortex-a/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S index 7a282cef1efc..6f72a13afb9a 100644 --- a/libcpu/aarch64/cortex-a/entry_point.S +++ b/libcpu/aarch64/cortex-a/entry_point.S @@ -7,6 +7,7 @@ * 2020-01-15 bigmagic the first version * 2020-08-10 SummerGift support clang compiler * 2023-04-29 GuEe-GUI support kernel's ARM64 boot header + * 2023-06-04 GuEe-GUI support cpu init by device-tree */ #ifndef __ASSEMBLY__ @@ -77,7 +78,7 @@ boot_arg2 .req x24 stack_top .req x25 .global _start -__start: +_start: /* * Boot CPU general-purpose register settings: * x0 = physical address of device tree blob (dtb) in system RAM. @@ -99,6 +100,10 @@ __start: bl init_kernel_bss bl init_cpu_stack_early + /* Save devicetree info */ + mov x0, dtb_paddr + bl rt_hw_fdt_install_early + /* Now we are in the end of boot cpu process */ ldr x8, =rtthread_startup b init_mmu_early