Last active
October 17, 2019 03:06
-
-
Save knknkn1162/016b8989da16e2151bedde0fa5fff252 to your computer and use it in GitHub Desktop.
hart with hart_id==0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.align 3 | |
.section .entry, "ax", %progbits | |
.globl _start | |
.globl _start_warm | |
_start: | |
csrr a6, CSR_MHARTID // assume that hart_id=0 | |
// The condition `zero < a6=0` is false | |
blt zero, a6, _wait_relocate_copy_done | |
/* Save load address */ | |
la t0, _load_start | |
la t1, _start | |
REG_S t1, 0(t0) // _load_start <- _start | |
_relocate: | |
la t0, _link_start // RISCV_PTR _fw_start | |
REG_L t0, 0(t0) | |
la t1, _link_end | |
REG_L t1, 0(t1) | |
la t2, _load_start // this is _start | |
REG_L t2, 0(t2) | |
sub t3, t1, t0 | |
add t3, t3, t2 | |
// _fw_start == _start, so jump | |
beq t0, t2, _relocate_done // yes and jump | |
// skip _relocate | |
_relocate_done: | |
/* | |
* Mark relocate copy done | |
* Use _boot_status copy relative to the load address | |
*/ | |
la t0, _boot_status | |
la t1, _link_start | |
REG_L t1, 0(t1) | |
la t2, _load_start | |
REG_L t2, 0(t2) | |
sub t0, t0, t1 | |
add t0, t0, t2 | |
li t1, BOOT_STATUS_RELOCATE_DONE // #define BOOT_STATUS_RELOCATE_DONE 1 | |
REG_S t1, 0(t0) | |
fence rw, rw | |
/* Reset all registers for boot HART */ | |
li ra, 0 | |
call _reset_regs | |
MOV_5R s0, a0, s1, a1, s2, a2, s3, a3, s4, a4 // save | |
call fw_save_info | |
MOV_5R a0, s0, a1, s1, a2, s2, a3, s3, a4, s4 // restore | |
/* Preload HART details | |
// .hart_count = VIRT_HART_COUNT=8, | |
// .hart_stack_size = VIRT_HART_STACK_SIZE=8192, | |
* s7 -> HART Count | |
* s8 -> HART Stack Size | |
*/ | |
la a4, platform | |
#if __riscv_xlen == 64 // yes | |
lwu s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4) // VIRT_HART_COUNT=8 | |
lwu s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4) // VIRT_HART_STACK_SIZE = 8192 | |
#else | |
lw s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4) | |
lw s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4) | |
#endif | |
/* Setup scratch space for all the HARTs*/ | |
la tp, _fw_end | |
mul a5, s7, s8 | |
add tp, tp, a5 | |
/* Keep a copy of tp */ | |
add t3, tp, zero | |
/* Counter */ | |
li t2, 1 | |
/* hartid 0 is mandated by RISC-V ISA */ | |
li t1, 0 | |
_scratch_init: // initialize scratch space which is `struct sbi_scratch` | |
add tp, t3, zero | |
mul a5, s8, t1 | |
sub tp, tp, a5 | |
li a5, SBI_SCRATCH_SIZE | |
sub tp, tp, a5 | |
/* Initialize scratch space */ | |
/* Store fw_start and fw_size in scratch space */ | |
la a4, _fw_start | |
la a5, _fw_end | |
mul t0, s7, s8 | |
add a5, a5, t0 | |
sub a5, a5, a4 | |
REG_S a4, SBI_SCRATCH_FW_START_OFFSET(tp) | |
REG_S a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp) | |
/* Store next arg1 in scratch space */ | |
MOV_3R s0, a0, s1, a1, s2, a2 // save s* | |
call fw_next_arg1 | |
REG_S a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp) | |
MOV_3R a0, s0, a1, s1, a2, s2 // restore a* | |
/* Store next address in scratch space */ | |
MOV_3R s0, a0, s1, a1, s2, a2 | |
call fw_next_addr // la a0, payload_bin | |
REG_S a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp) | |
MOV_3R a0, s0, a1, s1, a2, s2 | |
/* Store next mode in scratch space */ | |
MOV_3R s0, a0, s1, a1, s2, a2 | |
call fw_next_mode // li a0, PRV_S | |
REG_S a0, SBI_SCRATCH_NEXT_MODE_OFFSET(tp) | |
MOV_3R a0, s0, a1, s1, a2, s2 | |
/* Store warm_boot address in scratch space */ | |
la a4, _start_warm | |
REG_S a4, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp) | |
/* Store platform address in scratch space */ | |
la a4, platform | |
REG_S a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp) | |
/* Store hartid-to-scratch function address in scratch space */ | |
la a4, _hartid_to_scratch | |
REG_S a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp) | |
/* Clear tmp0 in scratch space */ | |
REG_S zero, SBI_SCRATCH_TMP0_OFFSET(tp) | |
/* Store firmware options in scratch space */ | |
MOV_3R s0, a0, s1, a1, s2, a2 | |
#ifdef FW_OPTIONS // no | |
li a4, FW_OPTIONS | |
#else | |
add a4, zero, zero | |
#endif | |
call fw_options // don't care | |
or a4, a4, a0 | |
REG_S a4, SBI_SCRATCH_OPTIONS_OFFSET(tp) // unsigned long options; | |
MOV_3R a0, s0, a1, s1, a2, s2 | |
/* Move to next scratch space */ | |
add t1, t1, t2 // t2: counter | |
// s7 -> HART Count | |
blt t1, s7, _scratch_init | |
/* Zero-out BSS */ | |
la a4, _bss_start | |
la a5, _bss_end | |
_bss_zero: | |
REG_S zero, (a4) | |
add a4, a4, __SIZEOF_POINTER__ | |
blt a4, a5, _bss_zero | |
/* Override pervious arg1 */ | |
MOV_3R s0, a0, s1, a1, s2, a2 | |
call fw_prev_arg1 // if not FW_PAYLOAD_FDT_PATH, set a0=0 | |
add t1, a0, zero | |
MOV_3R a0, s0, a1, s1, a2, s2 | |
beqz t1, _prev_arg1_override_done | |
add a1, t1, zero | |
_prev_arg1_override_done: | |
// if configure Flatened Device Tree (FDT). In `QEMU RISC-V Virt Machine Platform`, a1=0 | |
beqz a1, _fdt_reloc_done // yes and jump | |
// skip FDT configuration | |
_fdt_reloc_done: | |
/* mark boot hart done */ | |
li t0, BOOT_STATUS_BOOT_HART_DONE | |
la t1, _boot_status | |
REG_S t0, 0(t1) // now synced with hart with hart_id>=1 | |
fence rw, rw | |
j _start_warm | |
_start_warm: | |
// skip | |
call sbi_init |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment