399 lines
9.1 KiB
C
399 lines
9.1 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
||
|
|
||
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
||
|
be copied by any method or incorporated into another program without
|
||
|
the express written consent of Aerospace C.Power. This Information or any portion
|
||
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
||
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
||
|
liability for its use in any way and conveys no license or title under
|
||
|
any patent or copyright and makes no representation or warranty that this
|
||
|
Information is free from patent or copyright infringement.
|
||
|
|
||
|
****************************************************************************/
|
||
|
/* os shim includes */
|
||
|
#include "os_types.h"
|
||
|
#include "os_task.h"
|
||
|
#include "os_utils.h"
|
||
|
|
||
|
/* common includes */
|
||
|
#include "iot_io.h"
|
||
|
#include "iot_bitops.h"
|
||
|
#include "iot_config.h"
|
||
|
|
||
|
/* driver includes */
|
||
|
#include "iot_clock.h"
|
||
|
#include "iot_uart.h"
|
||
|
|
||
|
#include "iot_system.h"
|
||
|
|
||
|
/* cli includes */
|
||
|
#include "iot_uart_h.h"
|
||
|
|
||
|
/* debug includes*/
|
||
|
#include "dbg_io.h"
|
||
|
|
||
|
#include "platform.h"
|
||
|
|
||
|
#include "apb_dma.h"
|
||
|
#include "cpu.h"
|
||
|
#include "encoding.h"
|
||
|
#include "hw_reg_api.h"
|
||
|
#include "ahb_rf.h"
|
||
|
#include "ahb.h"
|
||
|
#include "trace.h"
|
||
|
#include "dtest_printf.h"
|
||
|
#include "iot_errno_api.h"
|
||
|
#include "ahb.h"
|
||
|
#include "rtc.h"
|
||
|
|
||
|
os_task_h exception_test_handle;
|
||
|
/* the mcause code will be test */
|
||
|
volatile uintptr_t g_mcause_set = 0;
|
||
|
/* the mcause code get from exception handler */
|
||
|
volatile uintptr_t g_mcause_get = 0;
|
||
|
/* set 1 if exception occer */
|
||
|
volatile int exception_occer = 0;
|
||
|
uint32_t mcause_test_bit_map = 0xFE;
|
||
|
|
||
|
extern void kl3_trap_entry();
|
||
|
extern int platform_init();
|
||
|
extern void intc_handler(uint32_t cpu);
|
||
|
extern uintptr_t kl3_handle_trap(uintptr_t mcause, uintptr_t epc, saved_registers *reg);
|
||
|
extern int uart_e_getc(int port);
|
||
|
|
||
|
|
||
|
void kl3_exception_handler(uintptr_t mcause)
|
||
|
{
|
||
|
uint32_t mbadaddr = 0;
|
||
|
|
||
|
//disble global interrupt;
|
||
|
__asm volatile ( "csrc mstatus,8" );
|
||
|
__asm volatile ( "csrr %0, mbadaddr" : "=r"(mbadaddr));
|
||
|
|
||
|
switch(mcause) {
|
||
|
case 0x0:
|
||
|
dprintf("mcause: 0x%02x[Instruction address misaligned]\n",
|
||
|
mcause);
|
||
|
break;
|
||
|
case 0x1:
|
||
|
dprintf("mcause: 0x%02x[Instruction access fault]\n",
|
||
|
mcause);
|
||
|
break;
|
||
|
case 0x2:
|
||
|
dprintf("mcause: 0x%02x[Illegal instruction]\n", mcause);
|
||
|
break;
|
||
|
case 0x3:
|
||
|
dprintf("mcause: 0x%02x[Breakpoint]\n", mcause);
|
||
|
break;
|
||
|
case 0x4:
|
||
|
dprintf("mcause: 0x%02x[Load address misaligned]\n",
|
||
|
mcause);
|
||
|
break;
|
||
|
case 0x5:
|
||
|
dprintf("mcause: 0x%02x[Load access fault]\n", mcause);
|
||
|
break;
|
||
|
case 0x6:
|
||
|
dprintf("mcause: 0x%02x[Store address misaligned]\n",
|
||
|
mcause);
|
||
|
break;
|
||
|
case 0x7:
|
||
|
dprintf("mcase: 0x%02x[Store access fault]\n", mcause);
|
||
|
break;
|
||
|
default:
|
||
|
dprintf("mcause: 0x%02x\n", mcause);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uintptr_t kl3_handle_trap(uintptr_t mcause,
|
||
|
uintptr_t epc, saved_registers *reg)
|
||
|
{
|
||
|
if ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT) {
|
||
|
intc_handler(cpu_get_mhartid());
|
||
|
} else {
|
||
|
//extern void exception_reg_dump(saved_registers *regs);
|
||
|
//exception_reg_dump(reg);
|
||
|
exception_occer = 1;
|
||
|
g_mcause_get = mcause;
|
||
|
void exception_test_loop(void);
|
||
|
void (*pgm_start)(void) = (void*) exception_test_loop;
|
||
|
pgm_start();
|
||
|
}
|
||
|
|
||
|
return epc;
|
||
|
}
|
||
|
|
||
|
void div_zero()
|
||
|
{
|
||
|
uint32_t a = 0;
|
||
|
uint32_t b = 1;
|
||
|
uint32_t c = 0;
|
||
|
|
||
|
c = b/a;
|
||
|
dprintf("div zero : c=%d\r\n", c);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause: 0x00[Instruction address misaligned]
|
||
|
*/
|
||
|
void instruction_address_misaligned(void)
|
||
|
{
|
||
|
void (*pgm_start)(void) = (void*) 0x1002ffd1;
|
||
|
pgm_start();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause: 0x01[Instruction access fault]
|
||
|
*/
|
||
|
void instruction_access_fault(void)
|
||
|
{
|
||
|
void (*pgm_start)(void) = (void*) 0x1002ffd0;
|
||
|
pgm_start();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause: 0x02[Illegal instruction]非法指令
|
||
|
*/
|
||
|
void illegal_instruction(void)
|
||
|
{
|
||
|
asm volatile("csrw sscratch, 0");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause: 0x03[Breakpoint]
|
||
|
*/
|
||
|
void break_point_fault(void)
|
||
|
{
|
||
|
uint32_t *p = (uint32_t *)0x00000000;
|
||
|
dprintf("*p = %d\n",*p);
|
||
|
}
|
||
|
/*
|
||
|
* 条件断点测试,产生0x03[Breakpoint],注意测试的变量尽量为全局的
|
||
|
*/
|
||
|
uint32_t test;
|
||
|
int trace_test_run(void)
|
||
|
{
|
||
|
|
||
|
//int ret = iot_trigger_watch_val_range((void *)&test, 1234,IOT_TRACE_MATCH_LESS);
|
||
|
int ret = iot_trigger_watch_detect((void *)&test);
|
||
|
if (ret != ERR_OK)
|
||
|
return 0;
|
||
|
|
||
|
test = 1233;
|
||
|
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause: 4,load address misaligned
|
||
|
*/
|
||
|
void load_instruction_address_misaligned(void)
|
||
|
{
|
||
|
uint32_t *p = (uint32_t*) 0x1002ffd1;
|
||
|
dprintf("align test p: %08x\r\n", *(p));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause: 5, load address fault
|
||
|
*/
|
||
|
void load_instruction_access_fault (void)
|
||
|
{
|
||
|
uint32_t *p = (uint32_t *) 0xffffff40;
|
||
|
dprintf("align test p: %08x\r\n", *(p));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause: 6,store address misaligned
|
||
|
*/
|
||
|
void store_instruction_addr_misaligned(void)
|
||
|
{
|
||
|
uint32_t *p = (uint32_t *)0x1002ffd1;
|
||
|
*p = 0xaabbccdd;
|
||
|
dprintf("align test p: %08x\r\n", *(p));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mcause:7,store address fault
|
||
|
*/
|
||
|
void store_instruction_addr_fault(void)
|
||
|
{
|
||
|
uint32_t *p = (uint32_t *)0xffffff40;
|
||
|
*p = 0xaabbccdd;
|
||
|
dprintf("align test p: %08x\r\n", *(p));
|
||
|
}
|
||
|
void exception_test(uintptr_t mcause)
|
||
|
{
|
||
|
switch(mcause) {
|
||
|
case 0x0:
|
||
|
dprintf("Test [Instruction address misaligned]\n");
|
||
|
break;
|
||
|
case 0x1:
|
||
|
dprintf("Test [invalid_instruction_access]\n");
|
||
|
instruction_access_fault();
|
||
|
break;
|
||
|
case 0x2:
|
||
|
dprintf("Test [instruction_illegal]\n");
|
||
|
illegal_instruction();
|
||
|
break;
|
||
|
case 0x3:
|
||
|
dprintf("Test [breakpoint fault]\n");
|
||
|
trace_test_run();
|
||
|
//break_point_fault();
|
||
|
break;
|
||
|
case 0x4:
|
||
|
dprintf("Test [misalign_access]\n");
|
||
|
load_instruction_address_misaligned();
|
||
|
break;
|
||
|
case 0x5:
|
||
|
dprintf("Test [Load access fault]\n");
|
||
|
load_instruction_access_fault();
|
||
|
break;
|
||
|
case 0x6:
|
||
|
dprintf("Test [addr_invalid]\n");
|
||
|
store_instruction_addr_misaligned();
|
||
|
break;
|
||
|
case 0x7:
|
||
|
dprintf("Test [Store access fault]\n");
|
||
|
store_instruction_addr_fault();
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void exception_test_loop()
|
||
|
{
|
||
|
/* if exception occer, need check exception code get is same as set */
|
||
|
if (exception_occer) {
|
||
|
exception_occer = 0;
|
||
|
kl3_exception_handler(g_mcause_get);
|
||
|
if (g_mcause_get == g_mcause_set) {
|
||
|
dcase_success();
|
||
|
} else {
|
||
|
dcase_failed();
|
||
|
}
|
||
|
/* test next exception code */
|
||
|
g_mcause_set++;
|
||
|
}
|
||
|
|
||
|
for (;;) {
|
||
|
if ((mcause_test_bit_map & (1 << g_mcause_set)) != 0) {
|
||
|
exception_test(g_mcause_set);
|
||
|
/* when exception occer, it will not run here */
|
||
|
dprintf("%d - mcause[0x%02x] test failed\n", __LINE__,g_mcause_set);
|
||
|
dcase_failed();
|
||
|
} else if (0 == mcause_test_bit_map >> g_mcause_set) {
|
||
|
dend();
|
||
|
for (;;) {
|
||
|
os_delay(1000);
|
||
|
}
|
||
|
}
|
||
|
g_mcause_set++;
|
||
|
os_delay(100);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void exception_test_task(void *arg)
|
||
|
{
|
||
|
dprintf("exception test task entry...\n");
|
||
|
|
||
|
/* init common modules */
|
||
|
iot_bitops_init();
|
||
|
|
||
|
/* init os related modules and utilities */
|
||
|
os_utils_init();
|
||
|
|
||
|
/*init uart module*/
|
||
|
iot_uart_init(1);
|
||
|
|
||
|
dconfig();
|
||
|
dstart();
|
||
|
dversion();
|
||
|
ahb_d_exp_enable();
|
||
|
exception_test_loop();
|
||
|
}
|
||
|
|
||
|
static int32_t iot_task_init(void)
|
||
|
{
|
||
|
div_zero();
|
||
|
/* create exception test task */
|
||
|
exception_test_handle = os_create_task(exception_test_task, NULL, 9);
|
||
|
|
||
|
if (exception_test_handle != NULL) {
|
||
|
dprintf("create exception test task successfully...\n");
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int32_t iot_task_start()
|
||
|
{
|
||
|
//start the tasks;
|
||
|
os_start_kernel();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void cache_init()
|
||
|
{
|
||
|
cache_enable(AHB_CACHE_D0);
|
||
|
cache_set_buffer_mode(AHB_CACHE_D0, 1);
|
||
|
cache_enable(AHB_CACHE_D1);
|
||
|
cache_set_buffer_mode(AHB_CACHE_D1, 1);
|
||
|
}
|
||
|
|
||
|
static int32_t iot_platform_init()
|
||
|
{
|
||
|
cache_init();
|
||
|
/*platform intialization*/
|
||
|
platform_init();
|
||
|
|
||
|
/*install trap entry*/
|
||
|
write_csr(mtvec, &kl3_trap_entry);
|
||
|
|
||
|
//resource initializations;
|
||
|
system_clock_init();
|
||
|
|
||
|
system_uart_init();
|
||
|
|
||
|
dbg_uart_init();
|
||
|
|
||
|
dbg_uart_stage1_init();
|
||
|
|
||
|
/* rtc init, idle used rtc lock */
|
||
|
iot_rtc_init();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32_t iot_module_init(void)
|
||
|
{
|
||
|
/* platform intialization; */
|
||
|
iot_platform_init();
|
||
|
|
||
|
/* create all the tasks; */
|
||
|
iot_task_init();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32_t iot_module_start(void)
|
||
|
{
|
||
|
int32_t res = 0;
|
||
|
|
||
|
res = iot_task_start();
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
iot_module_init();
|
||
|
iot_module_start();
|
||
|
|
||
|
return 0;
|
||
|
}
|