riscv gdb machine mode

[root@centos7 04_interrupt]# cat src/head.s
 .section .text.init
     .align 3
     .globl _start
     .extern start_kernel
     .extern stack_top
     .extern _strap 
     .extern bss_start
     .extern bss_end
     .equ MTIMR, 0x200bff8
     .equ MTIMECMP, 0x2004000
_start:
     csrci mstatus,8  
     li t0,0x1800  
     csrc mstatus,t0  
     li t0,0x800  
     csrs mstatus,t0  
     li t0,0x888  
     csrc mie,t0
     la t0,fail1  
     csrw mtvec,t0  
     la t0,super  
     csrw mepc,t0
     
lean_bss:  
         la t0, bss_start  
         la t1, bss_end  
         li t2,0
clean_loop:
     sw t2, 0(t0)
     addi t0, t0, 1
     bne t0, t1, clean_loop
     
init_mtimecpp:
     li t2,MTIMR                /* mtimecpp=mtimr+100000 */  
     ld t0,0(t2)
     li t1,0x100000
     add t0, t0, t1
     li t1, MTIMECMP
     sd t0, 0(t1)
open_interupt:
     li t0,0x0A                  /* set [m/s]staus & [m/s]ie & mideleg */
     csrs mstatus, t0  
     li t0,0x0A0  
     csrs mie, t0
     li t0,0x20
     csrs mideleg, t0  
     mret    # 转入super
     
super: 
    la t0,st_reg 
    csrw stvec,t0
    la sp,stack_top  
    call t0,start_kernel
    
fail1:
    csrr a1,mcause
    li t0,0x8000000000000007   
     /* check the mcause to see if it's a time trap*/
    beq a1,t0,is_a_trap  //中断委托代理
    li t2,MTIMECMP
      /* ecall from S so mtimecpp+=fff000/enable mie/disable mip */
    ld t0,0(t2)  
    li t1,0xfff000  
    add t0, t0, t1  
    sd t0, 0(t2)  
    li t0,0x80  
    csrs mie, t0  
    li t0,0x20  
    csrc mip,t1  
    csrr t0,mepc   ##更新mepc
    addi t0, t0, 4  
    csrw mepc,t0  
    mret
is_a_trap:
    li t0,0x80                   /* time trap so enable mip/disable mie */
    csrc mie, t0  
    li t0,0x20  
    csrs mip,t0  
    mret

 

 

     csrci mstatus,8  #MPIE清零
     li t0,0x1800  
     csrc mstatus,t0  #MPP=00
     li t0,0x800  
     csrs mstatus,t0  #MPP=01 s模式
     li t0,0x888  
     csrc mie,t0
     la t0,fail1  
     csrw mtvec,t0  
     la t0,super  
     csrw mepc,t0
  • machine mode处理函数分析异常原因,判断为时钟中断,为了将时钟中断委托给supervisor mode,于是将mip[stip]置位,并且为了防止在supervisor mode处理时钟中断时继续触发machine mode时钟中断,于是同时将mie[mtie]清零。

is_a_trap:
    li t0,0x80                   /* time trap so enable mip/disable mie */
    csrc mie, t0  #disable  mie time
    li t0,0x20  
    csrs mip,t0  #enable sTIP
    mret

当处理同步异常时应该在退出前给mepc+4,当处理中断时则不需要,请解释为什么要这样做。
mepc储存返回地址。出现同步异常后,返回地址更新为当前发生异常指令的地址,但是真正的返回地址应该是异常指令的下一条指令,故要执行mepc=mepc+4。处理中断时,mepc已储存下一条指令地址,故不需要自增。

  csrr t0,mepc   ##更新mepc
    addi t0, t0, 4  
    csrw mepc,t0  
    mret

整个代码没有设置xepc等价于

mip 寄存器

mip 寄存器指示了何种类型的中断正在传入 (pending),与它相同功能的寄存器有 sip 和 uip 。

在该寄存器中,只有低特权级别的软件中断位 (USIP, SSIP)、时钟中断 (UTIP, STIP) 、外部中断 (UEIP, SEIP) 是可以通过 CSR 指令写入的,其他都是只读的。若有中断委托给了权限级别 x ,被委托的中断所对应的位(在 xie 和 xip 寄存器中)就可以使用了,否则,相应的位接地变 0

xTIP: timer interrupt-pending bit in x mode 时钟中断
xSIP: software interrupts in x mode 软件中断
xEIP: external interrupt 外部中断

