본문 바로가기

Linux/ARM64

boot_cpu_init()

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