Index: stand/efi/fdt/efi_fdt.c =================================================================== --- stand/efi/fdt/efi_fdt.c +++ stand/efi/fdt/efi_fdt.c @@ -40,12 +40,18 @@ static EFI_GUID fdtdtb = FDT_TABLE_GUID; +struct fdt_header * +efi_fdt_get_header(void) +{ + return (efi_get_table(&fdtdtb)); +} + int fdt_platform_load_dtb(void) { struct fdt_header *hdr; - hdr = efi_get_table(&fdtdtb); + hdr = efi_fdt_get_header(); if (hdr == NULL) return (1); if (fdt_load_dtb_addr(hdr) != 0) Index: stand/efi/include/efilib.h =================================================================== --- stand/efi/include/efilib.h +++ stand/efi/include/efilib.h @@ -147,4 +147,7 @@ /* efipart.c */ int efipart_inithandles(void); +/* EFI-specific FDT functions */ +struct fdt_header *efi_fdt_get_header(void); + #endif /* _LOADER_EFILIB_H */ Index: stand/efi/loader/bootinfo.c =================================================================== --- stand/efi/loader/bootinfo.c +++ stand/efi/loader/bootinfo.c @@ -60,6 +60,10 @@ #include "geliboot.h" #endif +#if defined(__riscv) +#include +#endif + int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs); @@ -323,6 +327,38 @@ file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb); #endif +#if defined(__riscv) + struct fdt_header *hdr; + int chosen, prop_len; + const fdt32_t *prop; + uint32_t boot_hart; + + hdr = efi_fdt_get_header(); + if (hdr == NULL) { + printf("%s: Could not get EFI FDT for boot-hartid\n", + __func__); + return (EINVAL); + } + + chosen = fdt_path_offset(hdr, "/chosen"); + if (chosen < 0) { + printf("%s: Could not get EFI FDT /chosen for boot-hartid\n", + __func__); + return (EINVAL); + } + + prop = fdt_getprop(hdr, chosen, "boot-hartid", &prop_len); + if (prop == NULL || prop_len != sizeof(boot_hart)) { + printf("%s: Could not get EFI FDT /chosen/boot-hartid\n", + __func__); + return (EINVAL); + } + + boot_hart = fdt32_to_cpu(*prop); + file_addmetadata(kfp, MODINFOMD_BOOT_HART, sizeof(boot_hart), + &boot_hart); +#endif + do_vmap = true; efi_novmap = getenv("efi_disable_vmap"); if (efi_novmap != NULL) Index: sys/riscv/include/machdep.h =================================================================== --- sys/riscv/include/machdep.h +++ sys/riscv/include/machdep.h @@ -43,6 +43,7 @@ vm_offset_t kern_stack; vm_offset_t dtbp_virt; /* Device tree blob virtual addr */ vm_offset_t dtbp_phys; /* Device tree blob physical addr */ + uint32_t boot_hart; vm_offset_t modulep; /* loader(8) metadata */ }; Index: sys/riscv/include/metadata.h =================================================================== --- sys/riscv/include/metadata.h +++ sys/riscv/include/metadata.h @@ -32,6 +32,7 @@ #define MODINFOMD_DTBP 0x1001 #define MODINFOMD_EFI_MAP 0x1002 +#define MODINFOMD_BOOT_HART 0x1003 struct efi_map_header { size_t memory_size; Index: sys/riscv/riscv/genassym.c =================================================================== --- sys/riscv/riscv/genassym.c +++ sys/riscv/riscv/genassym.c @@ -107,4 +107,5 @@ kern_stack)); ASSYM(RISCV_BOOTPARAMS_DTBP_VIRT, offsetof(struct riscv_bootparams, dtbp_virt)); ASSYM(RISCV_BOOTPARAMS_DTBP_PHYS, offsetof(struct riscv_bootparams, dtbp_phys)); +ASSYM(RISCV_BOOTPARAMS_BOOT_HART, offsetof(struct riscv_bootparams, boot_hart)); ASSYM(RISCV_BOOTPARAMS_MODULEP, offsetof(struct riscv_bootparams, modulep)); Index: sys/riscv/riscv/locore.S =================================================================== --- sys/riscv/riscv/locore.S +++ sys/riscv/riscv/locore.S @@ -76,9 +76,8 @@ beqz t0, 1f j mpentry 1: - /* Store the boot hart */ - lla t0, boot_hart - sw a0, 0(t0) + /* Save hart ID */ + mv a2, a0 /* Load zero as modulep */ mv a0, zero @@ -101,15 +100,18 @@ .option pop /* - * Zero a1 to indicate that we have no DTB pointer. It is already - * included in the loader(8) metadata. + * Zero a1 to indicate that we have no DTB pointer and set a2 to -1 to + * indicate that we have no hart ID. They are already included in the + * loader(8) metadata. */ mv a1, zero + li a2, -1 /* * Page tables setup * a0 - modulep or zero * a1 - zero or dtbp + * a2 - -1 or hart ID */ pagetables: /* Get the kernel's load address */ @@ -254,6 +256,7 @@ sd t0, RISCV_BOOTPARAMS_DTBP_VIRT(sp) sd a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp) + sw a2, RISCV_BOOTPARAMS_BOOT_HART(sp) sd a0, RISCV_BOOTPARAMS_MODULEP(sp) mv a0, sp Index: sys/riscv/riscv/machdep.c =================================================================== --- sys/riscv/riscv/machdep.c +++ sys/riscv/riscv/machdep.c @@ -783,6 +783,10 @@ PRELOAD_PUSH_VALUE(uint32_t, sizeof(int)); PRELOAD_PUSH_VALUE(int, RB_VERBOSE); + PRELOAD_PUSH_VALUE(uint32_t, MODINFO_METADATA | MODINFOMD_BOOT_HART); + PRELOAD_PUSH_VALUE(uint32_t, sizeof(uint32_t)); + PRELOAD_PUSH_VALUE(uint32_t, rvbp->boot_hart); + /* End marker */ PRELOAD_PUSH_VALUE(uint32_t, 0); PRELOAD_PUSH_VALUE(uint32_t, 0); @@ -833,6 +837,7 @@ KASSERT(kmdp != NULL, ("No preload metadata found!")); /* Read the boot metadata */ + boot_hart = MD_FETCH(kmdp, MODINFOMD_BOOT_HART, uint32_t); boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); @@ -861,10 +866,6 @@ int mem_regions_sz; vm_offset_t lastaddr; vm_size_t kernlen; -#ifdef FDT - phandle_t chosen; - uint32_t hart; -#endif char *env; TSRAW(&thread0, TS_ENTER, __func__, NULL); @@ -889,17 +890,10 @@ } lastaddr = parse_metadata(); -#ifdef FDT /* - * Look for the boot hart ID. This was either passed in directly from - * the SBI firmware and handled by locore, or was stored in the device - * tree by an earlier boot stage. + * Check the boot hart ID. This was either passed in directly from the + * SBI firmware and handled by locore, or was passed to us by loader. */ - chosen = OF_finddevice("/chosen"); - if (OF_getencprop(chosen, "boot-hartid", &hart, sizeof(hart)) != -1) { - boot_hart = hart; - } -#endif if (boot_hart == BOOT_HART_INVALID) { panic("Boot hart ID was not properly set"); }