请注意,MTIP 、STIP 、UTIP 位分别对应机器模式、监管者模式、用户模式的时钟中断信号。MTIP 位是只读的,而 UTIP 和 STIP 位在机器模式下可以写入,这就是将时钟中断处理下放给低级权限的方式。

mie 寄存器 

mie 寄存器包含了相应的中断使能位,sie 和 uie 功能相似。注意观察 mcause 寄存器编码,可以发现,若 bit i 在 mie 和 mip 寄存器都置位,且全局中断位打开,那么中断 i 就会视作发生,并被处理。一般情况下,在低权限运行时,机器模式的中断一直有效。

xTIE: timer interrupt-enable bit in x mode 时钟中断使能位
xSIE: software interrupt-enable in x mode 软件中断使能位
xEIE: external interrupt-enable in x mode 外部中断使能位

注: WPRI: Write Preserve values, Reads Ignore values. 保留值
xIE: Interrupt Enable in x mode 中断使能
xPIE: Previous Interrupt Enable in x mode 之前的中断使能
xPP: Previous Privilege mode up to x mode 之前的特权级别

在中断使能方面,MIE 、SIE 、UIE 分别提供了 machine mode 、supervisor mode 、user mode 的全局中断使能位,若一个 hart 运行在特权级别 x 下,当 xIE = 1 时中断全局打开,反之则关闭。在 hart 于 x 运行时,无论 wIE 为何值,低权限中断 w < x 总是无效的,而无论 yIE 为何值,高权限中断 y > x 总是有效。

mcause 寄存器 

mcause 寄存器的作用是记录中断/异常事件的类型/起因。在当 trap 进入机器模式后,将异常/中断事件产生的起因(或者称之为谁导致了异常/中断事件)写入到该寄存器中。

mcause 寄存器编码形式,首位为 1 时是中断,0 时为异常
mcause 寄存器对应事件表
fail1:
    csrr a1,mcause
    li t0,0x8000000000000007   
     /* check the mcause to see if it's a time trap*/
    beq a1,t0,is_a_trap  ##相等
    li t2,MTIMECMP
      /* ecall from S so mtimecpp+=fff000/enable mie/disable mip */
    ld t0,0(t2)  
    li t1,0xfff000  
    add t0, t0, t1  
    sd t0, 0(t2)  
    li t0,0x80  
    csrs mie, t0  
    li t0,0x20  
    csrc mip,t1  
    csrr t0,mepc   
    addi t0, t0, 4  
    csrw mepc,t0  
    mret
is_a_trap:
    li t0,0x80                   /* time trap so enable mip/disable mie */
    csrc mie, t0  #disable  mie time
    li t0,0x20  
    csrs mip,t0  #enable sTIP
    mret
 [root@centos7 04_interrupt]# riscv64-unknown-elf-gdb -x debug.txt
GNU gdb (GDB) 11.1
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=aarch64-unknown-linux-gnu --target=riscv64-unknown-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
warning: Can not parse XML target description; XML support was disabled at compile time
0x0000000000001000 in ?? ()
(gdb) b _start
Breakpoint 1 at 0x80000000: file src/head.s, line 12.
(gdb) b lean_bss
Breakpoint 2 at 0x8000003a: file src/head.s, line 25.
(gdb) b clean_loop
Breakpoint 3 at 0x8000004c: file src/head.s, line 29.
(gdb) b init_mtimecpp
Breakpoint 4 at 0x80000056: file src/head.s, line 34.
(gdb) b open_interupt
Breakpoint 5 at 0x8000006e: file src/head.s, line 41.
(gdb) b super
Breakpoint 6 at 0x80000088: file src/head.s, line 50.
(gdb) b fail1
Breakpoint 7 at 0x800000a0: file src/head.s, line 56.
(gdb) b is_a_trap
Breakpoint 8 at 0x800000e0: file src/head.s, line 75.
(gdb) c
Continuing.

Breakpoint 1, _start () at src/head.s:12
12           csrci mstatus,8  
(gdb) c
Continuing.

Breakpoint 2, lean_bss () at src/head.s:25
25               la t0, bss_start  
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 4, init_mtimecpp () at src/head.s:34
34           li t2,MTIMR                /* mtimecpp=mtimr+100000 */  
(gdb) c
Continuing.

Breakpoint 5, open_interupt () at src/head.s:41
41           li t0,0x0A                  /* set [m/s]staus & [m/s]ie & mideleg */
(gdb) c
Continuing.

