The branch main has been updated by mhorne:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=04a812ae94e44982ee7f86e5de8a5caccdbc8a81

commit 04a812ae94e44982ee7f86e5de8a5caccdbc8a81
Author:     Mitchell Horne <mho...@freebsd.org>
AuthorDate: 2025-03-03 15:47:23 +0000
Commit:     Mitchell Horne <mho...@freebsd.org>
CommitDate: 2025-03-03 16:12:15 +0000

    riscv/stand: pass boot hart in loader metadata
    
    Use the RISCV_EFI_BOOT_PROTOCOL to fetch the boot hart ID, and
    communicate this to the kernel via new metadata field
    (MODINFOMD_BOOT_HART).
    
    If the boot hart is not found this way, fall back to the (now
    deprecated) device-tree method.
    
    The assumption that a hart ID can be represented with a 32-bit unsigned
    integer is unchanged in the kernel, but from the loader we pass the full
    64-bit value. This ensures that this API won't need to change in the
    future, should the wider value become necessary.
    
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D48887
---
 stand/efi/loader/arch/riscv/exec.c | 25 ++++++++++++++++
 sys/kern/subr_module.c             | 10 +++++++
 sys/riscv/include/metadata.h       |  1 +
 sys/riscv/riscv/machdep.c          | 61 +++++++++++++++++++++++++-------------
 4 files changed, 77 insertions(+), 20 deletions(-)

diff --git a/stand/efi/loader/arch/riscv/exec.c 
b/stand/efi/loader/arch/riscv/exec.c
index 0fc28cba78c1..9da61229ef68 100644
--- a/stand/efi/loader/arch/riscv/exec.c
+++ b/stand/efi/loader/arch/riscv/exec.c
@@ -2,6 +2,7 @@
  * Copyright (c) 2001 Benno Rice <be...@freebsd.org>
  * Copyright (c) 2007 Semihalf, Rafal Jaworowski <r...@semihalf.com>
  * All rights reserved.
+ * Copyright (c) 2024 The FreeBSD Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,6 +41,28 @@
 #include "bootstrap.h"
 #include "loader_efi.h"
 
+static void
+riscv_set_boot_hart(struct preloaded_file *fp)
+{
+       EFI_GUID riscvboot = RISCV_EFI_BOOT_PROTOCOL_GUID;
+       RISCV_EFI_BOOT_PROTOCOL *proto;
+       EFI_STATUS status = 0;
+       uint64_t boot_hartid = ULONG_MAX;
+
+       status = BS->LocateProtocol(&riscvboot, NULL, (void **)&proto);
+       if (EFI_ERROR(status)) {
+               return;
+       }
+
+       status = proto->GetBootHartId(proto, &boot_hartid);
+       if (EFI_ERROR(status)) {
+               return;
+       }
+
+       file_addmetadata(fp, MODINFOMD_BOOT_HARTID, sizeof(boot_hartid),
+           &boot_hartid);
+}
+
 static int
 __elfN(exec)(struct preloaded_file *fp)
 {
@@ -52,6 +75,8 @@ __elfN(exec)(struct preloaded_file *fp)
        if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
                return (EFTYPE);
 
+       riscv_set_boot_hart(fp);
+
        e = (Elf_Ehdr *)&fmp->md_data;
 
        efi_time_fini();
diff --git a/sys/kern/subr_module.c b/sys/kern/subr_module.c
index 596961606577..d07990cebdc3 100644
--- a/sys/kern/subr_module.c
+++ b/sys/kern/subr_module.c
@@ -442,6 +442,11 @@ preload_modinfo_type(struct sbuf *sbp, int type)
        case MODINFOMD_SPLASH:
                sbuf_cat(sbp, "MODINFOMD_SPLASH");
                break;
+#endif
+#ifdef MODINFOMD_BOOT_HARTID
+       case MODINFOMD_BOOT_HARTID:
+               sbuf_cat(sbp, "MODINFOMD_BOOT_HARTID");
+               break;
 #endif
        default:
                sbuf_cat(sbp, "unrecognized metadata type");
@@ -503,6 +508,11 @@ preload_modinfo_value(struct sbuf *sbp, uint32_t *bptr, 
int type, int len)
        case MODINFO_METADATA | MODINFOMD_HOWTO:
                sbuf_printf(sbp, "0x%08x", *bptr);
                break;
+#ifdef MODINFOMD_BOOT_HARTID
+       case MODINFO_METADATA | MODINFOMD_BOOT_HARTID:
+               sbuf_printf(sbp, "0x%lu", *(uint64_t *)bptr);
+               break;
+#endif
        case MODINFO_METADATA | MODINFOMD_SHDR:
        case MODINFO_METADATA | MODINFOMD_ELFHDR:
        case MODINFO_METADATA | MODINFOMD_FW_HANDLE:
diff --git a/sys/riscv/include/metadata.h b/sys/riscv/include/metadata.h
index 6ade03e15ea3..ddbad3fae3b4 100644
--- a/sys/riscv/include/metadata.h
+++ b/sys/riscv/include/metadata.h
@@ -31,6 +31,7 @@
 #define        MODINFOMD_DTBP          0x1001
 #define        MODINFOMD_EFI_MAP       0x1002
 #define        MODINFOMD_EFI_FB        0x1003
+#define        MODINFOMD_BOOT_HARTID   0x1004
 
 struct efi_map_header {
        size_t          memory_size;
diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c
index 03f5926c3739..fea4ca9a7b92 100644
--- a/sys/riscv/riscv/machdep.c
+++ b/sys/riscv/riscv/machdep.c
@@ -419,6 +419,45 @@ fake_preload_metadata(struct riscv_bootparams *rvbp)
 /* Support for FDT configurations only. */
 CTASSERT(FDT);
 
+static void
+parse_boot_hartid(void)
+{
+       uint64_t *mdp;
+#ifdef FDT
+       phandle_t chosen;
+       uint32_t hart;
+#endif
+
+       mdp = (uint64_t *)preload_search_info(preload_kmdp,
+           MODINFO_METADATA | MODINFOMD_BOOT_HARTID);
+       if (mdp != NULL && *mdp < UINT32_MAX) {
+               boot_hart = (uint32_t)*mdp;
+               goto out;
+       }
+
+#ifdef FDT
+       /*
+        * Deprecated:
+        *
+        * 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.
+        */
+       chosen = OF_finddevice("/chosen");
+       if (OF_getencprop(chosen, "boot-hartid", &hart, sizeof(hart)) != -1) {
+               boot_hart = hart;
+       }
+#endif
+
+       /* We failed... */
+       if (boot_hart == BOOT_HART_INVALID) {
+               panic("Boot hart ID was not properly set");
+       }
+
+out:
+       PCPU_SET(hart, boot_hart);
+}
+
 #ifdef FDT
 static void
 parse_fdt_bootargs(void)
@@ -462,6 +501,8 @@ parse_metadata(void)
        if (kern_envp == NULL)
                parse_fdt_bootargs();
 #endif
+       parse_boot_hartid();
+
        return (lastaddr);
 }
 
@@ -474,10 +515,6 @@ initriscv(struct riscv_bootparams *rvbp)
        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);
@@ -502,22 +539,6 @@ initriscv(struct riscv_bootparams *rvbp)
        }
        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.
-        */
-       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");
-       }
-       pcpup->pc_hart = boot_hart;
-
        efihdr = (struct efi_map_header *)preload_search_info(preload_kmdp,
            MODINFO_METADATA | MODINFOMD_EFI_MAP);
        if (efihdr != NULL) {

Reply via email to