/**
* @file		start.S
* @brief 	Custom start file for spv40 SoC
* @author	Z.L.T
* @date		05/15/2023
*/

#include "core_v5.h"

#define VAL(str) #str
#define TOSTRING(str) VAL(str)

#ifndef MOD_FILE_NAME
#define MOD_FILE_NAME ai.mod
#endif

#ifndef EXT_FILE_NAME
#define EXT_FILE_NAME ext.a
#endif

/* ==================		Data Binary Files		========================= */
  .section .mod, "a"
  .balign 4096
  .globl _mod_file
_mod_file:
  .incbin TOSTRING(MOD_FILE_NAME)

  .section .playback, "a"
  .balign 4096
  .globl _playback_file
_playback_file:
  .incbin "playback.dat"

  .section .ext, "a"
  .balign 4096
  .globl _ext_file
_ext_file:
  .incbin TOSTRING(EXT_FILE_NAME)

/* ====================  Firmware Header Definitions ======================== */
  .section .header, "a"
  .balign 4
  .globl _mbr
  .type _mbr, %object
_mbr:
.option push
.option norvc
	jal x0, _preinit			/* 0:jump code */
.option pop

	.4byte 0x40565053			/* 1:tag magic "SPV\x40" */
	.4byte __encrypted_bin_addr	/* 2: */
	.4byte 0x4f414d40			/* 3:user flag */
	.4byte __encrypted_bin_size	/* 4: */
	.4byte _fw_build_date		/* 5:string address: firmware build date */
	.4byte _fw_build_time		/* 6:string address: firmware build time */
	.4byte 0x4					/* 7:total bin partitions (including cpu's) */


	.4byte 0x00555043			/* bin name "CPU" */
	.4byte __cpu_file_addr		/* bin addr */
	.4byte __cpu_file_size		/* bin size */
	.4byte 0x0					/* bin check_sum */


	.4byte 0x00444f4d			/* bin name "MOD" */
	.4byte __mod_file_addr		/* bin addr */
	.4byte __mod_file_size		/* bin size */
	.4byte 0x1


	.4byte 0x004b4250			/* bin name "PBK" */
	.4byte __playback_file_addr	/* bin addr */
	.4byte __playback_file_size	/* bin size */
	.4byte 0x2


	.4byte 0x00545845			/* bin name "EXT" */
	.4byte __ext_file_addr		/* bin addr */
	.4byte __ext_file_size		/* bin size */
	.4byte 0x3

/****************************************************************************
 * Pre-Init Function														*
 ****************************************************************************/

	.section .preinit,"ax"
	.balign 4
	.globl _preinit
	.type _preinit, @function

_preinit:
/* ====================== User Application Entry ============================ */
.option push
.option norvc
  	lui t0, %hi(_remapping)
  	addi t0,t0,%lo(_remapping)
  	jr t0
.option pop
_remapping:
	la t0, _stack
	mv sp, t0
	call crypto
	call reset_vector

/****************************************************************************
 * Miscs														    		*
 ****************************************************************************/

	.section .rodata, "a"
	.balign 4
	.globl _fw_build_date
_fw_build_date:
//	.string TOSTRING(___DATE___)
	.string __DATE__

	.section .rodata, "a"
	.balign 4
	.globl _fw_build_time
_fw_build_time:
//	.string TOSTRING(___TIME___)
	.string __TIME__
/* ====================== Post-reset Code Process =========================== */
.section .nds_vector, "ax"
.globl reset_vector
.balign 4

/* ========================================================================== */
reset_vector:

  /* Check NMI MASK register configuration */
  li t0, 0x20005000
  lw t1, 0x10(t0)
  lw t2, 0x14(t0)
  or t0, t1, t2
  beqz t0, _start

  /* Decide whether this is an NMI or cold reset, based on mcause value */
  csrr t0, mcause
  bnez t0, nmi_handler

.globl _start
.type _start,@function

_start:
  /* Initialize global pointer regiter (gp) */
  .option push
  .option norelax
  la gp, __global_pointer$
  .option pop

  /* Initialize stack pointer (sp)*/
  la t0, _stack
  mv sp, t0


/* =================== SoC Specific Initialization ========================== */
  /*
   * RMU_BOOT register: clear bit 0 to disable BOOT_EN mechanism
   */
  li t0, 0x20003024
  lw t1, 0(t0)
  li t2, 0xfffffffe
  and t1, t1, t2
  sw t1, 0(t0)
  /* ======================================================================== */

/*
 * The AndeStar V5 predefine macro __nds_execit is defined if the architecture
 * supports AndeStar EXEC.IT extension.
 * All V5 ELF toolchains have this macro enabled by default.
 */
