linux IRQ Management (十) - 龙芯loongson 中断概述

  • 了解loongson 中断机制

1.MIPS 中断类型

  在mips体系结构中,中断、陷阱、系统调用和任何可以中断程序正常执行的情况都称作异常。mips的异常是精确异常,在发生任何异常时都指向一条指令,所有这条异常指令之前的指令都执行完成了,所有这条指令之后的指令都还没开始执行。

1.1.异常种类
在这里插入图片描述
在这里插入图片描述

1.2.异常相关寄存器

  MIPS exceptions are handled by a peripheral device to the CPU called coprocessor 0 (cp0). Coprocessor 0 contains a number of registers used to configure exception handling and to report the status of current exceptions.

  • The badvaddress register, cp0 register 8, contains the address that caused a bad address exception.
  • The status register, cp0 register 12, is used both to configure interrupts, and get more information about the exception that occurred.
    • The cause register, cp0 register 13, contains bits that identify the cause of the exception.
  • The EPC register, cp0 register 14, is the exception program counter. It contains the address of the instruction that was running when the exception occurred. It serves the same purpose for the exception handler that CPU register $ra serves for ordinary subprograms. When the exception handler completes, the EPC register allows the program that was interrupted to be resumed.

  Registers in coprocessor 0 cannot be used directly by MIPS instructions. Instead, there are two instructions that work much like load and store instructions. The mfc0 (move from coprocessor 0) instruction loads data from a coprocessor 0 register into a CPU register. The mtc0 likewise stores data in a cp0 register.

Note:

The mtc0 instruction, like the store instruction has the destination last. This is especially important to note, since the syntax for cp0 registers looks the same as the syntax for CPU registers. For example, the following copies the contents of CPU register 13 to cp0 register 12.
	mtc0    $13, $12
Since cp0 registers cannot be accessed by most instructions, changing their values requires using the read-modify-write cycle. This means we must:
Read the cp0 register into a CPU register
Modify the contents of the CPU register
Write the modified value back to the cp0 register
The read-modify-write cycle is extremely common in interacting with I/O devices and other system hardware.

1.2.1.k0/k1 :

  通用寄存器,异常处理函数可以将异常返回地址放到这两个中的任何一个,然后使用 jr 跳转到造成异常的指令处继续执行。

1.2.2. SR :cp0状态寄存器(register 12, select 0)
在这里插入图片描述

  • IE(Interrupt enable) : 使能全局中断。无论怎么设置,ERL与EXL会禁止所有的中断。
    • If the interrupt enable bit is 1, interrupts are allowed. If it is 0, they are disabled.
  • EXL(Exception level) : 异常级别。被异常设置,强制CPU进行内核模式并关掉中断,目的是保持EXL足够长的时间,使软件决定CPU新的特权级别和中断屏蔽位应该如何设置。
    • The exception level bit is normally 0, but is set to 1 after an exception occurs. When this bit is 1, interrupts are disabled and the EPC is not updated if another exception occurs. This bit prevents an exception handler from being disturbed by an interrupt or exception, but it should be reset when the handler finishes.
  • ERL :错误级别。
  • UM(User mode)
    • The user mode bit is 0 if the processor is running in kernel mode and 1 if it is running in user mode.
  • IM7-0(Interrupt mask) : 中断屏蔽。决定哪些中断源有请求时可以触发一个异常。8个中断源中的6个是CPU核外面的信号产生的(其中一个可以被浮点部件使用;它虽然在片上,但逻辑上是外部的);其他两个是cause寄存器中软件可写的中断位。
    • The 8 bit interrupt mask 8 field contains one bit for each of the 6 hardware level interrupts and the 2 software level interrupts. A mask bit set to 1 allows interrupts at that level to interrupt the processor. A mask bit set to 0 disables interrupts at that level.
  • BEV :启动时异常向量。
    • 当BEV=1时,CPU用kseg1空间的异常入口;
    • 当BEV=0时,CPU用kseg0空间的异常入口。正常运行中的操作系统里,BEV一般设置为0。

1.2.3.CAUSE :cp0原因寄存器(register 13, select 0)

  The Cause register, is a mostly read-only register whose value is set by the system when an interrupt or exception occurs. It specifies what kind of interrupt or exception just happened.

在这里插入图片描述

  • BD : 分支延迟。EPC寄存器的作用是存储异常处理完之后应该回到的地址。正常情况下,这指向发生异常的那条指令。但是,如果发生异常的指令是在一条分支指令的延迟槽里,EPC必须指向那条分支指令。重新执行分支指令没有什么害处,假设你从异常返回到了分支延迟指令,分支指令将没法跳转,从而这个异常将破坏程序的执行。cause(BD)只是当发生异常的指令在分支延迟槽时被置位,并且,EPC指向分支指令。如果分析发生异常的指令,只要看看cause(BD),如果cause(BD)=1,那么该指令的位置是EPC+4。

  • IP7-0 :中断被挂起。提示哪些中断要发生。cause(IP7-2)随着CPU硬件输入引脚上的信号而变化。cause(IP1-0)是软件中断位,可读可写并存储最后写入的值。当这8位中任何一位被置位,而且对应的SR(IM)位使能时,中断将被触发。

  • IV :将此位写为1 时,使用一个特殊的中断异常入口。

  • ExcCode :这5位指示发生了哪种类型异常。
    在这里插入图片描述
    在这里插入图片描述

  When an exception or interrupt occur, a code is stored in the cause register as a 5 bit value (bits 2-6). This field is commonly referred to as the exception code although it is used for both exceptions and interrupts.
在这里插入图片描述
在这里插入图片描述

