hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/riscv/kernel/cpu.c
....@@ -1,62 +1,88 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012 Regents of the University of California
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License
6
- * as published by the Free Software Foundation, version 2.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135
146 #include <linux/init.h>
157 #include <linux/seq_file.h>
168 #include <linux/of.h>
9
+#include <asm/smp.h>
1710
18
-/* Return -1 if not a valid hart */
19
-int riscv_of_processor_hart(struct device_node *node)
11
+/*
12
+ * Returns the hart ID of the given device tree node, or -ENODEV if the node
13
+ * isn't an enabled and valid RISC-V hart node.
14
+ */
15
+int riscv_of_processor_hartid(struct device_node *node)
2016 {
21
- const char *isa, *status;
17
+ const char *isa;
2218 u32 hart;
2319
2420 if (!of_device_is_compatible(node, "riscv")) {
2521 pr_warn("Found incompatible CPU\n");
26
- return -(ENODEV);
22
+ return -ENODEV;
2723 }
2824
2925 if (of_property_read_u32(node, "reg", &hart)) {
3026 pr_warn("Found CPU without hart ID\n");
31
- return -(ENODEV);
32
- }
33
- if (hart >= NR_CPUS) {
34
- pr_info("Found hart ID %d, which is above NR_CPUs. Disabling this hart\n", hart);
35
- return -(ENODEV);
27
+ return -ENODEV;
3628 }
3729
38
- if (of_property_read_string(node, "status", &status)) {
39
- pr_warn("CPU with hartid=%d has no \"status\" property\n", hart);
40
- return -(ENODEV);
41
- }
42
- if (strcmp(status, "okay")) {
43
- pr_info("CPU with hartid=%d has a non-okay status of \"%s\"\n", hart, status);
44
- return -(ENODEV);
30
+ if (!of_device_is_available(node)) {
31
+ pr_info("CPU with hartid=%d is not available\n", hart);
32
+ return -ENODEV;
4533 }
4634
4735 if (of_property_read_string(node, "riscv,isa", &isa)) {
4836 pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart);
49
- return -(ENODEV);
37
+ return -ENODEV;
5038 }
5139 if (isa[0] != 'r' || isa[1] != 'v') {
5240 pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa);
53
- return -(ENODEV);
41
+ return -ENODEV;
5442 }
5543
5644 return hart;
5745 }
5846
47
+/*
48
+ * Find hart ID of the CPU DT node under which given DT node falls.
49
+ *
50
+ * To achieve this, we walk up the DT tree until we find an active
51
+ * RISC-V core (HART) node and extract the cpuid from it.
52
+ */
53
+int riscv_of_parent_hartid(struct device_node *node)
54
+{
55
+ for (; node; node = node->parent) {
56
+ if (of_device_is_compatible(node, "riscv"))
57
+ return riscv_of_processor_hartid(node);
58
+ }
59
+
60
+ return -1;
61
+}
62
+
5963 #ifdef CONFIG_PROC_FS
64
+
65
+static void print_isa(struct seq_file *f, const char *isa)
66
+{
67
+ /* Print the entire ISA as it is */
68
+ seq_puts(f, "isa\t\t: ");
69
+ seq_write(f, isa, strlen(isa));
70
+ seq_puts(f, "\n");
71
+}
72
+
73
+static void print_mmu(struct seq_file *f, const char *mmu_type)
74
+{
75
+#if defined(CONFIG_32BIT)
76
+ if (strcmp(mmu_type, "riscv,sv32") != 0)
77
+ return;
78
+#elif defined(CONFIG_64BIT)
79
+ if (strcmp(mmu_type, "riscv,sv39") != 0 &&
80
+ strcmp(mmu_type, "riscv,sv48") != 0)
81
+ return;
82
+#endif
83
+
84
+ seq_printf(f, "mmu\t\t: %s\n", mmu_type+6);
85
+}
6086
6187 static void *c_start(struct seq_file *m, loff_t *pos)
6288 {
....@@ -78,22 +104,21 @@
78104
79105 static int c_show(struct seq_file *m, void *v)
80106 {
81
- unsigned long hart_id = (unsigned long)v - 1;
82
- struct device_node *node = of_get_cpu_node(hart_id, NULL);
107
+ unsigned long cpu_id = (unsigned long)v - 1;
108
+ struct device_node *node = of_get_cpu_node(cpu_id, NULL);
83109 const char *compat, *isa, *mmu;
84110
85
- seq_printf(m, "hart\t: %lu\n", hart_id);
86
- if (!of_property_read_string(node, "riscv,isa", &isa)
87
- && isa[0] == 'r'
88
- && isa[1] == 'v')
89
- seq_printf(m, "isa\t: %s\n", isa);
90
- if (!of_property_read_string(node, "mmu-type", &mmu)
91
- && !strncmp(mmu, "riscv,", 6))
92
- seq_printf(m, "mmu\t: %s\n", mmu+6);
111
+ seq_printf(m, "processor\t: %lu\n", cpu_id);
112
+ seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
113
+ if (!of_property_read_string(node, "riscv,isa", &isa))
114
+ print_isa(m, isa);
115
+ if (!of_property_read_string(node, "mmu-type", &mmu))
116
+ print_mmu(m, mmu);
93117 if (!of_property_read_string(node, "compatible", &compat)
94118 && strcmp(compat, "riscv"))
95
- seq_printf(m, "uarch\t: %s\n", compat);
119
+ seq_printf(m, "uarch\t\t: %s\n", compat);
96120 seq_puts(m, "\n");
121
+ of_node_put(node);
97122
98123 return 0;
99124 }