2009年4月8日星期三

ARM的跳转分支预测

ARM11微体系结构的整型部件使用了静态和动态分支预测。当跳转目标是立即数或固定的PC>偏移时,就对所有分支进行预测。

第一级分支预测是动态的,使用了一个128条目的转移地址缓存BTAC( Branch Target Address Cache)。如果一个跳转指令的PC值在BTAC里出现,那么那一条目所包含的转移历史(>目标地址)就被启用。

如果地址映射关系发生变化,那么BTAC就需要被清空。BTAC清空指令由CP15提供。地址映射
关系发生的情况是:

* 页表内容变化(SWAP、进程调度)
* FCSE PID(进程标识)寄存器变化
* 上下文标识寄存器变化

静态预测是对动态预测的补充,它是仅基于分支方向的预测,与跳转历史无关。

2009年4月5日星期日

内存是外设?

内存是外设?体系结构教科书上不是这么说的,事实是,体系结构教材根本不讲外设,但讲内存;而讲外设的书,一般也不讲内存。

但是从模拟器实现的角度讲,内存是外设。实际情况是,所有以物理地址访问的模块都是外设。内存RAM、ROM、ARM的TCM、UART、网络控制器,等等,全是接受物理地址,它们的实现方式,是一致的(继承自同一个类)。不同的是,内存不会产生中断,而有些外设也不产生中断,比如Frame Buffer,是无须产生中断的。

从CPU角度来看,内存的大延迟也足以把它当作外设了。

把内存不当作外设的理由是,没有内存,计算机没法工作,毕竟现代的计算机是存储程序式的计算系统,没有了内存,计算系统必须用其它方式保存状态,而其它方式都不如内存效率高、成本低。这样看,内存又是计算机系统本质内在的东西,和其它外设有根本不同,甚至极端地看,CPU里的寄存器也是存储,也是内存。内存之于计算,如同质量之于能量,在一定条件下,互相转化。比如,在图灵机里,计算是用一系列存储状态代表的。

所以,从计算的角度看,内存不是外设,没它不行;但从实现的角度看,内存是外设,因为它用物理地址访问。

2009年4月3日星期五

ARM紧致内存TCM的L1DMA

L1 DMA用于后台大数据量访问TCM时。通过CP15寄存器来设置读写方向,以及源和目标的起始地址和结束地址。

DMA设置用到的地址都是虚地址,所以DMA要做虚地址到物理地址的翻译,以及权限检查。具体实现可以利用TLB以提高性能,但要保证TLB和页表的一致性。权限错误可以配置成通过中断来报告给处理器。DMA操作的完成也可以通过此中断报告给处理器。

DMA进行状态也在CP15的相关寄存器中得到反应。

L1 DMA限制:
  • DMA通道最多2个
  • 只能有一个处于活动状态
  • DMA只限于TCM和外部RAM之间
  • 如果是应用级DMA,外部RAM必须是共享的
使用CP15寄存器11操作L1 DMA:
ARM指令
MCR p15, 0, Rd, c11, CRm, Opcode2
MRC p15, 0, Rd, c11, CRm, Opcode2


CP15寄存器11是个接口,它还有相关的辅助寄存器,如下表所示:
Register                            CRm      Opcode 2                       Function
Identification/Status 0 Present/Queued/
Privileged only: RO
Running/Interrupting
User Accessibility 1 0 Privileged only: RW
Channel Number 2 0 Read/Write
Enable 3 Stop/Start/Clear Write-only
Control 4 0 Read/Write
Internal Start Address 5 0 Read/Write
External Start Address 6 0 Read/Write
Internal End Address 7 0 Read/Write
Channel Status 8 0 Read-only
RESERVED SBZ/UNP 9-14 0 Read/Write
Context ID 15 0 Privileged only: R/W
其中,4、5、6、7、8、15号辅助寄存器都是每个DMA通道有一个,由2号通道编号寄存器来决定当前使用的是哪一个。

下面是对每个寄存器的解释:

