Skip to content

Commit f864683

Browse files
committed
Обновление ERRATA
Добавлена информация об исправлении листинга II.14-2.
1 parent 8fec329 commit f864683

File tree

1 file changed

+186
-4
lines changed

1 file changed

+186
-4
lines changed

ERRATA.md

Lines changed: 186 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,208 @@
22

33
![http://95.215.8.74:5000/days_since_last_commit.png](http://95.215.8.74:5000/days_since_last_commit.png)
44

5-
**13.05.2025**: Исправлен рисунок II.8-3 — исправлена опечатка в названии нижнего сигнала (`mem_wd_i``mem_wd_o`).
5+
**13.05.2025**: Исправлен _листинг II.14-2_ — теперь при обработке перехвата сохраняются все регистры регистрового файла, а не только оберегаемые.
6+
7+
В опубликованном издании при реализации обработчика намеренно не было реализовано сохранение необерегаемых регистров. Так было сделано в виду неправильной интерпретации [EABI](https://github.com/riscvarchive/riscv-eabi-spec/blob/master/EABI.adoc#eabi-interrupt-handler-context-save).
8+
9+
На самом деле, при входе в низкоуровневый обработчик необходимо сохранять весь регистровый файл.
10+
11+
<details>
12+
<summary> Обновлённый листинг </summary>
13+
14+
```asm
15+
.section .boot
16+
17+
.global _start
18+
_start:
19+
la gp, _gbl_ptr # Инициализация глобального указателя
20+
la sp, _stack_ptr # Инициализация указателя на стек
21+
22+
# Инициализация (зануление) сегмента bss
23+
la t0, _bss_start
24+
la t1, _bss_end
25+
_bss_init_loop:
26+
blt t1, t0, _irq_config
27+
sw zero, 0(t0)
28+
addi t0, t0, 4
29+
j _bss_init_loop
30+
31+
# Настройка вектора (mtvec) и маски (mie) прерываний, а также указателя на стек
32+
# прерываний (mscratch).
33+
_irq_config:
34+
la t0, _int_handler
35+
li t1, -1 # -1 (все биты равны 1) означает, что разрешены все прерывания
36+
la t2, _trap_stack_ptr
37+
csrw mtvec, t0
38+
csrw mscratch, t2
39+
csrw mie, t1
40+
41+
# Вызов функции main
42+
_main_call:
43+
li a0, 0 # Передача аргументов argc и argv в main. Формально, argc должен
44+
li a1, 0 # быть больше нуля, а argv должен указывать на массив строк,
45+
# нулевой элемент которого является именем исполняемого файла,
46+
# Но для простоты реализации оба аргумента всего лишь обнулены.
47+
# Это сделано для детерминированного поведения программы в случае,
48+
# если программист будет пытаться использовать эти аргументы.
49+
50+
# Вызов main.
51+
# Для того чтобы программа скомпоновалась, где-то должна быть описана
52+
# функция именно с таким именем.
53+
call main
54+
# Зацикливание после выхода из функции main
55+
_endless_loop:
56+
j _endless_loop
57+
58+
# Низкоуровневый обработчик прерывания отвечает за:
59+
# * Сохранение и восстановление контекста;
60+
# * Вызов высокоуровневого обработчика с передачей id источника прерывания в
61+
# качестве аргумента.
62+
# В основе кода лежит обработчик из репозитория urv-core:
63+
# https://github.com/twlostow/urv-core/blob/master/sw/common/irq.S
64+
# Из реализации убраны сохранения нереализованных CS-регистров.
65+
_int_handler:
66+
# Данная операция меняет местами регистры sp и mscratch.
67+
# В итоге указатель на стек прерываний оказывается в регистре sp, а вершина
68+
# программного стека оказывается в регистре mscratch.
69+
csrrw sp, mscratch, sp
70+
71+
# Далее мы поднимаемся по стеку прерываний и сохраняем все регистры.
72+
addi sp, sp, -144 # Указатель на стек должен быть выровнен до 16 байт, поэтому
73+
# поднимаемся вверх не на 136, а на 144.
74+
sw ra, 4(sp)
75+
# Мы хотим убедиться, что очередное прерывание не наложит стек прерываний на
76+
# программный стек, поэтому записываем в освободившийся регистр низ
77+
# программного стека, и проверяем что приподнятый указатель на верхушку
78+
# стека прерываний не залез в программный стек.
79+
# В случае, если это произошло (произошло переполнение стека прерываний),
80+
# мы хотим остановить работу процессора, чтобы не потерять данные, которые
81+
# могут помочь нам в отладке этой ситуации.
82+
la ra, _stack_ptr
83+
blt sp, ra, _endless_loop
84+
85+
sw gp,12(sp) # Мы перепрыгнули через смещение 8, поскольку там должен
86+
# лежать регистр sp, который ранее сохранили в mscratch.
87+
# Мы запишем его на стек чуть позже.
88+
sw tp,16(sp)
89+
sw t0,20(sp)
90+
sw t1,24(sp)
91+
sw t2,28(sp)
92+
sw s0,32(sp)
93+
sw s1,36(sp)
94+
sw a0,40(sp)
95+
sw a1,44(sp)
96+
sw a2,48(sp)
97+
sw a3,52(sp)
98+
sw a4,56(sp)
99+
sw a5,60(sp)
100+
sw a6,64(sp)
101+
sw a7,68(sp)
102+
sw s2,72(sp)
103+
sw s3,76(sp)
104+
sw s4,80(sp)
105+
sw s5,84(sp)
106+
sw s6,88(sp)
107+
sw s7,92(sp)
108+
sw s8,96(sp)
109+
sw s9,100(sp)
110+
sw s10,104(sp)
111+
sw s11,108(sp)
112+
sw t3,112(sp)
113+
sw t4,116(sp)
114+
sw t5,120(sp)
115+
sw t6,124(sp)
116+
117+
# Кроме того, мы сохраняем состояние регистров прерываний на случай, если
118+
# произойдет ещё одно прерывание.
119+
csrr t0,mscratch
120+
csrr t1,mepc
121+
csrr a0,mcause
122+
sw t0,8(sp)
123+
sw t1,128(sp)
124+
sw a0,132(sp)
125+
126+
# Вызов высокоуровневого обработчика прерываний.
127+
# Для того чтобы программа скомпоновалась, где-то должна быть описана
128+
# функция именно с таким именем.
129+
call int_handler
130+
131+
# Восстановление контекста. В первую очередь мы хотим восстановить CS-регистры,
132+
# на случай, если происходило вложенное прерывание. Для этого, мы должны
133+
# вернуть исходное значение указателя стека прерываний. Однако его нынешнее
134+
# значение нам ещё необходимо для восстановления контекста, поэтому мы
135+
# сохраним его в регистр a0, и будем восстанавливаться из него.
136+
mv a0,sp
137+
138+
lw t1,128(a0)
139+
addi sp,sp,144
140+
csrw mscratch,sp
141+
csrw mepc,t1
142+
lw ra,4(a0)
143+
lw sp,8(a0)
144+
lw gp,12(a0)
145+
lw tp,16(a0)
146+
lw t0,20(a0)
147+
lw t1,24(a0)
148+
lw t2,28(a0)
149+
lw s0,32(a0)
150+
lw s1,36(a0)
151+
lw a1,44(a0) # Мы пропустили a0, потому что сейчас он используется в
152+
# качестве указателя на верхушку стека и не может быть
153+
# восстановлен.
154+
lw a2,48(a0)
155+
lw a3,52(a0)
156+
lw a4,56(a0)
157+
lw a5,60(a0)
158+
lw a6,64(a0)
159+
lw a7,68(a0)
160+
lw s2,72(a0)
161+
lw s3,76(a0)
162+
lw s4,80(a0)
163+
lw s5,84(a0)
164+
lw s6,88(a0)
165+
lw s7,92(a0)
166+
lw s8,96(a0)
167+
lw s9,100(a0)
168+
lw s10,104(a0)
169+
lw s11,108(a0)
170+
lw t3,112(a0)
171+
lw t4,116(a0)
172+
lw t5,120(a0)
173+
lw t6,124(a0)
174+
lw a0,40(a0)
175+
176+
# Выход из обработчика прерывания
177+
mret
178+
179+
```
180+
181+
_Листинг 2. Пример содержимого файла первичных команд с поясняющими комментариями._
182+
183+
</details>
184+
185+
---
186+
187+
**13.05.2025**: _Исправлен рисунок II.8-3_ — опечатка в названии нижнего сигнала (`mem_wd_i``mem_wd_o`).
6188

7189
<details>
8190
<summary> Обновлённый рисунок </summary>
9191

10192
![.pic/Labs/lab_08_lsu/fig_03.wavedrom.svg](.pic/Labs/lab_08_lsu/fig_03.wavedrom.svg)
11193

12-
Рисунок II.8-3. Временна́я диаграмма запросов на запись со стороны ядра и сигнала mem_wd_o.
194+
_Рисунок II.8-3. Временна́я диаграмма запросов на запись со стороны ядра и сигнала mem_wd_o._
13195

14196
</details>
15197

16198
---
17199

18-
**29.03.2025**: Исправлен рисунок II.4-4 — убрана логика безусловного перехода, т.к. она должна была появиться только в следующем параграфе.
200+
**29.03.2025**: _Исправлен рисунок II.4-4_ — убрана логика безусловного перехода, т.к. она должна была появиться только в следующем параграфе.
19201

20202
<details>
21203
<summary> Обновлённый рисунок </summary>
22204

23205
![.pic/Labs/lab_04_cybercobra/ppd_4.drawio.svg](.pic/Labs/lab_04_cybercobra/ppd_4.drawio.svg)
24206

25-
Рисунок II.4-4. Реализация условного перехода.
207+
_Рисунок II.4-4. Реализация условного перехода._
26208

27209
</details>

0 commit comments

Comments
 (0)