@@ -57,22 +57,16 @@ _endless_loop:
57
57
# качестве аргумента.
58
58
# В основе кода лежит обработчик из репозитория urv-core:
59
59
# https://github.com/twlostow/urv-core/blob/master/sw/common/irq.S
60
- # Из реализации убраны сохранения нереализованных CS-регистров. Кроме того,
61
- # судя по документу приведенному ниже, обычное ABI подразумевает такое же
62
- # сохранение контекста, что и при программном вызове (EABI подразумевает еще
63
- # меньшее сохранение контекста), поэтому нет нужды сохранять весь регистровый
64
- # файл.
65
- # Документ:
66
- # https://github.com/riscv-non-isa/riscv-eabi-spec/blob/master/EABI.adoc
60
+ # Из реализации убраны сохранения нереализованных CS-регистров.
67
61
_int_handler:
68
62
# Данная операция меняет местами регистры sp и mscratch.
69
63
# В итоге указатель на стек прерываний оказывается в регистре sp , а вершина
70
64
# программного стека оказывается в регистре mscratch.
71
- csrrw sp , mscratch,sp
65
+ csrrw sp , mscratch, sp
72
66
73
67
# Далее мы поднимаемся по стеку прерываний и сохраняем все регистры.
74
- addi sp , sp , -80 # Указатель на стек должен быть выровнен до 16 байт, поэтому
75
- # поднимаемся вверх не на 76 , а на 80 .
68
+ addi sp , sp , -144 # Указатель на стек должен быть выровнен до 16 байт, поэтому
69
+ # поднимаемся вверх не на 136 , а на 144 .
76
70
sw ra, 4 (sp )
77
71
# Мы хотим убедиться, что очередное прерывание не наложит стек прерываний на
78
72
# программный стек, поэтому записываем в освободившийся регистр низ
@@ -84,32 +78,46 @@ _int_handler:
84
78
la ra, _stack_ptr
85
79
blt sp , ra, _endless_loop
86
80
87
- sw t0, 12 (sp ) # Мы перепрыгнули через смещение 8 , поскольку там должен
88
- # лежать регистр sp , который ранее сохранили в mscratch.
89
- # Мы запишем его на стек чуть позже.
90
- sw t1, 16 (sp )
91
- sw t2, 20 (sp )
92
- sw a0 , 24 (sp )
93
- sw a1 , 28 (sp )
94
- sw a2 , 32 (sp )
95
- sw a3 , 36 (sp )
96
- sw a4 , 40 (sp )
97
- sw a5 , 44 (sp )
98
- sw a6 , 48 (sp )
99
- sw a7 , 52 (sp )
100
- sw t3, 56 (sp )
101
- sw t4, 60 (sp )
102
- sw t5, 64 (sp )
103
- sw t6, 68 (sp )
81
+ sw gp,12 (sp ) # Мы перепрыгнули через смещение 8 , поскольку там должен
82
+ # лежать регистр sp , который ранее сохранили в mscratch.
83
+ # Мы запишем его на стек чуть позже.
84
+ sw tp,16 (sp )
85
+ sw t0,20 (sp )
86
+ sw t1,24 (sp )
87
+ sw t2,28 (sp )
88
+ sw s0,32 (sp )
89
+ sw s1,36 (sp )
90
+ sw a0 ,40 (sp )
91
+ sw a1 ,44 (sp )
92
+ sw a2 ,48 (sp )
93
+ sw a3 ,52 (sp )
94
+ sw a4 ,56 (sp )
95
+ sw a5 ,60 (sp )
96
+ sw a6 ,64 (sp )
97
+ sw a7 ,68 (sp )
98
+ sw s2,72 (sp )
99
+ sw s3,76 (sp )
100
+ sw s4,80 (sp )
101
+ sw s5,84 (sp )
102
+ sw s6,88 (sp )
103
+ sw s7,92 (sp )
104
+ sw s8,96 (sp )
105
+ sw s9,100 (sp )
106
+ sw s10,104 (sp )
107
+ sw s11,108 (sp )
108
+ sw t3,112 (sp )
109
+ sw t4,116 (sp )
110
+ sw t5,120 (sp )
111
+ sw t6,124 (sp )
104
112
105
113
# Кроме того, мы сохраняем состояние регистров прерываний на случай, если
106
- # произойдет еще одно прерывание.
107
- csrr t0, mscratch
108
- csrr t1, mepc
109
- csrr a0 , mcause
110
- sw t0, 8 (sp )
111
- sw t1, 72 (sp )
112
- sw a0 , 76 (sp )
114
+ # произойдет ещё одно прерывание.
115
+ csrr t0,mscratch
116
+ csrr t1,mepc
117
+ csrr a0 ,mcause
118
+ sw t0,8 (sp )
119
+ sw t1,128 (sp )
120
+ sw a0 ,132 (sp )
113
121
114
122
# Вызов высокоуровневого обработчика прерываний.
115
123
# Для того чтобы программа скомпоновалась, где-то должна быть описана
@@ -119,33 +127,47 @@ _int_handler:
119
127
# Восстановление контекста. В первую очередь мы хотим восстановить CS-регистры,
120
128
# на случай, если происходило вложенное прерывание. Для этого, мы должны
121
129
# вернуть исходное значение указателя стека прерываний. Однако его нынешнее
122
- # значение нам еще необходимо для восстановления контекста, поэтому мы
130
+ # значение нам ещё необходимо для восстановления контекста, поэтому мы
123
131
# сохраним его в регистр a0 , и будем восстанавливаться из него.
124
132
mv a0 ,sp
125
133
126
- lw t1, 72 (a0 )
127
- addi sp , sp , 80
128
- csrw mscratch, sp
129
- csrw mepc, t1
130
- lw ra, 4 (a0 )
131
- lw sp , 8 (a0 )
132
- lw t0, 12 (a0 )
133
- lw t1, 16 (a0 )
134
- lw t2, 20 (a0 )
135
- lw a1 , 28 (a0 ) # Мы пропустили a0 , потому что сейчас он используется в
136
- # качестве указателя на верхушку стека и не может быть
137
- # восстановлен.
138
- lw a2 , 32 (a0 )
139
- lw a3 , 36 (a0 )
140
- lw a4 , 40 (a0 )
141
- lw a5 , 44 (a0 )
142
- lw a6 , 48 (a0 )
143
- lw a7 , 52 (a0 )
144
- lw t3, 56 (a0 )
145
- lw t4, 60 (a0 )
146
- lw t5, 64 (a0 )
147
- lw t6, 68 (a0 )
148
- lw a0 , 40 (a0 )
134
+ lw t1,128 (a0 )
135
+ addi sp ,sp ,144
136
+ csrw mscratch,sp
137
+ csrw mepc,t1
138
+ lw ra,4 (a0 )
139
+ lw sp ,8 (a0 )
140
+ lw gp,12 (a0 )
141
+ lw tp,16 (a0 )
142
+ lw t0,20 (a0 )
143
+ lw t1,24 (a0 )
144
+ lw t2,28 (a0 )
145
+ lw s0,32 (a0 )
146
+ lw s1,36 (a0 )
147
+ lw a1 ,44 (a0 ) # Мы пропустили a0 , потому что сейчас он используется в
148
+ # качестве указателя на верхушку стека и не может быть
149
+ # восстановлен.
150
+ lw a2 ,48 (a0 )
151
+ lw a3 ,52 (a0 )
152
+ lw a4 ,56 (a0 )
153
+ lw a5 ,60 (a0 )
154
+ lw a6 ,64 (a0 )
155
+ lw a7 ,68 (a0 )
156
+ lw s2,72 (a0 )
157
+ lw s3,76 (a0 )
158
+ lw s4,80 (a0 )
159
+ lw s5,84 (a0 )
160
+ lw s6,88 (a0 )
161
+ lw s7,92 (a0 )
162
+ lw s8,96 (a0 )
163
+ lw s9,100 (a0 )
164
+ lw s10,104 (a0 )
165
+ lw s11,108 (a0 )
166
+ lw t3,112 (a0 )
167
+ lw t4,116 (a0 )
168
+ lw t5,120 (a0 )
169
+ lw t6,124 (a0 )
170
+ lw a0 ,40 (a0 )
149
171
150
172
# Выход из обработчика прерывания
151
173
mret
0 commit comments