boot_cpu_init 분석
cpu 러닝 상태로 만들기 위해 online, active, present, possible 각각 4개 기능을 true 로 설정해 준다.
(문c블로그 참조: http://jake.dothome.co.kr/boot_cpu_init/)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
__attribute__((optimize("-O0"))) void __init boot_cpu_init(void)
{
int cpu = smp_processor_id();
/* Mark the boot cpu "present", "online" etc for SMP and UP case */
set_cpu_online(cpu, true);
set_cpu_active(cpu, true);
set_cpu_present(cpu, true);
set_cpu_possible(cpu, true);
#ifdef CONFIG_SMP
__boot_cpu_id = cpu;
#endif
}
static inline unsigned long __my_cpu_offset(void)
{
unsigned long off;
/*
* We want to allow caching the value, so avoid using volatile and
* instead use a fake stack read to hazard against barrier().
*/
asm(ALTERNATIVE("mrs %0, tpidr_el1", //oldinstr: 부트업 cpu 또는 조건을 만족시키지 못할 때 수행할 1개의 assembly 명령어
"mrs %0, tpidr_el2", //newinstr: secondary cpu 들에서 조건을 만족시킬 때 대치될 1개의 assembly 명령어
ARM64_HAS_VIRT_HOST_EXTN) //feature: cpu 아키텍처가 지원하는 기능(capabilities) ARM64_HAS_VIRT_HOST_EXTN = 11 0b1011
: "=r" (off) :
"Q" (*(const unsigned long *)current_stack_pointer));
return off;
}
/* ./arch/arm64/include/asm/percpu.h:
45 "Q" (*(const unsigned long *)current_stack_pointer));
0xffff000011110290 <+24>: mov x0, sp //현재 stack pointer 값을 x0에 옮긴다.
41 asm(ALTERNATIVE("mrs %0, tpidr_el1",
--Type <RET> for more, q to quit, c to continue without paging--c
0xffff000011110294 <+28>: mrs x0, tpidr_el1 // tpidr_el1의 값을 x0에 옮긴다.(특수 레지스터는 mrs 명령어를 통해 이동)
0xffff000011110298 <+32>: str x0, [x29, #120] // tpidr_el1 값을 x29+#120 주소에 store 해준다.
0xffff00001111029c <+36>: ldr x1, [x29, #120] // tpidr_el1 값을 x1에 적는다.
아래 gdb display 값은 마지막 <+36> 명령어 까지 실행 후 값이다.
(gdb)
1: $pc = (void (*)()) 0xffff0000111102a0 <boot_cpu_init+40>
3: /x $x0 = 0x0
5: $sp = (void *) 0xffff000011263f00
6: /x $x29 = 0xffff000011263f00
7: /x $x1 = 0x0
8: $tpidr_el1 = void
*/
|
cs |
이전 smp_setup_processor_id() 함수에서 set_my_cpu_offset(0) 함수를 통해 tpidr_el1의 값에 id에 해당하는 비트를
00으로 설정해 주는 부분이 있었는데 첫줄 smp_processor_id 함수를 들어가면 __my_cpu_offset함수를 통해 이전에 설정 해줬던 tpidr_el1의 값을 읽어와 off 로 return 해준다.
(이전 글:https://kjt9109.tistory.com/entry/smpsetupprocessorid 에서 set_my_cpu_offset(0)을 참조)
따라서 smp_processor_id(); return은 0으로 값이 나온다.
'Linux > ARM64' 카테고리의 다른 글
arch_local_irq_disable() (0) | 2019.12.27 |
---|---|
smp_setup_processor_id() (0) | 2019.12.27 |
early_ioremap_init(void) (0) | 2019.12.24 |
early_fixmap_init(void) (0) | 2019.12.22 |