mirror of
https://github.com/MPSU/APS.git
synced 2025-09-18 02:10:40 +00:00
Удаление дубликата startup.S в ЛР № 16
Все ссылки и так вели на 14 лабу, прямым текстом написано брать оттуда
This commit is contained in:
@@ -1,151 +0,0 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
|
||||||
* Project Name : Architectures of Processor Systems (APS) lab work
|
|
||||||
* Organization : National Research University of Electronic Technology (MIET)
|
|
||||||
* Department : Institute of Microdevices and Control Systems
|
|
||||||
* Author(s) : Andrei Solodovnikov
|
|
||||||
* Email(s) : hepoh@org.miet.ru
|
|
||||||
|
|
||||||
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
|
|
||||||
* ------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
.section .boot
|
|
||||||
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
la gp, _gbl_ptr # Инициализация глобального указателя
|
|
||||||
la sp, _stack_ptr # Инициализация указателя на стек
|
|
||||||
|
|
||||||
# Инициализация (зануление) сегмента bss
|
|
||||||
la t0, _bss_start
|
|
||||||
la t1, _bss_end
|
|
||||||
_bss_init_loop:
|
|
||||||
blt t1, t0, _irq_config
|
|
||||||
sw zero, 0(t0)
|
|
||||||
addi t0, t0, 4
|
|
||||||
j _bss_init_loop
|
|
||||||
|
|
||||||
# Настройка вектора (mtvec) и маски (mie) прерываний, а также указателя на стек
|
|
||||||
# прерываний (mscratch).
|
|
||||||
_irq_config:
|
|
||||||
la t0, _int_handler
|
|
||||||
li t1, -1 # -1 (все биты равны 1) означает, что разрешены все прерывания
|
|
||||||
la t2, _trap_stack_ptr
|
|
||||||
csrw mtvec, t0
|
|
||||||
csrw mscratch, t2
|
|
||||||
csrw mie, t1
|
|
||||||
|
|
||||||
# Вызов функции main
|
|
||||||
_main_call:
|
|
||||||
li a0, 0 # Передача аргументов argc и argv в main. Формально, argc должен
|
|
||||||
li a1, 0 # быть больше нуля, а argv должен указывать на массив строк,
|
|
||||||
# нулевой элемент которого является именем исполняемого файла,
|
|
||||||
# Но для простоты реализации оба аргумента всего лишь обнулены.
|
|
||||||
# Это сделано для детерминированного поведения программы в случае,
|
|
||||||
# если программист будет пытаться использовать эти аргументы.
|
|
||||||
|
|
||||||
# Вызов main.
|
|
||||||
# Для того чтобы программа скомпоновалась, где-то должна быть описана
|
|
||||||
# функция именно с таким именем.
|
|
||||||
call main
|
|
||||||
# Зацикливание после выхода из функции main
|
|
||||||
_endless_loop:
|
|
||||||
j _endless_loop
|
|
||||||
|
|
||||||
# Низкоуровневый обработчик прерывания отвечает за:
|
|
||||||
# * Сохранение и восстановление контекста;
|
|
||||||
# * Вызов высокоуровневого обработчика с передачей id источника прерывания в
|
|
||||||
# качестве аргумента.
|
|
||||||
# В основе кода лежит обработчик из репозитория urv-core:
|
|
||||||
# https://github.com/twlostow/urv-core/blob/master/sw/common/irq.S
|
|
||||||
# Из реализации убраны сохранения нереализованных CS-регистров. Кроме того,
|
|
||||||
# в реализации сохраняются только необерегаемые регистры регистрового файла.
|
|
||||||
# Это сделано по причине того, что при вызове высокоуровневого обработчика
|
|
||||||
# прерываний, тот будет обязан сохранить оберегаемые регистры в соответствии
|
|
||||||
# с соглашением о вызовах.
|
|
||||||
_int_handler:
|
|
||||||
# Данная операция меняет местами регистры sp и mscratch.
|
|
||||||
# В итоге указатель на стек прерываний оказывается в регистре sp, а вершина
|
|
||||||
# программного стека оказывается в регистре mscratch.
|
|
||||||
csrrw sp, mscratch,sp
|
|
||||||
|
|
||||||
# Далее мы поднимаемся по стеку прерываний и сохраняем все регистры.
|
|
||||||
addi sp, sp, -80 # Указатель на стек должен быть выровнен до 16 байт, поэтому
|
|
||||||
# поднимаемся вверх не на 76, а на 80.
|
|
||||||
sw ra, 4(sp)
|
|
||||||
# Мы хотим убедиться, что очередное прерывание не наложит стек прерываний на
|
|
||||||
# программный стек, поэтому записываем в освободившийся регистр низ
|
|
||||||
# программного стека, и проверяем что приподнятый указатель на верхушку
|
|
||||||
# стека прерываний не залез в программный стек.
|
|
||||||
# В случае, если это произошло (произошло переполнение стека прерываний),
|
|
||||||
# мы хотим остановить работу процессора, чтобы не потерять данные, которые
|
|
||||||
# могут помочь нам в отладке этой ситуации.
|
|
||||||
la ra, _stack_ptr
|
|
||||||
blt sp, ra, _endless_loop
|
|
||||||
|
|
||||||
sw t0, 12(sp) # Мы перепрыгнули через смещение 8, поскольку там должен
|
|
||||||
# лежать регистр sp, который ранее сохранили в mscratch.
|
|
||||||
# Мы запишем его на стек чуть позже.
|
|
||||||
sw t1, 16(sp)
|
|
||||||
sw t2, 20(sp)
|
|
||||||
sw a0, 24(sp)
|
|
||||||
sw a1, 28(sp)
|
|
||||||
sw a2, 32(sp)
|
|
||||||
sw a3, 36(sp)
|
|
||||||
sw a4, 40(sp)
|
|
||||||
sw a5, 44(sp)
|
|
||||||
sw a6, 48(sp)
|
|
||||||
sw a7, 52(sp)
|
|
||||||
sw t3, 56(sp)
|
|
||||||
sw t4, 60(sp)
|
|
||||||
sw t5, 64(sp)
|
|
||||||
sw t6, 68(sp)
|
|
||||||
|
|
||||||
# Кроме того, мы сохраняем состояние регистров прерываний на случай, если
|
|
||||||
# произойдет ещё одно прерывание.
|
|
||||||
csrr t0, mscratch
|
|
||||||
csrr t1, mepc
|
|
||||||
csrr a0, mcause
|
|
||||||
sw t0, 8(sp)
|
|
||||||
sw t1, 72(sp)
|
|
||||||
sw a0, 76(sp)
|
|
||||||
|
|
||||||
# Вызов высокоуровневого обработчика прерываний.
|
|
||||||
# Для того чтобы программа скомпоновалась, где-то должна быть описана
|
|
||||||
# функция именно с таким именем.
|
|
||||||
call int_handler
|
|
||||||
|
|
||||||
# Восстановление контекста. В первую очередь мы хотим восстановить CS-регистры,
|
|
||||||
# на случай, если происходило вложенное прерывание. Для этого, мы должны
|
|
||||||
# вернуть исходное значение указателя стека прерываний. Однако его нынешнее
|
|
||||||
# значение нам ещё необходимо для восстановления контекста, поэтому мы
|
|
||||||
# сохраним его в регистр a0, и будем восстанавливаться из него.
|
|
||||||
mv a0,sp
|
|
||||||
|
|
||||||
lw t1, 72(a0)
|
|
||||||
lw t2, 76(a0)
|
|
||||||
addi sp, sp, 80
|
|
||||||
csrw mscratch, sp
|
|
||||||
csrw mepc, t1
|
|
||||||
csrw mcause, t2
|
|
||||||
lw ra, 4(a0)
|
|
||||||
lw sp, 8(a0)
|
|
||||||
lw t0, 12(a0)
|
|
||||||
lw t1, 16(a0)
|
|
||||||
lw t2, 20(a0)
|
|
||||||
lw a1, 28(a0) # Мы пропустили a0, потому что сейчас он используется в
|
|
||||||
# качестве указателя на верхушку стека и не может быть
|
|
||||||
# восстановлен.
|
|
||||||
lw a2, 32(a0)
|
|
||||||
lw a3, 36(a0)
|
|
||||||
lw a4, 40(a0)
|
|
||||||
lw a5, 44(a0)
|
|
||||||
lw a6, 48(a0)
|
|
||||||
lw a7, 52(a0)
|
|
||||||
lw t3, 56(a0)
|
|
||||||
lw t4, 60(a0)
|
|
||||||
lw t5, 64(a0)
|
|
||||||
lw t6, 68(a0)
|
|
||||||
lw a0, 40(a0)
|
|
||||||
|
|
||||||
# Выход из обработчика прерывания
|
|
||||||
mret
|
|
Reference in New Issue
Block a user