Linux smp_setup_processor_id(arm)

看到start_kernel的代码,看到smp_setup_processor_id(void)记一下,更多的是GCC语法,以及一点arm指令的分析。
从函数名也可以看出,这里是设置处理器ID。

void __init smp_setup_processor_id(void)
{
	u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
	cpu_logical_map(0) = mpidr;

	/*
	 * clear __my_cpu_offset on boot CPU to avoid hang caused by
	 * using percpu variable early, for example, lockdep will
	 * access percpu variable inside lock_release
	 */
	set_my_cpu_offset(0);
	pr_info("Booting Linux on physical CPU 0x%010lx [0x%08x]\n",
		(unsigned long)mpidr, read_cpuid_id());
}
static inline u64 __attribute_const__ read_cpuid_mpidr(void)
{
	return read_cpuid(MPIDR_EL1);
}

read_cpuid是个宏,定义如下:

#define read_cpuid(reg)			read_sysreg_s(SYS_ ## reg)
//-------->
read_sysreg_s(SYS_MPIDR_EL1)

#define read_sysreg_s(r) ({						\
	u64 __val;							\
	asm volatile(__mrs_s("%0", r) : "=r" (__val));			\
	__val;								\
})
//-------->
{
	u64 __val;
	asm volatile(__msrs_s("%0", SYS_MPIDR_EL1) : "=r" (__val));
	__val;
}
#define __mrs_s(v, r)						\
	DEFINE_MRS_S						\
"	mrs_s " v ", " __stringify(r) "\n"			\
	UNDEFINE_MRS_S
//-------->
DEFINE_MRS_S
"mrs_s  %0, SYS_MPIDR_EL1\n"
UNDEFINE_MRS_S

#define __DEFINE_MRS_MSR_S_REGNUM				\
"	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30\n" \
"	.equ	.L__reg_num_x\\num, \\num\n"			\
"	.endr\n"						\
"	.equ	.L__reg_num_xzr, 31\n"

#define DEFINE_MRS_S						\
	__DEFINE_MRS_MSR_S_REGNUM				\
"	.macro	mrs_s, rt, sreg\n"				\
	__emit_inst(0xd5200000|(\\sreg)|(.L__reg_num_\\rt))	\
"	.endm\n"

#define UNDEFINE_MRS_S						\
"	.purgem	mrs_s\n"
//-------->
.equ	.L__reg_num_x0, 0
.equ	.L__reg_num_x1, 1
.equ	.L__reg_num_x2, 2
.equ	.L__reg_num_x3, 3
.equ	.L__reg_num_x4, 4
.equ	.L__reg_num_x5, 5
.equ	.L__reg_num_x6, 6
.equ	.L__reg_num_x7, 7
.equ	.L__reg_num_x8, 8
.equ	.L__reg_num_x9, 9
.equ	.L__reg_num_x10, 10
.equ	.L__reg_num_x11, 11
.equ	.L__reg_num_x12, 12
.equ	.L__reg_num_x13, 13
.equ	.L__reg_num_x14, 14
.equ	.L__reg_num_x15, 15
.equ	.L__reg_num_x16, 16
.equ	.L__reg_num_x17, 17
.equ	.L__reg_num_x18, 18
.equ	.L__reg_num_x19, 19
.equ	.L__reg_num_x20, 20
.equ	.L__reg_num_x21, 21
.equ	.L__reg_num_x22, 22
.equ	.L__reg_num_x23, 23
.equ	.L__reg_num_x24, 24
.equ	.L__reg_num_x25, 25
.equ	.L__reg_num_x26, 26
.equ	.L__reg_num_x27, 27
.equ	.L__reg_num_x28, 28
.equ	.L__reg_num_x29, 29
.equ	.L__reg_num_x30, 30
.equ	.L__reg_num_xzr, 31

.macro mrs_s, rt, sreg
.inst 0xd5000000|(\\sreg)|(.L__reg_num_\\rt)
.endm

mrs_s  %0, SYS_MPIDR_EL1\n
//->
.inst(0xd5000000|(0x1800A0)|.L__reg_num_0)
//不懂为什么是L__reg_num_0而不是L__reg_num_x0,可能是"%0"中的%被解析成了x
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值