summaryrefslogtreecommitdiffstats
path: root/arch/riscv/kernel/cpu.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-25 18:01:29 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-25 18:01:29 -0700
commitc300af28572d05ae6891c359a7c8c2c81f01dccf (patch)
tree1fbe3781ca2527b71a274c6996a9699e36e6e810 /arch/riscv/kernel/cpu.c
parent0d1e8b8d2bcd3150d51754d8d0fdbf44dc88b0d3 (diff)
parentd26c4bbf992463c043fdee4b3e5efa3f08990862 (diff)
downloadlinux-c300af28572d05ae6891c359a7c8c2c81f01dccf.tar.bz2
Merge tag 'riscv-for-linus-4.20-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux
Pull RISC-V updates from Palmer Dabbelt: "This patch set contains a lot (at least, for me) of improvements to the RISC-V kernel port: - The removal of some cacheinfo values that were bogus. - On systems with F but without D the kernel will not show the F extension to userspace, as it isn't actually supported. - Support for futexes. - Removal of some unused code. - Cleanup of some menuconfig entries. - Support for systems without a floating-point unit, and for building kernels that will never use the floating-point unit. - More fixes to the RV32I port, which regressed again. It's really time to get this into a regression test somewhere so I stop breaking it. Thanks to Zong for resurrecting it again! - Various fixes that resulted from a year old review of our original patch set that I finally got around to. - Various improvements to SMP support, largely based around having switched to logical hart numbering, as well as some interrupt improvements. This one is in the same patch set as above, thanks to Atish for sheparding everything though as my patch set was a bit of a mess. I'm pretty sure this is our largest patch set since the original kernel contribution, and it's certainly the one with the most contributors. While I don't have anything else I know I'm going to submit for the merge window, I would be somewhat surprised if I didn't screw anything up. Thanks for the help, everyone!" * tag 'riscv-for-linus-4.20-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux: (31 commits) RISC-V: Cosmetic menuconfig changes riscv: move GCC version check for ARCH_SUPPORTS_INT128 to Kconfig RISC-V: remove the unused return_to_handler export RISC-V: Add futex support. RISC-V: Add FP register ptrace support for gdb. RISC-V: Mask out the F extension on systems without D RISC-V: Don't set cacheinfo.{physical_line_partition,attributes} RISC-V: Show IPI stats RISC-V: Show CPU ID and Hart ID separately in /proc/cpuinfo RISC-V: Use Linux logical CPU number instead of hartid RISC-V: Add logical CPU indexing for RISC-V RISC-V: Use WRITE_ONCE instead of direct access RISC-V: Use mmgrab() RISC-V: Rename im_okay_therefore_i_am to found_boot_cpu RISC-V: Rename riscv_of_processor_hart to riscv_of_processor_hartid RISC-V: Provide a cleaner raw_smp_processor_id() RISC-V: Disable preemption before enabling interrupts RISC-V: Comment on the TLB flush in smp_callin() RISC-V: Filter ISA and MMU values in cpuinfo RISC-V: Don't set cacheinfo.{physical_line_partition,attributes} ...
Diffstat (limited to 'arch/riscv/kernel/cpu.c')
-rw-r--r--arch/riscv/kernel/cpu.c87
1 files changed, 74 insertions, 13 deletions
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index ca6c81e54e37..3a5a2ee31547 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -14,9 +14,13 @@
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/of.h>
+#include <asm/smp.h>
-/* Return -1 if not a valid hart */
-int riscv_of_processor_hart(struct device_node *node)
+/*
+ * Returns the hart ID of the given device tree node, or -1 if the device tree
+ * node isn't a RISC-V hart.
+ */
+int riscv_of_processor_hartid(struct device_node *node)
{
const char *isa, *status;
u32 hart;
@@ -58,6 +62,64 @@ int riscv_of_processor_hart(struct device_node *node)
#ifdef CONFIG_PROC_FS
+static void print_isa(struct seq_file *f, const char *orig_isa)
+{
+ static const char *ext = "mafdc";
+ const char *isa = orig_isa;
+ const char *e;
+
+ /*
+ * Linux doesn't support rv32e or rv128i, and we only support booting
+ * kernels on harts with the same ISA that the kernel is compiled for.
+ */
+#if defined(CONFIG_32BIT)
+ if (strncmp(isa, "rv32i", 5) != 0)
+ return;
+#elif defined(CONFIG_64BIT)
+ if (strncmp(isa, "rv64i", 5) != 0)
+ return;
+#endif
+
+ /* Print the base ISA, as we already know it's legal. */
+ seq_puts(f, "isa\t\t: ");
+ seq_write(f, isa, 5);
+ isa += 5;
+
+ /*
+ * Check the rest of the ISA string for valid extensions, printing those
+ * we find. RISC-V ISA strings define an order, so we only print the
+ * extension bits when they're in order.
+ */
+ for (e = ext; *e != '\0'; ++e) {
+ if (isa[0] == e[0]) {
+ seq_write(f, isa, 1);
+ isa++;
+ }
+ }
+ seq_puts(f, "\n");
+
+ /*
+ * If we were given an unsupported ISA in the device tree then print
+ * a bit of info describing what went wrong.
+ */
+ if (isa[0] != '\0')
+ pr_info("unsupported ISA \"%s\" in device tree", orig_isa);
+}
+
+static void print_mmu(struct seq_file *f, const char *mmu_type)
+{
+#if defined(CONFIG_32BIT)
+ if (strcmp(mmu_type, "riscv,sv32") != 0)
+ return;
+#elif defined(CONFIG_64BIT)
+ if (strcmp(mmu_type, "riscv,sv39") != 0 &&
+ strcmp(mmu_type, "riscv,sv48") != 0)
+ return;
+#endif
+
+ seq_printf(f, "mmu\t\t: %s\n", mmu_type+6);
+}
+
static void *c_start(struct seq_file *m, loff_t *pos)
{
*pos = cpumask_next(*pos - 1, cpu_online_mask);
@@ -78,21 +140,20 @@ static void c_stop(struct seq_file *m, void *v)
static int c_show(struct seq_file *m, void *v)
{
- unsigned long hart_id = (unsigned long)v - 1;
- struct device_node *node = of_get_cpu_node(hart_id, NULL);
+ unsigned long cpu_id = (unsigned long)v - 1;
+ struct device_node *node = of_get_cpu_node(cpuid_to_hartid_map(cpu_id),
+ NULL);
const char *compat, *isa, *mmu;
- seq_printf(m, "hart\t: %lu\n", hart_id);
- if (!of_property_read_string(node, "riscv,isa", &isa)
- && isa[0] == 'r'
- && isa[1] == 'v')
- seq_printf(m, "isa\t: %s\n", isa);
- if (!of_property_read_string(node, "mmu-type", &mmu)
- && !strncmp(mmu, "riscv,", 6))
- seq_printf(m, "mmu\t: %s\n", mmu+6);
+ seq_printf(m, "processor\t: %lu\n", cpu_id);
+ seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
+ if (!of_property_read_string(node, "riscv,isa", &isa))
+ print_isa(m, isa);
+ if (!of_property_read_string(node, "mmu-type", &mmu))
+ print_mmu(m, mmu);
if (!of_property_read_string(node, "compatible", &compat)
&& strcmp(compat, "riscv"))
- seq_printf(m, "uarch\t: %s\n", compat);
+ seq_printf(m, "uarch\t\t: %s\n", compat);
seq_puts(m, "\n");
return 0;