初始提交
This commit is contained in:
38
startup/riscv/Makefile
Normal file
38
startup/riscv/Makefile
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
# OUTPUT type
|
||||
# 1 - .out
|
||||
# 2 - .a
|
||||
# 3 - .so
|
||||
OUTPUT_TYPE = 2
|
||||
OUTPUT_NAME = riscv
|
||||
|
||||
SUB_DIRS = src
|
||||
# .h files dir
|
||||
ADD_INCLUDE += inc
|
||||
|
||||
# predefined macro
|
||||
PRE_MARCO += __riscv_float_abi_soft
|
||||
|
||||
# lib dir
|
||||
ADD_LIBDIR =
|
||||
|
||||
# lib need to ld together
|
||||
ADD_LIB =
|
||||
|
||||
ifdef TOPDIR
|
||||
include $(TOPDIR)/build/makefile.cfg
|
||||
else
|
||||
include $(CURDIR)/build/makefile.cfg
|
||||
TOPDIR = $(CURDIR)
|
||||
export TOPDIR
|
||||
endif
|
||||
|
||||
# display the obj files and output name
|
||||
debug:
|
||||
@echo TOPDIR=$(TOPDIR)
|
||||
@echo OUTPUT_LIB=$(OUTPUT_FULL_NAME)
|
||||
@echo DEPS=$(DEPS)
|
||||
@echo OBJECTS=$(OBJECTS)
|
||||
@echo SRCS=$(SRCS)
|
||||
@echo OBJECTS folder=$(foreach dirname, $(SUB_DIRS), $(addprefix $(BIN_DIR)/, $(dirname)))
|
||||
@echo output_name=$(OUTPUT_FULL_NAME)
|
44
startup/riscv/inc/bits.h
Normal file
44
startup/riscv/inc/bits.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef _RISCV_BITS_H
|
||||
#define _RISCV_BITS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define likely(x) __builtin_expect((x), 1)
|
||||
#define unlikely(x) __builtin_expect((x), 0)
|
||||
|
||||
#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
|
||||
#define ROUNDDOWN(a, b) ((a)/(b)*(b))
|
||||
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
|
||||
|
||||
#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
|
||||
#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
|
||||
|
||||
#define STR(x) XSTR(x)
|
||||
#define XSTR(x) #x
|
||||
|
||||
#ifdef __riscv64
|
||||
# define SLL32 sllw
|
||||
# define STORE sd
|
||||
# define LOAD ld
|
||||
# define LWU lwu
|
||||
# define LOG_REGBYTES 3
|
||||
#else
|
||||
# define SLL32 sll
|
||||
# define STORE sw
|
||||
# define LOAD lw
|
||||
# define LWU lw
|
||||
# define LOG_REGBYTES 2
|
||||
#endif
|
||||
#define REGBYTES (1 << LOG_REGBYTES)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
1335
startup/riscv/inc/encoding.h
Normal file
1335
startup/riscv/inc/encoding.h
Normal file
File diff suppressed because it is too large
Load Diff
35
startup/riscv/inc/platform.h
Normal file
35
startup/riscv/inc/platform.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/****************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _PLATFORM_H
|
||||
#define _PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Some things missing from the official encoding.h
|
||||
#define MCAUSE_INT 0x80000000
|
||||
#define MCAUSE_CAUSE 0x7FFFFFFF
|
||||
|
||||
int platform_init();
|
||||
|
||||
uint32_t interrupt_get_err_trigger(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PLATFORM_H */
|
25
startup/riscv/inc/sections.h
Normal file
25
startup/riscv/inc/sections.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _SECTIONS_H
|
||||
#define _SECTIONS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern unsigned char _rom[];
|
||||
extern unsigned char _rom_end[];
|
||||
|
||||
extern unsigned char _ram[];
|
||||
extern unsigned char _ram_end[];
|
||||
|
||||
extern unsigned char _ftext[];
|
||||
extern unsigned char _etext[];
|
||||
extern unsigned char _fbss[];
|
||||
extern unsigned char _ebss[];
|
||||
extern unsigned char _end[];
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SECTIONS_H */
|
200
startup/riscv/src/entry.S
Normal file
200
startup/riscv/src/entry.S
Normal file
@@ -0,0 +1,200 @@
|
||||
// See LICENSE for license details
|
||||
|
||||
#ifndef ENTRY_S
|
||||
#define ENTRY_S
|
||||
|
||||
#include "encoding.h"
|
||||
#include "bits.h"
|
||||
|
||||
.section .iram
|
||||
|
||||
#define MSTATUS_PRV1 0x1800
|
||||
|
||||
/* When trap is an interrupt, this function is called */
|
||||
interrupt:
|
||||
.global pxCurrentTCB
|
||||
/* make room in stack */
|
||||
addi sp, sp, -REGBYTES * 32
|
||||
/* Save Context */
|
||||
STORE x1, 0x0(sp)
|
||||
STORE x2, 1 * REGBYTES(sp)
|
||||
STORE x3, 2 * REGBYTES(sp)
|
||||
STORE x4, 3 * REGBYTES(sp)
|
||||
STORE x6, 5 * REGBYTES(sp)
|
||||
STORE x7, 6 * REGBYTES(sp)
|
||||
STORE x8, 30 * REGBYTES(sp)
|
||||
STORE x9, 8 * REGBYTES(sp)
|
||||
STORE x10, 9 * REGBYTES(sp)
|
||||
STORE x11, 10 * REGBYTES(sp)
|
||||
STORE x12, 11 * REGBYTES(sp)
|
||||
STORE x13, 12 * REGBYTES(sp)
|
||||
STORE x14, 13 * REGBYTES(sp)
|
||||
STORE x15, 14 * REGBYTES(sp)
|
||||
STORE x16, 15 * REGBYTES(sp)
|
||||
STORE x17, 16 * REGBYTES(sp)
|
||||
STORE x18, 17 * REGBYTES(sp)
|
||||
STORE x19, 18 * REGBYTES(sp)
|
||||
STORE x20, 19 * REGBYTES(sp)
|
||||
STORE x21, 20 * REGBYTES(sp)
|
||||
STORE x22, 21 * REGBYTES(sp)
|
||||
STORE x23, 22 * REGBYTES(sp)
|
||||
STORE x24, 23 * REGBYTES(sp)
|
||||
STORE x25, 24 * REGBYTES(sp)
|
||||
STORE x26, 25 * REGBYTES(sp)
|
||||
STORE x27, 26 * REGBYTES(sp)
|
||||
STORE x28, 27 * REGBYTES(sp)
|
||||
STORE x29, 28 * REGBYTES(sp)
|
||||
STORE x30, 29 * REGBYTES(sp)
|
||||
STORE x31, 7 * REGBYTES(sp)
|
||||
csrr x5, mscratch
|
||||
STORE x5, 4 * REGBYTES(sp)
|
||||
/* Store current stackpointer in task control block (TCB) */
|
||||
LOAD t0, pxCurrentTCB //pointer
|
||||
STORE sp, 0x0(t0)
|
||||
/* Saves current error program counter (EPC) as task program counter */
|
||||
csrr t0, mepc
|
||||
STORE t0, 31 * REGBYTES(sp)
|
||||
/* Interrupt handling*/
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, sp
|
||||
call handle_interrupt
|
||||
NOP
|
||||
/* Load stack pointer from the current TCB */
|
||||
LOAD sp, pxCurrentTCB
|
||||
LOAD sp, 0x0(sp)
|
||||
/* Load task program counter */
|
||||
LOAD t0, 31 * REGBYTES(sp)
|
||||
csrw mepc, t0
|
||||
/* Run in machine mode */
|
||||
li t0, MSTATUS_PRV1
|
||||
csrs mstatus, t0
|
||||
/* Restore registers, Skip global pointer because that does not change */
|
||||
LOAD x1, 0x0(sp)
|
||||
LOAD x4, 3 * REGBYTES(sp)
|
||||
LOAD x5, 4 * REGBYTES(sp)
|
||||
LOAD x6, 5 * REGBYTES(sp)
|
||||
LOAD x7, 6 * REGBYTES(sp)
|
||||
LOAD x8, 30 * REGBYTES(sp)
|
||||
LOAD x9, 8 * REGBYTES(sp)
|
||||
LOAD x10, 9 * REGBYTES(sp)
|
||||
LOAD x11, 10 * REGBYTES(sp)
|
||||
LOAD x12, 11 * REGBYTES(sp)
|
||||
LOAD x13, 12 * REGBYTES(sp)
|
||||
LOAD x14, 13 * REGBYTES(sp)
|
||||
LOAD x15, 14 * REGBYTES(sp)
|
||||
LOAD x16, 15 * REGBYTES(sp)
|
||||
LOAD x17, 16 * REGBYTES(sp)
|
||||
LOAD x18, 17 * REGBYTES(sp)
|
||||
LOAD x19, 18 * REGBYTES(sp)
|
||||
LOAD x20, 19 * REGBYTES(sp)
|
||||
LOAD x21, 20 * REGBYTES(sp)
|
||||
LOAD x22, 21 * REGBYTES(sp)
|
||||
LOAD x23, 22 * REGBYTES(sp)
|
||||
LOAD x24, 23 * REGBYTES(sp)
|
||||
LOAD x25, 24 * REGBYTES(sp)
|
||||
LOAD x26, 25 * REGBYTES(sp)
|
||||
LOAD x27, 26 * REGBYTES(sp)
|
||||
LOAD x28, 27 * REGBYTES(sp)
|
||||
LOAD x29, 28 * REGBYTES(sp)
|
||||
LOAD x30, 29 * REGBYTES(sp)
|
||||
LOAD x31, 7 * REGBYTES(sp)
|
||||
|
||||
addi sp, sp, REGBYTES * 32
|
||||
mret
|
||||
|
||||
.section .iram.entry
|
||||
.align 4
|
||||
.global trap_entry
|
||||
|
||||
trap_entry:
|
||||
/* Interrupt trap */
|
||||
csrw mscratch, t0
|
||||
csrr t0, mcause
|
||||
blt t0, x0, interrupt
|
||||
|
||||
/* System call and other traps */
|
||||
csrrw t0, mscratch, sp
|
||||
la sp, _trap_sp
|
||||
addi sp, sp, -REGBYTES*32
|
||||
STORE x1, 0*REGBYTES(sp)
|
||||
STORE x2, 1*REGBYTES(sp)
|
||||
STORE x3, 2*REGBYTES(sp)
|
||||
STORE x4, 3*REGBYTES(sp)
|
||||
STORE x5, 4*REGBYTES(sp)
|
||||
STORE x6, 5*REGBYTES(sp)
|
||||
STORE x7, 6*REGBYTES(sp)
|
||||
STORE x8, 30*REGBYTES(sp)
|
||||
STORE x9, 8*REGBYTES(sp)
|
||||
STORE x10, 9*REGBYTES(sp)
|
||||
STORE x11, 10*REGBYTES(sp)
|
||||
STORE x12, 11*REGBYTES(sp)
|
||||
STORE x13, 12*REGBYTES(sp)
|
||||
STORE x14, 13*REGBYTES(sp)
|
||||
STORE x15, 14*REGBYTES(sp)
|
||||
STORE x16, 15*REGBYTES(sp)
|
||||
STORE x17, 16*REGBYTES(sp)
|
||||
STORE x18, 17*REGBYTES(sp)
|
||||
STORE x19, 18*REGBYTES(sp)
|
||||
STORE x20, 19*REGBYTES(sp)
|
||||
STORE x21, 20*REGBYTES(sp)
|
||||
STORE x22, 21*REGBYTES(sp)
|
||||
STORE x23, 22*REGBYTES(sp)
|
||||
STORE x24, 23*REGBYTES(sp)
|
||||
STORE x25, 24*REGBYTES(sp)
|
||||
STORE x26, 25*REGBYTES(sp)
|
||||
STORE x27, 26*REGBYTES(sp)
|
||||
STORE x28, 27*REGBYTES(sp)
|
||||
STORE x29, 28*REGBYTES(sp)
|
||||
STORE x30, 29*REGBYTES(sp)
|
||||
STORE x31, 7*REGBYTES(sp)
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, sp
|
||||
STORE a1, 31*REGBYTES(sp)
|
||||
call handle_trap
|
||||
csrw mepc, a0
|
||||
# Remain in M-mode after mret
|
||||
li t0, MSTATUS_MPP
|
||||
csrs mstatus, t0
|
||||
LOAD x1, 0*REGBYTES(sp)
|
||||
LOAD x2, 1*REGBYTES(sp)
|
||||
LOAD x3, 2*REGBYTES(sp)
|
||||
LOAD x4, 3*REGBYTES(sp)
|
||||
LOAD x5, 4*REGBYTES(sp)
|
||||
LOAD x6, 5*REGBYTES(sp)
|
||||
LOAD x7, 6*REGBYTES(sp)
|
||||
LOAD x8, 30*REGBYTES(sp)
|
||||
LOAD x9, 8*REGBYTES(sp)
|
||||
LOAD x10, 9*REGBYTES(sp)
|
||||
LOAD x11, 10*REGBYTES(sp)
|
||||
LOAD x12, 11*REGBYTES(sp)
|
||||
LOAD x13, 12*REGBYTES(sp)
|
||||
LOAD x14, 13*REGBYTES(sp)
|
||||
LOAD x15, 14*REGBYTES(sp)
|
||||
LOAD x16, 15*REGBYTES(sp)
|
||||
LOAD x17, 16*REGBYTES(sp)
|
||||
LOAD x18, 17*REGBYTES(sp)
|
||||
LOAD x19, 18*REGBYTES(sp)
|
||||
LOAD x20, 19*REGBYTES(sp)
|
||||
LOAD x21, 20*REGBYTES(sp)
|
||||
LOAD x22, 21*REGBYTES(sp)
|
||||
LOAD x23, 22*REGBYTES(sp)
|
||||
LOAD x24, 23*REGBYTES(sp)
|
||||
LOAD x25, 24*REGBYTES(sp)
|
||||
LOAD x26, 25*REGBYTES(sp)
|
||||
LOAD x27, 26*REGBYTES(sp)
|
||||
LOAD x28, 27*REGBYTES(sp)
|
||||
LOAD x29, 28*REGBYTES(sp)
|
||||
LOAD x30, 29*REGBYTES(sp)
|
||||
LOAD x31, 7*REGBYTES(sp)
|
||||
|
||||
addi sp, sp, REGBYTES*31
|
||||
csrr sp, mscratch
|
||||
mret
|
||||
|
||||
.weak handle_trap
|
||||
handle_trap:
|
||||
1:
|
||||
j 1b
|
||||
#endif
|
97
startup/riscv/src/entry_def.S
Normal file
97
startup/riscv/src/entry_def.S
Normal file
@@ -0,0 +1,97 @@
|
||||
// See LICENSE for license details
|
||||
|
||||
#ifndef DEF_ENTRY_S
|
||||
#define DEF_ENTRY_S
|
||||
|
||||
#include "encoding.h"
|
||||
#include "bits.h"
|
||||
|
||||
.section .text.entry
|
||||
.align 4
|
||||
.global def_trap_entry
|
||||
|
||||
def_trap_entry:
|
||||
addi sp, sp, -32*REGBYTES
|
||||
STORE x1, 1*REGBYTES(sp)
|
||||
STORE x2, 2*REGBYTES(sp)
|
||||
STORE x3, 3*REGBYTES(sp)
|
||||
STORE x4, 4*REGBYTES(sp)
|
||||
STORE x5, 5*REGBYTES(sp)
|
||||
STORE x6, 6*REGBYTES(sp)
|
||||
STORE x7, 7*REGBYTES(sp)
|
||||
STORE x8, 30*REGBYTES(sp)
|
||||
STORE x9, 9*REGBYTES(sp)
|
||||
STORE x10, 10*REGBYTES(sp)
|
||||
STORE x11, 11*REGBYTES(sp)
|
||||
STORE x12, 12*REGBYTES(sp)
|
||||
STORE x13, 13*REGBYTES(sp)
|
||||
STORE x14, 14*REGBYTES(sp)
|
||||
STORE x15, 15*REGBYTES(sp)
|
||||
STORE x16, 16*REGBYTES(sp)
|
||||
STORE x17, 17*REGBYTES(sp)
|
||||
STORE x18, 18*REGBYTES(sp)
|
||||
STORE x19, 19*REGBYTES(sp)
|
||||
STORE x20, 20*REGBYTES(sp)
|
||||
STORE x21, 21*REGBYTES(sp)
|
||||
STORE x22, 22*REGBYTES(sp)
|
||||
STORE x23, 23*REGBYTES(sp)
|
||||
STORE x24, 24*REGBYTES(sp)
|
||||
STORE x25, 25*REGBYTES(sp)
|
||||
STORE x26, 26*REGBYTES(sp)
|
||||
STORE x27, 27*REGBYTES(sp)
|
||||
STORE x28, 28*REGBYTES(sp)
|
||||
STORE x29, 29*REGBYTES(sp)
|
||||
STORE x30, 8*REGBYTES(sp)
|
||||
STORE x31, 0x0(sp)
|
||||
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, sp
|
||||
STORE a1, 31*REGBYTES(sp)
|
||||
call handle_trap
|
||||
csrw mepc, a0
|
||||
|
||||
# Remain in M-mode after mret
|
||||
li t0, MSTATUS_MPP
|
||||
csrs mstatus, t0
|
||||
|
||||
LOAD x1, 1*REGBYTES(sp)
|
||||
LOAD x2, 2*REGBYTES(sp)
|
||||
LOAD x3, 3*REGBYTES(sp)
|
||||
LOAD x4, 4*REGBYTES(sp)
|
||||
LOAD x5, 5*REGBYTES(sp)
|
||||
LOAD x6, 6*REGBYTES(sp)
|
||||
LOAD x7, 7*REGBYTES(sp)
|
||||
LOAD x8, 30*REGBYTES(sp)
|
||||
LOAD x9, 9*REGBYTES(sp)
|
||||
LOAD x10, 10*REGBYTES(sp)
|
||||
LOAD x11, 11*REGBYTES(sp)
|
||||
LOAD x12, 12*REGBYTES(sp)
|
||||
LOAD x13, 13*REGBYTES(sp)
|
||||
LOAD x14, 14*REGBYTES(sp)
|
||||
LOAD x15, 15*REGBYTES(sp)
|
||||
LOAD x16, 16*REGBYTES(sp)
|
||||
LOAD x17, 17*REGBYTES(sp)
|
||||
LOAD x18, 18*REGBYTES(sp)
|
||||
LOAD x19, 19*REGBYTES(sp)
|
||||
LOAD x20, 20*REGBYTES(sp)
|
||||
LOAD x21, 21*REGBYTES(sp)
|
||||
LOAD x22, 22*REGBYTES(sp)
|
||||
LOAD x23, 23*REGBYTES(sp)
|
||||
LOAD x24, 24*REGBYTES(sp)
|
||||
LOAD x25, 25*REGBYTES(sp)
|
||||
LOAD x26, 26*REGBYTES(sp)
|
||||
LOAD x27, 27*REGBYTES(sp)
|
||||
LOAD x28, 28*REGBYTES(sp)
|
||||
LOAD x29, 29*REGBYTES(sp)
|
||||
LOAD x30, 8*REGBYTES(sp)
|
||||
LOAD x31, 0x0(sp)
|
||||
addi sp, sp, 32*REGBYTES
|
||||
mret
|
||||
|
||||
.weak handle_trap
|
||||
handle_trap:
|
||||
1:
|
||||
j 1b
|
||||
|
||||
#endif
|
533
startup/riscv/src/exception.c
Normal file
533
startup/riscv/src/exception.c
Normal file
@@ -0,0 +1,533 @@
|
||||
/****************************************************************************
|
||||
|
||||
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 "iot_irq.h"
|
||||
#include "iot_io.h"
|
||||
#include "iot_system.h"
|
||||
#include "dbg_io.h"
|
||||
#include "platform.h"
|
||||
#include "encoding.h"
|
||||
#include "iot_config.h"
|
||||
|
||||
#include "iot_dbglog.h"
|
||||
#include "iot_string.h"
|
||||
#include "iot_cli_type_definition.h"
|
||||
#include "iot_version.h"
|
||||
#include "iot_mtd.h"
|
||||
#include "os_task.h"
|
||||
#include "hw_mem_map.h"
|
||||
|
||||
#define DBGLOG_HEAD_SIZE (MAX_FRAME_CODE_LEN + CLI_MSG_HEADER_LEN \
|
||||
+ DBGLOG_PAYLOAD_OFFSET)
|
||||
|
||||
static char *g_dbglog_buf = (char*)&_heap_end;
|
||||
static char g_dbg_msg[80];
|
||||
uint32_t g_payload_len = 0;
|
||||
|
||||
#define DBG_BUF_CPY(buf, msg, len) { \
|
||||
len = iot_strlen(msg); \
|
||||
g_payload_len += len; \
|
||||
os_mem_cpy(buf, msg, len); \
|
||||
buf += len; \
|
||||
}
|
||||
|
||||
void print_error_msg(const char *err_msg)
|
||||
{
|
||||
while(*err_msg != '\0'){
|
||||
dbg_putchar(*err_msg);
|
||||
++err_msg;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t g_exception_flash_dump = 1;
|
||||
|
||||
void trigger_zero_addr_access_detect()
|
||||
{
|
||||
volatile uint32_t tdata1 = 0;
|
||||
volatile uint32_t tdata2 = 0;
|
||||
|
||||
tdata2 = 0x100;
|
||||
__asm volatile ( "csrw tdata2, %0" : "=r"(tdata2) );
|
||||
|
||||
__asm volatile ( "csrr %0, tdata1" : "=r"(tdata1));
|
||||
tdata1 &= ~(0x3FFFF);
|
||||
tdata1 |= (0x0 << TDATA1_ACTION_OFFSET) | (0x0 << TDATA1_CHAIN_OFFSET) |
|
||||
(0x3 << TDATA1_MATCH_OFFSET) | (0x1 << TDATA1_MMODE_OFFSET) |
|
||||
(0x0 << TDATA1_HMODE_OFFSET) | (0x0 << TDATA1_SMODE_OFFSET) |
|
||||
(0x0 << TDATA1_UMODE_OFFSET) | (0x1 << TDATA1_EXE_OFFSET) |
|
||||
(0x1 << TDATA1_STORE_OFFSET) | (0x1 << TDATA1_LOAD_OFFSET);
|
||||
__asm volatile ( "csrw tdata1, %0" : "=r"(tdata1) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void iot_illegal_instruct(uintptr_t epc)
|
||||
{
|
||||
uint32_t *pc = (uint32_t *) (epc & 0xFFFFFFF0);
|
||||
uint32_t i = 0;
|
||||
uint32_t len = 0;
|
||||
char *tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
for (i = 0; i < 8; i++) {
|
||||
iot_sprintf(g_dbg_msg, "0x%08x, value: 0x%08x\n", pc+i, *(pc+i));
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
}
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t iot_recover_check()
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
//next boot will recover from original part,when the first boot from upgrade
|
||||
extern int32_t g_systick_count; // systick time
|
||||
extern uint32_t g_disable_feed_dog; // ignore software watchdog
|
||||
uint32_t tick_time = g_systick_count; // cost time , unit is ms
|
||||
uint32_t first_boot = dev_get_first_boot_val(); // first boot from upgrade
|
||||
|
||||
if (tick_time < IOT_RECOVER_TIME
|
||||
&& first_boot && (g_disable_feed_dog == 0)) {
|
||||
// switch part
|
||||
ret = 1;
|
||||
dev_switch_part();
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int check_stack_overflow(uint32_t stack_addr)
|
||||
{
|
||||
int addr_group[] = MEM_MAP_GROUP;
|
||||
int mem_num, i;
|
||||
|
||||
mem_num = sizeof(addr_group) / sizeof(addr_group[0]);
|
||||
|
||||
for (i = 0; i < mem_num; i += 2) {
|
||||
if ((stack_addr >= addr_group[i]) && (stack_addr < (
|
||||
addr_group[i] + addr_group[i+1]))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((stack_addr > (uint32_t)&_heap_end) && (stack_addr <= (
|
||||
uint32_t)&_sp)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iot_backtrace(uintptr_t epc, saved_registers *regs)
|
||||
{
|
||||
uint32_t s0 = 0;
|
||||
volatile uint32_t deep_len = 0;
|
||||
uint32_t ret_fun = 0;
|
||||
uint32_t frame_start = 0;
|
||||
char *tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
uint32_t len = 0;
|
||||
uint8_t cnt = 0;
|
||||
|
||||
s0 = regs->fp;
|
||||
g_backtrace_dump.regs[deep_len].ra = epc;
|
||||
g_backtrace_dump.regs[deep_len].s0 = s0;
|
||||
frame_start = s0;
|
||||
g_backtrace_dump.regs[deep_len].stack = frame_start;
|
||||
deep_len++;
|
||||
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
while( s0 <= frame_start && deep_len < BACKTRACE_DUMP_DEEP_LEN) {
|
||||
s0 = frame_start;
|
||||
if (check_stack_overflow(s0)) {
|
||||
break;
|
||||
}
|
||||
uint32_t *tmp = (uint32_t *) (s0 & (~0x3));
|
||||
uint32_t text_s = (uint32_t)&_start;
|
||||
uint32_t text_e = (uint32_t)&_etext;
|
||||
uint32_t iram_s = (uint32_t)&_iram_start;
|
||||
uint32_t iram_e = (uint32_t)&_iram_end;
|
||||
ret_fun = *(tmp-1);
|
||||
if (((ret_fun > text_s) && (ret_fun < text_e)) ||
|
||||
((ret_fun > iram_s) && (ret_fun < iram_e)) ){
|
||||
frame_start = *(tmp-2);
|
||||
} else {
|
||||
frame_start = *(tmp-1);
|
||||
ret_fun = regs->ra;
|
||||
}
|
||||
|
||||
g_backtrace_dump.regs[deep_len].ra = ret_fun;
|
||||
g_backtrace_dump.regs[deep_len].s0 = s0;
|
||||
g_backtrace_dump.regs[deep_len].stack = frame_start;
|
||||
deep_len++;
|
||||
cnt++;
|
||||
iot_sprintf(g_dbg_msg, "func: 0x%08x, s0: 0x%08x, stack: 0x%08x\n",
|
||||
ret_fun, s0, frame_start);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
if (cnt == 3) {
|
||||
cnt = 0;
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID,
|
||||
IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
}
|
||||
}
|
||||
g_backtrace_dump.deep_len = deep_len;
|
||||
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void exception_reg_dump(saved_registers *regs)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t len = 0;
|
||||
char *tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
iot_sprintf(g_dbg_msg, "exception registers dump\n");
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
iot_sprintf(g_dbg_msg, "ra = 0x%08x\n", regs->ra);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
iot_sprintf(g_dbg_msg, "sp = 0x%08x\n", regs->sp);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
iot_sprintf(g_dbg_msg, "gp = 0x%08x\n", regs->gp);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
iot_sprintf(g_dbg_msg, "tp = 0x%08x\n", regs->tp);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
for(i=0; i<3; i++) {
|
||||
iot_sprintf(g_dbg_msg, "t%d = 0x%08x\n", i, regs->t0_2[i]);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
}
|
||||
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
iot_sprintf(g_dbg_msg, "fp = 0x%08x\n", regs->fp);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
iot_sprintf(g_dbg_msg, "s1 = 0x%08x\n", regs->s1);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
for(i=0; i<8; i++) {
|
||||
iot_sprintf(g_dbg_msg, "a%d = 0x%08x\n", i, regs->a0_7[i]);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
}
|
||||
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
for(i=2; i<12; i++) {
|
||||
iot_sprintf(g_dbg_msg, "s%d = 0x%08x\n", i, regs->s2_11[i-2]);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
}
|
||||
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
for(i=3; i<5; i++) {
|
||||
iot_sprintf(g_dbg_msg, "t%d = 0x%08x\n", i, regs->t3_4[i-3]);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
|
||||
}
|
||||
iot_sprintf(g_dbg_msg, "t5 = 0x%08x\n", regs->t5);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
|
||||
iot_sprintf(g_dbg_msg, "t6 = 0x%08x\n", regs->t6);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void assert_failed( unsigned char *pucFile, unsigned long ulLine )
|
||||
{
|
||||
( void ) pucFile;
|
||||
( void ) ulLine;
|
||||
|
||||
//disble global interrupt;
|
||||
__asm volatile ( "csrc mstatus,8" );
|
||||
|
||||
uint32_t ast_ra = 0;
|
||||
__asm volatile ("mv %0, ra" : "=r"(ast_ra));
|
||||
if (pucFile) {
|
||||
iot_sprintf(g_dbg_msg, "%s, line: %d ra:0x%08x Asserted!\n",
|
||||
pucFile, ulLine, ast_ra);
|
||||
} else {
|
||||
iot_sprintf(g_dbg_msg, "NULL, line: %d ra:0x%08x Asserted!\n",
|
||||
ulLine, ast_ra);
|
||||
}
|
||||
print_error_msg(g_dbg_msg);
|
||||
|
||||
// disable iot_printf
|
||||
iot_print_config(false);
|
||||
|
||||
#if IOT_FLASH_BUILD
|
||||
char *tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
uint32_t len = 0;
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* do a breakpoint exception */
|
||||
asm volatile("ebreak");
|
||||
}
|
||||
|
||||
void assert_failed_simple()
|
||||
{
|
||||
//disble global interrupt;
|
||||
__asm volatile ( "csrc mstatus,8" );
|
||||
|
||||
uint32_t ast_ra = 0;
|
||||
__asm volatile ("mv %0, ra" : "=r"(ast_ra));
|
||||
iot_sprintf(g_dbg_msg, "NULL, line: 0 ra:0x%08x Asserted!\n",
|
||||
ast_ra);
|
||||
print_error_msg(g_dbg_msg);
|
||||
|
||||
// disable iot_printf
|
||||
iot_print_config(false);
|
||||
|
||||
#if IOT_FLASH_BUILD
|
||||
char *tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
uint32_t len = 0;
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* do a breakpoint exception */
|
||||
asm volatile("ebreak");
|
||||
}
|
||||
|
||||
void assert_failed_dump(unsigned char *pucFile, unsigned long ulLine,
|
||||
uint32_t *dump_p, uint32_t dump_size)
|
||||
{
|
||||
( void ) pucFile;
|
||||
( void ) ulLine;
|
||||
uint32_t len = 0;
|
||||
char *tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
|
||||
//disble global interrupt;
|
||||
__asm volatile ( "csrc mstatus,8" );
|
||||
|
||||
uint32_t ast_ra = 0;
|
||||
__asm volatile ("mv %0, ra" : "=r"(ast_ra));
|
||||
iot_sprintf(g_dbg_msg, "ra:0x%08x, line: %d Asserted!\n", ast_ra, ulLine);
|
||||
print_error_msg(g_dbg_msg);
|
||||
|
||||
// disable iot_printf
|
||||
iot_print_config(false);
|
||||
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
|
||||
if (dump_size > 512) {
|
||||
dump_size = 512;
|
||||
}
|
||||
iot_sprintf(g_dbg_msg, "dump data[%d]:\n", dump_size);
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
for(int i = 0; i < dump_size; i++) {
|
||||
iot_sprintf(g_dbg_msg, "%08x ", *(dump_p + i));
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
if ((i%32 == 0) || (i == (dump_size-1))) {
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID,
|
||||
IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* do a breakpoint exception */
|
||||
asm volatile("ebreak");
|
||||
}
|
||||
|
||||
void exception_handler(uintptr_t mcause, uintptr_t epc, saved_registers *reg)
|
||||
{
|
||||
uint32_t mbadaddr = 0;
|
||||
uint32_t len = 0;
|
||||
char *tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
uint32_t cpu1_ticks = iot_cpu1_count_get();
|
||||
|
||||
// disable iot_printf
|
||||
iot_print_config(false);
|
||||
|
||||
|
||||
// dump exception registers
|
||||
exception_reg_dump(reg);
|
||||
|
||||
//disble global interrupt;
|
||||
__asm volatile ( "csrc mstatus,8" );
|
||||
__asm volatile ( "csrr %0, mbadaddr" : "=r"(mbadaddr));
|
||||
|
||||
switch(mcause) {
|
||||
case 0x0:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x[Instruction address misaligned]\n",
|
||||
mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
case 0x1:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x[Instruction access fault]\n",
|
||||
mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
case 0x2:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x[Illegal instruction]\n", mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
iot_illegal_instruct(epc);
|
||||
break;
|
||||
case 0x3:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x[Breakpoint]\n", mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
case 0x4:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x[Load address misaligned]\n",
|
||||
mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
case 0x5:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x[Load access fault]\n", mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
case 0x6:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x[Store address misaligned]\n",
|
||||
mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
case 0x7:
|
||||
iot_sprintf(g_dbg_msg, "mcase: 0x%02x[Store access fault]\n", mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
default:
|
||||
iot_sprintf(g_dbg_msg, "mcause: 0x%02x\n", mcause);
|
||||
print_error_msg(g_dbg_msg);
|
||||
break;
|
||||
}
|
||||
|
||||
g_payload_len = 0;
|
||||
os_mem_set(g_dbglog_buf, 0x0, sizeof(g_dbglog_buf));
|
||||
tmp_buf = g_dbglog_buf + DBGLOG_HEAD_SIZE;
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
if (g_exception_flash_dump) {
|
||||
if (iot_recover_check()) {
|
||||
iot_sprintf(g_dbg_msg,"next boot will recover from original part");
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
}
|
||||
}
|
||||
iot_sprintf(g_dbg_msg,
|
||||
"mepc: 0x%08x, mbadaddr: 0x%08x, ver:0x%08x(%d.%d.%d.%d)-%c-%d\n",
|
||||
epc, mbadaddr, iot_version_hex(), iot_version_major(),
|
||||
iot_version_minor(), iot_version_micro(), iot_version_build(),
|
||||
iot_version_type()?'d':'r', mtd_get_flash_size());
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
|
||||
iot_sprintf(g_dbg_msg, "cpu1 ticks: 0x%08x 0x%08x\n", cpu1_ticks,
|
||||
iot_cpu1_count_get());
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
|
||||
if (os_task_crash_get_task_info(g_dbg_msg, sizeof(g_dbg_msg)) > 0) {
|
||||
print_error_msg(g_dbg_msg);
|
||||
DBG_BUF_CPY(tmp_buf, g_dbg_msg, len);
|
||||
}
|
||||
|
||||
if(g_exception_flash_dump){
|
||||
iot_crash_dbglog_input(RISCV_DUMP_EXCP_MID, IOT_RISCV_DUMP_EXCP_INFO_ID,
|
||||
(uint8_t *)g_dbglog_buf, g_payload_len);
|
||||
}
|
||||
|
||||
iot_backtrace(epc, reg);
|
||||
|
||||
if (g_exception_flash_dump) {
|
||||
iot_sprintf(g_dbg_msg, "save log information\n");
|
||||
print_error_msg(g_dbg_msg);
|
||||
g_exception_flash_dump = 0;
|
||||
iot_log_save_done(g_exception_flash_dump);
|
||||
}
|
||||
}
|
||||
|
135
startup/riscv/src/platform.c
Executable file
135
startup/riscv/src/platform.c
Executable file
@@ -0,0 +1,135 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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 "iot_config.h"
|
||||
#include "cpu.h"
|
||||
#include "ahb.h"
|
||||
#include "iot_irq.h"
|
||||
#include "mtd.h"
|
||||
#include "iot_system.h"
|
||||
#include "snapshot.h"
|
||||
#include "iot_gptmr.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "encoding.h"
|
||||
#include "iot_busmon.h"
|
||||
#include "gp_timer.h"
|
||||
#include "iot_io.h"
|
||||
|
||||
extern void trap_entry();
|
||||
|
||||
extern void vPortSysTickHandler( void );
|
||||
extern void intc_handler(uint32_t cpu);
|
||||
extern void exception_handler(uintptr_t mcause,
|
||||
uintptr_t epc, saved_registers *reg);
|
||||
volatile uint32_t g_trap_reg_addr = 0;
|
||||
exception_cb_t exception;
|
||||
|
||||
#if INTERRUPT_LATENCY_DEBUG
|
||||
uint32_t g_interrupt_total_time = 0;
|
||||
uint32_t g_interrupt_max_time = 0;
|
||||
uint32_t g_systick_total_time = 0;
|
||||
uint32_t g_systick_max_time = 0;
|
||||
|
||||
void dump_interrupt_stat_info()
|
||||
{
|
||||
iot_printf("Interrupt:total:%d, max:%d\n",
|
||||
g_interrupt_total_time, g_interrupt_max_time);
|
||||
|
||||
iot_printf("Systick:total:%d, max:%d\n",
|
||||
g_systick_total_time, g_systick_max_time);
|
||||
}
|
||||
#endif
|
||||
|
||||
uintptr_t IRAM_ATTR handle_interrupt(uintptr_t mcause,
|
||||
uintptr_t epc, saved_registers *reg)
|
||||
{
|
||||
g_trap_reg_addr = (volatile uint32_t) reg;
|
||||
|
||||
#if INTERRUPT_LATENCY_DEBUG
|
||||
uint32_t start, end;
|
||||
uint32_t delta = 0;
|
||||
#endif
|
||||
|
||||
#if SNAPSHOT_MONITOR_DEBUG
|
||||
iot_busmon_enable();
|
||||
#endif
|
||||
if ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT) {
|
||||
#if INTERRUPT_LATENCY_DEBUG
|
||||
start = gp_timer_get_current_val(0);
|
||||
#endif
|
||||
|
||||
intc_handler(cpu_get_mhartid());
|
||||
__asm volatile ("nop");
|
||||
|
||||
#if INTERRUPT_LATENCY_DEBUG
|
||||
end = gp_timer_get_current_val(0);
|
||||
delta = end - start;
|
||||
if (delta > g_interrupt_max_time) {
|
||||
g_interrupt_max_time = delta;
|
||||
}
|
||||
g_interrupt_total_time += delta;
|
||||
#endif
|
||||
} else if ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER){
|
||||
#if INTERRUPT_LATENCY_DEBUG
|
||||
start = gp_timer_get_current_val(0);
|
||||
#endif
|
||||
|
||||
vPortSysTickHandler();
|
||||
__asm volatile ("nop");
|
||||
|
||||
#if INTERRUPT_LATENCY_DEBUG
|
||||
end = gp_timer_get_current_val(0);
|
||||
delta = end - start;
|
||||
if (delta > g_systick_max_time) {
|
||||
g_systick_max_time = delta;
|
||||
}
|
||||
g_systick_total_time += delta;
|
||||
#endif
|
||||
}
|
||||
#if SNAPSHOT_MONITOR_DEBUG
|
||||
iot_busmon_disable();
|
||||
#endif
|
||||
return epc;
|
||||
}
|
||||
|
||||
uint32_t interrupt_get_err_trigger(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int platform_init()
|
||||
{
|
||||
/*install trap entry*/
|
||||
write_csr(mtvec, &trap_entry);
|
||||
|
||||
clear_csr(mie, MIP_MEIP);
|
||||
clear_csr(mie, MIP_MTIP);
|
||||
|
||||
iot_interrupt_init(cpu_get_mhartid());
|
||||
|
||||
iot_gp_timer_init();
|
||||
|
||||
set_csr(mie, MIP_MEIP);
|
||||
|
||||
// Enable interrupts in general.
|
||||
set_csr(mstatus, MSTATUS_MIE);
|
||||
|
||||
exception.handler = exception_handler;
|
||||
exception.full_dump = iot_log_full_dump;
|
||||
|
||||
return 0;
|
||||
}
|
90
startup/riscv/src/start.S
Normal file
90
startup/riscv/src/start.S
Normal file
@@ -0,0 +1,90 @@
|
||||
// See LICENSE for license details.
|
||||
#include "encoding.h"
|
||||
.section .init
|
||||
.globl _start
|
||||
.type _start,@function
|
||||
|
||||
_start:
|
||||
li t0, MSTATUS_MIE
|
||||
csrc mstatus, t0
|
||||
li t0, MIP_MTIP
|
||||
csrc mie, t0
|
||||
li t0, MIP_MEIP
|
||||
csrc mie, t0
|
||||
li t0, 0
|
||||
csrc mcause, t0
|
||||
|
||||
#if RUN_IN_PSRAM
|
||||
/* set cache valid space */
|
||||
lui a5, 0x50000
|
||||
lw a6, 140(a5)
|
||||
li a7, 8
|
||||
slli a7, a7, 4
|
||||
andi a6, a6, -241
|
||||
or a6, a6, a7
|
||||
sw a6, 140(a5)
|
||||
#endif
|
||||
|
||||
la gp, _gp
|
||||
la sp, _sp
|
||||
|
||||
/* Save sbl input param */
|
||||
addi sp, sp, -16
|
||||
sw a0, (sp)
|
||||
sw a1, 4(sp)
|
||||
sw a2, 8(sp)
|
||||
sw a3, 12(sp)
|
||||
|
||||
/* Load data section */
|
||||
la a0, _data_lma
|
||||
la a1, _data
|
||||
la a2, _edata
|
||||
bgeu a1, a2, 2f
|
||||
1:
|
||||
lw t0, (a0)
|
||||
sw t0, (a1)
|
||||
addi a0, a0, 4
|
||||
addi a1, a1, 4
|
||||
bltu a1, a2, 1b
|
||||
2:
|
||||
/* Load iram section */
|
||||
la a0, _iram_lma
|
||||
la a1, _iram_start
|
||||
la a2, _iram_end
|
||||
bgeu a1, a2, 2f
|
||||
1:
|
||||
lw t0, (a0)
|
||||
sw t0, (a1)
|
||||
addi a0, a0, 4
|
||||
addi a1, a1, 4
|
||||
bltu a1, a2, 1b
|
||||
2:
|
||||
/* Clear bss section */
|
||||
la a0, __bss_start
|
||||
la a1, _end
|
||||
bgeu a0, a1, 2f
|
||||
1:
|
||||
sw zero, (a0)
|
||||
addi a0, a0, 4
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
/* init function*/
|
||||
call _init
|
||||
|
||||
#ifndef __riscv_float_abi_soft
|
||||
/* Enable FPU */
|
||||
li t0, MSTATUS_FS
|
||||
csrs mstatus, t0
|
||||
csrr t1, mstatus
|
||||
and t1, t1, t0
|
||||
beqz t1, 1f
|
||||
fssr x0
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* argc = argv = 0 */
|
||||
li a0, 0
|
||||
li a1, 0
|
||||
call main
|
||||
#tail exit
|
||||
1: j 1b
|
220
startup/riscv/src/startup_init.c
Normal file
220
startup/riscv/src/startup_init.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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_mem.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "apb.h"
|
||||
#include "sec_glb.h"
|
||||
#include "ana_hw.h"
|
||||
#include "ledc.h"
|
||||
#include "efuse.h"
|
||||
|
||||
#include "iot_config.h"
|
||||
#include "iot_irq.h"
|
||||
#include "iot_wdg.h"
|
||||
#include "iot_clock.h"
|
||||
#include "iot_gptmr.h"
|
||||
#include "iot_system.h"
|
||||
#include "iot_power_mgmt.h"
|
||||
#include "iot_io.h"
|
||||
#include "iot_board.h"
|
||||
|
||||
#include "iot_system_api.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "encoding.h"
|
||||
|
||||
extern void def_trap_entry();
|
||||
extern void intc_handler(uint32_t cpu);
|
||||
extern void trigger_zero_addr_access_detect();
|
||||
extern exception_cb_t exception;
|
||||
|
||||
extern void ahb_core0_enable();
|
||||
|
||||
static uint32_t g_exception_nesting = 0;
|
||||
|
||||
uintptr_t IRAM_ATTR handle_trap(uintptr_t mcause,
|
||||
uintptr_t epc, saved_registers *reg)
|
||||
{
|
||||
if ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT) {
|
||||
intc_handler(cpu_get_mhartid());
|
||||
} else {
|
||||
uint8_t toggle = 0;
|
||||
g_exception_nesting++;
|
||||
|
||||
if( g_exception_nesting == 1) {
|
||||
#if IOT_EXCEPTION_DEBUG
|
||||
iot_led_gpio_on(IOT_PLC_TX_LED);
|
||||
iot_led_gpio_off(IOT_PLC_RX_LED);
|
||||
iot_led_gpio_on(IOT_RS485_LED);
|
||||
iot_led_gpio_off(IOT_PLC_TR_LED);
|
||||
#endif
|
||||
exception.handler(mcause, epc, reg);
|
||||
#if IOT_FULL_DUMP_DEBUG
|
||||
exception.full_dump();
|
||||
#endif
|
||||
|
||||
#if IOT_EXCEPTION_DEBUG
|
||||
wdg_deinit(HAL_WDG_CPU_0);
|
||||
#if DUAL_WDG_ON_ONE_CPU_ENABLE
|
||||
wdg_deinit(HAL_WDG_CPU_1);
|
||||
#endif
|
||||
iot_power_mgmt_stop_charge();
|
||||
#else
|
||||
wdg_cpu_reset(HAL_WDG_CPU_0);
|
||||
#endif
|
||||
} else {
|
||||
#if IOT_EXCEPTION_DEBUG
|
||||
iot_led_gpio_on(IOT_PLC_TX_LED);
|
||||
iot_led_gpio_off(IOT_PLC_RX_LED);
|
||||
iot_led_gpio_on(IOT_RS485_LED);
|
||||
iot_led_gpio_off(IOT_PLC_TR_LED);
|
||||
#endif
|
||||
|
||||
#if IOT_EXCEPTION_DEBUG
|
||||
wdg_deinit(HAL_WDG_CPU_0);
|
||||
#if DUAL_WDG_ON_ONE_CPU_ENABLE
|
||||
wdg_deinit(HAL_WDG_CPU_1);
|
||||
#endif
|
||||
iot_power_mgmt_stop_charge();
|
||||
#else
|
||||
wdg_cpu_reset(HAL_WDG_CPU_0);
|
||||
#endif
|
||||
}
|
||||
|
||||
while(1){
|
||||
volatile uint32_t i = 0;
|
||||
|
||||
if (g_exception_nesting == 1) {
|
||||
/* 1s delay */
|
||||
for(i = 0; i < 10000000; i++);
|
||||
} else {
|
||||
/* 5s delay */
|
||||
for(i = 0; i < 50000000; i++);
|
||||
}
|
||||
|
||||
if (!toggle) {
|
||||
iot_led_gpio_on(IOT_PLC_RX_LED);
|
||||
iot_led_gpio_on(IOT_PLC_TR_LED);
|
||||
} else {
|
||||
iot_led_gpio_off(IOT_PLC_RX_LED);
|
||||
iot_led_gpio_off(IOT_PLC_TR_LED);
|
||||
}
|
||||
toggle = !toggle;
|
||||
}
|
||||
}
|
||||
|
||||
return epc;
|
||||
}
|
||||
|
||||
#if RUN_ON_CPU_1
|
||||
static int sp_applet_start()
|
||||
{
|
||||
g_cpu1_state.flags = CPU_FLAG_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#if (!(IOT_FTM_SUPPORT == 1 && IOT_MP_SUPPORT == 0))
|
||||
static const uint8_t sp_applet_bin[] = {
|
||||
#include "sp_applet.txt"
|
||||
};
|
||||
#define SP_APPLET_RAM_ADDR 0x00fc1000
|
||||
#define SP_APPLET_WAIT_COUNT 10
|
||||
#define SP_APPLET_WAIT_UNIT_TIME 500
|
||||
#endif
|
||||
|
||||
int sp_applet_start()
|
||||
{
|
||||
#if (!(IOT_FTM_SUPPORT == 1 && IOT_MP_SUPPORT == 0))
|
||||
uint8_t *dst = (uint8_t*)SP_APPLET_RAM_ADDR;
|
||||
uint8_t *src = (uint8_t*)sp_applet_bin;
|
||||
uint32_t len = sizeof(sp_applet_bin)/sizeof(sp_applet_bin[0]);
|
||||
volatile int delay_cnt = SP_APPLET_WAIT_COUNT;
|
||||
|
||||
/* clean buffer of g_cpu1_state. */
|
||||
os_mem_set(&g_cpu1_state, 0, sizeof(g_cpu1_state));
|
||||
|
||||
sec_glb_core1_disable();
|
||||
os_mem_cpy(dst, src, len);
|
||||
sec_glb_core1_set_start(SP_APPLET_RAM_ADDR);
|
||||
sec_glb_core1_reset(1);
|
||||
sec_glb_core1_enable();
|
||||
|
||||
/* wait until cpu1 running. */
|
||||
while(delay_cnt--) {
|
||||
if (CPU_FLAG_RUNNING == g_cpu1_state.flags) {
|
||||
break;
|
||||
}
|
||||
iot_delay_us_cpu_cycle(SP_APPLET_WAIT_UNIT_TIME);
|
||||
}
|
||||
|
||||
#else
|
||||
g_cpu1_state.flags = CPU_FLAG_INVALID;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void _init()
|
||||
{
|
||||
/* get and set reset reason */
|
||||
iot_board_reset_get_and_set();
|
||||
|
||||
/* sp's applet load */
|
||||
sp_applet_start();
|
||||
|
||||
/* efuse protect */
|
||||
//efuse_protect();
|
||||
|
||||
/*disable limited curent to 250mA*/
|
||||
apb_enable_ana_lmtcur(false);
|
||||
|
||||
#if (defined(IOT_FLASH_DCDC_TRIM_ENABLE) && IOT_FLASH_DCDC_TRIM_ENABLE)
|
||||
ana_pmu_set_ref_dcdc();
|
||||
#endif
|
||||
|
||||
apb_enable_ana_pfm(false);
|
||||
|
||||
/*enable core0*/
|
||||
ahb_core0_enable();
|
||||
|
||||
write_csr(mtvec, &def_trap_entry);
|
||||
|
||||
clear_csr(mie, MIP_MEIP);
|
||||
clear_csr(mie, MIP_MTIP);
|
||||
|
||||
iot_interrupt_init(cpu_get_mhartid());
|
||||
|
||||
set_csr(mie, MIP_MEIP);
|
||||
|
||||
// Enable interrupts in general.
|
||||
set_csr(mstatus, MSTATUS_MIE);
|
||||
|
||||
//iot_gp_timer_init();
|
||||
|
||||
// Enable trigger registers to detech zero address access
|
||||
trigger_zero_addr_access_detect();
|
||||
|
||||
/* enable log print */
|
||||
iot_print_config(true);
|
||||
}
|
||||
|
||||
void _fini()
|
||||
{
|
||||
|
||||
}
|
Reference in New Issue
Block a user