实现中断与异常

This commit is contained in:
2025-04-18 19:18:49 +08:00
parent a096b91bc1
commit 38d433558d
11 changed files with 392 additions and 10 deletions

49
riscv/context.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef context_h__
#define context_h__
#include "stdint.h"
typedef struct {
uint32_t ra;//x1 0
uint32_t sp;//x2 1
uint32_t gp;//x3 2
uint32_t tp;//x4 3
uint32_t t0;//x5 4
uint32_t t1;//x6 5
uint32_t t2;//x7 6
uint32_t t6;//x31 7
uint32_t s1;//x9 8
uint32_t a0;//x10 9
uint32_t a1;//x11 10
uint32_t a2;//x12 11
uint32_t a3;//x13 12
uint32_t a4;//x14 13
uint32_t a5;//x15 14
uint32_t a6;//x16 15
uint32_t a7;//x17 16
uint32_t s2;//x18 17
uint32_t s3;//x19 18
uint32_t s4;//x20 19
uint32_t s5;//x21 20
uint32_t s6;//x22 21
uint32_t s7;//x23 22
uint32_t s8;//x24 23
uint32_t s9;//x25 24
uint32_t s10;//x26 25
uint32_t s11;//x27 26
uint32_t t3;//x28 27
uint32_t t4;//x29 28
uint32_t t5;//x30 29
uint32_t s0;//fp(x8) 30
uint32_t mstatus;//31
uint32_t mepc;//32
} stack_context;
#endif

View File

@@ -2,6 +2,43 @@
#ifndef head_h__
#define head_h__
#define read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define write_csr(reg, val) ({ \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
else \
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
#define swap_csr(reg, val) ({ unsigned long __tmp; \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
else \
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
__tmp; })
#define set_csr(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define clear_csr(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
int my_printf(const char* fmt, ...);
void cpu_test();

13
riscv/interrupt.c Normal file
View File

@@ -0,0 +1,13 @@
#include "context.h"
#include "head.h"
void interrupt_entry(uint32_t irq_num) {
my_printf("interrupt_entry %d\n", irq_num);
}
void trap_entry(uint32_t irq_num) {
my_printf("trap_entry %d\n", irq_num);
write_csr(mscratch, 0xffffffff);
}

View File

@@ -44,12 +44,19 @@ int main()
{
int a=1;
int b=2;
// typedef void (*fun_t)(void);
// fun_t fun = (fun_t)0xffffffff;
// fun();
int c = add(a, b);
my_printf("Hello World! %s\n", "Andy");
my_printf("add(%d, %d)=%d\n", a, b, c);
a = 67;b = -78;
my_printf("mul(%d, %d)=%d\n", a, b, a * b);
my_printf("ram_val test: %s\n", g_string);
set_csr(mstatus, 0x00000008);
set_csr(mie, (1 << 3));
set_csr(mip, (1 << 3));
cpu_test();
return 0;
}

View File

@@ -4,6 +4,7 @@
.type _start,@function
.extern main
.extern trap_handler
_start:
la sp, _sp
@@ -30,6 +31,8 @@ _start:
addi a0, a0, 4
bltu a0, a1, 1b
2:
la a0, trap_handler
csrw mtvec, a0
/* Call global constructors */
# la a0, __libc_fini_array

116
riscv/trap.S Normal file
View File

@@ -0,0 +1,116 @@
.equ REGBYTES, 0x4
.macro PUSH_ALL_REG
addi sp, sp, -33*REGBYTES
sw x1, 0*REGBYTES(sp) //ra
sw x2, 1*REGBYTES(sp) //sp
sw x3, 2*REGBYTES(sp) //gp
sw x4, 3*REGBYTES(sp) //tp
sw x5, 4*REGBYTES(sp) //t0
sw x6, 5*REGBYTES(sp) //t1
sw x7, 6*REGBYTES(sp) //t2
sw x8, 30*REGBYTES(sp)
sw x9, 8*REGBYTES(sp)
sw x10, 9*REGBYTES(sp) //a0
sw x11, 10*REGBYTES(sp) //a1
sw x12, 11*REGBYTES(sp) //a2
sw x13, 12*REGBYTES(sp) //a3
sw x14, 13*REGBYTES(sp) //a4
sw x15, 14*REGBYTES(sp) //a5
sw x16, 15*REGBYTES(sp) //a6
sw x17, 16*REGBYTES(sp) //a7
sw x18, 17*REGBYTES(sp)
sw x19, 18*REGBYTES(sp)
sw x20, 19*REGBYTES(sp)
sw x21, 20*REGBYTES(sp)
sw x22, 21*REGBYTES(sp)
sw x23, 22*REGBYTES(sp)
sw x24, 23*REGBYTES(sp)
sw x25, 24*REGBYTES(sp)
sw x26, 25*REGBYTES(sp)
sw x27, 26*REGBYTES(sp)
sw x28, 27*REGBYTES(sp) //t3
sw x29, 28*REGBYTES(sp) //t4
sw x30, 29*REGBYTES(sp) //t5
sw x31, 7*REGBYTES(sp) //t6
csrr t0, mstatus
sw t0, 31*REGBYTES(sp)
csrr t0, mepc
sw t0, 32*REGBYTES(sp)
.endm
.macro POP_ALL_REG
lw t0, 31* REGBYTES(sp)
csrw mstatus, t0
lw t0, 32 * REGBYTES(sp)
csrw mepc, t0
lw x1, 0*REGBYTES(sp) //ra
lw x5, 4*REGBYTES(sp)
lw x6, 5*REGBYTES(sp)
lw x7, 6*REGBYTES(sp)
lw x8, 30*REGBYTES(sp)
lw x9, 8*REGBYTES(sp)
lw x10, 9*REGBYTES(sp)
lw x11, 10*REGBYTES(sp)
lw x12, 11*REGBYTES(sp)
lw x13, 12*REGBYTES(sp)
lw x14, 13*REGBYTES(sp)
lw x15, 14*REGBYTES(sp)
lw x16, 15*REGBYTES(sp)
lw x17, 16*REGBYTES(sp)
lw x18, 17*REGBYTES(sp)
lw x19, 18*REGBYTES(sp)
lw x20, 19*REGBYTES(sp)
lw x21, 20*REGBYTES(sp)
lw x22, 21*REGBYTES(sp)
lw x23, 22*REGBYTES(sp)
lw x24, 23*REGBYTES(sp)
lw x25, 24*REGBYTES(sp)
lw x26, 25*REGBYTES(sp)
lw x27, 26*REGBYTES(sp)
lw x28, 27*REGBYTES(sp)
lw x29, 28*REGBYTES(sp)
lw x30, 29*REGBYTES(sp)
lw x31, 7*REGBYTES(sp)
addi sp, sp, 33*REGBYTES
.endm
# .section .interrupt.text
.extern trap_entry
.global trap_entry_
.align 4
trap_entry_:
csrw mscratch, sp
la sp, _exc_sp
call trap_entry
csrr sp, mscratch
POP_ALL_REG
mret
# .section .interrupt.text
.extern trap_entry
.extern interrupt_entry
.global trap_handler
.equ TRAP_INTERRUPT_MODE_MASK, 0x80000000
.align 4
trap_handler:
PUSH_ALL_REG
csrr a0, mcause
li a1, TRAP_INTERRUPT_MODE_MASK
li a2, 0x000000ff
and a1, a0, a1
and a0, a2, a0
beqz a1, trap_entry_
csrw mscratch, sp
la sp, _irq_sp
call interrupt_entry
csrr sp, mscratch
POP_ALL_REG
mret