smp启动-cpu_operation-init_bootcpu_ops
上一篇: https://www.cnblogs.com/zhangzhiwei122/p/16090641.html
setup_arch->init_bootcpu_ops
arch/arm64/kernel/setup.c
284void __init __no_sanitize_address setup_arch(char **cmdline_p) 285{ 339 340 if (acpi_disabled) 341 unflatten_device_tree(); 347 request_standard_resources(); 348 349 early_ioremap_reset(); 350 351 if (acpi_disabled) 352 psci_dt_init(); 353 else 354 psci_acpi_init(); 355 356 init_bootcpu_ops(); 357 smp_init_cpus(); 358 smp_build_mpidr_hash();
init_bootcpu_ops
arch/arm64/include/asm/cpu_ops.h
40struct cpu_operations { 41 const char *name; 42 int (*cpu_init)(unsigned int); 43 int (*cpu_prepare)(unsigned int); 44 int (*cpu_boot)(unsigned int); 45 void (*cpu_postboot)(void); 46#ifdef CONFIG_HOTPLUG_CPU 47 bool (*cpu_can_disable)(unsigned int cpu); 48 int (*cpu_disable)(unsigned int cpu); 49 void (*cpu_die)(unsigned int cpu); 50 int (*cpu_kill)(unsigned int cpu); 51#endif 52#ifdef CONFIG_CPU_IDLE 53 int (*cpu_init_idle)(unsigned int); 54 int (*cpu_suspend)(unsigned long); 55#endif 56}; 57 58int __init init_cpu_ops(int cpu); 59extern const struct cpu_operations *get_cpu_ops(int cpu); 60 61static inline void __init init_bootcpu_ops(void) 62{ 63 init_cpu_ops(0); 64}
40 ~ 56 定义了 数据类型 struct cpu_operations
58 行声明函数 init_cpu_ops ( int cpu)
61 ~ 64 行,辅助函数, init_bootcpu_ops() , 使用参数 0 调用 58 行声明的函数, init_cpu_ops
init_cpu_ops(int cpu)
arch/arm64/kernel/cpu_ops.c
99int __init init_cpu_ops(int cpu) 100{ 101 const char *enable_method = cpu_read_enable_method(cpu); 102 103 if (!enable_method) 104 return -ENODEV; 105 106 cpu_ops[cpu] = cpu_get_ops(enable_method); 107 if (!cpu_ops[cpu]) { 108 pr_warn("Unsupported enable-method: %s\n", enable_method); 109 return -EOPNOTSUPP; 110 } 111 112 return 0; 113}
101 - 从 dtb 解析得到 指定 cpu 的 dts 节点,然后从节点里面取出 enable-method 属性的值,字符串,返回
示例: cpu 的dts 信息
106 行,将得到字符串 psci 传入 cpu_get_ops函数,得到一个 cpu_operations 指针,放入到 cpu_ops[ cpu ] 里面。
cpu_get_ops(char *)
arch/arm64/kernel/cpu_ops.c
25static const struct cpu_operations *const dt_supported_cpu_ops[] __initconst = { 26 &smp_spin_table_ops, 27 &cpu_psci_ops, 28 NULL, 29}; 39static const struct cpu_operations * __init cpu_get_ops(const char *name) 40{ 41 const struct cpu_operations *const *ops; 42 43 ops = acpi_disabled ? dt_supported_cpu_ops : acpi_supported_cpu_ops; 44 45 while (*ops) { 46 if (!strcmp(name, (*ops)->name)) 47 return *ops; 48 49 ops++; 50 } 51 52 return NULL; 53}
25 ~ 29 定义了 cpu_operations 指针数组 dt_supported_cpu_ops
43行,在不支持acpi 的情况下,指针 ops 指向 dt_supported_cpu_ops 数组 ( 指针 的指针)
*ops 取得 数组中的值,值非空的情况下,匹配 (*ops)->name,和传入的 char* name 是否 相同,字符串相同时,返回 *ops .
下面是 cpu_psci_ops 对象的定义,和传入的 psci 字符串相匹配
arch/arm64/kernel/psci.c
110 111const struct cpu_operations cpu_psci_ops = { 112 .name = "psci", 113 .cpu_init = cpu_psci_cpu_init, 114 .cpu_prepare = cpu_psci_cpu_prepare, 115 .cpu_boot = cpu_psci_cpu_boot, 116#ifdef CONFIG_HOTPLUG_CPU 117 .cpu_can_disable = cpu_psci_cpu_can_disable, 118 .cpu_disable = cpu_psci_cpu_disable, 119 .cpu_die = cpu_psci_cpu_die, 120 .cpu_kill = cpu_psci_cpu_kill, 121#endif 122};
下一篇: smp_init_cpus
https://www.cnblogs.com/zhangzhiwei122/p/16091111.html