summaryrefslogtreecommitdiff
path: root/bsp/xuantie/libraries/xuantie_libraries/lib_cpu/interrupt_gcc.S
blob: 1f44d77ce5b73e66bf74b238e7511b7038c7ed29 (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
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018/10/02     Bernard      The first version
 * 2018/12/27     Jesven       Add SMP schedule
 * 2021/02/02     lizhirui     Add userspace support
 */
#define __ASSEMBLY__
#include "stackframe.h"

.equ RISCV_MSTATUS_MIE,        (1<<3)       /*machine-level interrupt bit*/

.section      .text.entry
.align 3

#ifdef RT_USING_SMP
    .global Mcoret_Handler
    .type   Mcoret_Handler, %function
Mcoret_Handler:
    SAVE_ALL
    /* switch to interrupt stack */
    move  s0, sp

    /* get cpu id */
    csrr  t0, mhartid

    /* switch interrupt stack of current cpu */
    la    sp, g_base_irqstack
    addi  t1, t0, 1
    li    t2, CONFIG_ARCH_INTERRUPTSTACK
    mul   t1, t1, t2
    add   sp, sp, t1 /* sp = (cpuid + 1) * CONFIG_ARCH_INTERRUPTSTACK + g_base_irqstack */

    call  CORET_IRQHandler

    # /* s0 --> sp */
    mv   sp, s0
    mv   a0, s0
    call rt_scheduler_do_irq_switch

    RESTORE_ALL
    mret

    .size   Mcoret_Handler, . - Mcoret_Handler
#endif

    .global Mtspend_Handler
    .global tspend_handler
    .type   Mtspend_Handler, %function
    .type   tspend_handler, %function
Mtspend_Handler:
tspend_handler:
    SAVE_ALL
#ifdef RT_USING_SMP
    /* switch to interrupt stack */
    move  s0, sp

    /* get cpu id */
    csrr  t0, mhartid

    /* switch interrupt stack of current cpu */
    la    sp, g_base_irqstack
    addi  t1, t0, 1
    li    t2, CONFIG_ARCH_INTERRUPTSTACK
    mul   t1, t1, t2
    add   sp, sp, t1 /* sp = (cpuid + 1) * CONFIG_ARCH_INTERRUPTSTACK + g_base_irqstack */
    call  rt_interrupt_enter
    call  ipi_irq
    call  rt_interrupt_leave

    /* s0 --> sp */
    mv  sp, s0
    mv  a0, s0
    call rt_scheduler_do_irq_switch
#else
    /* get rt_thread_switch_interrupt_flag */
    la    t0, rt_thread_switch_interrupt_flag
    LOAD  t2, 0(t0)
    beqz  t2, tspend_exit       /* tspend already handled */
    /* clear rt_thread_switch_interrupt_flag to 0 */
    STORE zero, 0(t0)

    /* switch thread */
    la    t0, rt_interrupt_from_thread
    LOAD  t1, 0(t0)
    STORE sp, 0(t1)

    la    t0, rt_interrupt_to_thread
    LOAD  t1, 0(t0)
    LOAD  sp, 0(t1)

tspend_exit:
#if CONFIG_INTC_CLIC || CONFIG_INTC_CLIC_PLIC
#else
    /* clear tspend */
    li    t0, RISCV_VIC_TSPDR
    li    t2, 0x0
    sw    t2, 0(t0)
#endif
#endif /* RT_USING_SMP */

    RESTORE_ALL
    mret

    .size   Mtspend_Handler, . - Mtspend_Handler
    .size   tspend_handler, . - tspend_handler

#ifdef  RT_USING_SMP
#define rt_hw_interrupt_disable rt_hw_local_irq_disable
#define rt_hw_interrupt_enable  rt_hw_local_irq_enable
#endif

.global cpu_intrpt_restore
.type   cpu_intrpt_restore, %function
.global rt_hw_interrupt_enable
.type   rt_hw_interrupt_enable, %function
cpu_intrpt_restore:
rt_hw_interrupt_enable:
    csrs mstatus, a0    /* restore to old csr */
    jr ra

.size cpu_intrpt_restore, . - cpu_intrpt_restore
.size rt_hw_interrupt_enable, . - rt_hw_interrupt_enable

.global cpu_intrpt_save
.type   cpu_intrpt_save, %function
.global rt_hw_interrupt_disable
.type   rt_hw_interrupt_disable, %function
cpu_intrpt_save:
rt_hw_interrupt_disable:
    csrrci a0, mstatus, 8  /*  clear MIE */
    jr ra

.size cpu_intrpt_save, . - cpu_intrpt_save
.size rt_hw_interrupt_disable, . - rt_hw_interrupt_disable

.global cpu_is_irq_enable
.type   cpu_is_irq_enable, %function
cpu_is_irq_enable:
    csrr a0, mstatus
    andi a0, a0, RISCV_MSTATUS_MIE
    ret

.size cpu_is_irq_enable, . - cpu_is_irq_enable