PowerPC 体系结构之存储管理

取 BOOKE 精要,兼顾 E500 规范。 E500 规范是 BOOKE 的 32-bit 实现,更详细些,大部与 BOOKE 兼容。

BOOKE 对存储管理的规范较抽象,没有非常多的细节(比如 TLB 每项的结构必须如此等等),涉及细节则多以 E500 为例子。

1. 概述

E500 实现有两级 TLB,即:L1 TLB 和 L2 TLB。L1 TLB 可以理解为 L2 TLB 的部分缓存。访问 L1 TLB 的效率要比 L2 的效率高,相应的实现的花费也就高。L1 TLB 由硬件维护,不可编程精确控制。故下面的讨论皆针对 L2 TLB,为方便简称其为 TLB。

E500 没有对虚拟地址空间进行划分,即没有固定使用某段虚拟地址固定映射到某段物理地址 (MIPS,主要用于支持设备资源的固定映射以及方便内核对内存的管理)。而是引入了一个更灵活的设计:将 TLB 分为 TLB0 和 TLB1。

TLB0 即用于页映射的 TLB,可动态被替换,页大小固定为 4 KB。E500v1 实现为 2 路组相联,256 项;E500v2 实现为 4 路组相联,512 项。

TLB1 则设计用于映射大页(比如 16MB, 256MB …),支持可变页大小,E500v1 可支持 9 个页大小(最大 256MB),E500v2 则支持 11 个页大小(最大 4GB)。使用时可将某项设为永驻 TLB1 (通过置 Invalidation Protection 位,简写为 IPROT 位),不会被动态替换,实现为全相联,共 16 项,可将其理解为用于映射 16 个段的可编程固定映射机制。

PowerPC 体系结构之中断异常

取 BOOKE 之精要。

1. 异常类型

00 Critical Interrupt     来自于外部中断控制器,具有较高的优先级
01 Machine Check    严重的内部状态错误,如 Cache 数据的校验失败
02  Data Storage    数据读写异常,如:用户态读一个非用户态的页 (UR=0)
03  Instruction Storage    读指令异常,如:用户态时取一个用户态不可执行的页 (UX=0)
04 External Interrupt    来自于外部中断控制器
05  Alignment    非对齐访问异常
06 Program    程序异常,如:执行非法指令,用户态执行特权指令
07  Floating-Point unavailable    在无浮点部件的 CPU 上执行浮点指令即会触发此异常
08 System call    系统调用
09  Auxiliary Processor Unavailable    在无协处理器的 CPU 上执行协处理器指令即触发此异常
10  Decrementer    DEC 寄存器归零异常,DEC 是一个内部时钟计数器,Linux 用之实现时钟中断
11  Fixed-interval timer interrupt
12 Watchdog timer interrupt
13 Data TLB error    数据 TLB Miss 异常
14 Instruction TLB error    指令 TLB Miss 异常
15 Debug    调试异常,用于支持调试

16 – 31   Reserved for future use   保留给将来体系结构升级用
32 – 63   Allocated for implementation-dependent use   具体实现相关

其中 0,1,12,15 为 Critical Exception,当其发生时,使用 CSRR0 & CSRR1 保存当前 PC 或 (PC + 4) 和 MSR;其他异常发生时,则使用 SRR0 & SRR1 保存当前 PC 或 (PC + 4) 和 MSR

可以看到 BOOKE 体系结构层面规定的异常即为前 16 个,这其中的有些异常是个笼统的抽象(比如 Data Storage 就需要区分是读还是写导致的),为了更细地描述发生异常的原因,PowerPC 引入了一个 ESR (Exception Syndrome Register),让硬件在异常发生时,在其中指出更具体的原因。比如 若 ESR[40] 被置位,则说明异常是由写操作引起的。

PowerPC 体系结构之指令集 (II)

3.3 整数指令

这类指令大致分为如下几类:

整数访存指令
整数算术运算指令
整数逻辑运算指令
整数比较指令
整数陷阱指令
整数移位指令
XER 指令

其中以整数循环移位指令最为特别。

3.3.1 整数访存指令

3.3.1.1 Load Byte/Half-word/Word and Zero

该类指令从指定地址处读取 8 位、16 位、32 位数据,置入 RT,RT 高位置 0

lbz/lbzu            RT, D(RA)
lbzx/lbzux          RT, RA, RB

lhz/lhzu            RT, D(RA)
lhzx/lhzux          RT, RA, RB

