Skip to content

Commit 8916c90

Browse files
RISC-V: Support for 64bit hartid on RV64 platforms
The hartid can be a 64bit value on RV64 platforms. This series updates the code so that 64bit hartid can be supported on RV64 platforms. * 'riscv-64bit_hartid' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/linux.git: riscv/efi_stub: Add 64bit boot-hartid support on RV64 riscv: cpu: Add 64bit hartid support on RV64 riscv: smp: Add 64bit hartid support on RV64 riscv: spinwait: Fix hartid variable type riscv: cpu_ops_sbi: Add 64bit hartid support on RV64
2 parents b498166 + 171549f commit 8916c90

File tree

12 files changed

+60
-43
lines changed

12 files changed

+60
-43
lines changed

arch/riscv/include/asm/processor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ static inline void wait_for_interrupt(void)
7979
}
8080

8181
struct device_node;
82-
int riscv_of_processor_hartid(struct device_node *node);
83-
int riscv_of_parent_hartid(struct device_node *node);
82+
int riscv_of_processor_hartid(struct device_node *node, unsigned long *hartid);
83+
int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid);
8484

8585
extern void riscv_fill_hwcap(void);
8686
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);

arch/riscv/include/asm/smp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask);
4242
/* Hook for the generic smp_call_function_single() routine. */
4343
void arch_send_call_function_single_ipi(int cpu);
4444

45-
int riscv_hartid_to_cpuid(int hartid);
45+
int riscv_hartid_to_cpuid(unsigned long hartid);
4646

4747
/* Set custom IPI operations */
4848
void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops);
@@ -70,7 +70,7 @@ static inline void show_ipi_stats(struct seq_file *p, int prec)
7070
{
7171
}
7272

73-
static inline int riscv_hartid_to_cpuid(int hartid)
73+
static inline int riscv_hartid_to_cpuid(unsigned long hartid)
7474
{
7575
if (hartid == boot_cpu_hartid)
7676
return 0;

arch/riscv/kernel/cpu.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,36 @@
1414
* Returns the hart ID of the given device tree node, or -ENODEV if the node
1515
* isn't an enabled and valid RISC-V hart node.
1616
*/
17-
int riscv_of_processor_hartid(struct device_node *node)
17+
int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
1818
{
1919
const char *isa;
20-
u32 hart;
2120

2221
if (!of_device_is_compatible(node, "riscv")) {
2322
pr_warn("Found incompatible CPU\n");
2423
return -ENODEV;
2524
}
2625

27-
hart = of_get_cpu_hwid(node, 0);
28-
if (hart == ~0U) {
26+
*hart = (unsigned long) of_get_cpu_hwid(node, 0);
27+
if (*hart == ~0UL) {
2928
pr_warn("Found CPU without hart ID\n");
3029
return -ENODEV;
3130
}
3231

3332
if (!of_device_is_available(node)) {
34-
pr_info("CPU with hartid=%d is not available\n", hart);
33+
pr_info("CPU with hartid=%lu is not available\n", *hart);
3534
return -ENODEV;
3635
}
3736

3837
if (of_property_read_string(node, "riscv,isa", &isa)) {
39-
pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart);
38+
pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart);
4039
return -ENODEV;
4140
}
4241
if (isa[0] != 'r' || isa[1] != 'v') {
43-
pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa);
42+
pr_warn("CPU with hartid=%lu has an invalid ISA of \"%s\"\n", *hart, isa);
4443
return -ENODEV;
4544
}
4645

47-
return hart;
46+
return 0;
4847
}
4948

