Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3128718
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: 嵌入式

2014-09-04 15:25:04

原文地址:http://blog.chinaunix.net/uid-10701701-id-91735.html

2008.9.27

MIPS CP0: MIPS CPU control



CP0 包含的控制包括:

--- CPU feature: endianness, system interface work mode

--- cache control, 并且不同的MIPS,起指令的风格有所不同

--- 异常/中断控制

--- MMU 控制

--- 其他 : timer, event counters, parity error

MIPS 预留些指令编码, 总共可以支持4个CP, CP0 是系统控制, CP1是浮点. CP0是必须的. 早期的MIPS标准不包涵CP0的部分, 从MIPS32/64才开始标准化,以使OS从一个CPU到另一个比较方便些. 

访问CP0数据

mtc0    s,       # Move to coprocessor 0 , 大部分CP0的寄存器都是32bit的(无论CPU本身是32bit还是64bit)
dmtc0                  #64bit 版本

mtc0 s,$12,1    #早期只有32个寄存器留给CP0, MIPS32/64扩展到了256个, 所以加了3个bit即select域 这里的1就是

mfc0 d,$n    # Move from coprocessor 
dmfc0

除了访问CP0的数据, 还有一些指令用于消除exception的影响. 考虑从内核态返回用户态, 一个要求就是返回和改变运行级别需要是个原子操作, 不能分开. 现在的MIPS使用eret就可以了, 老的需要在跳转指令的延迟槽内放一条rfe指令.


需要考虑CP0的一些典型时机

--- Power up
一般要设置SR的一些可写位到确定的状态, 因为很多硬件启动后,一些bit是未定义状态.

--- handling exception
早期MIPS任何异常都到一个指定的地址去执行handler(除了一个MMU的), 后来引入多个entry point.(以后章节有详细介绍). 在异常处理的入口, CPU仅仅把返回地址保存在EPC内,而没有任何其他动作. CPU根本就不知道还有堆栈这个东西. 可以使用的寄存器是k0,k1, 用他们可以保存你要保存的任何东西.  然后需要查询Cause寄存器来确定是什么原因引起的异常.
--- Return from exception
返回到EPC指定的地址, 一般好要调整SR, 如恢复用户优先级状态, 使能中断,(还有unwinding exception efect, 需要考察,RFC), 最后eret 把返回用户空间和重置SR(EXL)结合成一个原子性的操作来执行.

--- Interrupt
SR用于调整中断mask, 设置那些中断可以被继续take, MIPS 通过这中方式利用软件来实现中断优先级.(MIPS硬件认为 all interrupt are created equal)
      
--- Instructions just there to cause exceptions
break, syscall


CP0 Hazards

修改CP0的指令,在pipeline到达执行步骤的时候, 新的指令已经开始预取, 并且执行完成后,硬件也许还要几个cycle才能完成配置. 如何能让下面的指令在修改CP0之后才开始运行就是个问题了.

SGI R10000 从硬件内部实现互锁,我们不用担心. 一般的软件解决办法是用足够的nop指令,加上branch(可以废弃预取).2003年以前(第二版MIPS32/64)CPU手册会给出一个CP0 hazards列表描述需要的等待时间. 这种方案有缺点, 特别是在指令级并行的时候, 甚至出现了ssnoop(超标量nop). 

MIPS32/64的方案是引入harzrd barrier 指令. 两种:
--- execution harzard 只有读取CP0才会受影响
--- instruction harzard  最坏,指令预取就受到影响

harzard的另外分类: 只影响OS, 影响user的.

异常和eret可以消除所有的harzards. 

3个harzard barrier指令:
----ehb                  execution harzard barrier (old CPU 就是一个nop)
----jr.hb  jalr.hb     instruction harzard barrier. old的cpu上只会被解码成jr和jalr.

instruct harzar 种类:(如果没有eret, 就要用jr.hb 或者jalr.hb了)
改变TLB
改变EntryHi(ASID)域
改名ERL mode
cache 指令修改了cache line
改变wachpoint 寄存器
改变shadow register 配置
CP0寄存器改变引起中断禁止

