Page MenuHomeFreeBSD

D39811.id121141.diff
No OneTemporary

D39811.id121141.diff

diff --git a/sys/riscv/riscv/identcpu.c b/sys/riscv/riscv/identcpu.c
--- a/sys/riscv/riscv/identcpu.c
+++ b/sys/riscv/riscv/identcpu.c
@@ -41,6 +41,7 @@
#include <sys/systm.h>
#include <sys/ctype.h>
#include <sys/kernel.h>
+#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/sysctl.h>
@@ -48,7 +49,6 @@
#include <machine/cpufunc.h>
#include <machine/elf.h>
#include <machine/md_var.h>
-#include <machine/trap.h>
#ifdef FDT
#include <dev/fdt/fdt_common.h>
@@ -73,6 +73,25 @@
struct cpu_desc cpu_desc[MAXCPU];
+static struct mtx cap_mtx;
+MTX_SYSINIT(cap_mtx, &cap_mtx, "CPU feature mutex", MTX_SPIN);
+
+/*
+ * We only track features/capabilities that are common across all CPUs. When
+ * APs come online we can have multiple concurrent calls to identify_cpu(), so
+ * updates are protected with a mutex.
+ */
+#define UPDATE_GLOBAL_CAP(t, v) \
+ do { \
+ if (PCPU_GET(cpuid) == 0) { \
+ (t) = (v); \
+ } else { \
+ mtx_lock_spin(&cap_mtx); \
+ (t) &= (v); \
+ mtx_unlock_spin(&cap_mtx); \
+ } \
+ } while (0)
+
/*
* Micro-architecture tables.
*/
@@ -263,31 +282,34 @@
#ifdef FDT
static void
-fill_elf_hwcap(void *dummy __unused)
+identify_cpu_features_fdt(struct cpu_desc *desc)
{
char isa[1024];
u_long hwcap;
phandle_t node;
ssize_t len;
+ pcell_t reg;
node = OF_finddevice("/cpus");
if (node == -1) {
- if (bootverbose)
- printf("fill_elf_hwcap: Can't find cpus node\n");
+ printf("%s: could not find /cpus node in FDT\n", __func__);
return;
}
/*
- * Iterate through the CPUs and examine their ISA string. While we
- * could assign elf_hwcap to be whatever the boot CPU supports, to
- * handle the (unusual) case of running a system with hetergeneous
- * ISAs, keep only the extension bits that are common to all harts.
+ * Locate our current CPU's node in the device-tree, and parse its
+ * contents to detect supported CPU/ISA features and extensions.
*/
for (node = OF_child(node); node > 0; node = OF_peer(node)) {
/* Skip any non-CPU nodes, such as cpu-map. */
if (!ofw_bus_node_is_compatible(node, "riscv"))
continue;
+ /* Find this CPU */
+ if (OF_getencprop(node, "reg", &reg, sizeof(reg)) <= 0 ||
+ reg != PCPU_GET(hart))
+ continue;
+
len = OF_getprop(node, "riscv,isa", isa, sizeof(isa));
KASSERT(len <= sizeof(isa), ("ISA string truncated"));
if (len == -1) {
@@ -310,15 +332,25 @@
isa[i] = tolower(isa[i]);
parse_riscv_isa(isa, len, &hwcap);
- if (elf_hwcap != 0)
- elf_hwcap &= hwcap;
- else
- elf_hwcap = hwcap;
+ UPDATE_GLOBAL_CAP(elf_hwcap, hwcap);
+
+ /* We are done. */
+ break;
+ }
+ if (node <= 0) {
+ printf("%s: could not find FDT node for CPU %u, hart %u\n",
+ __func__, PCPU_GET(cpuid), PCPU_GET(hart));
}
}
+#endif
-SYSINIT(identcpu, SI_SUB_CPU, SI_ORDER_ANY, fill_elf_hwcap, NULL);
+static void
+identify_cpu_features(struct cpu_desc *desc)
+{
+#ifdef FDT
+ identify_cpu_features_fdt(desc);
#endif
+}
static void
identify_cpu_vendor(struct cpu_desc *desc)
@@ -377,6 +409,7 @@
identify_cpu_vendor(desc);
identify_cpu_microarch(desc);
+ identify_cpu_features(desc);
}
void

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 5, 2:52 AM (3 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40222184
Default Alt Text
D39811.id121141.diff (3 KB)

Event Timeline