MIPS架构深入理解3-协处理器0

简介: MIPS架构深入理解3-协处理器0

1 引言


1.1 什么是协处理器0


前面我们已经对MIPS架构CPU有了粗略的了解。显然,它提供了众多优秀的功能。但是,应用的场景不同,往往需要CPU做的事情也不一样,这就需要必须能够对CPU以及它提供的功能进行有选择的配置。这是协处理器诞生的根本原因。

ARM架构也使用协处理器进行控制,称为协处理器15,(cp15)。

MIPS架构CPU使用协处理器0进行CPU的配置和管理。那么,它到底能够干什么呢?

  • CPU配置
  • Cache控制
  • 异常、中断控制:
    中断或异常发生时的行为和处理的定义。
  • 内存管理单元控制
  • 其它工作:
    定时器(timer)、事件计数器(event)、奇偶/错误校验。一些与CPU紧密相关,而又不便通过I/O进行访问的功能,都会被添加到协处理器0中进行控制。


1.2 包含的寄存器


对于相关的寄存器,在此,不再详述。使用时,参阅相关的数据手册即可。


2 CPU控制指令


2.1 写CPU控制寄存器的指令


mtc0 s, <n>     # 把数据拷贝到协处理器0

这条指令的作用是把通用寄存器s中的值拷贝到协处理器的寄存器n中,数据位数是32位。大部分的协处理器寄存器是32位的,对于少数的64位协处理器寄存器可以使用dmtc0指令进行操作。这是设置CPU控制寄存器的唯一方法。

32位架构的时候,最多有32个协处理器寄存器。但是MIPS32/64架构扩展到了256个寄存器,为了向前兼容,在指令中添加select域来控制多个寄存器。比如

mtc0 s, $12, 1

select域的值等于1,其作用就是把通用寄存器s的值写入到协处理器的寄存器12组中的编号为1的寄存器中。也就是说,寄存器12可以有多个具体的寄存器,使用select域选择对应的哪个寄存器。


2.2 读取CPU控制寄存器的指令


mfc0 d, $n      # 把协处理器第n个寄存器中的值写入到通用寄存器d中

上述指令的作用是把协处理器0中的第n个寄存器中的内容读取到通用寄存器d中。


2.3 特殊的控制指令eret


所有的架构的CPU在面对特权等级切换的时候(一般就是异常返回时),都会面临一个问题:一方面,在返回用户态程序之前就降低特权等级,那么会立即引发一个异常指令访问的二次异常;另一方面,如果返回到用户程序之后再降低特权等级,那么可能会被恶意程序利用内核态运行某些指令。解决这个问题的办法就是,保证异常返回时的指令是原子操作。MIPS架构的CPU提供了这个指令eret


3 特殊寄存器的使用场景


  1. 上电后:需要设置SR寄存器,使CPU进入一个可工作的状态。
  2. 处理异常:
    在异常入口处,不会保存任何程序计数器,只把返回地址存入EPC寄存器中。MIPS架构CPU硬件对于堆栈一无所知,所以发生异常时,无法打印堆栈中的数据。(ARM和X86硬件可以保存堆栈,所以,发生异常时,可以打印堆栈中的关键数据)。对于MIPS架构,程序发生异常时,只能看EPC寄存器中的值,然后通过反汇编得到执行代码的地址,从而获取到导致异常的代码大概位置。充分利用异常发生时的信息,是调试程序的一种有效手段。
    MIPS架构也为异常处理程序保留了2个寄存器v0v1。我们的程序可以把一些异常需要的重要信息保存在这儿。但是,通用寄存器极易发生变化,大部分时候,这两个寄存器不建议使用。
    可以通过查看Cause寄存器,判断属于哪类异常,从而做相应的处理。
  3. 从异常返回时:
    保存返回地址到EPC寄存器中。
    不论是何种异常,返回时,都要恢复SR寄存器和特权等级、使能中断并消除异常带来的影响。最后eret指令返回用户程序并复位SR(EXL)寄存器。
  4. 中断:
    通过SR寄存器中的中断控制位,可以设置哪些中断具有更高的优先级。虽然,MIPS架构硬件没有提供中断优先级,但是软件可以任意设置。
  5. 一些特殊的指令:
    比如系统调用(syscall)和调试断点(break),还有一些CPU实现了一些特殊的指令。


4 CP0协处理器操作时可能发生的问题


