102 lines
2.7 KiB
ArmAsm
102 lines
2.7 KiB
ArmAsm
/*
|
|
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
|
* Contributors: 2018 Antmicro <www.antmicro.com>
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/toolchain.h>
|
|
|
|
/* exports */
|
|
GTEXT(__start)
|
|
|
|
/* imports */
|
|
GTEXT(__initialize)
|
|
GTEXT(_isr_wrapper)
|
|
|
|
SECTION_FUNC(vectors, __start)
|
|
#if defined(CONFIG_RISCV_GP)
|
|
/* Initialize global pointer */
|
|
.option push
|
|
.option norelax
|
|
la gp, __global_pointer$
|
|
.option pop
|
|
#endif
|
|
|
|
.option norvc;
|
|
|
|
#if defined(CONFIG_RISCV_VECTORED_MODE)
|
|
#if defined(CONFIG_RISCV_HAS_CLIC)
|
|
|
|
/*
|
|
* CLIC vectored mode
|
|
*
|
|
* CLIC vectored mode uses mtvec exclusively for exception handling and
|
|
* mtvec.base must be aligned to 64 bytes (this is done using
|
|
* CONFIG_ARCH_SW_ISR_TABLE_ALIGN)
|
|
*/
|
|
la t0, _isr_wrapper
|
|
addi t0, t0, 0x03 /* Enable CLIC vectored mode by setting LSB */
|
|
csrw mtvec, t0
|
|
|
|
/*
|
|
* CLIC vectored mode has a similar concept to CLINT vectored mode,
|
|
* where an interrupt vector table is used for specific interrupts.
|
|
* However, in CLIC vectored mode, the handler table contains the
|
|
* address of the interrupt handler instead of an opcode containing a
|
|
* jump instruction, this is done by leveraging
|
|
* CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS.
|
|
* When an interrupt occurs in CLIC vectored mode, the address of the
|
|
* handler entry from the vector table is loaded and then jumped to in
|
|
* hardware. This time mtvt is used as the base address for the
|
|
* interrupt table.
|
|
*/
|
|
la t0, _irq_vector_table
|
|
csrw 0x307, t0 /* mtvt */
|
|
|
|
#else /* !CONFIG_RISCV_HAS_CLIC */
|
|
|
|
/*
|
|
* CLINT vectored mode
|
|
*
|
|
* Set mtvec (Machine Trap-Vector Base-Address Register)
|
|
* to _irq_vector_table (interrupt vector table). Add 1 to base
|
|
* address of _irq_vector_table to indicate that vectored mode
|
|
* is used (LSB = 0x1). CPU will mask the LSB out of
|
|
* the address so that base address of _irq_vector_table is used.
|
|
*
|
|
* NOTE: _irq_vector_table is 256-byte aligned. Incorrect alignment
|
|
* of _irq_vector_table breaks this code.
|
|
*/
|
|
la t0, _irq_vector_table /* Load address of interrupt vector table */
|
|
addi t0, t0, 0x01 /* Enable vectored mode by setting LSB */
|
|
csrw mtvec, t0
|
|
|
|
#endif /* CONFIG_RISCV_HAS_CLIC */
|
|
|
|
#else /* !CONFIG_RISCV_VECTORED_MODE */
|
|
|
|
#if defined(CONFIG_RISCV_HAS_CLIC) && !defined(CONFIG_LEGACY_CLIC)
|
|
|
|
la t0, _isr_wrapper
|
|
addi t0, t0, 0x03 /* Set mode bits to 3, signifying CLIC. Everything else is reserved. */
|
|
csrw mtvec, t0
|
|
|
|
#else /* !CONFIG_RISCV_HAS_CLIC || CONFIG_LEGACY_CLIC */
|
|
|
|
/*
|
|
* CLINT direct mode
|
|
*
|
|
* Set mtvec (Machine Trap-Vector Base-Address Register)
|
|
* to _isr_wrapper.
|
|
*/
|
|
la t0, _isr_wrapper
|
|
csrw mtvec, t0
|
|
|
|
#endif /* CONFIG_RISCV_HAS_CLIC&& !CONFIG_LEGACY_CLIC */
|
|
|
|
#endif /* CONFIG_RISCV_VECTORED_MODE */
|
|
|
|
/* Jump to __reset */
|
|
tail __reset
|