2022-11-10 22:22:48 +08:00
|
|
|
|
/*
|
2023-08-02 13:27:09 +08:00
|
|
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
2022-11-10 22:22:48 +08:00
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*
|
|
|
|
|
* Email: opensource_embedded@phytium.com.cn
|
|
|
|
|
*
|
|
|
|
|
* Change Logs:
|
|
|
|
|
* Date Author Notes
|
|
|
|
|
* 2022-10-26 huanghe first commit
|
|
|
|
|
* 2022-10-26 zhugengyu support aarch64
|
2023-05-11 10:25:21 +08:00
|
|
|
|
* 2023-04-13 zhugengyu support RT-Smart
|
2023-08-02 13:27:09 +08:00
|
|
|
|
* 2023-07-27 zhugengyu update aarch32 gtimer usage
|
2022-11-10 22:22:48 +08:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "rtconfig.h"
|
|
|
|
|
#include <rthw.h>
|
|
|
|
|
#include <rtthread.h>
|
|
|
|
|
|
|
|
|
|
#include <mmu.h>
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#include <mm_aspace.h> /* TODO: why need application space when RT_SMART off */
|
|
|
|
|
#include <mm_page.h>
|
|
|
|
|
|
|
|
|
|
#ifdef RT_USING_SMART
|
2023-08-02 13:27:09 +08:00
|
|
|
|
#include <page.h>
|
|
|
|
|
#include <lwp_arch.h>
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#endif
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
#include <gicv3.h>
|
|
|
|
|
#if defined(TARGET_ARMV8_AARCH64)
|
|
|
|
|
#include <psci.h>
|
|
|
|
|
#include <gtimer.h>
|
|
|
|
|
#include <cpuport.h>
|
|
|
|
|
#else
|
2023-11-21 17:42:23 +08:00
|
|
|
|
#include <gtimer.h>
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
#include <interrupt.h>
|
|
|
|
|
#include <board.h>
|
|
|
|
|
|
|
|
|
|
#include "fearly_uart.h"
|
|
|
|
|
#include "fcpu_info.h"
|
2023-08-02 13:27:09 +08:00
|
|
|
|
#include "fiopad.h"
|
|
|
|
|
|
|
|
|
|
#ifdef RT_USING_SMP
|
|
|
|
|
#include "fpsci.h"
|
|
|
|
|
#endif
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-11-21 17:42:23 +08:00
|
|
|
|
extern FIOPadCtrl iopad_ctrl;
|
2022-11-10 22:22:48 +08:00
|
|
|
|
/* mmu config */
|
2023-05-11 10:25:21 +08:00
|
|
|
|
extern struct mem_desc platform_mem_desc[];
|
|
|
|
|
extern const rt_uint32_t platform_mem_desc_size;
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
void idle_wfi(void)
|
|
|
|
|
{
|
|
|
|
|
asm volatile("wfi");
|
|
|
|
|
}
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
/**
|
|
|
|
|
* This function will initialize board
|
|
|
|
|
*/
|
|
|
|
|
extern size_t MMUTable[];
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-08-02 13:27:09 +08:00
|
|
|
|
rt_region_t init_page_region =
|
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
PAGE_START,
|
|
|
|
|
PAGE_END
|
|
|
|
|
};
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-11-21 17:42:23 +08:00
|
|
|
|
void FIOMuxInit(void)
|
|
|
|
|
{
|
|
|
|
|
FIOPadCfgInitialize(&iopad_ctrl, FIOPadLookupConfig(FIOPAD0_ID));
|
|
|
|
|
#ifdef RT_USING_SMART
|
|
|
|
|
iopad_ctrl.config.base_address = (uintptr)rt_ioremap((void *)iopad_ctrl.config.base_address, 0x2000);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#if defined(TARGET_ARMV8_AARCH64) /* AARCH64 */
|
|
|
|
|
|
|
|
|
|
/* aarch64 use kernel gtimer */
|
|
|
|
|
|
|
|
|
|
#else /* AARCH32 */
|
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
/* aarch32 implment gtimer by bsp */
|
|
|
|
|
static rt_uint32_t timer_step;
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-11-21 17:42:23 +08:00
|
|
|
|
#define CNTP_CTL_ENABLE (1U << 0) /* Enables the timer */
|
|
|
|
|
#define CNTP_CTL_IMASK (1U << 1) /* Timer interrupt mask bit */
|
|
|
|
|
#define CNTP_CTL_ISTATUS (1U << 2) /* The status of the timer */
|
|
|
|
|
void GenericTimerInterruptEnable(u32 id)
|
|
|
|
|
{
|
|
|
|
|
u64 ctrl = gtimer_get_control();
|
|
|
|
|
if (ctrl & CNTP_CTL_IMASK)
|
|
|
|
|
{
|
|
|
|
|
ctrl &= ~CNTP_CTL_IMASK;
|
|
|
|
|
gtimer_set_control(ctrl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GenericTimerStart(u32 id)
|
|
|
|
|
{
|
|
|
|
|
u32 ctrl = gtimer_get_control(); /* get CNTP_CTL */
|
|
|
|
|
|
|
|
|
|
if (!(ctrl & CNTP_CTL_ENABLE))
|
|
|
|
|
{
|
|
|
|
|
ctrl |= CNTP_CTL_ENABLE; /* enable gtimer if off */
|
|
|
|
|
gtimer_set_control(ctrl); /* set CNTP_CTL */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-10 22:22:48 +08:00
|
|
|
|
void rt_hw_timer_isr(int vector, void *parameter)
|
|
|
|
|
{
|
2023-11-21 17:42:23 +08:00
|
|
|
|
gtimer_set_load_value(timer_step);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
rt_tick_increase();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int rt_hw_timer_init(void)
|
|
|
|
|
{
|
|
|
|
|
rt_hw_interrupt_install(GENERIC_TIMER_NS_IRQ_NUM, rt_hw_timer_isr, RT_NULL, "tick");
|
|
|
|
|
rt_hw_interrupt_umask(GENERIC_TIMER_NS_IRQ_NUM);
|
2023-11-21 17:42:23 +08:00
|
|
|
|
timer_step = gtimer_get_counter_frequency();
|
|
|
|
|
FASSERT_MSG((timer_step > 1000000), "invalid freqency %ud", timer_step);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
timer_step /= RT_TICK_PER_SECOND;
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-11-21 17:42:23 +08:00
|
|
|
|
gtimer_set_load_value(timer_step);
|
2023-08-02 13:27:09 +08:00
|
|
|
|
GenericTimerInterruptEnable(GENERIC_TIMER_ID0);
|
|
|
|
|
GenericTimerStart(GENERIC_TIMER_ID0);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
INIT_BOARD_EXPORT(rt_hw_timer_init);
|
2023-11-21 17:42:23 +08:00
|
|
|
|
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef RT_USING_SMP
|
|
|
|
|
void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(TARGET_ARMV8_AARCH64)
|
2023-05-11 10:25:21 +08:00
|
|
|
|
void rt_hw_board_aarch64_init(void)
|
|
|
|
|
{
|
|
|
|
|
/* AARCH64 */
|
2023-08-02 13:27:09 +08:00
|
|
|
|
#if defined(RT_USING_SMART)
|
|
|
|
|
/* 1. init rt_kernel_space table (aspace.start = KERNEL_VADDR_START , aspace.size = ), 2. init io map range (rt_ioremap_start \ rt_ioremap_size) 3. */
|
|
|
|
|
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
|
2023-05-11 10:25:21 +08:00
|
|
|
|
rt_page_init(init_page_region);
|
|
|
|
|
|
|
|
|
|
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
|
|
|
|
|
|
2023-08-02 13:27:09 +08:00
|
|
|
|
/* init memory pool */
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#ifdef RT_USING_HEAP
|
|
|
|
|
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
rt_hw_interrupt_init();
|
|
|
|
|
|
|
|
|
|
rt_hw_gtimer_init();
|
|
|
|
|
|
2023-08-02 13:27:09 +08:00
|
|
|
|
FEarlyUartProbe();
|
2023-05-11 10:25:21 +08:00
|
|
|
|
|
2023-11-21 17:42:23 +08:00
|
|
|
|
FIOMuxInit();
|
2023-05-11 10:25:21 +08:00
|
|
|
|
|
|
|
|
|
/* compoent init */
|
|
|
|
|
#ifdef RT_USING_COMPONENTS_INIT
|
|
|
|
|
rt_components_board_init();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* shell init */
|
|
|
|
|
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
|
|
|
|
|
/* set console device */
|
|
|
|
|
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
rt_thread_idle_sethook(idle_wfi);
|
|
|
|
|
|
|
|
|
|
#ifdef RT_USING_SMP
|
2023-08-02 13:27:09 +08:00
|
|
|
|
FPsciInit();
|
2023-05-11 10:25:21 +08:00
|
|
|
|
/* install IPI handle */
|
|
|
|
|
rt_hw_interrupt_set_priority(RT_SCHEDULE_IPI, 16);
|
|
|
|
|
rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
|
|
|
|
|
rt_hw_interrupt_umask(RT_SCHEDULE_IPI);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#else
|
2023-05-11 10:25:21 +08:00
|
|
|
|
|
|
|
|
|
void rt_hw_board_aarch32_init(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
#if defined(RT_USING_SMART)
|
|
|
|
|
|
|
|
|
|
/* set io map range is 0xf0000000 ~ 0x10000000 , Memory Protection start address is 0xf0000000 - rt_mpr_size */
|
2023-08-02 13:27:09 +08:00
|
|
|
|
rt_hw_mmu_map_init(&rt_kernel_space, (void *)0xf0000000, 0x10000000, MMUTable, PV_OFFSET);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
|
|
|
|
|
rt_page_init(init_page_region);
|
|
|
|
|
|
|
|
|
|
/* rt_kernel_space 在start_gcc.S 中被初始化,此函数将iomap 空间放置在kernel space 上 */
|
2023-08-02 13:27:09 +08:00
|
|
|
|
rt_hw_mmu_ioremap_init(&rt_kernel_space, (void *)0xf0000000, 0x10000000);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
/* */
|
2023-08-02 13:27:09 +08:00
|
|
|
|
arch_kuser_init(&rt_kernel_space, (void *)0xffff0000);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#else
|
|
|
|
|
/*
|
|
|
|
|
map kernel space memory (totally 1GB = 0x10000000), pv_offset = 0 if not RT_SMART:
|
|
|
|
|
0x80000000 ~ 0x80100000: kernel stack
|
|
|
|
|
0x80100000 ~ __bss_end: kernel code and data
|
|
|
|
|
*/
|
2023-08-02 13:27:09 +08:00
|
|
|
|
rt_hw_mmu_map_init(&rt_kernel_space, (void *)0x80000000, 0x10000000, MMUTable, 0);
|
|
|
|
|
rt_hw_mmu_ioremap_init(&rt_kernel_space, (void *)0x80000000, 0x10000000);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2023-08-02 13:27:09 +08:00
|
|
|
|
/* init memory pool */
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#ifdef RT_USING_HEAP
|
|
|
|
|
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
|
|
|
|
|
#endif
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
extern int rt_hw_cpu_id(void);
|
|
|
|
|
|
|
|
|
|
u32 cpu_id, cpu_offset = 0;
|
|
|
|
|
GetCpuId(&cpu_id);
|
|
|
|
|
|
|
|
|
|
#if defined(FT_GIC_REDISTRUBUTIOR_OFFSET)
|
|
|
|
|
cpu_offset = FT_GIC_REDISTRUBUTIOR_OFFSET ;
|
|
|
|
|
#endif
|
2023-05-11 10:25:21 +08:00
|
|
|
|
rt_uint32_t redist_addr = 0;
|
|
|
|
|
|
2023-08-02 13:27:09 +08:00
|
|
|
|
FEarlyUartProbe();
|
|
|
|
|
|
2023-11-21 17:42:23 +08:00
|
|
|
|
FIOMuxInit();
|
2023-08-02 13:27:09 +08:00
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#if defined(RT_USING_SMART)
|
2023-08-02 13:27:09 +08:00
|
|
|
|
redist_addr = (uint32_t)rt_ioremap(GICV3_RD_BASE_ADDR, 4 * 128 * 1024);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
#else
|
|
|
|
|
redist_addr = GICV3_RD_BASE_ADDR;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + (cpu_id + cpu_offset) * GICV3_RD_OFFSET, rt_hw_cpu_id());
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-08-29 10:27:54 +08:00
|
|
|
|
#if defined(TARGET_E2000Q) || defined(TARGET_PHYTIUMPI)
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
#if RT_CPUS_NR == 2
|
2023-05-11 10:25:21 +08:00
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#elif RT_CPUS_NR == 3
|
2023-05-11 10:25:21 +08:00
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
|
|
|
|
|
arm_gic_redist_address_set(0, redist_addr, 2);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#elif RT_CPUS_NR == 4
|
2023-05-11 10:25:21 +08:00
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
|
|
|
|
|
arm_gic_redist_address_set(0, redist_addr, 2);
|
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + GICV3_RD_OFFSET, 3);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
#if RT_CPUS_NR == 2
|
2023-05-11 10:25:21 +08:00
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#elif RT_CPUS_NR == 3
|
2023-05-11 10:25:21 +08:00
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
|
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + (2 + cpu_offset) * GICV3_RD_OFFSET, 2);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#elif RT_CPUS_NR == 4
|
2023-05-11 10:25:21 +08:00
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
|
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + (2 + cpu_offset) * GICV3_RD_OFFSET, 2);
|
|
|
|
|
arm_gic_redist_address_set(0, redist_addr + (3 + cpu_offset) * GICV3_RD_OFFSET, 3);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
rt_hw_interrupt_init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* compoent init */
|
|
|
|
|
#ifdef RT_USING_COMPONENTS_INIT
|
|
|
|
|
rt_components_board_init();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* shell init */
|
|
|
|
|
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
|
|
|
|
|
/* set console device */
|
|
|
|
|
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
rt_thread_idle_sethook(idle_wfi);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
#ifdef RT_USING_SMP
|
2023-08-02 13:27:09 +08:00
|
|
|
|
FPsciInit();
|
2022-11-10 22:22:48 +08:00
|
|
|
|
/* install IPI handle */
|
|
|
|
|
rt_hw_interrupt_set_priority(RT_SCHEDULE_IPI, 16);
|
|
|
|
|
rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
|
|
|
|
|
rt_hw_interrupt_umask(RT_SCHEDULE_IPI);
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
}
|
|
|
|
|
#endif
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
/**
|
|
|
|
|
* This function will initialize hardware board
|
|
|
|
|
*/
|
|
|
|
|
void rt_hw_board_init(void)
|
2022-11-10 22:22:48 +08:00
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
|
|
|
|
|
#if defined(TARGET_ARMV8_AARCH64)
|
|
|
|
|
rt_hw_board_aarch64_init();
|
|
|
|
|
#else
|
|
|
|
|
rt_hw_board_aarch32_init();
|
|
|
|
|
#endif
|
2022-11-10 22:22:48 +08:00
|
|
|
|
}
|
|
|
|
|
|