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