5049
/*
@@ -53,11 +52,16 @@ int riscv_of_processor_hartid(struct device_node *node)
5352
* To achieve this, we walk up the DT tree until we find an active
5453
* RISC-V core (HART) node and extract the cpuid from it.
5554
*/
56-
int riscv_of_parent_hartid(struct device_node *node)
55+
int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
5756
{
57+
int rc;
58+
5859
for (; node; node = node->parent) {
59-
if (of_device_is_compatible(node, "riscv"))
60-
return riscv_of_processor_hartid(node);
60+
if (of_device_is_compatible(node, "riscv")) {
61+
rc = riscv_of_processor_hartid(node, hartid);
62+
if (!rc)
63+
return 0;
64+
}
6165
}
6266

6367
return -1;

arch/riscv/kernel/cpu_ops_sbi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static int sbi_hsm_hart_get_status(unsigned long hartid)
6565
static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
6666
{
6767
unsigned long boot_addr = __pa_symbol(secondary_start_sbi);
68-
int hartid = cpuid_to_hartid_map(cpuid);
68+
unsigned long hartid = cpuid_to_hartid_map(cpuid);
6969
unsigned long hsm_data;
7070
struct sbi_hart_boot_data *bdata = &per_cpu(boot_data, cpuid);
7171

@@ -107,7 +107,7 @@ static void sbi_cpu_stop(void)
107107
static int sbi_cpu_is_stopped(unsigned int cpuid)
108108
{
109109
int rc;
110-
int hartid = cpuid_to_hartid_map(cpuid);
110+
unsigned long hartid = cpuid_to_hartid_map(cpuid);
111111

112112
rc = sbi_hsm_hart_get_status(hartid);
113113

arch/riscv/kernel/cpu_ops_spinwait.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data");
1818
static void cpu_update_secondary_bootdata(unsigned int cpuid,
1919
struct task_struct *tidle)
2020
{
21-
int hartid = cpuid_to_hartid_map(cpuid);
21+
unsigned long hartid = cpuid_to_hartid_map(cpuid);
2222

2323
/*
2424
* The hartid must be less than NR_CPUS to avoid out-of-bound access
@@ -27,7 +27,7 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid,
2727
* spinwait booting is not the recommended approach for any platforms
2828
* booting Linux in S-mode and can be disabled in the future.
2929
*/
30-
if (hartid == INVALID_HARTID || hartid >= NR_CPUS)
30+
if (hartid == INVALID_HARTID || hartid >= (unsigned long) NR_CPUS)
3131
return;
3232

3333
/* Make sure tidle is updated */

arch/riscv/kernel/cpufeature.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ void __init riscv_fill_hwcap(void)
7272
struct device_node *node;
7373
const char *isa;
7474
char print_str[NUM_ALPHA_EXTS + 1];
75-
int i, j;
75+
int i, j, rc;
7676
static unsigned long isa2hwcap[256] = {0};
77+
unsigned long hartid;
7778

7879
isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
7980
isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M;
@@ -91,7 +92,8 @@ void __init riscv_fill_hwcap(void)
9192
DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
9293
const char *temp;
9394

94-
if (riscv_of_processor_hartid(node) < 0)
95+
rc = riscv_of_processor_hartid(node, &hartid);
96+
if (rc < 0)
9597
continue;
9698

9799
if (of_property_read_string(node, "riscv,isa", &isa)) {

arch/riscv/kernel/smp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ static struct {
4747
unsigned long bits ____cacheline_aligned;
4848
} ipi_data[NR_CPUS] __cacheline_aligned;
4949

50-
int riscv_hartid_to_cpuid(int hartid)
50+
int riscv_hartid_to_cpuid(unsigned long hartid)
5151
{
5252
int i;
5353

5454
for (i = 0; i < NR_CPUS; i++)
5555
if (cpuid_to_hartid_map(i) == hartid)
5656
return i;
5757

58-
pr_err("Couldn't find cpu id for hartid [%d]\n", hartid);
58+
pr_err("Couldn't find cpu id for hartid [%lu]\n", hartid);
5959
return -ENOENT;
6060
}
6161

arch/riscv/kernel/smpboot.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
7272
void __init setup_smp(void)
7373
{
7474
struct device_node *dn;
75-
int hart;
75+
unsigned long hart;
7676
bool found_boot_cpu = false;
7777
int cpuid = 1;
78+
int rc;
7879

7980
cpu_set_ops(0);
8081

8182
for_each_of_cpu_node(dn) {
82-
hart = riscv_of_processor_hartid(dn);
83-
if (hart < 0)
83+
rc = riscv_of_processor_hartid(dn, &hart);
84+
if (rc < 0)
8485
continue;
8586

8687
if (hart == cpuid_to_hartid_map(0)) {
@@ -90,7 +91,7 @@ void __init setup_smp(void)
9091
continue;
9192
}
9293
if (cpuid >= NR_CPUS) {
93-
pr_warn("Invalid cpuid [%d] for hartid [%d]\n",
94+
pr_warn("Invalid cpuid [%d] for hartid [%lu]\n",
9495
cpuid, hart);
9596
continue;
9697
}

drivers/clocksource/timer-riscv.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,20 +101,21 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
101101

102102
static int __init riscv_timer_init_dt(struct device_node *n)
103103
{
104-
int cpuid, hartid, error;
104+
int cpuid, error;
105+
unsigned long hartid;
105106
struct device_node *child;
106107
struct irq_domain *domain;
107108

108-
hartid = riscv_of_processor_hartid(n);
109-
if (hartid < 0) {
110-
pr_warn("Not valid hartid for node [%pOF] error = [%d]\n",
109+
error = riscv_of_processor_hartid(n, &hartid);
110+
if (error < 0) {
111+
pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n",
111112
n, hartid);
112-
return hartid;
113+
return error;
113114
}
114115

115116
cpuid = riscv_hartid_to_cpuid(hartid);
116117
if (cpuid < 0) {
117-
pr_warn("Invalid cpuid for hartid [%d]\n", hartid);
118+
pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
118119
return cpuid;
119120
}
120121

@@ -140,7 +141,7 @@ static int __init riscv_timer_init_dt(struct device_node *n)
140141
return -ENODEV;
141142
}
142143

143-
pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
144+
pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n",
144145
__func__, cpuid, hartid);
145146
error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
146147
if (error) {

drivers/firmware/efi/libstub/riscv-stub.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <asm/efi.h>
1010
#include <asm/sections.h>
11+
#include <asm/unaligned.h>
1112

1213
#include "efistub.h"
1314

@@ -29,7 +30,7 @@ static int get_boot_hartid_from_fdt(void)
2930
{
3031
const void *fdt;
3132
int chosen_node, len;
32-
const fdt32_t *prop;
33+
const void *prop;
3334

3435
fdt = get_efi_config_table(DEVICE_TREE_GUID);
3536
if (!fdt)
@@ -40,10 +41,16 @@ static int get_boot_hartid_from_fdt(void)
4041
return -EINVAL;
4142

4243
prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len);
43-
if (!prop || len != sizeof(u32))
44+
if (!prop)
45+
return -EINVAL;
46+
47+
if (len == sizeof(u32))
48+
hartid = (unsigned long) fdt32_to_cpu(*(fdt32_t *)prop);
49+
else if (len == sizeof(u64))
50+
hartid = (unsigned long) fdt64_to_cpu(__get_unaligned_t(fdt64_t, prop));
51+
else
4452
return -EINVAL;
4553

46-
hartid = fdt32_to_cpu(*prop);
4754
return 0;
4855
}
4956

0 commit comments

Comments
 (0)