summaryrefslogtreecommitdiff
path: root/bsp/hpmicro/libraries/hpm_sdk/soc/HPM6750/toolchains/trap.c
blob: c4abe867e48714de15dc08ff9eaca3eeda0b7bfc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Copyright (c) 2021 hpmicro
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#include "hpm_common.h"
#include "hpm_soc.h"

/********************** MCAUSE exception types **************************************/
#define MCAUSE_INSTR_ADDR_MISALIGNED (0U)       //!< Instruction Address misaligned
#define MCAUSE_INSTR_ACCESS_FAULT (1U)          //!< Instruction access fault
#define MCAUSE_ILLEGAL_INSTR (2U)               //!< Illegal instruction
#define MCAUSE_BREAKPOINT (3U)                  //!< Breakpoint
#define MCAUSE_LOAD_ADDR_MISALIGNED (4U)        //!< Load address misaligned
#define MCAUSE_LOAD_ACCESS_FAULT (5U)           //!< Load access fault
#define MCAUSE_STORE_AMO_ADDR_MISALIGNED (6U)   //!< Store/AMO address misaligned
#define MCAUSE_STORE_AMO_ACCESS_FAULT (7U)      //!< Store/AMO access fault
#define MCAUSE_ECALL_FROM_USER_MODE (8U)        //!< Environment call from User mode
#define MCAUSE_ECALL_FROM_SUPERVISOR_MODE (9U)  //!< Environment call from Supervisor mode
#define MCAUSE_ECALL_FROM_MACHINE_MODE (11U)    //!< Environment call from machine mode
#define MCAUSE_INSTR_PAGE_FAULT (12U)           //!< Instruction page fault
#define MCAUSE_LOAD_PAGE_FAULT (13)             //!< Load page fault
#define MCAUSE_STORE_AMO_PAGE_FAULT (15U)       //!< Store/AMO page fault

#define IRQ_S_SOFT          	1
#define IRQ_H_SOFT          	2
#define IRQ_M_SOFT          	3
#define IRQ_S_TIMER         	5
#define IRQ_H_TIMER         	6
#define IRQ_M_TIMER         	7
#define IRQ_S_EXT           	9
#define IRQ_H_EXT           	10
#define IRQ_M_EXT           	11
#define IRQ_COP             	12
#define IRQ_HOST            	13



__attribute__((weak)) void mchtmr_isr(void)
{
}

__attribute__((weak)) void swi_isr(void)
{
}

__attribute__((weak)) void syscall_handler(long n, long a0, long a1, long a2, long a3)
{
}

__attribute__((weak)) long exception_handler(long cause, long epc)
{
    switch (cause) {
        case MCAUSE_INSTR_ADDR_MISALIGNED:
            break;
        case MCAUSE_INSTR_ACCESS_FAULT:
            break;
        case MCAUSE_ILLEGAL_INSTR:
            break;
        case MCAUSE_BREAKPOINT:
            break;
        case MCAUSE_LOAD_ADDR_MISALIGNED:
            break;
        case MCAUSE_LOAD_ACCESS_FAULT:
            break;
        case MCAUSE_STORE_AMO_ADDR_MISALIGNED:
            break;
        case MCAUSE_STORE_AMO_ACCESS_FAULT:
            break;
        case MCAUSE_ECALL_FROM_USER_MODE:
            break;
        case MCAUSE_ECALL_FROM_SUPERVISOR_MODE:
            break;
        case MCAUSE_ECALL_FROM_MACHINE_MODE:
            break;
        case MCAUSE_INSTR_PAGE_FAULT:
            break;
        case MCAUSE_LOAD_PAGE_FAULT:
            break;
        case MCAUSE_STORE_AMO_PAGE_FAULT:
            break;
        default:
            break;
    }
    /* Unhandled Trap */
    return epc;
}

#ifndef CONFIG_FREERTOS
void irq_handler_trap(void) __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4)));
#else
void irq_handler_trap(void) __attribute__ ((section(".isr_vector")));
#endif
void irq_handler_trap(void)
{
    long mcause = read_csr(CSR_MCAUSE);
    long mepc = read_csr(CSR_MEPC);
    long mstatus = read_csr(CSR_MSTATUS);
#if SUPPORT_PFT_ARCH
    long mxstatus = read_csr(CSR_MXSTATUS);
#endif
#ifdef __riscv_dsp
    int ucode = read_csr(CSR_UCODE);
#endif
#ifdef __riscv_flen
    int fcsr = read_fcsr();
#endif

    /* clobbers list for ecall */
#ifdef __riscv_32e
    __asm volatile("" : : :"t0", "a0", "a1", "a2", "a3");
#else
    __asm volatile("" : : :"a7", "a0", "a1", "a2", "a3");
#endif

    /* Do your trap handling */
    if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_TIMER)) {
        /* Machine timer interrupt */
        mchtmr_isr();
    }
#ifdef USE_NONVECTOR_MODE
    else if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_EXT)) {

        typedef void(*isr_func_t)(void);

        /* Machine-level interrupt from PLIC */
        uint32_t irq_index = __plic_claim_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE);
        if (irq_index) {
        /* Workaround: irq number returned by __plic_claim_irq might be 0, which is caused by plic. So skip invalid irq_index as a workaround */
#ifndef DISABLE_IRQ_PREEMPTIVE
            enable_global_irq(CSR_MSTATUS_MIE_MASK);
#endif
            ((isr_func_t)__vector_table[irq_index])();
            __plic_complete_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE, irq_index);
        }

    }
#endif

    else if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_SOFT)) {
        /* Machine SWI interrupt */
        intc_m_claim_swi();
        swi_isr();
        intc_m_complete_swi();
    } else if (!(mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == MCAUSE_ECALL_FROM_MACHINE_MODE)) {
        /* Machine Syscal call */
        __asm volatile(
        "mv a4, a3\n"
        "mv a3, a2\n"
        "mv a2, a1\n"
        "mv a1, a0\n"
        #ifdef __riscv_32e
        "mv a0, t0\n"
        #else
        "mv a0, a7\n"
        #endif
        "jalr %0\n"
        : :"r"(syscall_handler) : "a4"
        );
        mepc += 4;
    } else {
        mepc = exception_handler(mcause, mepc);
    }

    /* Restore CSR */
    write_csr(CSR_MSTATUS, mstatus);
    write_csr(CSR_MEPC, mepc);
#if SUPPORT_PFT_ARCH
    write_csr(CSR_MXSTATUS, mxstatus);
#endif
#ifdef __riscv_dsp
    write_csr(CSR_UCODE, ucode);
#endif
#ifdef __riscv_flen
    write_fcsr(fcsr);
#endif
}