Breakpoint 6, super () at src/head.s:50
50              la t0,st_reg 
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 8, is_a_trap () at src/head.s:75
75          li t0,0x80                   /* time trap so enable mip/disable mie */
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 7, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) cc
[root@centos7 04_interrupt]# cat src/entry.s
.section .text.entry
     .align 3
     .global st_reg  
     .global ld_reg  
     .global myentry  
     .extern strap_c
     
st_reg:
     sd sp, -8(sp)  
     sd ra, -16(sp)  
     sd gp, -24(sp)  
     sd tp, -32(sp)  
     sd t0, -40(sp)  
     sd t1, -48(sp)  
     sd t2, -56(sp)
     sd s0, -64(sp)  
     sd s1, -72(sp)  
     sd a0, -80(sp)  
     sd a1, -88(sp)  
     sd a2, -96(sp)  
     sd a3, -104(sp)  
     sd a4, -112(sp)  
     sd a5, -120(sp)  
     sd a6, -128(sp)  
     sd a7, -136(sp)  
     sd s2, -144(sp)  
     sd s3, -152(sp)  
     sd s4, -160(sp)  
     sd s5, -168(sp)  
     sd s6, -176(sp)  
     sd s7, -184(sp)  
     sd s8, -192(sp)  
     sd s9, -200(sp)  
     sd s10, -208(sp) 
     sd s11, -216(sp) 
     sd t3, -224(sp)  
     sd t4, -232(sp)  
     sd t5, -240(sp)  
     sd t6, -248(sp)  
     addi sp, sp, -248
     
myentry: 
         call strap_c  
         ecall
     
ld_reg: 
     ld t6, 0(sp)  
     ld t5, 8(sp)  
     ld t4, 16(sp)  
     ld t3, 24(sp)  
     ld s11, 32(sp)  
     ld s10, 40(sp)  
     ld s9, 48(sp)  
     ld s8, 56(sp)  
     ld s7, 64(sp)  
     ld s6, 72(sp)  
     ld s5, 80(sp)  
     ld s4, 88(sp)  
     ld s3, 96(sp)  
     ld s2, 104(sp)  
     ld a7, 112(sp)  
     ld a6, 120(sp)  
     ld a5, 128(sp)  
     ld a4, 136(sp)  
     ld a3, 144(sp)  
     ld a2, 152(sp)  
     ld a1, 160(sp)  
     ld a0, 168(sp)  
     ld s1, 176(sp)  
     ld s0, 184(sp)  
     ld t2, 192(sp)  
     ld t1, 200(sp)  
     ld t0, 208(sp)
     ld tp, 216(sp)  
     ld gp, 224(sp)  
     ld ra, 232(sp)  
     ld sp, 240(sp)  
     sret
[root@centos7 04_interrupt]# qemu-system-riscv64 -M virt -kernel kernel.img -bios none -serial stdio -s -S
VNC server running on ::1:5900
ZJU OS LAB 2             GROUP-05
[S] Supervisor Mode Timer Interrupt 
[S] Supervisor Mode Timer Interrupt 
[S] Supervisor Mode Timer Interrupt 
[S] Supervisor Mode Timer Interrupt 
qemu-system-riscv64: terminating on signal 2
[root@centos7 04_interrupt]# cat debug.txt 
file kernel.elf
target remote :1234
 b _start
 b lean_bss
 b clean_loop
 b init_mtimecpp
 b open_interupt
 b super
 b st_reg
 b myentry
 b strap_c
 b ld_reg
 b fail1
 b is_a_trap
[root@centos7 04_interrupt]# riscv64-unknown-elf-gdb -x debug.txt
GNU gdb (GDB) 11.1
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=aarch64-unknown-linux-gnu --target=riscv64-unknown-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
warning: Can not parse XML target description; XML support was disabled at compile time
0x0000000000001000 in ?? ()
Breakpoint 1 at 0x80000000: file src/head.s, line 12.
Breakpoint 2 at 0x8000003a: file src/head.s, line 25.
Breakpoint 3 at 0x8000004c: file src/head.s, line 29.
Breakpoint 4 at 0x80000056: file src/head.s, line 34.
Breakpoint 5 at 0x8000006e: file src/head.s, line 41.
Breakpoint 6 at 0x80000088: file src/head.s, line 50.
Breakpoint 7 at 0x800000f8: file src/entry.s, line 9.
Breakpoint 8 at 0x80000178: file src/entry.s, line 43.
Breakpoint 9 at 0x8000031c: file src/strap.c, line 6.
Breakpoint 10 at 0x80000180: file src/entry.s, line 47.
Breakpoint 11 at 0x800000a0: file src/head.s, line 56.
Breakpoint 12 at 0x800000e0: file src/head.s, line 75.
(gdb) c
Continuing.

