Hi Zhiwei, thanks for your reply, I make a mistake, t0 is 0x1000 so both lw a1, 32(t0) or ld a1, 32(t0) just read from the brom offset 32byte.
Thanks, Eric Chan 刘志伟 <zhiwei_...@c-sky.com> 於 2022年10月5日 週三 下午5:47寫道: > I think the a1 from QEMU reset vector is the device tree(fdt_laddr) though > I don't know if it is directly used by the OpenSBI or just passed to the > Linux kernel. > > Thanks, > Zhiwei > > ------------------------------------------------------------------ > 发件人:Philippe Mathieu-Daudé via <qemu-devel@nongnu.org> > 发送时间:2022年10月3日(星期一) 20:37 > 收件人:Eric Chan <e14002...@gmail.com>; qemu-devel <qemu-devel@nongnu.org> > 抄 送:qemu-riscv <qemu-ri...@nongnu.org> > 主 题:Re: Question about RISC-V brom register a1 set value > > Cc'ing the RISC-V specific mailing list. > > On 1/10/22 01:48, Eric Chan wrote: > > Hi, qemu > > > > As I know, brom will pass 3 parameters to the next stage bootloader, ex: > > openSBI. > > a0 will pass hartid, a2 will pass fw_dynamic_info start address. > > although a1 doesn't use directly in openSBI. > > a1 read value is determined in compile time rather than read from the > > original a1 that passes from brom. > > In qemu/hw/riscv/boot.c > > both 32bit and 64bit machines read 4byte that offset 32byte from the > > brom start address. > > > > for 64 bits machine: a1 read low 32bit data member magic of > fw_dynamic_info, > > the value will same as FW_DYNAMIC_INFO_MAGIC_VALUE because risc-v is > > little endian. > > > > for 32bits machine: each data member of fw_dynamic_info is 4 bytes, so > > a1 will read the version rather than magic. > > > > Do the 32bit and 64bit pass different parameters are expected? > > If it is not expected, I guess the original version is 64bit machine, > > and then supports 32bit but misses this detail, I hope I can have an > > opportunity to fix this problem. > > If it is expected, why they must be done? > > > > Thanks, > > Eric Chan > > > > qemu/include/hw/riscv/boot_opensbi.h > > #define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f > > qemu/hw/riscv/boot.c > > void riscv_setup_rom_reset_vec(MachineState *machine, > > RISCVHartArrayState *harts, > > hwaddr start_addr, > > hwaddr rom_base, hwaddr rom_size, > > uint64_t kernel_entry, > > uint64_t fdt_load_addr) > > { > > int i; > > uint32_t start_addr_hi32 = 0x00000000; > > uint32_t fdt_load_addr_hi32 = 0x00000000; > > > > if (!riscv_is_32bit(harts)) { > > start_addr_hi32 = start_addr >> 32; > > fdt_load_addr_hi32 = fdt_load_addr >> 32; > > } > > /* reset vector */ > > uint32_t reset_vec[10] = { > > 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */ > > 0x02828613, /* addi a2, t0, %pcrel_lo(1b) */ > > 0xf1402573, /* csrr a0, mhartid */ > > 0, > > 0, > > 0x00028067, /* jr t0 */ > > start_addr, /* start: .dword */ > > start_addr_hi32, > > fdt_load_addr, /* fdt_laddr: .dword */ > > fdt_load_addr_hi32, > > /* fw_dyn: */ > > }; > > if (riscv_is_32bit(harts)) { > > reset_vec[3] = 0x0202a583; /* lw a1, 32(t0) */ > > reset_vec[4] = 0x0182a283; /* lw t0, 24(t0) */ > > } else { > > reset_vec[3] = 0x0202b583; /* ld a1, 32(t0) */ > > reset_vec[4] = 0x0182b283; /* ld t0, 24(t0) */ > > } > > > > /* copy in the reset vector in little_endian byte order */ > > for (i = 0; i < ARRAY_SIZE(reset_vec); i++) { > > reset_vec[i] = cpu_to_le32(reset_vec[i]); > > } > > rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), > > rom_base, &address_space_memory); > > riscv_rom_copy_firmware_info(machine, rom_base, rom_size, > sizeof(reset_vec), > > kernel_entry); > > } > > > > opensbi/firmware/fw_dynamic.S > > fw_boot_hart: > > /* Sanity checks */ > > li a1, FW_DYNAMIC_INFO_MAGIC_VALUE > > REG_L a0, FW_DYNAMIC_INFO_MAGIC_OFFSET(a2) > > bne a0, a1, _bad_dynamic_info > > li a1, FW_DYNAMIC_INFO_VERSION_MAX > > REG_L a0, FW_DYNAMIC_INFO_VERSION_OFFSET(a2) > > bgt a0, a1, _bad_dynamic_info > > > > /* Read boot HART id */ > > li a1, FW_DYNAMIC_INFO_VERSION_2 > > blt a0, a1, 2f > > REG_L a0, FW_DYNAMIC_INFO_BOOT_HART_OFFSET(a2) > > ret > > 2: li a0, -1 > > ret > > >