内核的schedule和SMP多核处理器启动协议

目录

一,学习SMP系统我需要掌握哪些硬件知识

1,cp15和CPSR

[(1)0, c1, c0, 0控制mmc icache dcache的使能和禁用](#(1)0, c1, c0, 0控制mmc icache dcache的使能和禁用)

[(2)0, c0,c0,5可以读取当前cpuid](#(2)0, c0,c0,5可以读取当前cpuid)

[(3)0, c1, c0, 0控制MMU、缓存、对齐检查等](#(3)0, c1, c0, 0控制MMU、缓存、对齐检查等)

(4)cpsr寄存器

2,PMU

3,sgrf

4,grf

5,timer

6,sram

[(1)sram@ff700000 system sram 96k](#(1)sram@ff700000 system sram 96k)

[(2)sram@ff720000 pmu-sram,4k](#(2)sram@ff720000 pmu-sram,4k)

7,gic中断管理

二,SMP类型

1,PSCI

2,spin-table

3,rockchip,rk3066-smp


一,学习SMP系统我需要掌握哪些硬件知识

1,cp15和CPSR

(1)0, c1, c0, 0控制mmc icache dcache的使能和禁用

uint32_t read_p15_c1(void)

{

uint32_t value;

asm volatile(

"mrc p15, 0, %0, c1, c0, 0"

: "=r" (value)

:

: "memory");

return value;

}

write_p15_c1(read_p15_c1() | (1 << 0));//mmu enable

write_p15_c1(read_p15_c1() & ~(1 << 0));//mmu disable

write_p15_c1(read_p15_c1() | (1 << 2));//dcache enable

write_p15_c1(read_p15_c1() & ~(1 << 2));//dcache disable

write_p15_c1(read_p15_c1() | (1 << 12));//icache enable

write_p15_c1(read_p15_c1() & ~(1 << 12));//icache disable

(2)0, c0,c0,5可以读取当前cpuid

uint32_t smp_processor_id(void)

{

uint32_t tmp;

asm volatile(

"mrc p15,0,%0,c0,c0,5\n"

"and %0,%0,#0x3\n"

: "=r" (tmp)

:

: "memory");

return tmp;

}

(3)0, c1, c0, 0控制MMU、缓存、对齐检查等

SCTLR是ARMv7架构中最重要的系统控制寄存器,控制着处理器的核心行为,包括MMU、缓存、对齐检查等

asm volatile(

"mrc p15, 0, %0, c1, c0, 0\n"

: "=r" (sctlr)

:

: "memory");

// MMU和缓存

printf("MMU状态: %s\n", (sctlr & (1 << 0)) ? "启用" : "禁用");

printf("对齐检查: %s\n", (sctlr & (1 << 1)) ? "启用" : "禁用");

printf("数据缓存: %s\n", (sctlr & (1 << 2)) ? "启用" : "禁用");

printf("指令缓存: %s\n", (sctlr & (1 << 12)) ? "启用" : "禁用");

// 保护特性

printf("WXN(写执行从不): %s\n", (sctlr & (1 << 19)) ? "启用" : "禁用");

printf("UCI(用户缓存指令): %s\n", (sctlr & (1 << 26)) ? "启用" : "禁用");

printf("SPAN(PXN设置): %s\n", (sctlr & (1 << 23)) ? "启用" : "禁用");

// 异常处理

printf("异常字节序: %s\n", (sctlr & (1 << 25)) ? "大端" : "小端");

printf("异常入口: %s\n", (sctlr & (1 << 30)) ? "Thumb" : "ARM");

// 其他

printf("非对齐访问: %s\n", (sctlr & (1 << 22)) ? "启用" : "禁用");

printf("nTWI(Thumb等待中断): %s\n", (sctlr & (1 << 16)) ? "禁用" : "启用");

printf("nTWE(Thumb等待事件): %s\n", (sctlr & (1 << 18)) ? "禁用" : "启用");

(4)cpsr寄存器


N(bit31):当两个补码表示的 有符号整数运算的时候,N=1 表示运算对的结果为负数,N=0
表示结果为正数。
Z(bit30):Z=1 表示运算结果为零,Z=0 表示运算结果不为零,对于 CMP 指令,Z=1 表示
进行比较的两个数大小相等。
C(bit29):在加法指令中,当结果产生了进位,则 C=1,表示无符号数运算发生上溢,其它
情况下 C=0。在减法指令中,当运算中发生借位,则 C=0,表示无符号数运算发生下溢,其它
情况下 C=1。对于包含移位操作的非加/减法运算指令,C 中包含最后一次溢出的位的数值,对
于其它非加/减运算指令,C 位的值通常不受影响。
V(bit28):对于加/减法运算指令,当操作数和运算结果表示为二进制的补码表示的带符号
数时,V=1 表示符号位溢出,通常其他位不影响 V 位。
Q(bit27):仅 ARM v5TE_J 架构支持,表示饱和状态,Q=1 表示累积饱和,Q=0 表示累积
不饱和。
IT[1:0](bit26:25):和 IT[7:2](bit15:bit10)一起组成 IT[7:0],作为 IF-THEN 指令执行状态。
J(bit24):仅 ARM_v5TE-J 架构支持,J=1 表示处于 Jazelle 状态,此位通常和 T(bit5)位一起
表示当前所使用的指令集
GE[3:0](bit19:16):SIMD 指令有效,大于或等于。
IT[7:2](bit15:10):参考 IT[1:0]。
E(bit9):大小端控制位,E=1 表示大端模式,E=0 表示小端模式。
A(bit8):禁止异步中断位,A=1 表示禁止异步中断。
I(bit7):I=1 禁止 IRQ,I=0 使能 IRQ。
F(bit6):F=1 禁止 FIQ,F=0 使能 FIQ。
T(bit5):控制指令执行状态,表明本指令是 ARM 指令还是 Thumb 指令,通常和 J(bit24)一
起表明指令类型,参考 J(bit24)位。
M[4:0]:处理器模式控制位
10000 User 模式
10001 FIQ 模式
10010 IRQ 模式
10011 Supervisor(SVC)模式
10110 Monitor(MON)模式
10111 Abort(ABT)模式
11010 Hyp(HYP)模式
11011 Undef(UND)模式
11111 System(SYS)模式
快速修改bit7的方法:
CPSID I - 禁用IRQ中断
CPSIE I - 启用IRQ中断

2,PMU

pmu: power-management@ff730000 {

compatible = "rockchip,rk3288-pmu", "syscon", "simple-mfd";

reg = <0x0 0xff730000 0x0 0x100 >;

power: power-controller {

compatible = "rockchip,rk3288-power-controller";

#power-domain-cells = <1 >;/**is a provider, is a power domain**/

#address-cells = <1 >;

#size-cells = <0 >;

assigned-clocks = <&cru SCLK_EDP_24M>;

assigned-clock-parents = <&xin24m>;

};

};

重点寄存器

ox0090配置低功耗模式是否触发idle请求

3,sgrf

sgrf: syscon@ff740000 {

compatible = "rockchip,rk3288-sgrf", "syscon";

reg = <0x0 0xff740000 0x0 0x1000 >;

};

4,grf

grf: syscon@ff770000 {

compatible = "rockchip,rk3288-grf", "syscon";

reg = <0xff770000 0x1000 >;

};

重点寄存器

5,timer

三类timer都要掌握

(1)arm自带的timer arm,armv7-timer

(2)Alive Timer(保活定时器)timer6和timer7

(3)CPU Timer timer0-5

6,sram

spin-table或rockchip,rk3066-smp需要使用sram,主核心(通常是 CPU0)需要将一个启动地址写入到一个共享的内存位置,然后唤醒从核心(CPU1、CPU2 等)。从核心被唤醒后会读取这个共享内存位置,获取启动地址并跳转执行。这个共享内存位置必须是一段从核心上电后就能访问的内存,并且主核心和从核心都能访问。通常,SRAM 被用作这个共享内存。

(1)sram@ff700000 system sram 96 k

bus_intmem: sram@ff700000 {

compatible = "mmio-sram";

reg = <0x0 0xff700000 0x0 0x18000 >;

#address-cells = <1 >;

#size-cells = <1 >;

ranges = <0 0x0 0xff700000 0x18000 >;/**childaddr,parentaddr,lenth**/

smp-sram@0 {

compatible = "rockchip,rk3066-smp-sram";

reg = <0x00 0x10 >;

};

ddr_sram: ddr-sram@1000 {

compatible = "rockchip,rk3288-ddr-sram";

reg = <0x1000 0x4000 >;

};

};

(2)sram@ff720000 pmu-sram,4 k

pmu_sram: sram@ff720000 {

compatible = "rockchip,rk3288-pmu-sram", "mmio-sram";

reg = <0x0 0xff720000 0x0 0x1000 >;

};

7,gic中断管理

一些配置影响Distributor向哪个CPU interfaces分发中断,比如

GICD_ITARGETSR bit assignments, for a multiprocessor implementation

二,SMP类型

三种SMP多核处理器启动协议

1,PSCI

2,spin-table

3,rockchip,rk3066-smp

相关推荐
_运维那些事儿2 小时前
VM环境的CI/CD
linux·运维·网络·阿里云·ci/cd·docker·云计算
Y1rong3 小时前
linux之文件IO
linux
Trouvaille ~3 小时前
【Linux】UDP Socket编程实战(一):Echo Server从零到一
linux·运维·服务器·网络·c++·websocket·udp
嵌入小生0073 小时前
Shell | 命令、编程及Linux操作系统的基本概念
linux·运维·服务器
-Try hard-4 小时前
Linuv软件编程 | Shell命令
linux·运维·服务器
释怀不想释怀4 小时前
Linux快捷键,软件安装启动
linux·运维·服务器
Hello World . .4 小时前
Linux:软件编程
linux·运维·服务器·vim
人间打气筒(Ada)5 小时前
k8s:CNI网络插件flannel与calico
linux·云原生·容器·kubernetes·云计算·k8s
老师用之于民5 小时前
【DAY21】Linux软件编程基础&Shell 命令、脚本及系统管理实操
linux·运维·chrome·经验分享·笔记·ubuntu