我们知道CPU的指令是按照流水线的方式执行。有可能,操作协处理器的指令还没执行彻底,其它指令就已经开始执行了。如何才能保证CP0的操作生效后,再执行相关指令呢?

因为MIPS架构的设计理念是 硬件尽量简单,辅以软件实现。所以,早期的软件开发人员使用nop操作,保证操作协处理器的正确性。但是,这无疑增加了软件开发人员的难度。于是,MIPS32/64架构定义了新的指令:避险指令。

三个避险指令:

  1. ehb指令
    消除执行危险。早期的MIPS架构CPU把这个当做一个nop操作。
  2. jr.hb和jalr.hb指令
    跳转寄存器指令,用来消除指令危险。最常见的使用方式就是替换普通的子程序返回和子程序调用指令。
    旧架构上,这两个指令还是会被解释成jr和jalr指令。在这些CPU上,指令会清除CPU的管道流水线。而且大部分时候,对于不遵守MIPS32/64架构规范的CPU还会提供必要的延时。


4.1 指令危险


指令危险和用户危险通常发生在改变CP0状态的时候(比如,改变某个寄存器、TLB项、或者一个cache行),这会影响我们普通的取值指令(在某些情况下,还会影响load/store指令访问内存的方式)。

我们必须规避这种不可控的风险。在改变CP0操作之后,添加危险屏障指令,消除这种可能产生的不可控的危险。

这类危险都有:

  1. 改变TLB项:
    在受影响的内存页上取指、加载和存储数据。
  2. 改变EntryHi寄存器(ASID域)
    非全局映射内存区域上的取指、加载和存储数据。
  3. 改变到ERL模式
    从kuseg内存区域取指、加载和存储数据。
  4. cache指令改变cache行
    在受影响的line上取指、加载和存储数据。
  5. 改变watchpoint寄存器
    在匹配的地址上取指、加载和存储数据
  6. 影子寄存器设置发生改变
    任何使用通用寄存器的情况(执行危险)
  7. 修改CP0寄存器,禁止中断
    仍然能够被中断的指令(异常危险)

它们中大部分都是指令危险,可以使用jr.hbjalr.hb指令避免这种指令危险。


4.2 CP0指令间的危险


mfc0tlbwitlbwrtlbr指令、读取CP0的cache指令以及tlbp指令都依赖于CP0寄存器中的值。所以,这些指令执行时,有可能发生执行危险。为了保证安全,可以在

可以在读取CP0寄存器值的指令之前,添加ehb指令。


相关文章
|
缓存 测试技术 数据中心
【计算机架构】计算 CPU 动态功耗 | 集成电路成本 | SPEC 基准测试 | Amdahl 定律 | MIPS 性能指标
【计算机架构】计算 CPU 动态功耗 | 集成电路成本 | SPEC 基准测试 | Amdahl 定律 | MIPS 性能指标
435 0
|
4月前
|
前端开发 Linux Shell
技术心得:基于AR9331(MIPS架构)分析系统启动过程(uboot)
技术心得:基于AR9331(MIPS架构)分析系统启动过程(uboot)
55 0
|
6月前
|
网络协议 Linux 测试技术
NFS - MIPS架构下构建NFS共享目录服务
NFS - MIPS架构下构建NFS共享目录服务
196 1
|
缓存 安全 Linux
MIPS架构深入理解9-向MIPS移植软件之Cache管理
MIPS架构深入理解9-向MIPS移植软件之Cache管理
|
存储 安全 编译器
MIPS架构深入理解11-向MIPS移植软件之编程语言
MIPS架构深入理解11-向MIPS移植软件之编程语言
|
监控 算法 网络协议
MIPS架构番外篇1-一条小小的除法指令引起的翻车事故
MIPS架构番外篇1-一条小小的除法指令引起的翻车事故
|
存储 缓存 程序员
MIPS架构深入理解10-向MIPS移植软件之内存序
MIPS架构深入理解10-向MIPS移植软件之内存序
|
存储 缓存 Unix
MIPS架构深入理解8-向MIPS移植软件之大小端模式
MIPS架构深入理解8-向MIPS移植软件之大小端模式
|
存储 Unix 编译器
MIPS架构深入理解7-汇编语言理解
MIPS架构深入理解7-汇编语言理解
|
存储 负载均衡 安全
MIPS架构深入理解6-异常和中断
MIPS架构深入理解6-异常和中断