标识/状态寄存器(0)
这是一组寄存器,由opcode2来标识:
0:present寄存器
1:queued寄存器
2:Running寄存器
3:interrupting寄存器

这几个寄存器的结构一样,从最低位起,每一位表示每个DMA通道的相应状况,即:
  • 是否实现
  • 是否有排队
  • 是否有DMA操作正在运行
  • 是否正在给处理器发中断
ARM指令:
MRC p15, 0, Rd, c11, c0, n ; where n is 0, 1, 2, or 3

用户可访问寄存器(1)
每一通道有一位(U位),表明该通道是否允许用户态访问其寄存器。

通道编号寄存器(2)
此寄存器的内容决定当前的DMA通道。

使能寄存器(3)
操作此辅助寄存器可以开始、停止或清楚当前的DMA通道。具体操作由opcode2决定:
Opcode2 Operation
0 Stop
1 Start
2 Clear
3-7 Reserved


ARM指令:
MCR p15, 0, Rd, c11, c3, n ; where n is 0, 1, or 2

START命令开始DMA传输,如果当前没有进行中的DMA传输,那么DMA传输开始,状态进入到运行状态,否则进入到队列等待状态。DMA通道处于进行中是指该通道要么正在传输、正在等待、或发生了错误号大于0b01000的错误,并且传输已停止。
STOP命令将尽快终止DMA传输,并使DMA进入空闲状态,开始地址寄存器被设置为DMA传输终止时的值,可用于继续此次传输。对于无副作用的传输,STOP发出后,DMA可以扔掉手中的数据,立即停止;但如果源或目标地址的读写具有副作用,比如读写的是标记为外设的存储区域,那么DMA必须处理完手中的数据后,才停止。STOP命令可以用于在调试器命令处理器停止运行的情况下,因为L1 DMA开始传输后,不受处理器的其它部分影响,处理器其它部分停止,L1 DMA可以继续运行。
CLEAR命令把DMA从错误状态转置于空闲状态,并清除可能的中断标记(在控制寄存器中设置的)。开始地址寄存器的内容不改变。

控制寄存器
TR[31] RT[30] IC[29] IE[28] FT[27] UM[26] UNP/SBZ[25-20] ST[19-8] UNP/SBZ[7-2] TS[1-0]
ARM指令:
MCR p15, 0, Rd, c11, c4, 0
MRC p15, 0, Rd, c11, c4, 0


TS:Transaction Size,传输的单位长度,00:字节,01:半字,10:字,11:双字
ST:Stride,跨度,正整数或0,以字节为单位。是指每单位传输外部地址的增量,内部地址不受影响。为0时,每次传输后外部地址不增加,这可用于对FIFO传输。
UM:User Mode,置1时表明用户态传输。
FT:Full Transfer,完全传输。传输方向是从TCM到外部存储时,FT=0,只传输那些自上次FT=0的DMA或复位后TCM中改变的内容,即执行增量式传输,把传输量降为最低。;FT=1,传输所有DMA范围中的数据。 在FT=0的DMA后,TCM需要记录那些内容改变了,而对FT=1的DMA则不必记录变化。
IE:Interrupt on Error,传输发生错误时产生中断。受U位制约,如果U=0,IE=0,那么DMA发生错误时不产生中断;如果U=1,或者IE=1,那么发生错误时,产生中断。中断由启动操作或清除操作清楚。
IC:Interrupt on Completion,DMA完成时产生中断。中断的清楚需要清除操作。0:不产生完成中断;1:反之。
DT:Direction of Transfer,传输方向。0:从L2存储到TCM,1:反方向
TR:Target TCM,目标TCM。0代表数据TCM,1代表指令TCM

内部起始地址寄存器
地址是虚拟地址,并随传输过程而变化,当传输结束时,该寄存器内容是结束地址。起始地址必须根据传输单位大小对齐。因为是虚拟地址,所以MMU会根据页表进行地址翻译,并应用页表中的权限位。也许会产生权限不足引发的中断。
ARM指令:
MCR p15, 0, Rd, c11, c5, 0
MRC p15, 0, Rd, c11, c5, 0