Breakpoint 1, _start () at src/head.s:12
12           csrci mstatus,8  
(gdb) c
Continuing.

Breakpoint 2, lean_bss () at src/head.s:25
25               la t0, bss_start  
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 3, clean_loop () at src/head.s:29
29           sw t2, 0(t0)
(gdb) c
Continuing.

Breakpoint 4, init_mtimecpp () at src/head.s:34
34           li t2,MTIMR                /* mtimecpp=mtimr+100000 */  
(gdb) c
Continuing.

Breakpoint 5, open_interupt () at src/head.s:41
41           li t0,0x0A                  /* set [m/s]staus & [m/s]ie & mideleg */
(gdb) c
Continuing.

Breakpoint 6, super () at src/head.s:50
50              la t0,st_reg 
(gdb) c
Continuing.

Breakpoint 11, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 12, is_a_trap () at src/head.s:75
75          li t0,0x80                   /* time trap so enable mip/disable mie */
(gdb) c
Continuing.

Breakpoint 7, st_reg () at src/entry.s:9
9            sd sp, -8(sp)  
(gdb) c
Continuing.

Breakpoint 8, myentry () at src/entry.s:43
43               call strap_c  
(gdb) c
Continuing.

Breakpoint 9, strap_c () at src/strap.c:6
6            count0++;
(gdb) c
Continuing.

Breakpoint 11, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 10, ld_reg () at src/entry.s:47
47           ld t6, 0(sp)  
(gdb) c
Continuing.

Breakpoint 7, st_reg () at src/entry.s:9
9            sd sp, -8(sp)  
(gdb) c
Continuing.

Breakpoint 8, myentry () at src/entry.s:43
43               call strap_c  
(gdb) c
Continuing.

Breakpoint 9, strap_c () at src/strap.c:6
6            count0++;
(gdb) c
Continuing.

Breakpoint 11, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 10, ld_reg () at src/entry.s:47
47           ld t6, 0(sp)  
(gdb) c
Continuing.

Breakpoint 7, st_reg () at src/entry.s:9
9            sd sp, -8(sp)  
(gdb) c
Continuing.

Breakpoint 8, myentry () at src/entry.s:43
43               call strap_c  
(gdb) c
Continuing.

Breakpoint 9, strap_c () at src/strap.c:6
6            count0++;
(gdb) c
Continuing.

Breakpoint 11, fail1 () at src/head.s:56
56          csrr a1,mcause
(gdb) c
Continuing.

Breakpoint 10, ld_reg () at src/entry.s:47
47           ld t6, 0(sp)  
(gdb) c
Continuing.

Breakpoint 7, st_reg () at src/entry.s:9
9            sd sp, -8(sp)  
(gdb) cc
Undefined command: "cc".  Try "help".
(gdb) q
A debugging session is active.

        Inferior 1 [process 1] will be detached.

Quit anyway? (y or n) y

 

0x0000000000001000 in ?? ()
Breakpoint 1 at 0x80000000: file src/head.s, line 12.
Breakpoint 2 at 0x8000003a: file src/head.s, line 25.
Breakpoint 3 at 0x8000004c: file src/head.s, line 29.
Breakpoint 4 at 0x80000056: file src/head.s, line 34.
Breakpoint 5 at 0x8000006e: file src/head.s, line 41.
Breakpoint 6 at 0x80000088: file src/head.s, line 50.
Breakpoint 7 at 0x800000f8: file src/entry.s, line 9.
Breakpoint 8 at 0x800001ce: file src/main.c, line 7.
Breakpoint 9 at 0x80000178: file src/entry.s, line 43.
Breakpoint 10 at 0x8000031c: file src/strap.c, line 6.
Breakpoint 11 at 0x80000180: file src/entry.s, line 46.
Breakpoint 12 at 0x800000a0: file src/head.s, line 56.
Breakpoint 13 at 0x800000e0: file src/head.s, line 75.
(gdb) b src/entry.s:77
Breakpoint 14 at 0x800001be: file src/entry.s, line 77.
(gdb) c

fail mret

 

ld_reg ret返回

 

 is_a_trap mret返回

 

更改 is_a_trap

is_a_trap:
    li t0,0x80                   /* time trap so enable mip/disable mie */
    csrc mie, t0  #disable  mie time
    li t0,0x20  
    csrs mip,t0  #enable sTIP
    mret

 

 

原文地址:https://www.cnblogs.com/dream397/p/15689980.html