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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| + _start: \-- mv tp, a0 "tp register save hartid" |-- csrw MODE_PREFIX(tvec), t0 "设置中断stvec 入口为 trap_entry" |-- li t0, SIE_SSIE |-- csrs MODE_PREFIX(ie), t0 "设置sie 协处理器, 打开中断, 用来处理ipi 中断" |-+ call_board_init_f "Set sp in internal/ex RAM to call board_init_f" \ -- li t1, CONFIG_SYS_INIT_SP_ADDR "设置初始栈基址" | -- li t0, -16 | -- and sp, t1, t0 "将堆栈16 bits对齐" |-+ call_board_init_f_0 "从堆栈开始的地方,为u-boot的global data(struct global_data)分配空间" \ -- mv a0, sp | -+ jal board_init_f_alloc_reserve \ - top -= CONFIG_VAL(SYS_MALLOC_F_LEN) "如定义了CONFIG_SYS_MALLOC_F_LEN,需预留出early malloc所需的空间" | -- slli t0, tp, CONFIG_STACK_SIZE_SHIFT "tp代表的是hartid, 每个hart 分配STACK_SIZE 空间" | -- sub sp, a0, t0 "sp = a0 - t0, 地址在初始栈基址上向上增长, a0 初始栈基址 top - malloc空间" | -- bnez tp, secondary_hart_loop "其他hart 跳转到 secondary_hart_loop, hart 0 继续" | -+ jal board_init_f_init_reserve "初始化uboot的global data, 置0" \ -- "如定义了SYS_MALLOC_F_LEN,则会初始化gd->malloc_base" | -- jal icache_enable | -- jal dcache_enable | -+ jalr -> board_init_f "调用board_init_f接口,执行前置的初始化操作" common/board_f.c \ -+ initcall_run_list(init_sequence_f) "执行init_sequence_f" 里的一系列初始化函数 \ -+ init_sequence_f \ -- initf_malloc | -- arch_cpu_init | -- arch_cpu_init_dm | -- timer_init | -- env_init | -- console_init_f | -- print_cpuinfo | -- dram_init | -- .. | -- reloc_fdt | -- reloc_bootstage | -- setup_reloc | -+ jump_to_copy \ -+ relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr) "开始进行主核relocate" \ -- mv s2, a0 /* save addr_sp */ | -- mv s3, a1 /* save addr of gd */ | -- mv s4, a2 /* save addr of destination */ | -+ stack_setup \ -- slli t0, tp, CONFIG_STACK_SIZE_SHIFT | -- sub sp, s2, t0 "gd->start_addr_sp - offset(of hartid)" 设置新的sp, 这个sp 是reloc 后的sp "gd->start_addr_sp = gd->relocaddr;" | -- clear_bss clbss_l "将__bss_start到__bss_end" 之间reloc 到 ram上的bss 区段清0 | -- copy_loop "reloc 将_start到_bss_start之间的代码段拷贝到 relocaddr处" | -+ fix_rela_dyn "Update dynamic relocations after board_init_f" | -+ relocate_secondary_harts \ -- la t0, secondary_hart_relocate | -- add a0, t0, t6 "到reloc 地址上执行secondary_hart_relocate" a0 为 secondary_hart_relocate | -- mv a1, s2 "s2 为 addr_sp" | -- mv a2, s3 "s3 为 gd 指针" | -+ jal smp_call_function \ -+ send_ipi_many(&ipi); "发送ipi中断", 前面传的三个参数保存在 gd->arch.ipi 中 \ -+ riscv_send_ipi(reg) "reg为从uboot fdt中查到的所有的hart" \ -- SBI_CALL_1(SBI_SEND_IPI, hart_mask); "调用opensbi的函数, 给指定的hart发送ipi中断" -----------------------------ipi中断, 跳入其他核---------------------------------------------- | -+ secondary_hart_loop "其他hart处在secondary_hart_loop 处调了 wfi 等待" \ -- csrr t0, MODE_PREFIX(ip) "读sip" | -- andi t0, t0, SIE_SSIE | -- mv a0, tp "hartid 为第一个参数" | -+ jal handle_ipi "如果来了software 中断, 即会跳到 handle_ipi 处理, 否则继续 secondary_hart_loop" \-+ handle_ipi(hartid) "对应的hart 收到ipi 中断" \ -- riscv_clear_ipi(hart); "会导致 mip.SSIP = sip.SSIP 清0" | -- invalidate_icache_all(); | -- smp_function = gd->arch.ipi[hart].addr; "此处为传递的第一个参数, secondary_hart_relocate" | -+ smp_function(hart, gd->arch.ipi[hart].arg0, gd->arch.ipi[hart].arg1); \ -+ secondary_hart_relocate \ -- slli t0, tp, CONFIG_STACK_SIZE_SHIFT | -- sub sp, a1, t0 "a1 为 new_sp, new_sp - offset(of hartid)" | -- mv gp, a2 "更新gd指针到gp寄存器" | -- secondary_hart_loop wfi "其他核响应完ipi后, 只更新了sp和gp, 然后继续挂起等待" ---------------------------------回主核------------------------------------------------- | -+ call_board_init_r \ -- jal invalidate_icache_all | -- jal flush_dcache_all | -- mv a0, s3 /* gd_t */ | -- mv a1, s4 /* dest_addr */ | -+ jalr -> board_init_r "跳转到reloc board_init_r执行" \ -+ initcall_run_list(init_sequence_r) \ -+ init_sequence_r \ -- initr_reloc_global_data | -- initr_barrier | -- bootstage_relocate | -- board_init | -- arch_early_init_r | -- initr_secondary_cpu | -- interrupt_init | -- board_late_init "board 相关修改" | -+ run_main_loop "loop 等待接收输入的命令"
|