#ifdef __nds_execit
  la t0, _ITB_BASE_
  csrw uitb, t0
#endif

#ifdef __riscv_flen
  /* Enable FPU */
  li t0, MSTATUS_FS
  csrrs t0, mstatus, t0
  /* Initialize FCSR */
  fscsr zero
#endif

  /* Enable L1ICache and L1Dache */
  li t0, 0x3
  csrs mcache_ctl, t0

  /*
   * Enable Misaligned access(bit 6)
   * Turn on BTB and RAS(bit 3)
   * Turn on vector PLIC (bit 1)
   */
  li t0, 0x4a
  csrw mmisc_ctl, t0

  /* Initialize Machine Trap-Vector Base register */
  la t0, vector_base
  csrw mtvec, t0

  call once_loader
/*
 * ====================== User Application Ends ================================
 */

/*
 * Default Non-Maskable Interrupt (NMI) Handler
 */
.section .nds_vector, "ax"
.globl nmi_handler
.weak nmi_handler
.balign 4

nmi_handler:
1:
  j 1b

/*
 * Default PLIC IRQ placeholder
 */
.text
.globl default_irq_entry
.balign 4
default_irq_entry:
1:
  j 1b


/*
 * ===================== Interrupt Table Definition ============================												*
 */
.section .vector_table, "a"

  .weak wdog_irq_entry
  .weak pmu_irq_entry
  .weak lradc_irq_entry
  .weak adui_irq_entry
  .weak udsp_irq_entry
  .weak npu_tab_irq_entry
  .weak npu_res_irq_entry
  .weak timer0_irq_entry
  .weak timer1_irq_entry
  .weak timer2_irq_entry
  .weak timer3_irq_entry
  .weak capture0_irq_entry
  .weak capture1_irq_entry
  .weak capture2_irq_entry
  .weak capture3_irq_entry
  .weak irrx_irq_entry
  .weak irtx_irq_entry
  .weak spi0_irq_entry
  .weak spi1_irq_entry
  .weak sdc_irq_entry
  .weak adc_irq_entry
  .weak dac_irq_entry
  .weak src_irq_entry
  .weak dma_irq_entry
  .weak mmu_irq_entry
  .weak norc_irq_entry
  .weak uart0_irq_entry
  .weak uart1_irq_entry
  .weak uart2_irq_entry
  .weak i2c0_irq_entry
  .weak i2c1_irq_entry
  .weak asi0_irq_entry
  .weak asi1_irq_entry
  .weak usb_mac_irq_entry
  .weak usb_dma_irq_entry
  .weak gpio0_irq_entry
  .weak gpio1_irq_entry
  .weak pwm_irq_entry
  .weak camera_irq_entry
  .weak uart3_irq_entry
  .weak psram_irq_entry
  .weak mpu_irq_entry

  .set wdog_irq_entry,		default_irq_entry
  .set pmu_irq_entry,		default_irq_entry
  .set lradc_irq_entry,		default_irq_entry
  .set adui_irq_entry,		default_irq_entry
  .set udsp_irq_entry,		default_irq_entry
  .set npu_tab_irq_entry,	default_irq_entry
  .set npu_res_irq_entry,	default_irq_entry
  .set timer0_irq_entry,	default_irq_entry
  .set timer1_irq_entry,	default_irq_entry
  .set timer2_irq_entry,	default_irq_entry
  .set timer3_irq_entry,	default_irq_entry
  .set capture0_irq_entry,	default_irq_entry
  .set capture1_irq_entry,	default_irq_entry
  .set capture2_irq_entry,	default_irq_entry
  .set capture3_irq_entry,	default_irq_entry
  .set irrx_irq_entry,		default_irq_entry
  .set irtx_irq_entry,		default_irq_entry
  .set spi0_irq_entry,		default_irq_entry
  .set spi1_irq_entry,		default_irq_entry
  .set sdc_irq_entry,		default_irq_entry
  .set adc_irq_entry,		default_irq_entry
  .set dac_irq_entry,		default_irq_entry
  .set src_irq_entry,		default_irq_entry
  .set dma_irq_entry,		default_irq_entry
  .set mmu_irq_entry,		default_irq_entry
  .set norc_irq_entry,		default_irq_entry
  .set uart0_irq_entry,		default_irq_entry
  .set uart1_irq_entry,		default_irq_entry
  .set uart2_irq_entry,		default_irq_entry
  .set i2c0_irq_entry,		default_irq_entry
  .set i2c1_irq_entry,		default_irq_entry
  .set asi0_irq_entry,		default_irq_entry
  .set asi1_irq_entry,		default_irq_entry
  .set usb_mac_irq_entry,	default_irq_entry
  .set usb_dma_irq_entry,	default_irq_entry
  .set gpio0_irq_entry,		default_irq_entry
  .set gpio1_irq_entry,		default_irq_entry
  .set pwm_irq_entry,		default_irq_entry
  .set camera_irq_entry,	default_irq_entry
  .set uart3_irq_entry,		default_irq_entry
  .set psram_irq_entry,		default_irq_entry
  .set mpu_irq_entry,		default_irq_entry

  .globl vector_base
  .balign 256