lwz/lwzu            RT, D(RA)
lwzx/lwzux          RT, RA, RB

RT, RA, RB 皆为 GPR,D 为有符号立即数。则有效地址的计算分别为:RA[32:63] + D,RA[32:63] + RB[32:63],有效地址高 32 位置 0。

后缀 u 表示 Update,即将有效地址更新到 RA 中
后缀 x 表示 Indexed,即使用 RA + RB 的寻址方式

以上用于 32 位,对 64 位,上述指令皆加后缀 ‘e’。则有效地址的 0 ~ 31 位, 不再置 0,其计算方式如下:RA + D,RA + RB。

此外,用于 64 位的还有对双字操作的支持:

lde/ldue/ldxe/lduxe

PowerPC 体系结构之指令集 (I)

1. 概述

Book E 定义的 PowerPC 指令集的指令可分为以下几类:

分支跳转指令
CR 指令 整数指令
浮点指令
处理器控制指令
存储管理相关指令

CR 指令主要是对 CR 内部位运算支持的一些指令,如 crand, cror, crxor 等等。

2. 常用指令

先看一个测试程序:

int test_call(int a, int b, int c)
{
	a = b + c;
	return a;
}

int test_if(int s)
{
	int i;
	if(s > 0)
		i = s;
	else if(s < 0)
		i = -s;
	else
		i = s * 8;
	return i;
}

int test_cyc1(int c)
{
	int sum = 0;
	do {
		sum += c;
		c--;
	} while(c > 0);
	return c;
}

int test_cyc2(int c)
{
	int sum = 0;
	for(; c > 0; c--)
		sum += c;
	return c;
}

int main()
{
	int a, b, c, d;
	a = test_if(5);
	b = test_cyc1(10);
	c = test_cyc2(10);
	d = test_call(1, 2, 3);
	return a + b + c + d;
}

引入的目的在于查看判断、循环和过程调用这些基本结构在 PowerPC 里怎么被支持。

-O2 参数编译后,objdump -S -d 反汇编,则:

PowerPC 体系结构之 ULR 和 ABI

A. 以下取 Book E 之 ULR 精要

ULR (User Level Register) 即用户态程序能用的寄存器,包括只读的和可读写的。

最常用的 ULR 包括以下寄存器:

1. GRP (General Purpose Register) 通用寄存器,即用于定点运算的寄存器,共 32 个

2. CR (Condition Register) 指令状态寄存器,其格式如下所示:


注意:Book E 对寄存器的位编号与通常不同,因其支持 PowerPC 64,故其将 64 位寄存器从最高位 (MSB) 到最低位 (LSB) 编号为 0 ~ 63,32 位寄存器则编号为 32 ~ 63。

CR 以4位为单位分成 8 个域,每个域能描述 4 种状态。

2.1 CR0 用于存放 RC 位为1 的整数指令执行后的状态。CR[32:35] 依次表示小于、大于、等于和溢出。当指令执行的结果小于、大于或等于 0 时则置相应的CR[32:34] 的位;CR[35] 的值则直接复制自XER 的 SO (Summary Overflow)位。

2.2 CR1用于存放 RC 位为 1 的所有浮点指令执行后的浮点异常状态。其内容直接复制于浮点状态与控制寄存器 (FPSCR),CR[36:39] 依次对应于浮点异常 (FX)、浮点使能异常 (FEX)、浮点非法操作异常 (VX) 和浮点溢出异常 (OX)。

RC 位为 1 的指令,其助记符的最后有一个 ‘.‘ ,如 addic./divw./mullw./neg./and./or./xor./nand./nor.

2.3 对于比较指令(整数和浮点),可以通过操作数 BF 指定比较结果所存储的 CR 域:

cmp   3, 0, r3, r4        (cmp    BF, L, RA, RB)

操作数 L = 0,表示此为 32 位比较,即只比较 r3, r4 的 32 ~ 63 位。若 r3 > r4,则将 CR3[gt] (CR[45]) 置位。浮点比较类似,但域内第 4 位含义与整数不同,整数依然表示溢出 (SO),且其值拷贝自 XER[SO];而对浮点比较,若该位被置,则表示某一浮点操作数不是数值。

2.4 此外 RC 位为 1 的条件存储指令 (stwcx./stwcxe./stdcxe.),在存储操作成功时置 CR0[2] (EQ 位) 为 1。