外部起始地址寄存器
与内部起始地址寄存器的描述基本相同。
ARM指令:
MCR p15, 0, Rd, c11, c6, 0
MRC p15, 0, Rd, c11, c6, 0

内部结束地址寄存器
这个寄存器的内容是DMA结束传输的位置,即DMA不传输这个地址,
ARM指令:
MCR p15, 0, Rd, c11, c7, 0
MRC p15, 0, Rd, c11, c7, 0


通道状态寄存器
包含最新DMA的状态,格式:
UNP/SBZ[31-12] ES[11-7] IS[6-2] Status[1-0]
ARM指令:
MCR p15, 0, Rd, c11, c8, 0

Status:状态。00:空闲,01:排队,10:运行,11:错误/完成
IS:内部地址错误状态。编码如下:
0b00xxx = No Error (reset value)
0b01000 = TCM out of range
0b11100 =External Abort on Translation of 1st Level Page Table
0b11110 = External Abort on Translation of 2nd Level Page Table
0b10101 = Translation fault (Section)
0b10111 = Translation fault (Page)
0b11001 = Domain fault (Section)
0b11011 = Domain fault (Page)
0b11101 = Permission fault (Section)
0b11111 = Permission fault (Page).


ES:外部地址错误。编码如下:
0b00xxx = No Error (reset value)
0b01001 = Unshared Data Error
0b11010 = External Abort (can be imprecise)
0b11100 = External Abort on Translation of 1st Level Page Table
0b11110 = External Abort on Translation of 2nd Level Page Table
0b10101 = Translation fault (Section)
0b10111 = Translation fault (Page)
0b11001 = Domain fault (Section)
0b11011 = Domain fault (Page)
0b11101 = Permission fault (Section).
0b11111 = Permission fault (Page).


这些错误基本上是MMU做地址转换时动态产生的。

发生错误时,出错的地址反映在相应的起始地址寄存器中,除非是外部错误(0b11010)。非共享数据错发生在用户态程序访问非共享存储区时。

当一个DMA无错误完成时,如果有排队的DMA,则由排队状态转为运行状态。

上下文标识寄存器
该寄存器包含使用此DMA通道的进程标识。一般在初始化DMA通道时写此寄存器。此寄存器的低8位在地址翻译时也要用到,以允许不同的虚拟地址映射共存。此寄存器只能被特权模式程序读写。
ARM指令:
MCR p15, 0, Rd, c11, c15, 0
MRC p15, 0, Rd, c11, c15, 0

2009年4月2日星期四

对ARM紧致内存TCM的理解

紧致内存是指片上快速存储区,与片上缓存具有同等的性能,但因为程序可完全控制紧致内存,因而比统计复用的缓存有更好的可预测性。这是ARM5TE引入的特性,目的是通过这一快速的存储区,一方面提高某些关键代码(如中断处理函数)的性能,另方面使存储访问延迟保持一致,这是实时性应用所要求的。ARM6对TCM操作做了进一步的规范。

TCM的应用领域:可预测的实时处理(中断处理)、避免缓存分析(加密算法)、或单纯的性能提高(处理器侧编解码)等。

如同缓存的哈佛结构,指令TCM和数据TCM是分开的。TCM有两种使用方式:作为快缓存使用,和作为本地内存使用。

本地内存
这时,TCM被用作更快速的内存,如同一般的RAM。因为指令段有时也是数据访问的对象,指令TCM实际上是指令数据一体化TCM。对TCM写操作后和后续对此写操作的依赖指令之间必须跟一个阻塞操作。

快缓存(smartcache)
TCM可以配置成当作外部RAM的缓存使用,对应的外部RAM也要设置可缓存标志。如果被缓存的外部RAM可以由多处理器共享,那么TCM是否与共享数据保持一致并没有规定,而由具体实现厂家决定。

