Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Mar 2025 16:12:31 GMT
From:      Mitchell Horne <mhorne@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 04a812ae94e4 - main - riscv/stand: pass boot hart in loader metadata
Message-ID:  <202503031612.523GCV5C008222@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mhorne:

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

commit 04a812ae94e44982ee7f86e5de8a5caccdbc8a81
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2025-03-03 15:47:23 +0000
Commit:     Mitchell Horne <mhorne@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 <benno@FreeBSD.org>
  * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202503031612.523GCV5C008222>