1.2.4.EPC (register 14)

  Exception Program Counter (EPC) register. When an interrupt or exception occurs, the address of the currently executing instruction is copied from the Program Counter (PC) to EPC. This is the address that your handler jumps back to when it finishes.

1.2.5.Badvaddr (register 8, select 0)

  无效虚拟地址寄存器。这个寄存器存储引发异常的地址。在任何MMU相关的异常出现时设置,譬如,一个用户程序试图访问kuseg以外的地址,或者地址没有正确对齐,等等。对于任何其他类型的异常,该寄存器的值是未定义的。注意,总线地址异常并不设置它。

2.异常相关指令

  • ei:打开中断。无条件将状态寄存器SR(IE)的全局中断位置1,恢复di指令返回的SR寄存器的值,原子操作。
  • di : 关闭中断。清除状态寄存器SR(IE)的全局中断位,将SR的原始值返回到一个通用寄存器中,原子操作。
  • eret : 异常返回指令。清除SR(EXL)标志位并跳转到存储在EPC寄存器中的地址。

3.异常处理入口

  mips的所有异常入口,都在内存映射中不使用tlb进行地址转换的kseg0(缓存的)和kseg1(非缓存的)中。出于对性能的考虑,访问中断入口地址时都要经过缓存,但是在系统启动期间,上电或者重启时,缓存未经过初始化是不能用的,所以把异常入口放在一个非缓存的区域。当SR(BEV)=1时,使用非缓存(kseg1)的异常入口,当SR(BEV)=0时,使用缓存的(kseg0)异常入口。EBase寄存器可以通过编程一起移动所有的异常入口到其他地址。

  每个异常处理例程预留128(0x80)个byte,可以存放32条异常处理指令。
在这里插入图片描述

3.1.异常时,mips cpu要做如下工作:

  • 设置EPC, 指向重新启动的位置。

  • 置SR(EXL)位,迫使CPU进入内核模式(高级特权)并且禁止中断。

  • 设置cause寄存器,使得软件能看到异常的原因。地址异常时,也要设置BadVAddr寄存器。存储管理系统异常还要设置一些MMU寄存器。

  • CPU从异常处理入口点取指执行。

3.2.异常处理流程

  • 引导:在异常处理例程入口,准备足够的空间,存储寄存器状态,保证被打断的程序的关键状态不被覆盖。一般用k0,k1索引一块内存区域用来存储其他寄存器。

  • 区分不同的异常:通过cause(exccode)判断发生了什么异常。

  • 构建异常处理函数:在这里需要提供一块内存区域用作栈,并且不能被其他程序占用。用这个栈存储被打断的程序的一些重要的状态,并调用一些可以改变的子程序。

  • 处理异常。

  • 准备返回:高级函数通常作为子例程调用,所以,最终要返回到底层的异常处理程序。在此,恢复存储的寄存器,CPU通过修改SR,设置成安全的模式(内核态,禁止异常),也就是异常发生后的模式。

  • 从异常返回:eret(清除SR(EXL)标志位并跳转到存储在EPC寄存器中的地址)

3.3.异常优先级
在这里插入图片描述
3.4.中断资源

  mips异常机制是通用的,发生最多的两个异常是TLB缺失和中断。mips cpu在cause寄存器中有8个独立的中断位。其中,6个外部中断(IP2 ~ IP7),2个软中断(IP0~IP1)。片上的计数器/定时器会连接到一个硬件中断位上去。
在这里插入图片描述
在这里插入图片描述
中断响应:

  每个中断输入引脚上的有效输入每个周期都会被采样,如果没使能,就会引起一个异常。cpu是否响应中断,有以下几个条件决定:

  • 全局中断使能位SR(IE)必须置1,否则没有中断响应。
  • 设置SR(EXL)和SR(ERL)位,将阻止中断(任何异常之后会立即设置这二者之一)。
  • 状态寄存器里有8个单独的中断屏蔽位SR(IM),每个对应cause寄存器的一个中断位CAUSE(IP)。要使能某个中断,其对应的屏蔽位SR(IM)必须置为1。

中断处理流程:

  当收到一个异常并通过cause(ExcCode)发现这个异常是硬件中断后,中断处理就开始了。通过查看cause(IP),可以知道发生了哪个中断,处理流程如下:

  • 查看cause(IP),把它和SR(IM)中当前中断屏蔽位做逻辑与,获得一个活跃而且使能的中断请求位图。可能有不止一个是活跃的,任何一个都可能触发中断。

  • 选择一个活跃而且使能的中断来处理。大多数OS分配固定的优先级给不同的输入,首先处理最高优先级的中断,这是由软件决的。

  • 存储SR(IM)里老的中断屏蔽位(有可能已经在主异常处理例程中存储过整个SR寄存器)。

  • 改变SR(IM),以保证禁止当前中断以及所有优先级小于等于本中断的中断。

  • 如果在主异常处理例程中没有做,则存储嵌套异常所要求的状态(用户寄存器等)。

  • 设置全局中断使能位SR(IE),以允许处理高优先级中断。改变cpu特权级别SR(KSU),使cpu处于内核态。清除SR(EXL),以离开异常模式,并把这些改动反映到状态寄存器中。

  • 调用中断处理过程。

  • 中断返回,这时要再次禁止中断,恢复中断前的寄存器值,以恢复被中断认为的执行。

4.中断调用流程:
在这里插入图片描述

refer to

  • https://www.codenong.com/cs105906275/
  • http://www.it.uu.se/education/course/homepage/os/vt18/module-1/mips-coprocessor-0/
  • http://www.cs.uwm.edu/classes/cs315/Bacon/Lecture/HTML/ch15s05.html

猜你喜欢

转载自blog.csdn.net/weixin_41028621/article/details/109443894