TCM与缓存的内容不会自动保持一致,这意味着TCM映射到的内存区域必须是不缓存的区域。如果一个地址同时落在缓存和TCM内,那么访问这一地址的结果是不能预测的。另一个限制是各个TCM必须要配置成不相交的。

TCM的配置
通过CP15的0、1、9号寄存器进行:
0号寄存器
读CP15的0号寄存器,opcode2为2:
MRC p15, 0, Rd, C0, C0, 2
返回TCM状态寄存器的内容,其中,16-18位代表数据TCM个数,0-3代表指令TCM个数。

1号寄存器
ARM6之前,1号寄存器的16位和18位用于使能数据TCM和指令TCM(ARM946,ARM966),ARM6因为可以使用9号寄存器控制每一块TCM的使能状态,所以1号寄存器的这两个位就过时了,应该置1。

9号寄存器
每个TCM都有一个TCM区域寄存器,设置这个寄存器就可以设置TCM的基址和大小。在设置TCM区域寄存器前,需要设置TCM选择寄存器。
下面是访问这些相关寄存器的指令:

ARM Instruction                             TCM Region Register
MRC/MCR P15, 0, Rd, C9, C1, 0 Data TCM Region Register
MRC/MCR P15, 0, Rd, C9, C1, 1 Instruction/Unified TCM Region Register
MRC/MCR P15, 0, Rd, C9, C2, 0 TCM Selection Register

TCM区域寄存器的结构:
Base Address (Physical Address)[31-12] SBZ/UNP[11-7] Size[6-2] SC[1] En[0]

其中:
En位是使能位,置1时使能此TCM;
SC位置位表示此TCM被用作快缓存(smartcache),清零表示本地内存;
Size字段是只读的,含义如下:
Size         Memory     Size             Memory
filed size field size
0b00000 0K 0b01101 4M
0b00011 4K 0b01110 8M
0b00100 8K 0b01111 16M
0b00101 16K 0b10000 32M
0b00110 32K 0b10001 64M
0b00111 64K 0b10010 128M
0b01000 128K 0b10011 256M
0b01001 256K 0b10100 512M
0b01010 512K 0b10101 1G
0b01011 1M 0b10110 2G
0b01100 2M 0b10111 4G
注意TCM区域寄存器配置出来的各个TCM块不能相交,否则后果不可预测(会损坏硬件?)。

2009年4月1日星期三

对ARM的TrustZone理解

TrustZone是ARM对ARM6的扩展,其实只是增加了一条指令,一个配置状态位,以及一个新的有别于核心态和用户态的安全态。ARM并没有把TrustZone设计成能够解决所有的安全问题,它的目标是希望TrustZone能把一些安全性要求高的代码放在安全区域里执行,这也就是TrustZone名字的由来。

ARM把TrustZone固化在硬件里的道理是,系统的安全性不能全靠软件来保证,而且改写现有的不安全的软件,使之更安全也不大可行。较为可行的方案就是引入一块安全的硬件逻辑,并且只让一小块软>件控制此安全逻辑。这样既保护了既有投资,也把系统的安全风险降到最小。

因为操作系统和普通应用都可以运行在安全态,所以安全态不同于传统的运行态环状的特权划分,因此ARM把安全态描述成一个平行区域,称之为安全区,又称为安全监控模式。

核心态程序要进入到安全区运行,必须执行安全监控中断( secure monitor interrupt, SMI) 指令,而应用程序则必须通过API 函数来调用SMI 指令,此时,操作系统要负责检查应用程序是否安全,若通过检查则执行SMI 指令进入到安全区。这样,整个系统的安全性就全由操作系统负责了。换句话说,TrustZone需要软件的支持,才能达到安全目标。

执行SMI 指令的具体动作是,SMI 在CP15的安全状态寄存器中设置S位.。S位扩展还体现在AMBA总线上,这样外设也可以实现对TrustZone的支持。

