/* write to this register to report test outcome */
.set test_result_reg, 0x20000000
.set test_fail, 1
.set test_pass, 123456789

/* we start at addr 0 */
.section .boot_spike, "ax"
j .text.start

.section .boot_riscy, "ax"
j .text.start

.section .vectors, "ax"
.option norvc
vector_table:
	j sw_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler

/* this is fixed to 0x8000, used for PULP_SECURE=0. We redirect this entry to the
new vector table (which is at mtvec) */
.section .legacy_irq, "ax"
	j vector_table
	j __no_irq_handler
	j __no_irq_handler
	j __no_irq_handler

/* exception handling */
__no_irq_handler:
	la a0, no_exception_handler_msg
	jal ra, puts
	j __no_irq_handler


sw_irq_handler:
	csrr t0, mcause
	slli t0, t0, 1  /* shift off the high bit */
	srli t0, t0, 1
	li t1, 2
	beq t0, t1, handle_illegal_insn
	li t1, 11
	beq t0, t1, handle_ecall
	li t1, 3
	beq t0, t1, handle_ebreak
	j handle_unknown

handle_ecall:
	la a0, ecall_msg
	/* jal ra, puts */
	j end_test

handle_ebreak:
	la a0, ebreak_msg
	/* jal ra, puts */
	j end_test

handle_illegal_insn:
	la a0, illegal_insn_msg
	/* jal ra, puts */
	j end_test

handle_unknown:
	la a0, unknown_msg
	/* jal ra, puts */
	j end_test

end_test:
	li a0, test_pass
	sw a0, test_results, t1
	li a0, test_result_reg
	lw a1, test_results /* report result */
	sw a1,0(a0)
	wfi

.section .rodata
illegal_insn_msg:
	.string "illegal instruction exception handler entered\n"
ecall_msg:
	.string "ecall exception handler entered\n"
ebreak_msg:
	.string "ebreak exception handler entered\n"
unknown_msg:
	.string "unknown exception handler entered\n"
no_exception_handler_msg:
	.string "no exception handler installed\n"
riscv_tests_msg:
	.string "running riscv-tests\n"
riscv_compliance_tests_msg:
	.string "running riscv-compliance-tests\n"
timeout_msg:
	.string "\n\nTEST TIMEOUT, aborting...\n\n"

.section .data
.global test_results
test_results:
	.word 123456789

/* from the picorv32 project, written by clifford wolf */
.section .text.start
.global application_entry_point

/* set vector table address */
li a0, 0x100
csrw mtvec, a0

/* zero-initialize all registers */
addi x1, zero, 0
addi x2, zero, 0
addi x3, zero, 0
addi x4, zero, 0
addi x5, zero, 0
addi x6, zero, 0
addi x7, zero, 0
addi x8, zero, 0
addi x9, zero, 0
addi x10, zero, 0
addi x11, zero, 0
addi x12, zero, 0
addi x13, zero, 0
addi x14, zero, 0
addi x15, zero, 0
addi x16, zero, 0
addi x17, zero, 0
addi x18, zero, 0
addi x19, zero, 0
addi x20, zero, 0
addi x21, zero, 0
addi x22, zero, 0
addi x23, zero, 0
addi x24, zero, 0
addi x25, zero, 0
addi x26, zero, 0
addi x27, zero, 0
addi x28, zero, 0
addi x29, zero, 0
addi x30, zero, 0
addi x31, zero, 0

/* set stack pointer */
lui sp, %hi(4*1024*1024)
addi sp, sp, %lo(4*1024*1024)

/* push zeros on the stack for argc and argv */
/* (stack is aligned to 16 bytes in riscv calling convention) */
addi sp,sp,-16
sw zero,0(sp)
sw zero,4(sp)
sw zero,8(sp)
sw zero,12(sp)

/* jump to libc init */
j application_entry_point