CP0指令之间的exec harzard
所有mfc0明显都是依赖于CP0寄存器的,如cache,tlb(RFC). tlbp因为ASID而依赖于EntryHi.  ehb就足够了. 最好放到这些指令的前边几条语句里,因为有些CPU在ehb后几个cycle不容许访问CP0.


控制寄存器的一些详细解释

原书罗列了不少, 不过还不如去看RM, 这里仅仅罗列下, 把最感兴趣的简单解释下.(基于MIPS32/64)
MIPS CPU可是没有uncache mode的, 一切cache和地址转换都是基于程序地址的,而不是CPU模式. 
CU3-0     Coprocessor enable bit.  set 0 mean enable user code run CP0 instruction.
RP           Reduced Power
FR           set to 0 可以模拟MIPSI的那种浮点行为, 即偶数号浮点寄存器规则.
RE           reverse endianness in user mode. 还没有人用这个特点. (另外 MIPS在CPU reset的时候可以设置CPU的endiness.)
MX          Enable DSP 或者 MDMX. (没有CPU实现了两个ASE吧,呵呵)
BEV         Boot exception vectors, 置1的时候使用kseg1内的vectory entry
TS           TLB shutdown. 有些CPU在发现可以匹配2条TLB的时候会置位TS, 并且只能在reset 后才能清除(否则CPU可能会坏掉...).
SR,NMI    soft reset或者NMI中断发生时SR置位. head reset时SR被清除. NMI 只在NMI exception的时候置位.
IM7-0      Interrupt mask. 8 source, set is enable. 如果使用EIC模式的中断, IMbit的含义就变了. 有6个外部信号(一个是FPU),
               2个是cause 寄存器内的软件中断.
UX,SX,KX (and PX)  对应user,supervisor,kernel. 对应bit置位将把对应的模式的TLB miss异常重新定位到另一个地址并,软件需要处
                 理64bit的地址.还会使能64bit对应的mem map. 并且如果SR(UX) 清0, CPU将不会容许user mode执行64bit指令.如果
                 需要user mod使用64bit指令,但是只用32bit的地址,可以设置SR(PX).
KSU        CPU优先级. 0 is kernel, 1 for supervisor,2 is user. 如果EXL和ERL因为exception而置位, 不管这里是什么, CPU总是处
              于kernel 模式.
ERL         error level.当发生 parity/ECC错误是置位. 这种异常被单独处理,因为异常处理函数也可能产生这中问题.这个bit一旦置位, 0
               到0x7fff ffff的地址变成不可cache的, 并且映射到同样的物理地址, 同时所有到user space的地址转消失.
EXL         exception level. 为任何异常设置, 强制进入kernel mode, 禁止中断.
IE            全局中断使能. 注意, ERL和EXL也禁止所有中断.

BD:   异常的指令是在delay slot中的. EPC 还是指向brach指令. 也就是如果BD=1, 异常的指令就在EPC+4这个地址.
TI:    内部timer 产生的中断.
CE:   coprocessor error. 如果是应为SR(CUx)没有使能, 则Cause(CE)含有CP的编号.
DC:   禁止Count 寄存器进行计数(可以更省电).
PCI:  一个CP0性能计数器溢出,则产生这个异常.
IV:    置1则使用一个特殊的中断入口.
WP:  watch point 相关,置1则使用特殊的中断入口点( RFC).
IP7-0:  Interrup pending. IP7-2 反应CPU的外部信号. IP1-0是软件中断bit.如果相应bit置位了(IP7-2被外部信号,IP1-0 by软件),而
            SR(IM)是使能的,则将产生一个中断.
ExcCode:  异常码. 

Exception Restart Address (EPC) Register
也就是如果Cause(BD)=1, 异常的指令就在EPC+4这个地址,否则就是在EPC.


Bad Virtual Address (BadVAddr) Register
引起异常的地址, MMU相关,错误的align, user试图访问非kuseg地址, 都会设置这个寄存器, 但是注意,bus error 不会设置这个寄存器.

Count/Compare Registers: The On-CPU Timer
一些细节参考IntCtl寄存器. count是一个32bit寄存器, 以pipline,或者以pipeline一半或者其他的分数倍的速度来计数.参考rdhwr指令的CC (2)寄存器.  一旦Count寄存器到达compare指定的值,就会产生一个中断, 中断信号一直维持到下一次写Compare寄存器.中断处理函数要每次写一个合适的值才能持续的按照一定的间隔来产生中断. 一般写后要检查counter,确保没有超过当前设置的compare值.



