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

 

posted @ 2022-04-02 10:19  张志伟122  阅读(199)  评论(0编辑  收藏  举报