smp启动-smp_init_cpus
上一篇: cpu_ops
https://www.cnblogs.com/zhangzhiwei122/p/16090770.html
setup_arch -> smp_init_cpus
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();
smp_init_cpus
710void __init smp_init_cpus(void) 711{ 714 if (acpi_disabled) 715 of_parse_and_init_cpus(); 719 if (cpu_count > nr_cpu_ids) 720 pr_warn("Number of cores (%d) exceeds configured maximum of %u - clipping\n", 721 cpu_count, nr_cpu_ids); 722 727 728 /* 729 * We need to set the cpu_logical_map entries before enabling 730 * the cpus so that cpu processor description entries (DT cpu nodes 731 * and ACPI MADT entries) can be retrieved by matching the cpu hwid 732 * with entries in cpu_logical_map while initializing the cpus. 733 * If the cpu set-up fails, invalidate the cpu_logical_map entry. 734 */ 735 for (i = 1; i < nr_cpu_ids; i++) { 736 if (cpu_logical_map(i) != INVALID_HWID) { 737 if (smp_cpu_setup(i)) 738 set_cpu_logical_map(i, INVALID_HWID); 739 } 740 } 741}
715 行,调用 of_parse_and_init_cpus (本文件,static 函数)进行 dtb的解析,并 初始化解析到的 cpu .
719 - 如果 715 行解析得到的 cpu_count 大于 nr_cpu_ids ,则 告警
728 ~ 740 ,注释清楚,在 使能 cpu 之前,先要把 找到的 cpu 都给 放到 cpu logical map 里面。
下面的 for 循环默认cpu logical map 里面已经放了对应的 cpu hwid 了。 (由 of_parse_and_init_cpus 放入到 logical map 里面)
for 循环,遍历,对于不是 invalid hwid 的项,调用 smp_cpu_setup(i) 进行初始化,如果初始化失败,则设置 这个 idx 对应的 cpu hwid 为 invalid hwid .
of_parse_and_init_cpus
530 static bool bootcpu_valid __initdata;
531 static unsigned int cpu_count = 1;
652static void __init of_parse_and_init_cpus(void) 653{ 654 struct device_node *dn; 655 656 for_each_of_cpu_node(dn) { 657 u64 hwid = of_get_cpu_mpidr(dn); 658 659 if (hwid == INVALID_HWID) 660 goto next; 661 662 if (is_mpidr_duplicate(cpu_count, hwid)) { 663 pr_err("%pOF: duplicate cpu reg properties in the DT\n", 664 dn); 665 goto next; 666 } 667 668 /* 669 * The numbering scheme requires that the boot CPU 670 * must be assigned logical id 0. Record it so that 671 * the logical map built from DT is validated and can 672 * be used. 673 */ 674 if (hwid == cpu_logical_map(0)) { 675 if (bootcpu_valid) { 676 pr_err("%pOF: duplicate boot cpu reg property in DT\n", 677 dn); 678 goto next; 679 } 680 681 bootcpu_valid = true; 682 early_map_cpu_to_node(0, of_node_to_nid(dn)); 683 684 /* 685 * cpu_logical_map has already been 686 * initialized and the boot cpu doesn't need 687 * the enable-method so continue without 688 * incrementing cpu. 689 */ 690 continue; 691 } 692 693 if (cpu_count >= NR_CPUS) 694 goto next; 695 696 pr_debug("cpu logical map 0x%llx\n", hwid); 697 set_cpu_logical_map(cpu_count, hwid); 698 699 early_map_cpu_to_node(cpu_count, of_node_to_nid(dn)); 700next: 701 cpu_count++; 702 } 703}
530 ~ 531 定义了两个 static 变量, bootcpu_valid ( false) , cpu_count ( 1 )
656 行开始for 循环,
657 - of_get_cpu_mpidr 返回 dts cpu 节点的 reg 属性值 或者 invalid hwid .
659 ~ 660 ,如果是 invalid hwid , 则到 700 行,将 cpu_count ++ 后,继续for 循环。
662 ~ 666 ,id_mpidr_duplicate 检查 新的 hwid 和 之前存下的 hwid 【cpu logical map 从 0 到 cpu_count 】都不相同,如果相同,则打印信息后,跳转到 700 行
674 ~ 691 行,cpu logical map 0 里面,填入的是 boot cpu 的 mpidr 寄存器里面 得到的 hwid 值(见: https://www.cnblogs.com/zhangzhiwei122/p/16051676.html) 。假设是 0, 则和 dts 中 cpu0 的reg 里面的0 相同,
681 设置 bootcpu_valid 为true . 如果在此之前,bootcpu_valid 已经是 true , 675 ~ 678, 则打印告警后,转到 700行 。
690行,continue, 不对 cpu_count 进行增加
693 ~ 694 检查,对于大于 menuconfig 里面配置的 cpu, 直接转到 700 行,
697 对新的hwid ,以 cpu_count 为 idx, 放入到 cpu logical map 里面。
682 ~ 699 行,map cpu to node, 在 smp ,单个CPU ,多核心 情况下,都在 node 0 里面。暂时不关心。
smp_cpu_setup
514static int __init smp_cpu_setup(int cpu) 515{ 516 const struct cpu_operations *ops; 517 518 if (init_cpu_ops(cpu)) 519 return -ENODEV; 520 521 ops = get_cpu_ops(cpu); 522 if (ops->cpu_init(cpu)) 523 return -ENODEV; 524 525 set_cpu_possible(cpu, true); 526 527 return 0; 528}
518 - init_cpu_ops 初始化 指定 cpu的 cpu operations ,和 init_bootcpu_ops https://www.cnblogs.com/zhangzhiwei122/p/16090770.html 类似
521 ~ 523 ,调用 cpu operations 结构体里面的 cpu_init 函数,对于psci 启动的cpu 则是 arch/arm64/kernel/psci.c 中的 cpu_psci_cpu_init 函数。
525 设置 possble cpu bitmap ,对应 bit 设置为 1 ,后面for each possible cpu 循环可以找到。
下一篇: smp_prepare_boot_cpu boot cpu 相关的一些初始化 cpu_data, feature alternative instruction; priority masking
https://www.cnblogs.com/zhangzhiwei122/p/16091458.html