M         如果有至少一个的另外的寄存器,则为1. (need verify)
Impl     需要查特定的CPU 手册才能确定.
BE        1 是big endian 0是littel-endian (只读?)
AT        0 MIPS32; 1 MIPS64 instruction but MIPS32 address map; 2 full MIPS64
MT        mmu type. 0--none; 1-- MIPS32/64 compliant TLB; 2 BAT(极老的U); 3--MIPS32 FMT fixed mapping; 
VI         1 indicate the L1 cache is VIVT.
K0         kseg0 的cache配置, 含义和TLB entry的 EntryLo-1(C) 相同.


config1(M)                如果config2 存在则为1. 
Config1(MMUsize)    size of TLB( 共有MMUsize+1个TLB entry)
L1-cache/L1-Dcache   S:64x2^S个 index (乘以associativity 就是cache lines)  L:0是没有cache, 否则cache line大小是:
                                   2X2^L个byte   A: Associativity  cache 是(A+1) Way的.
C2  1代表CP2存在   
MD  1代表FPU 实现了MDMX
PC   performance counter
WR  1代表至少有一个watchpoint register
CA   1 代表MIPS16e可用
EP   1代表 EJTAG 可用
FP    1代表FPU存在.


M    同上
TU  特定实现的关于L3的信息
TS,TL,TA  L3cache的信息, 类似于上边的IS,IL,IA
SU   实现相关的关于L2 cache的信息
SS,SL,SA  L2 cache的set, cache line size, Associativity

M      同上
LPA   large physical address (迄今无人实现,看CPU手册吧)
DSPP DSP存在则为1
VEIC  EIC-compatible interrupt 控制器存在则为1
VInt   如果可以处理Vectored interrupt则为1
SP     如果只是sub-4k page size则为1, 大部分都不支持.
MT     MT 存在则为1(multi threading)
SM     smartMIPS存在则为1. (安全加密相关, 一般针对smart card)
TL     EJTAG 的instructin trace功能存在则为1


可以重新安排异常向量位置,可以让SMP每个CPU都用自己的中断服务向量.
1,0   高位固定,这限制了中断向量必须位于kseg0.
Exception Base: 4k为单位. 参考中断部分的描述.
CPUNum  本CPU编号(一般是硬件决定的)

IPTI,IPPCI   只读.描述timer和performance counter中断是如何连接的. 和nonvectored和simple-vectored(VI) 中断模式相关. 3bit的值指出那个中断输入信号和timer(performance counter overflow interrupt)共享.有效值是2-7(0,和1是软件中断没有中断信号线).参考Cause(IPx). IPT和IPPC信号是送到CPU外面的,一般系统嗯设计人员把信号反接回来,所以这些值是有系统设计而不是CPU决定的.

VS  可写, 指定vector spacing大小,VSx32, 有效值是1,2,4,8,16. 设置为0则所有中断到同样的地址.

和SRSmap共同来配置shadow寄存器, 类似ARM的那种机制.

HSS  CPU/VPE提供的最高编号的寄存器集. (个数减1) 一般只读.
CSS   当前使用的寄存器集. 只读. 在eret的时候被PSS替代.
ESS   可写. 其他异常使用的寄存器集. (除了VI/EIC 模式)
PSS   eret之后PSS覆盖CSS. 用rdpgpr wrpgpr访问. 可写.
EICSS  EIC模式,外部可以建议使用一个寄存器集(非0 IPL,RFC), 这里是采用了的寄存器集. 

Note: PSS和CSS 不是总是被异常所更新. 只有那些写了一个新的地址到EPC的(或等效,RFC). 不会更新EPC的包含:
---- SR(EXl)已经设置后发生的异常
----  cache error (异常地址在ErrorEPC)
----- EJtag debug 异常, 返回地址在DEC.


Load-Linked Address (LLAddr) Register
ll/sc 调试专用.
阅读(1523) | 评论(0) | 转发(0) |
0

上一篇:MIPS 指令

下一篇:裸奔之MMU

给主人留下些什么吧!~~