396 lines
8.7 KiB
C
396 lines
8.7 KiB
C
#include "asm/includes.h"
|
|
#include "system/includes.h"
|
|
#include "app_config.h"
|
|
|
|
#define LOG_TAG "[SETUP]"
|
|
#define LOG_ERROR_ENABLE
|
|
#define LOG_DEBUG_ENABLE
|
|
#define LOG_INFO_ENABLE
|
|
#define LOG_CLI_ENABLE
|
|
#include "debug.h"
|
|
|
|
extern void sys_timer_init(void);
|
|
extern void tick_timer_init(void);
|
|
extern void exception_irq_handler(void);
|
|
extern int __crc16_mutex_init();
|
|
extern void debug_uart_init();
|
|
extern void boot_power_init();
|
|
extern void perf_counter_init(void);
|
|
/* --------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief 裸机程序入口
|
|
*/
|
|
/* ----------------------------------------------------------------------------*/
|
|
void system_main(void)
|
|
{
|
|
//分支预测
|
|
q32DSP(core_num())->PMU_CON1 &= ~BIT(8);
|
|
|
|
wdt_close();
|
|
|
|
#if (TCFG_MAX_LIMIT_SYS_CLOCK==MAX_LIMIT_SYS_CLOCK_160M)
|
|
clk_early_init(PLL_REF_XOSC_DIFF, TCFG_CLOCK_OSC_HZ, 240 * MHz);// 240:max clock 160
|
|
#else
|
|
clk_early_init(PLL_REF_XOSC_DIFF, TCFG_CLOCK_OSC_HZ, 192 * MHz);
|
|
#endif
|
|
|
|
//heap内存管理,STDIO需要heap
|
|
memory_init();
|
|
|
|
//uart init
|
|
debug_uart_init();
|
|
|
|
//STDIO init
|
|
log_early_init(1024 * 2);
|
|
|
|
//debug info
|
|
printf("%s : %s %s", __FUNCTION__, __DATE__, __TIME__);
|
|
|
|
while (1) {
|
|
asm("idle");
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief 裸机环境启动,进入无操作系统环境
|
|
*/
|
|
/* ----------------------------------------------------------------------------*/
|
|
#define SYSTEM_SSP_SIZE 512
|
|
u32 system_ssp_stack[SYSTEM_SSP_SIZE];//2Kbyte
|
|
void system_start(void)
|
|
{
|
|
asm("ssp = %0"::"i"(system_ssp_stack + SYSTEM_SSP_SIZE));
|
|
asm("r0 = %0"::"i"(system_main));
|
|
asm("reti = r0");
|
|
asm("rti");
|
|
}
|
|
|
|
|
|
#if CONFIG_DEBUG_ENABLE || CONFIG_DEBUG_LITE_ENABLE
|
|
#endif
|
|
|
|
#if 0
|
|
___interrupt
|
|
void exception_irq_handler(void)
|
|
{
|
|
___trig;
|
|
|
|
exception_analyze();
|
|
|
|
log_flush();
|
|
while (1);
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 此函数在cpu0上电后首先被调用,负责初始化cpu内部模块
|
|
*
|
|
* 此函数返回后,操作系统才开始初始化并运行
|
|
*
|
|
*/
|
|
|
|
#if 0
|
|
static void early_putchar(char a)
|
|
{
|
|
if (a == '\n') {
|
|
UT2_BUF = '\r';
|
|
__asm_csync();
|
|
while ((UT2_CON & BIT(15)) == 0);
|
|
}
|
|
UT2_BUF = a;
|
|
__asm_csync();
|
|
while ((UT2_CON & BIT(15)) == 0);
|
|
}
|
|
|
|
void early_puts(char *s)
|
|
{
|
|
do {
|
|
early_putchar(*s);
|
|
} while (*(++s));
|
|
}
|
|
#endif
|
|
|
|
void cpu_assert_debug()
|
|
{
|
|
#if CONFIG_DEBUG_ENABLE
|
|
log_flush();
|
|
local_irq_disable();
|
|
while (1);
|
|
#else
|
|
P3_PCNT_SET0 = 0xac;
|
|
cpu_reset();
|
|
#endif
|
|
}
|
|
|
|
|
|
extern void sputchar(char c);
|
|
extern void sput_buf(const u8 *buf, int len);
|
|
void sput_u32hex(u32 dat);
|
|
|
|
|
|
|
|
__attribute__((weak))
|
|
void maskrom_init(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
extern u32 FREE_DACHE_WAY;
|
|
extern u32 FREE_IACHE_WAY;
|
|
|
|
extern u32 dcache_ram_bss_begin;
|
|
extern u32 dcache_ram_bss_size;
|
|
extern u32 dcache_ram_bss_end;
|
|
|
|
extern u32 dcache_ram_data_addr;
|
|
extern u32 dcache_ram_data_begin;
|
|
extern u32 dcache_ram_data_size;
|
|
|
|
extern u32 icache_ram_bss_begin;
|
|
extern u32 icache_ram_bss_size;
|
|
extern u32 icache_ram_bss_end;
|
|
|
|
extern u32 icache_ram_data_code_addr;
|
|
extern u32 icache_ram_data_code_begin;
|
|
extern u32 icache_ram_data_code_size;
|
|
|
|
__attribute__((weak))
|
|
AT(.must_ram_code)
|
|
void cache_ram_init(void)
|
|
{
|
|
#if (TCFG_FREE_ICACHE_WAY || TCFG_FREE_DCACHE_WAY)
|
|
// 用 volatile 避免被优化而导致出错
|
|
volatile u8 dcache_way = 4 - (u32)(&FREE_DACHE_WAY);
|
|
volatile u8 icache_way = 4 - (u32)(&FREE_IACHE_WAY);
|
|
|
|
if (dcache_way != 4) {
|
|
/* memset((void *)(0x370000 + 0xF800), 0, 0xFC00 - 0xF800); // 清空 lru */
|
|
DcuInitial();
|
|
// 空出way当ram用
|
|
DcuSetWayNum(dcache_way);
|
|
|
|
memset((u8 *)(&dcache_ram_bss_begin), 0, (u32)&dcache_ram_bss_size);
|
|
memcpy((u8 *)&dcache_ram_data_addr, (u8 *)&dcache_ram_data_begin, (u32)&dcache_ram_data_size);
|
|
}
|
|
|
|
if (icache_way != 4) {
|
|
IcuFlushinvAll();
|
|
DcuFlushinvAll();
|
|
|
|
IcuDisable();
|
|
/* memset((void *)(0x3c0000 + 0xF800), 0, 0xFC00 - 0xF800); // 清空 lru */
|
|
IcuInitial();
|
|
// 空出way当ram用
|
|
IcuSetWayNum(icache_way);
|
|
|
|
memset((u8 *)(&icache_ram_bss_begin), 0, (u32)&icache_ram_bss_size);
|
|
memcpy((u8 *)&icache_ram_data_code_addr, (u8 *)&icache_ram_data_code_begin, (u32)&icache_ram_data_code_size);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
AT(.must_ram_code)
|
|
void icache_way_switch(u8 num)
|
|
{
|
|
local_irq_disable();
|
|
|
|
IcuFlushinvAll();
|
|
IcuDisable();
|
|
IcuInitial();
|
|
IcuSetWayNum(num);
|
|
IcuEnable();
|
|
|
|
local_irq_enable();
|
|
}
|
|
|
|
#if (CPU_CORE_NUM > 1)
|
|
void cpu1_setup_arch()
|
|
{
|
|
q32DSP(core_num())->PMU_CON1 &= ~BIT(8); //open bpu
|
|
|
|
request_irq(IRQ_EXCEPTION_IDX, 7, exception_irq_handler, 1);
|
|
|
|
//用于控制其他核进入停止状态。
|
|
extern void cpu_suspend_handle(void);
|
|
request_irq(IRQ_SOFT0_IDX, 7, cpu_suspend_handle, 0);
|
|
request_irq(IRQ_SOFT1_IDX, 7, cpu_suspend_handle, 1);
|
|
irq_unmask_set(IRQ_SOFT0_IDX, 0, 0); //设置CPU0软中断0为不可屏蔽中断
|
|
irq_unmask_set(IRQ_SOFT1_IDX, 0, 1); //设置CPU1软中断1为不可屏蔽中断
|
|
|
|
debug_init();
|
|
}
|
|
|
|
void cpu1_main()
|
|
{
|
|
extern void cpu1_run_notify(void);
|
|
cpu1_run_notify();
|
|
|
|
interrupt_init();
|
|
|
|
q32DSP(core_num())->PMU_CON1 &= ~BIT(8); //分支预测
|
|
cpu1_setup_arch();
|
|
|
|
os_start();
|
|
|
|
log_e("os err \r\n") ;
|
|
while (1) {
|
|
__asm__ volatile("idle");
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
void cpu1_main()
|
|
{
|
|
|
|
}
|
|
#endif /* #if (CPU_CORE_NUM > 1) */
|
|
|
|
//==================================================//
|
|
|
|
/* extern void gpio_longpress_pin0_reset_config(u32 pin, u32 level, u32 time); */
|
|
void memory_init(void);
|
|
|
|
__attribute__((weak))
|
|
void app_main()
|
|
{
|
|
while (1) {
|
|
asm("idle");
|
|
}
|
|
}
|
|
|
|
#define IIO_DEBUG_TOGGLE(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT ^= BIT(x);}
|
|
|
|
void io_toggle(void)
|
|
{
|
|
while (1) {
|
|
IIO_DEBUG_TOGGLE(A, 6);
|
|
IIO_DEBUG_TOGGLE(A, 6);
|
|
}
|
|
}
|
|
|
|
// 读取示例
|
|
int get_clk_trim_val(void)
|
|
{
|
|
int ret = 0;
|
|
u32 trim_val = 0;
|
|
|
|
ret = sdfile_early_init();
|
|
if (ret) {
|
|
printf("sdfile_early_init ret %d\n", ret);
|
|
}
|
|
|
|
ret = syscfg_tools_early_init();
|
|
if (ret) {
|
|
printf("syscfg_tools_early_init ret %d\n", ret);
|
|
}
|
|
|
|
// ID号必需满足 CFG_STORE_VM_ONLY_BEGIN < id < CFG_STORE_VM_ONLY_END
|
|
ret = syscfg_early_read(53, &trim_val, sizeof(trim_val));
|
|
printf("trim read ret %d, val 0x%x\n", ret, trim_val);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// 读取示例
|
|
int set_clk_trim_val(u32 trim_val)
|
|
{
|
|
// !!! 必须要注意, trim值只能写一次, 即只有读取trim失败, 重新trim完后再写到vm; 如果是读取trim值成功了,则不能再次trim并写vm(需要擦除vm后才可再次写)
|
|
// ID号必需满足 CFG_STORE_VM_ONLY_BEGIN < id < CFG_STORE_VM_ONLY_END
|
|
int ret = syscfg_write(53, &trim_val, sizeof(trim_val));
|
|
printf("clk trim val set ret %d\n", ret);
|
|
return 0;
|
|
}
|
|
|
|
|
|
void setup_arch(void)
|
|
{
|
|
boot_power_init();
|
|
|
|
//system_start();
|
|
|
|
//关闭所有timer的ie使能
|
|
bit_clr_ie(IRQ_TIME0_IDX);
|
|
bit_clr_ie(IRQ_TIME1_IDX);
|
|
bit_clr_ie(IRQ_TIME2_IDX);
|
|
bit_clr_ie(IRQ_TIME3_IDX);
|
|
|
|
/* gpio_longpress_pin0_reset_config(IO_PORTB_01, 0, 0); */
|
|
|
|
memory_init();
|
|
|
|
#if CONFIG_DEBUG_ENABLE || CONFIG_DEBUG_LITE_ENABLE
|
|
debug_uart_init();
|
|
#if CONFIG_DEBUG_ENABLE
|
|
log_early_init(1024 * 2);
|
|
#endif
|
|
#endif
|
|
|
|
wdt_init(WDT_APP_INIT_TIME);
|
|
/* wdt_close(); */
|
|
q32DSP(core_num())->PMU_CON1 &= ~BIT(8); //分支预测
|
|
|
|
efuse_init();
|
|
/* clk_voltage_init(TCFG_CLOCK_MODE, SYSVDD_VOL_SEL_126V); */
|
|
/* xosc_hcs_trim(); */
|
|
|
|
debug_init();
|
|
|
|
sdfile_init();
|
|
syscfg_tools_init();
|
|
|
|
/* clk_early_init(PLL_REF_XOSC_DIFF, TCFG_CLOCK_OSC_HZ, 480 * MHz); */
|
|
clk_early_init(PLL_REF_XOSC_DIFF, TCFG_CLOCK_OSC_HZ, 576 * MHz);
|
|
|
|
#if 0
|
|
//临时添加:by IC wangjie
|
|
SFR(JL_LSBCLK->PRP_CON1, 0, 3, 1);
|
|
SFR(JL_LSBCLK->PRP_CON1, 26, 1, 1);
|
|
// bt clk config by IC luokaijie
|
|
SFR(JL_LSBCLK->PRP_CON2, 0, 2, 1);
|
|
SFR(JL_LSBCLK->PRP_CON2, 2, 2, 1);
|
|
SFR(JL_LSBCLK->PRP_CON2, 4, 2, 1);
|
|
SFR(JL_LSBCLK->PRP_CON2, 8, 1, 1);
|
|
asm("csync");
|
|
#endif
|
|
|
|
perf_counter_init();
|
|
|
|
os_init();
|
|
tick_timer_init();
|
|
sys_timer_init();
|
|
|
|
log_i("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
log_i(" setup_arch %s %s", __DATE__, __TIME__);
|
|
log_i("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
power_early_flowing();
|
|
|
|
clock_dump();
|
|
#if 0
|
|
|
|
|
|
void mvbg_current_trim(); //pmu used
|
|
mvbg_current_trim();
|
|
void audio_vbg_current_trim(); //audio used
|
|
audio_vbg_current_trim();
|
|
#endif
|
|
|
|
//Register debugger interrupt
|
|
request_irq(0, 2, exception_irq_handler, 0);
|
|
request_irq(1, 2, exception_irq_handler, 0);
|
|
|
|
#ifdef CONFIG_CODE_MOVABLE_ENABLE
|
|
code_movable_init();
|
|
#endif
|
|
|
|
__crc16_mutex_init();
|
|
|
|
|
|
app_main();
|
|
}
|
|
|