安全监控程序(固件)是独立于操作系统的、自足的、不可重入的一小段代码。只要CP15安全状态寄存的S位处于置1状态,安全监控程序就要起作用(监测所有处理器操作)。首先监控程序要负责保存>上下文状态,即寄存器内容(一般保存到紧致内存TCM中),并且把当前处理器配置信息保存到CP15的单独一组分编(banked)寄存器中。TrustZone的开销是增加了大约350位状态信息,完成上下文切换需要200时钟周期。

由于TrustZone为安全区配备了单独的缓存、TLB和紧致内存TCM,上下文切换并不会导致这些性能构件内容的倒换,也即不会导致系统性能的降低。

ARM建议把安全监控程序及其运行时需要的内存置于一个TCM块中,以使延迟更低且更可预测。

安全扩展对于中断处理也有影响。因为中断既可以来自外设,也可来自软件,那就必须假定中断有可能造成安全漏洞,这样,在安全代码执行时,就不能简单地让任何中断切入进来。ARM建议的方案是,把中断也分为安全的和非安全的,安全代码只能被安全中断打断。当然,也可以把所有中断都提升为安全的,但那样会引入不必要的延迟。

TrustZone是体系结构的扩展,系统软件可以利用这一扩展提供安全支持,TrustZone本身并不能实现安全保障功能,但这一解决方案硬件实现不复杂,也不增加许多功耗,仍是具有很好性价比的安全嵌入式解决方案。

2009年3月31日星期二

嵌入式开发的新途径

嵌入式开发的传统过程是:
  • 编程
  • 交叉编译
  • 下载到板子或模拟器
  • 运行和交叉调试

如此往复循环。在此之前,需要购买或自己构建交叉工具链。

这一过程,如果使用一个足够强大的模拟器,可以简化为以下步骤:
  • 编程
  • 直接编译
  • 直接执行
  • 运行+直接调试或交叉调调试
可见最大的改动在于变交叉开发为直接开发,就像是在开发传统的非嵌入式软件(PC软件或服务器软件)。在此过程中,不再使用交叉编译,而是直接编译!

如同虚拟化工具能够给服务器软件或网络编程带来便利,模拟器能给嵌入式软件开发带来同样的便利,甚至更多——因为嵌入式开发与传统开发相比,更受限于可以使用的资源,如果能让嵌入式开发人员享受主机资源,那相对的开发效率提升是非常可观的。

对于模拟器的功能需求,至少有以下几点:
  • 必须是足够精确的全系统模拟器;
  • 必须具有远程(源码级)调试能力;
  • 必须具有虚拟化功能,即能让开发人员自由使用宿主机的资源,包括网络资源、存储资源能等;
  • 必须能够灵活配置,以使用户能够按需分配资源,如内存大小,处理器个数等;
也就是说,模拟器不仅仅只作为简单的模拟执行目标机指令的软件,而是能够行使嵌入式软件开发环境的功能。我正在开发的quark模拟器正是以此为目标的。

(quark模拟器正在最后测试,不久将发布第一个版本,该版本将支持ARM体系结构)

2009年3月30日星期一

s3c2410的时钟电源模块的初始值

在我的quark模拟器上,如果按照s3c2410手册上的默认值初始化时钟电源模块,Linux会panic:

setup_timer: HZ is too small, cannot configure timer!

经过交叉gdb进行源码级追踪,这条打印信息来自arch/arm/plat-s3c24xx/time.c文件的
s3c2410_timer_setup()函数。

正确的初始值应该是:

Reg_locktime = 0x00ffffff;
Reg_mpllconf = 0x0005c040;
Reg_upllconf = 0x00048032;
Reg_clkctrl = 0x00007de0;
Reg_sclkctrl = 0x00000004;
Reg_cdivctrl = 0x00000003;

u-boot也要这样修改,才可正常启动Linux。当然,本文应该也适用于真实的板子。

看好IBM收购SUN的技术理由

IBM之收购SUN,无论最后结果怎样,从技术层面分析,IBM会受益匪浅。以下详析之:

