diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-25 18:01:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-25 18:01:29 -0700 |
commit | c300af28572d05ae6891c359a7c8c2c81f01dccf (patch) | |
tree | 1fbe3781ca2527b71a274c6996a9699e36e6e810 /arch/riscv/kernel/cpu.c | |
parent | 0d1e8b8d2bcd3150d51754d8d0fdbf44dc88b0d3 (diff) | |
parent | d26c4bbf992463c043fdee4b3e5efa3f08990862 (diff) | |
download | linux-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.c | 87 |
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; |