1/* 2 * Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com> 3 * Contributors: 2018 Antmicro <www.antmicro.com> 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8#include <zephyr/toolchain.h> 9 10/* exports */ 11GTEXT(__start) 12 13/* imports */ 14GTEXT(__initialize) 15GTEXT(_isr_wrapper) 16 17SECTION_FUNC(vectors, __start) 18#if defined(CONFIG_RISCV_GP) 19 /* Initialize global pointer */ 20 .option push 21 .option norelax 22 la gp, __global_pointer$ 23 .option pop 24#endif 25 26 .option norvc; 27 28#if defined(CONFIG_RISCV_VECTORED_MODE) 29#if defined(CONFIG_RISCV_HAS_CLIC) 30 31 /* 32 * CLIC vectored mode 33 * 34 * CLIC vectored mode uses mtvec exclusively for exception handling and 35 * mtvec.base must be aligned to 64 bytes (this is done using 36 * CONFIG_ARCH_SW_ISR_TABLE_ALIGN) 37 */ 38 la t0, _isr_wrapper 39 addi t0, t0, 0x03 /* Enable CLIC vectored mode by setting LSB */ 40 csrw mtvec, t0 41 42 /* 43 * CLIC vectored mode has a similar concept to CLINT vectored mode, 44 * where an interrupt vector table is used for specific interrupts. 45 * However, in CLIC vectored mode, the handler table contains the 46 * address of the interrupt handler instead of an opcode containing a 47 * jump instruction, this is done by leveraging 48 * CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS. 49 * When an interrupt occurs in CLIC vectored mode, the address of the 50 * handler entry from the vector table is loaded and then jumped to in 51 * hardware. This time mtvt is used as the base address for the 52 * interrupt table. 53 */ 54 la t0, _irq_vector_table 55 csrw 0x307, t0 /* mtvt */ 56 57#else /* !CONFIG_RISCV_HAS_CLIC */ 58 59 /* 60 * CLINT vectored mode 61 * 62 * Set mtvec (Machine Trap-Vector Base-Address Register) 63 * to _irq_vector_table (interrupt vector table). Add 1 to base 64 * address of _irq_vector_table to indicate that vectored mode 65 * is used (LSB = 0x1). CPU will mask the LSB out of 66 * the address so that base address of _irq_vector_table is used. 67 * 68 * NOTE: _irq_vector_table is 256-byte aligned. Incorrect alignment 69 * of _irq_vector_table breaks this code. 70 */ 71 la t0, _irq_vector_table /* Load address of interrupt vector table */ 72 addi t0, t0, 0x01 /* Enable vectored mode by setting LSB */ 73 csrw mtvec, t0 74 75#endif /* CONFIG_RISCV_HAS_CLIC */ 76 77#else /* !CONFIG_RISCV_VECTORED_MODE */ 78 79#if defined(CONFIG_RISCV_HAS_CLIC) && !defined(CONFIG_LEGACY_CLIC) 80 81 la t0, _isr_wrapper 82 addi t0, t0, 0x03 /* Set mode bits to 3, signifying CLIC. Everything else is reserved. */ 83 csrw mtvec, t0 84 85#else /* !CONFIG_RISCV_HAS_CLIC || CONFIG_LEGACY_CLIC */ 86 87 /* 88 * CLINT direct mode 89 * 90 * Set mtvec (Machine Trap-Vector Base-Address Register) 91 * to _isr_wrapper. 92 */ 93 la t0, _isr_wrapper 94 csrw mtvec, t0 95 96#endif /* CONFIG_RISCV_HAS_CLIC&& !CONFIG_LEGACY_CLIC */ 97 98#endif /* CONFIG_RISCV_VECTORED_MODE */ 99 100 /* Jump to __reset */ 101 tail __reset 102