-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Nuclei CPU IP design defines the value of the mhartid csr, which includes the cluster id and hartid. The cluster id and hartid are either 32 bits (rv32) or 64 bits (rv64), and the number of bits occupied by the hartid varies with the number of hart. For instance, if some cluster has 4 harts, then the hartid in this cluster occupies 2 bits. By default, the Nuclei linux sdk on the Nuclei Evalsoc platform occupies 8 bits for hartid. You need to modify the source code in the linux sdk that involve hartid values based on your hardware system. mhartid csr can only be accessed in M mode. Therefore, code running in M mode that uses mhartid csr may need to be modified, such as freeloader, opensbi, uboot spl, etc. If the S mode can use the shartid nuclei customized csr, you can also refer to this document.
Note
- This doc assumes that linux is running on only one cluster
- You can grep
hartidin all the related source code, and then take care of the changes.
1. freeloader hartid patch
Define the value of MHARTID_MASK based on the number of bits occupied by the hardware hartid. For example, if your hartid is 4, then hartid occupies 2 bits. Define the following macro:
#define MHARTID_MASK 0x3
The following code does not define MHARTID_MASK macro,your need to define it based on real hardware solution,otherwise,an error will be reported when compiling. In addition, we define GET_MASKED_HARTID macro to obtain hartid value.
diff --git a/freeloader.S b/freeloader.S
index 3266f1f..43b2d8a 100644
--- a/freeloader.S
+++ b/freeloader.S
@@ -80,6 +80,19 @@
#define LWU lw
#endif
+/* define hartid mask bits */
+#ifndef MHARTID_MASK
+#error "MHARTID_MASK is not defined!"
+#else
+#define HARTID_MASK MHARTID_MASK
+#endif
+
+.macro GET_MASKED_HARTID result_reg
+ # Read hartid into result register
+ csrr \result_reg, mhartid
+ and \result_reg, \result_reg, HARTID_MASK
+.endm
_check_hart:
/* Hart 0 copy images, other hart wait copy finished, and jump to boot */
- csrr a0, mhartid
+ GET_MASKED_HARTID a0
beq a0, zero, _copy_image
_wait_copy:
@@ -233,7 +246,7 @@ _loop_wait:
j _wait_copy
_start_smporamp:
- csrr t0, mhartid
+ GET_MASKED_HARTID t0
li t1, AMP_START_CORE
+ GET_MASKED_HARTID t0
li t1, AMP_START_CORE
// branch to amp boot if amp start core >= hartid
bgeu t0, t1, _start_amp
@@ -242,7 +255,7 @@ _start_smporamp:
_start_amp:
// Increase REBOOT_CNT_BASE + hartid * 4
li t0, REBOOT_CNT_BASE
- csrr t2, mhartid
+ GET_MASKED_HARTID t2
li t1, 4
mul t1, t1, t2
add t0, t0, t1
@@ -255,7 +268,7 @@ _start_amp:
// jump address t0 = AMPFW_START_BASE + AMPFW_SIZE * (mhartid - 1)
li t0, AMPFW_START_BASE
li t1, AMPFW_SIZE
- csrr t2, mhartid
+ GET_MASKED_HARTID t2
// mhartid must > 1 here
addi t2, t2, -1
// hart program offset = AMPfw_size * (hartid-1)
@@ -415,7 +428,8 @@ _start_boot:
* hartid via a0 register
* device tree blob address in memory via a1 register. The address must be aligned to 8 bytes.
*/
- csrr a0, mhartid /* hart ID */
+ GET_MASKED_HARTID a0 /* hart ID */2. opensbi hartid patch
Define the value of MHARTID_MASK based on the number of bits occupied by the hardware hartid. For example, if your hartid is 4, then hartid occupies 2 bits. Define the following macro:
#define MHARTID_MASK 0x3
The following code does not define MHARTID_MASK macro,your need to define it based on real hardware solution,otherwise,an error will be reported when compiling. In addition, we define GET_MASKED_HARTID macro to obtain hartid value.
diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index b947423..205e795 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -42,6 +42,12 @@
999:
.endm
+.macro GET_MASKED_HARTID result_reg
+ # Read hartid into result register
+ csrr \result_reg, mhartid
+ and \result_reg, \result_reg, HARTID_MASK
+.endm
+
.section .entry, "ax", %progbits
.align 3
.globl _start
@@ -456,7 +462,7 @@ _start_warm:
REG_L s9, SBI_PLATFORM_HART_INDEX2ID_OFFSET(a4)
/* Find HART id */
- csrr s6, CSR_MHARTID
+ GET_MASKED_HARTID s6
/* Find HART index */
beqz s9, 3f
diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h
index 1ff36de..2342535 100644
--- a/include/sbi/riscv_asm.h
+++ b/include/sbi/riscv_asm.h
@@ -162,8 +162,15 @@ void csr_write_num(int csr_num, unsigned long val);
__asm__ __volatile__("ebreak" ::: "memory"); \
} while (0)
+/* define hartid mask bits */
+#ifndef MHARTID_MASK
+#error "MHARTID_MASK is not defined!"
+#else
+#define HARTID_MASK MHARTID_MASK
+#endif
+
/* Get current HART id */
-#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID))
+#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID) & HARTID_MASK)3. uboot spl hartid patch
Define the value of MHARTID_MASK based on the number of bits occupied by the hardware hartid. For example, if your hartid is 4, then hartid occupies 2 bits. Define the following macro:
#define MHARTID_MASK 0x3
The following code does not define MHARTID_MASK macro,your need to define it based on real hardware solution,otherwise,an error will be reported when compiling. In addition, we define GET_MASKED_HARTID macro to obtain hartid value.
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 6cecadfac..c7528f422 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -32,6 +32,19 @@
#define SYM_SIZE 0x18
#endif
+/* define hartid mask bits */
+#ifndef MHARTID_MASK
+#error "MHARTID_MASK is not defined!"
+#else
+#define HARTID_MASK MHARTID_MASK
+#endif
+
+.macro GET_MASKED_HARTID result_reg
+ # Read hartid into result register
+ csrr \result_reg, mhartid
+ and \result_reg, \result_reg, HARTID_MASK
+.endm
+
.section .data
secondary_harts_relocation_error:
.ascii "Relocation of secondary harts has failed, error %d\n"
@@ -40,7 +53,7 @@ secondary_harts_relocation_error:
.globl _start
_start:
#if CONFIG_IS_ENABLED(RISCV_MMODE)
- csrr a0, CSR_MHARTID
+ GET_MASKED_HARTID a0
:4. optee os shartid patch
Perhaps you use shartid csr to read hartid in supervisor mode. you need to modify code like above. The following example
is optee os may use shartid.
Define the value of SHARTID_MASK based on the number of bits occupied by the hardware hartid. For example, if your hartid is 4, then hartid occupies 2 bits. Define the following macro:
#define SHARTID_MASK 0x3
The following code does not define SHARTID_MASK macro,your need to define it based on real hardware solution.
diff --git a/core/arch/riscv/include/riscv.h b/core/arch/riscv/include/riscv.h
index 2d5042f..a148eba 100644
--- a/core/arch/riscv/include/riscv.h
+++ b/core/arch/riscv/include/riscv.h
@@ -60,13 +60,20 @@
#ifndef __ASSEMBLER__
#ifdef CFG_SHART_FEATURE
+
+#ifndef SHARTID_MASK
+#error "SHARTID_MASK is not defined!"
+#else
+#define HARTID_MASK SHARTID_MASK
+#endif
+
static inline __noprof unsigned long read_hartid(void)
{
unsigned long hartid;
asm volatile("csrr %0, 0xdc0" : "=r" (hartid));
- return hartid;
+ return hartid & HARTID_MASK;
}