表面看来,IBM和SUN的技术大不相同:IBM的服务器基于Powerpc架构,而SUN基于SPARC架构,这也是二公司技术最不兼容之处。其实,技 术收购根本有利之处在于引入创新的思想,而非现成的产品。SUN的SPARC最新成果吞吐量计算架构(多核多线程),即使IBM也能借鉴许多,在处理器领 域,IBM收购SUN的最大收益不是SPARC本身,而是SPARC的最新思想,未开源的知识产权,以及优秀的体系结构人才。

SPARC产业链本身也并不是一无是处。SPARC服务器至今仍然是给SUN带来利润最多的产品。SUN的最新产品——基于16核CMT(片上多线 程)UltraSPARC和交易内存(transactional memory)的ROCK服务器,应该在今年(秋季)就能面市。所以,这个时候IBM收购SUN,相当于买了一只怀着金蛋的母鸡。即使ROCK不能创造奇 迹,SUN的数据中心产品,存储系统也是IBM此方面产品的有力补充——别忘了,SUN在2005年花费40忆美元购买了StorageTek。

其他的硬件技术和产品,包括SUN的万兆级以太网芯片、基于PCIE的AdvancedTCA工控平台,平板电脑(SunRay)等等,都是可以现成部署 的技术,IBM可以拿来就用,或者拿来就卖。比如万兆级以太网控制器Neptune,已经有现成的买家Marvell。这些技术或产品在SUN都属于小兵 种,但实际上每一个拿出来都可以玩转一个产业。所以SUN是名副其实的技术驱动公司。

软件方面,收购可使IBM彻底拥有Java,考虑到Java在服务器和嵌入式领域的主导地位,IBM不仅获得了知识产权,也获得了绝对的技术话语权和产业 主导权。Java没有给SUN带来应得的利润,但IBM则绝对有本事让Java更上层楼。Java作为编程语言,也许没什么太闪光的地方,但Java的价 值在于它所蕴含的巨大应用前景。SUN在Java的积累不言而喻,此外SUN还吸收一些业界的最新成果,这包括去年收购的开发出Java嵌入式操作系统的 Savaje公司。

IBM有自己的UNIX操作系统AIX,但SUN的Solaris近几年创出许多伟大的新技术,这就包括著名的Dtrace和ZFS,前者是内核级追踪工 具,后者则是号称最后的(Z!)文件管理系统。拥有了Solaris技术队伍,IBM可以轻松地把这些前沿的技术移植到AIX。虽然是不同的操作系统,但 UNIX本身具有的标准化程度使这项任务不象表面上那样困难——实际上,应该非常轻松!此外,Solaris本身也值得作为单独的产品继续得到支持——不 应该忽视现有的Solaris用户群。

SUN花10忆美元巨资购买的MySQL也是IBM的DB2的完美补充:MySQL能探触到DB2够不到的应用领域,比如企业级应用,拥有了MySQL,IBM在数据库方面则可以和Oracle一较高下了。

以上任何一项技术都绝非泛泛,没有人可以小看这些技术。IBM接管这些技术,应该是非常乐意的。而另一方面,似乎也只有IBM能消化这些技术——你不能想象DELL能吞下SPARC或Solaris,而HP,鉴于其丢弃Alpha处理器、PA-RISC和HP-UX的前科,也决无胆量重做冯妇。

SUN有无数闪光的技术,SUN之所以走到今天,不是技术落后,恰恰相反,正是因为技术的先进,反而使得SUN产品的营销和支持成本太高,SUN的客户开 玩笑说,玩转SUN的产品需要PhD才行!其实并不是SUN的用户界面不够友好,而是掌握那些技术需要有一个学习过程,没有用户喜欢频繁的技术更新。有时 保守的技术反而能阻止客户的退出。

IBM和SUN,技术上貌似差别很大,但实际上异曲同工,IBM收购SUN,实是亲者快,仇者痛之举!