Files
kunlun/dtest/dtest3/kl3_exception_test/kl3_exception_test.c
2024-09-28 14:24:04 +08:00

399 lines
9.1 KiB
C
Executable File

/****************************************************************************
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;
}