浅谈ARMv8-A系列CPU的架构
1978年底,物理学家Hermann Hauser和工程师Chris Curry,在英国剑桥创办了CPU公司(Cambridge Processing Unit),主要业务是为当地市场供应电子设备。1979年,CPU公司改名为Acorn计算机公司。
▲图源网上 Hermann Hauser和Chris Curry
1981年,Acorn计算机公司迎来了一个难得的机遇 。英国广播公司BBC,为提高英国电脑普及水平,打算制作一档节目,他们希望Acorn能生产一款与之配套的电脑。英国政府也参与其中,这意味着电脑一旦采购,将进入英国的每一间教室。
在Acorn计算机公司即将大展身手之际,他们很快发现,自己设计的产品硬件并不能满足需求。因为当时中央处理器的发展潮流,正在从8位变成16位。但Acorn并没有合适的芯片可以用。
起初,Acorn计算机公司在验证了市面上的主流芯片后,由于各种缺陷不能满足要求而苦恼。于是,他们打算去找当时如日中天的Intel,希望对方提供一些80286处理器的设计资料和样品。但是却遭到了拒绝。备受打击的Acorn公司,一气之下决定自己干,从头开始造芯片(别人的山珍海味再香,也不如自己的窝窝头好吃~)。
当时,Acorn公司的研发人员,从美国加州大学伯克利分校,找到了一个关于新型处理器的研究——精简指令集,恰好可以满足他们的设计要求。在此基础上,经过多年的艰苦奋斗,来自剑桥大学的计算机科学家Sophie Wilson和Steve Furber最终完成了微处理器的设计。
▲图源网上-Sophie Wilson和Steve Furber
对于这块芯片,Acorn给它命名为Acorn RISC Machine。Acorn是公司名称,Machine是机器,RISC是精简指令集。嗯,这就是大名鼎鼎的“ARM”三个字母的由来。
01
重头戏RISC
RISC的全称是"精简指令集计算机"(reduced instruction set computer),它支持的指令比较简单,所以功耗小、价格便宜,特别适合移动设备。早期使用ARM芯片的典型设备,就是苹果公司的牛顿PDA。“简化指令集”,是相对于“复杂指令集”(CISC,complex instruction set computer)的一个概念。
早期的处理器都是CISC架构(包括英特尔的处理器),随著时间推移,有越来越多的指令集加入。由于当时编译器的技术并不纯熟,程序都会直接以机器码或是组合语言写成,为了减少程序的设计时间,逐渐开发出指令单一,但可以做复杂操作的程序代码。设计师只需写下简单的指令,再交给CPU去执行就可以了。
但是后来有人发现,整个指令集中,只有约20%的指令常常会被使用到,大约占了整个程序的80%;剩余80%的指令,只占了整个程序的20%。于是,1979年美国加州大学伯克利分校的David Patterson教授提出了RISC的想法,主张硬件应该专心加速常用的指令,较为复杂的指令则利用常用的指令去组合。
最后,ARM“有意无意地”选择了与Intel不同的设计路线——Intel持续迈向x86高效能设计,ARM则专注于低成本、低功耗的研发方向。
02
ARMv8诞生的契机
历史总是诡谲荒诞,原来被Intel最瞧不起的移动端市场业务,竟然在苹果iPhone问世以后,呈现井喷式的爆发增长起来。获利最大的公司之一,当属ARM。因为此时的ARM早已调整了业务方向,改为IP授权的方式,将自己的ARM设计卖给全球的芯片设计和制造公司。
▲图源网上
后面的事情大家都知道了,苹果安卓两家在全球移动端市场平分江山,以ARM的IP为核心的芯片充斥到我们生活的方方面面。并且在芯片制程技术的快速发展下,以及ARM公司的不断努力,手机移动端的处理器性能在不断拔高。彼时,已经出现使用ARM芯片的电脑和服务器了。微软非常机智,很快就发布了适配ARM架构的windows操作系统。
与此同时,新的趋势正在酝酿,主要包括大内存(Large Memory)、虚拟化(Virtualization)和安全(Security)。Virtualization在ARMv7上已经有简单的硬件实现,Security也有可能基于当前架构扩展,唯有Large memory的需求,有点棘手。
▲图源网上
由于处理器性能越来越强,运行于其上的软件也来越复杂,复杂到单一应用对内存的需求可能超出32-bit架构所能支持的最大内存(4G),这就是Large memory需求的起因。不过,后来的ARMv7架构通过Large Physical Address Extensions (LPAE) 技术,可以支持高达40bits的物理地址空间。但受限于32-bit的指令集,虚拟地址空间依旧只有32bits(4G),如果有应用需要更大的虚拟内存,怎么办?只能定义一个新的架构,使用64-bit的指令集(ARM64)。
很显然,ARMv8应运而生!
既然要做高性能的处理器,那么在指令集和架构设计上,就要丢弃原本ARM指令集的一些设计和包袱。但是又因为ARM的通用性,几乎现在所有的电子端设备都可以看到ARM的身影,于是ARM又保留了向下兼容的特性。
不仅如此,ARM还放弃了早期的处理器核心命名规范,改用全新的cortex系命名规则,并对指令集划分三个方向,分别面向高端、中端、低端三大市场。 中低端芯片在ARMv6、ARMv7指令集架构时代就已见势头,真正看ARM雄厚的芯片设计能力,在高性能端处理器上展现的,还得是ARMv8指令集架构。
ARMv8指令集,同样分了三个系列,ARMv8-A、ARMv8-R、ARMv8-M。由于这里篇幅有限,我们只讨论ARMv8-A架构。那么接下来,就带领大家看看ARMv8架构的精巧设计。
03
ARMv8-A架构的主要特性
看一个架构好不好,不仅要关注一下它的设计重点,还要看看它的发展由来。我们知道,在ARMv8之前,处理器可以工作在多种处理器模式(称作processor mode)下,包括User、FIQ、IRQ、Abort、Undefined、System等,之所以存在不同的模式,主要有2个方面的考虑:安全性和高效性。以ARMv7以前为例:
安全性的角度:不同的处理器模式,有不同的硬件访问权限,称作privilege level。主要有2个level,privilege和non-privilege。其中只有User模式属于non-privilege level,其它均是privilege level。安全起见,大多数时候,软件都运行在User mode。一旦需要其它操作,则需要切换到相应的privilege模式下。这样根据不同的处理器模式,可以利用对硬件的访问权限,做好数据隔离。可以说是最原始、最朴素的安全思想。
高效性的角度:这些处理器模式,除User模式外,其它模式基本上与各类异常一一对应。不同的模式,对应有自己的寄存器,例如R13(SP)、R14(LR)等等,可以使模式切换过程(也是异常处理过程)更为高效、便利。
在ARMv7-A架构时代,对privilege level有了新的定义,称作PL0和PL1。后来又增加了PL2,用于虚拟化扩展(Virtualization Extension)。另外,增加了两个新模式:Monitor和Supervisor,分别用于security扩展和virtualization扩展。
后来,PL0/1/2的概念在ARMv8架构上继续整合,诞生了全新的Exception Level,简称EL0-EL3。Exception level本身就已经包好了privilege的信息,即ELn的privilege随着n的增大而增大。类似地,可以将EL0归属于non-privilege level,EL1/2/3属于privilege level。
这些Exception level的具体意义可参考下图:
这里有一些关键点:
1)ARMv8-A支持64位模式和32位模式。但在AArch64中,已经没有User、SVC、ABT等处理器模式的概念,为了向下兼容,在AArch32里,就把这些处理器模式map到了4个Exception level。
2)Application位于特权等级最低的EL0,Guest OS(Linux kernel、window等)位于EL1,提供虚拟化支持的Hypervisor位于EL2(可以不实现),提供Security支持的Seurity Monitor位于EL3(可以不实现)。
3)只有在异常发生时(或者异常处理返回时),才能切换Exception level(这也是Exception level的命名原因,为了处理异常)。当异常发生时,有两种选择,停留在当前的EL,或者跳转到更高的EL,EL不能降级。同样,异常处理返回时,也有两种选择,停留在当前EL,或者调到更低的EL。
上面提到AArch64,就是在ARMv8首次引入的指令集形式。并且在此基础上,又对以往的指令集版本进行了总结。总共分为四种:A64(固定32位长度指令集)、A32(固定32位长度指令集)、T32(可变32位长度指令集,即Thumb-2)、T16(Thumb)。
现在,我们可以对ARMv8-A架构的主要特性做一下总结:
1)新增一套AArch64的指令集,简称A64。
2)由于需要向下兼容ARMv7,所以同时支持现存的32-bit指令集(A32和T32)。
3)定义AArch64和AArch32两套运行环境(称作Execution state),分别执行AArch64和AArch32指令集。软件可以在需要的时候,切换Execution state,同时物理硬件上也是两套寄存器共存。
4)AArch64最大的改动,使用新的概念(exception level),重新解释了processor mode、privilege level等概念。
5)在ARMv7 security extension的基础上,新增security model,支持安全相关的应用需求。
6)在ARMv7 virtualization extension的基础上,提供完整的virtualization框架,从硬件上支持虚拟化。
04
基于SkyEye的ARMv8-A架构的仿真实现
SkyEye目前支持的ARMv8架构处理器,有国产飞腾系列的FT1500、FT2000AHK、FT2000A/C4等型号。根据SkyEye的仿真框架,指令集与处理器是分开实现的,A64指令集单独抽象,以提供处理器级别仿真的基本能力。
对AArch64仿真,主要抽象了指令集对应的行为,比如exception level,security model和virtualization框架;在此基础上解析到具体的指令集,可以实现ISA级别仿真。
处理器仿真,在指令集仿真框架的基础上,进行差异化实现,主要在处理器的资源差异上进行仿真模块的分配。比如不同处理器支持的MMU有所差异。
参考资料及文献:
[1] 《ARMv8-A指令集手册》