vector_base:
  .4byte trap_entry				/* 0    : Exception & MSIP & MTIP Handler */
  .4byte wdog_irq_entry			/* 1	: WDOG PLIC Interrupt */
  .4byte pmu_irq_entry			/* 2	: PMU PLIC Interrupt */
  .4byte lradc_irq_entry		/* 3	: LRADC PLIC Interrupt */
  .4byte adui_irq_entry			/* 4	: ADUI PLIC Interrupt */
  .4byte udsp_irq_entry			/* 5	: UDSP PLIC Interrupt */
  .4byte npu_tab_irq_entry		/* 6	: NPU_TAB PLIC Interrupt */
  .4byte npu_res_irq_entry		/* 7	: NPU_RES PLIC Interrupt */
  .4byte timer0_irq_entry		/* 8	: TIMER0 PLIC Interrupt */
  .4byte timer1_irq_entry		/* 9	: TIMER1 PLIC Interrupt */
  .4byte timer2_irq_entry		/* 10	: TIMER2 PLIC Interrupt */
  .4byte timer3_irq_entry		/* 11	: TIMER3 PLIC Interrupt */
  .4byte capture0_irq_entry		/* 12	: CAPTURE0 PLIC Interrupt */
  .4byte capture1_irq_entry		/* 13	: CAPTURE1 PLIC Interrupt */
  .4byte capture2_irq_entry		/* 14	: CAPTURE2 PLIC Interrupt */
  .4byte capture3_irq_entry		/* 15	: CAPTURE3 PLIC Interrupt */
  .4byte irrx_irq_entry			/* 16	: IRRX PLIC Interrupt */
  .4byte irtx_irq_entry			/* 17	: IRTX PLIC Interrupt */
  .4byte spi0_irq_entry			/* 18	: SPI0 PLIC Interrupt */
  .4byte spi1_irq_entry			/* 19	: SPI1 PLIC Interrupt */
  .4byte sdc_irq_entry			/* 20	: SDC PLIC Interrupt */
  .4byte adc_irq_entry			/* 21	: ADC PLIC Interrupt */
  .4byte dac_irq_entry			/* 22	: DAC PLIC Interrupt */
  .4byte src_irq_entry			/* 23	: SRC PLIC Interrupt */
  .4byte dma_irq_entry			/* 24	: DMA PLIC Interrupt */
  .4byte mmu_irq_entry			/* 25	: MMU PLIC Interrupt */
  .4byte norc_irq_entry			/* 26	: NORC PLIC Interrupt */
  .4byte uart0_irq_entry		/* 27	: UART0 PLIC Interrupt */
  .4byte uart1_irq_entry		/* 28	: UART1 PLIC Interrupt */
  .4byte uart2_irq_entry		/* 29	: UART2 PLIC Interrupt */
  .4byte i2c0_irq_entry			/* 30	: I2C0 PLIC Interrupt */
  .4byte i2c1_irq_entry			/* 31	: I2C1 PLIC Interrupt */
  .4byte asi0_irq_entry			/* 32	: ASI0 PLIC Interrupt */
  .4byte asi1_irq_entry			/* 33	: ASI1 PLIC Interrupt */
  .4byte usb_mac_irq_entry		/* 34	: USB_MAC PLIC Interrupt */
  .4byte usb_dma_irq_entry		/* 35	: USB_DMA PLIC Interrupt */
  .4byte gpio0_irq_entry		/* 36	: GPIO0 PLIC Interrupt */
  .4byte gpio1_irq_entry		/* 37	: GPIO1 PLIC Interrupt */
  .4byte pwm_irq_entry			/* 38	: PWM PLIC Interrupt */
  .4byte camera_irq_entry		/* 39	: CAMERA PLIC Interrupt */
  .4byte uart3_irq_entry		/* 40	: UART3 PLIC Interrupt */
  .4byte psram_irq_entry		/* 41	: PSRAM PLIC Interrupt */
  .4byte mpu_irq_entry			/* 42	: MPU PLIC Interrupt */

