linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] LoongArch, MIPS: Unify Loongson IOCSR handling
@ 2024-09-12 20:55 Jiaxun Yang
  2024-09-12 20:55 ` [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG Jiaxun Yang
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Jiaxun Yang @ 2024-09-12 20:55 UTC (permalink / raw)
  To: Huacai Chen, WANG Xuerui, Rafael J. Wysocki, Viresh Kumar,
	Thomas Gleixner, Thomas Bogendoerfer
  Cc: loongarch, linux-kernel, linux-pm, linux-mips, kvm, Jiaxun Yang

Hi folks,

This series unfied LoongArch and MIPS's IOCSR functions and
macros so they will expose same interface to arch-indenpendent
drivers.

This can reduce code deuplication, and also help my unifed IPI driver
and MIPS extio driver effort.

This is touching many sub-systems in once so might be hard to merge.

Huacai, can you apply first three patch via loongarch-next tree.
For last two patch maybe better merge them via a second PR after
all subsystem PRs merged.

No functional change so hope it's not too late for 6.12 :-)

Please review.
Thanks

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
Changes in v2:
- Drop patch 1
- Move IOCSR probing to cpu_probe_loongson
- Fix build error for CPUFREQ driver
- Link to v1: https://lore.kernel.org/r/20240907-iocsr-v1-0-0c99b3334444@flygoat.com

---
Jiaxun Yang (4):
      LoongArch: Probe more CPU features from CPUCFG
      LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common
      LoongArch: Extract IOCSR definitions to standalone header
      MIPS: Loongson64: Use shared IOCSR header

 MAINTAINERS                                        |   1 +
 arch/loongarch/include/asm/cpu.h                   |   4 +
 arch/loongarch/include/asm/loongarch.h             |  93 +----------------
 arch/loongarch/kernel/cpu-probe.c                  | 103 ++++++++++++-------
 arch/loongarch/kernel/relocate_kernel.S            |   5 +-
 arch/loongarch/kernel/smp.c                        |  23 +++--
 .../include/asm/mach-loongson64/loongson_regs.h    |  58 +++--------
 arch/mips/kvm/vz.c                                 |   2 +-
 arch/mips/loongson64/smp.c                         |  44 ++++----
 drivers/cpufreq/loongson3_cpufreq.c                |  11 +-
 drivers/irqchip/irq-loongarch-avec.c               |   5 +-
 drivers/irqchip/irq-loongson-eiointc.c             |   5 +-
 drivers/platform/mips/cpu_hwmon.c                  |   7 +-
 include/linux/loongson/iocsr.h                     | 113 +++++++++++++++++++++
 14 files changed, 254 insertions(+), 220 deletions(-)
---
base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
change-id: 20240906-iocsr-829075458511

Best regards,
-- 
Jiaxun Yang <jiaxun.yang@flygoat.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG
  2024-09-12 20:55 [PATCH v2 0/4] LoongArch, MIPS: Unify Loongson IOCSR handling Jiaxun Yang
@ 2024-09-12 20:55 ` Jiaxun Yang
  2024-09-13  8:46   ` Huacai Chen
  2024-09-12 20:55 ` [PATCH v2 2/4] LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common Jiaxun Yang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Jiaxun Yang @ 2024-09-12 20:55 UTC (permalink / raw)
  To: Huacai Chen, WANG Xuerui, Rafael J. Wysocki, Viresh Kumar,
	Thomas Gleixner, Thomas Bogendoerfer
  Cc: loongarch, linux-kernel, linux-pm, linux-mips, kvm, Jiaxun Yang

Probe ISA level, TLB, IOCSR information from CPUCFG to
improve kernel resilience to different core implementations.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/loongarch/include/asm/cpu.h       |  4 +++
 arch/loongarch/include/asm/loongarch.h |  3 +-
 arch/loongarch/kernel/cpu-probe.c      | 54 ++++++++++++++++++++++++----------
 3 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h
index 843f9c4ec980..251a15439cff 100644
--- a/arch/loongarch/include/asm/cpu.h
+++ b/arch/loongarch/include/asm/cpu.h
@@ -100,6 +100,8 @@ enum cpu_type_enum {
 #define CPU_FEATURE_HYPERVISOR		25	/* CPU has hypervisor (running in VM) */
 #define CPU_FEATURE_PTW			26	/* CPU has hardware page table walker */
 #define CPU_FEATURE_AVECINT		27	/* CPU has avec interrupt */
+#define CPU_FEATURE_IOCSR		28	/* CPU has IOCSR */
+#define CPU_FEATURE_LSPW		29	/* CPU has LSPW */
 
 #define LOONGARCH_CPU_CPUCFG		BIT_ULL(CPU_FEATURE_CPUCFG)
 #define LOONGARCH_CPU_LAM		BIT_ULL(CPU_FEATURE_LAM)
@@ -129,5 +131,7 @@ enum cpu_type_enum {
 #define LOONGARCH_CPU_HYPERVISOR	BIT_ULL(CPU_FEATURE_HYPERVISOR)
 #define LOONGARCH_CPU_PTW		BIT_ULL(CPU_FEATURE_PTW)
 #define LOONGARCH_CPU_AVECINT		BIT_ULL(CPU_FEATURE_AVECINT)
+#define LOONGARCH_CPU_IOCSR		BIT_ULL(CPU_FEATURE_IOCSR)
+#define LOONGARCH_CPU_LSPW		BIT_ULL(CPU_FEATURE_LSPW)
 
 #endif /* _ASM_CPU_H */
diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
index 631d249b3ef2..23af28f00c3c 100644
--- a/arch/loongarch/include/asm/loongarch.h
+++ b/arch/loongarch/include/asm/loongarch.h
@@ -60,8 +60,7 @@
 #define  CPUCFG0_PRID			GENMASK(31, 0)
 
 #define LOONGARCH_CPUCFG1		0x1
-#define  CPUCFG1_ISGR32			BIT(0)
-#define  CPUCFG1_ISGR64			BIT(1)
+#define  CPUCFG1_ISA			GENMASK(1, 0)
 #define  CPUCFG1_PAGING			BIT(2)
 #define  CPUCFG1_IOCSR			BIT(3)
 #define  CPUCFG1_PABITS			GENMASK(11, 4)
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index 14f0449f5452..5dc8ca3c4387 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -92,11 +92,29 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 	unsigned long asid_mask;
 
 	c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
-		     LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
+		     LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
 
 	elf_hwcap = HWCAP_LOONGARCH_CPUCFG;
 
 	config = read_cpucfg(LOONGARCH_CPUCFG1);
+
+	switch (config & CPUCFG1_ISA) {
+	case 0:
+		set_isa(c, LOONGARCH_CPU_ISA_LA32R);
+		break;
+	case 1:
+		set_isa(c, LOONGARCH_CPU_ISA_LA32S);
+		break;
+	case 2:
+		set_isa(c, LOONGARCH_CPU_ISA_LA64);
+		break;
+	default:
+		pr_warn("Warning: unknown ISA level\n");
+	}
+	if (config & CPUCFG1_PAGING)
+		c->options |= LOONGARCH_CPU_TLB;
+	if (config & CPUCFG1_IOCSR)
+		c->options |= LOONGARCH_CPU_IOCSR;
 	if (config & CPUCFG1_UAL) {
 		c->options |= LOONGARCH_CPU_UAL;
 		elf_hwcap |= HWCAP_LOONGARCH_UAL;
@@ -157,6 +175,8 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 		elf_hwcap |= HWCAP_LOONGARCH_LBT_MIPS;
 	}
 #endif
+	if (config & CPUCFG2_LSPW)
+		c->options |= LOONGARCH_CPU_LSPW;
 
 	config = read_cpucfg(LOONGARCH_CPUCFG6);
 	if (config & CPUCFG6_PMP)
@@ -222,6 +242,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
 {
 	uint64_t *vendor = (void *)(&cpu_full_name[VENDOR_OFFSET]);
 	uint64_t *cpuname = (void *)(&cpu_full_name[CPUNAME_OFFSET]);
+	const char *core_name = "Unknown";
 
 	if (!__cpu_full_name[cpu])
 		__cpu_full_name[cpu] = cpu_full_name;
@@ -232,40 +253,43 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
 	switch (c->processor_id & PRID_SERIES_MASK) {
 	case PRID_SERIES_LA132:
 		c->cputype = CPU_LOONGSON32;
-		set_isa(c, LOONGARCH_CPU_ISA_LA32S);
 		__cpu_family[cpu] = "Loongson-32bit";
-		pr_info("32-bit Loongson Processor probed (LA132 Core)\n");
+		core_name = "LA132";
 		break;
 	case PRID_SERIES_LA264:
 		c->cputype = CPU_LOONGSON64;
-		set_isa(c, LOONGARCH_CPU_ISA_LA64);
 		__cpu_family[cpu] = "Loongson-64bit";
-		pr_info("64-bit Loongson Processor probed (LA264 Core)\n");
+		core_name = "LA264";
 		break;
 	case PRID_SERIES_LA364:
 		c->cputype = CPU_LOONGSON64;
-		set_isa(c, LOONGARCH_CPU_ISA_LA64);
 		__cpu_family[cpu] = "Loongson-64bit";
-		pr_info("64-bit Loongson Processor probed (LA364 Core)\n");
+		core_name = "LA364";
 		break;
 	case PRID_SERIES_LA464:
 		c->cputype = CPU_LOONGSON64;
-		set_isa(c, LOONGARCH_CPU_ISA_LA64);
 		__cpu_family[cpu] = "Loongson-64bit";
-		pr_info("64-bit Loongson Processor probed (LA464 Core)\n");
+		core_name = "LA464";
 		break;
 	case PRID_SERIES_LA664:
 		c->cputype = CPU_LOONGSON64;
-		set_isa(c, LOONGARCH_CPU_ISA_LA64);
 		__cpu_family[cpu] = "Loongson-64bit";
-		pr_info("64-bit Loongson Processor probed (LA664 Core)\n");
+		core_name = "LA664";
 		break;
 	default: /* Default to 64 bit */
-		c->cputype = CPU_LOONGSON64;
-		set_isa(c, LOONGARCH_CPU_ISA_LA64);
-		__cpu_family[cpu] = "Loongson-64bit";
-		pr_info("64-bit Loongson Processor probed (Unknown Core)\n");
+		if (c->isa_level & LOONGARCH_CPU_ISA_LA64) {
+			c->cputype = CPU_LOONGSON64;
+			__cpu_family[cpu] = "Loongson-64bit";
+		} else if (c->isa_level & LOONGARCH_CPU_ISA_LA32S) {
+			c->cputype = CPU_LOONGSON32;
+			__cpu_family[cpu] = "Loongson-32bit";
+		} else if (c->isa_level & LOONGARCH_CPU_ISA_LA32R) {
+			c->cputype = CPU_LOONGSON32;
+			__cpu_family[cpu] = "Loongson-32bit Reduced";
+		}
 	}
+
+	pr_info("%s Processor probed (%s Core)\n", __cpu_family[cpu], core_name);
 }
 
 #ifdef CONFIG_64BIT

-- 
2.46.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/4] LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common
  2024-09-12 20:55 [PATCH v2 0/4] LoongArch, MIPS: Unify Loongson IOCSR handling Jiaxun Yang
  2024-09-12 20:55 ` [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG Jiaxun Yang
@ 2024-09-12 20:55 ` Jiaxun Yang
  2024-09-12 20:59   ` Jiaxun Yang
  2024-09-12 20:55 ` [PATCH v2 3/4] LoongArch: Extract IOCSR definitions to standalone header Jiaxun Yang
  2024-09-12 20:55 ` [PATCH v2 4/4] MIPS: Loongson64: Use shared IOCSR header Jiaxun Yang
  3 siblings, 1 reply; 9+ messages in thread
From: Jiaxun Yang @ 2024-09-12 20:55 UTC (permalink / raw)
  To: Huacai Chen, WANG Xuerui, Rafael J. Wysocki, Viresh Kumar,
	Thomas Gleixner, Thomas Bogendoerfer
  Cc: loongarch, linux-kernel, linux-pm, linux-mips, kvm, Jiaxun Yang

IOCSR register definition appears to be a platform specific
spec instead of architecture spec, even for Loongson CPUs
there is no guarantee that IOCSR will always present.

Thus it's dangerous to perform IOCSR probing without checking
CPU type and instruction availability.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/loongarch/kernel/cpu-probe.c | 50 +++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index 5dc8ca3c4387..d1a9bb77145f 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -182,22 +182,6 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 	if (config & CPUCFG6_PMP)
 		c->options |= LOONGARCH_CPU_PMP;
 
-	config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
-	if (config & IOCSRF_CSRIPI)
-		c->options |= LOONGARCH_CPU_CSRIPI;
-	if (config & IOCSRF_EXTIOI)
-		c->options |= LOONGARCH_CPU_EXTIOI;
-	if (config & IOCSRF_FREQSCALE)
-		c->options |= LOONGARCH_CPU_SCALEFREQ;
-	if (config & IOCSRF_FLATMODE)
-		c->options |= LOONGARCH_CPU_FLATMODE;
-	if (config & IOCSRF_EIODECODE)
-		c->options |= LOONGARCH_CPU_EIODECODE;
-	if (config & IOCSRF_AVEC)
-		c->options |= LOONGARCH_CPU_AVECINT;
-	if (config & IOCSRF_VM)
-		c->options |= LOONGARCH_CPU_HYPERVISOR;
-
 	config = csr_read32(LOONGARCH_CSR_ASID);
 	config = (config & CSR_ASID_BIT) >> CSR_ASID_BIT_SHIFT;
 	asid_mask = GENMASK(config - 1, 0);
@@ -240,15 +224,10 @@ static char cpu_full_name[MAX_NAME_LEN] = "        -        ";
 
 static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int cpu)
 {
+	uint32_t config;
+	const char *core_name = "Unknown";
 	uint64_t *vendor = (void *)(&cpu_full_name[VENDOR_OFFSET]);
 	uint64_t *cpuname = (void *)(&cpu_full_name[CPUNAME_OFFSET]);
-	const char *core_name = "Unknown";
-
-	if (!__cpu_full_name[cpu])
-		__cpu_full_name[cpu] = cpu_full_name;
-
-	*vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
-	*cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
 
 	switch (c->processor_id & PRID_SERIES_MASK) {
 	case PRID_SERIES_LA132:
@@ -290,6 +269,31 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
 	}
 
 	pr_info("%s Processor probed (%s Core)\n", __cpu_family[cpu], core_name);
+
+	if (c->options & LOONGARCH_CPU_IOCSR)
+		return;
+
+	*vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
+	*cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
+
+	if (!__cpu_full_name[cpu])
+		__cpu_full_name[cpu] = cpu_full_name;
+
+	config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
+	if (config & IOCSRF_CSRIPI)
+		c->options |= LOONGARCH_CPU_CSRIPI;
+	if (config & IOCSRF_EXTIOI)
+		c->options |= LOONGARCH_CPU_EXTIOI;
+	if (config & IOCSRF_FREQSCALE)
+		c->options |= LOONGARCH_CPU_SCALEFREQ;
+	if (config & IOCSRF_FLATMODE)
+		c->options |= LOONGARCH_CPU_FLATMODE;
+	if (config & IOCSRF_EIODECODE)
+		c->options |= LOONGARCH_CPU_EIODECODE;
+	if (config & IOCSRF_AVEC)
+		c->options |= LOONGARCH_CPU_AVECINT;
+	if (config & IOCSRF_VM)
+		c->options |= LOONGARCH_CPU_HYPERVISOR;
 }
 
 #ifdef CONFIG_64BIT

-- 
2.46.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/4] LoongArch: Extract IOCSR definitions to standalone header
  2024-09-12 20:55 [PATCH v2 0/4] LoongArch, MIPS: Unify Loongson IOCSR handling Jiaxun Yang
  2024-09-12 20:55 ` [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG Jiaxun Yang
  2024-09-12 20:55 ` [PATCH v2 2/4] LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common Jiaxun Yang
@ 2024-09-12 20:55 ` Jiaxun Yang
  2024-09-12 20:55 ` [PATCH v2 4/4] MIPS: Loongson64: Use shared IOCSR header Jiaxun Yang
  3 siblings, 0 replies; 9+ messages in thread
From: Jiaxun Yang @ 2024-09-12 20:55 UTC (permalink / raw)
  To: Huacai Chen, WANG Xuerui, Rafael J. Wysocki, Viresh Kumar,
	Thomas Gleixner, Thomas Bogendoerfer
  Cc: loongarch, linux-kernel, linux-pm, linux-mips, kvm, Jiaxun Yang

As IOCSR is not a part of architecture specification, it is not
really appropriate to define those stuff in loongarch.h.

Extract those definitions to include/linux/loongson/iocsr.h, so
that they can be shared with MIPS based Loongson systems as well.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 MAINTAINERS                             |   1 +
 arch/loongarch/include/asm/loongarch.h  |  90 --------------------------
 arch/loongarch/kernel/cpu-probe.c       |   7 +-
 arch/loongarch/kernel/relocate_kernel.S |   5 +-
 arch/loongarch/kernel/smp.c             |  23 +++----
 drivers/cpufreq/loongson3_cpufreq.c     |  11 ++--
 drivers/irqchip/irq-loongarch-avec.c    |   5 +-
 drivers/irqchip/irq-loongson-eiointc.c  |   5 +-
 include/linux/loongson/iocsr.h          | 110 ++++++++++++++++++++++++++++++++
 9 files changed, 142 insertions(+), 115 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0a3d9e17295a..f0f4c427e9a3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13305,6 +13305,7 @@ F:	Documentation/translations/zh_CN/arch/loongarch/
 F:	arch/loongarch/
 F:	drivers/*/*loongarch*
 F:	drivers/cpufreq/loongson3_cpufreq.c
+F:	include/linux/loongson
 
 LOONGSON GPIO DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
index 23af28f00c3c..4ac228230720 100644
--- a/arch/loongarch/include/asm/loongarch.h
+++ b/arch/loongarch/include/asm/loongarch.h
@@ -1048,84 +1048,6 @@
 
 #define ESTATF_IP		0x00003fff
 
-#define LOONGARCH_IOCSR_FEATURES	0x8
-#define  IOCSRF_TEMP			BIT_ULL(0)
-#define  IOCSRF_NODECNT			BIT_ULL(1)
-#define  IOCSRF_MSI			BIT_ULL(2)
-#define  IOCSRF_EXTIOI			BIT_ULL(3)
-#define  IOCSRF_CSRIPI			BIT_ULL(4)
-#define  IOCSRF_FREQCSR			BIT_ULL(5)
-#define  IOCSRF_FREQSCALE		BIT_ULL(6)
-#define  IOCSRF_DVFSV1			BIT_ULL(7)
-#define  IOCSRF_EIODECODE		BIT_ULL(9)
-#define  IOCSRF_FLATMODE		BIT_ULL(10)
-#define  IOCSRF_VM			BIT_ULL(11)
-#define  IOCSRF_AVEC			BIT_ULL(15)
-
-#define LOONGARCH_IOCSR_VENDOR		0x10
-
-#define LOONGARCH_IOCSR_CPUNAME		0x20
-
-#define LOONGARCH_IOCSR_NODECNT		0x408
-
-#define LOONGARCH_IOCSR_MISC_FUNC	0x420
-#define  IOCSR_MISC_FUNC_SOFT_INT	BIT_ULL(10)
-#define  IOCSR_MISC_FUNC_TIMER_RESET	BIT_ULL(21)
-#define  IOCSR_MISC_FUNC_EXT_IOI_EN	BIT_ULL(48)
-#define  IOCSR_MISC_FUNC_AVEC_EN	BIT_ULL(51)
-
-#define LOONGARCH_IOCSR_CPUTEMP		0x428
-
-#define LOONGARCH_IOCSR_SMCMBX		0x51c
-
-/* PerCore CSR, only accessible by local cores */
-#define LOONGARCH_IOCSR_IPI_STATUS	0x1000
-#define LOONGARCH_IOCSR_IPI_EN		0x1004
-#define LOONGARCH_IOCSR_IPI_SET		0x1008
-#define LOONGARCH_IOCSR_IPI_CLEAR	0x100c
-#define LOONGARCH_IOCSR_MBUF0		0x1020
-#define LOONGARCH_IOCSR_MBUF1		0x1028
-#define LOONGARCH_IOCSR_MBUF2		0x1030
-#define LOONGARCH_IOCSR_MBUF3		0x1038
-
-#define LOONGARCH_IOCSR_IPI_SEND	0x1040
-#define  IOCSR_IPI_SEND_IP_SHIFT	0
-#define  IOCSR_IPI_SEND_CPU_SHIFT	16
-#define  IOCSR_IPI_SEND_BLOCKING	BIT(31)
-
-#define LOONGARCH_IOCSR_MBUF_SEND	0x1048
-#define  IOCSR_MBUF_SEND_BLOCKING	BIT_ULL(31)
-#define  IOCSR_MBUF_SEND_BOX_SHIFT	2
-#define  IOCSR_MBUF_SEND_BOX_LO(box)	(box << 1)
-#define  IOCSR_MBUF_SEND_BOX_HI(box)	((box << 1) + 1)
-#define  IOCSR_MBUF_SEND_CPU_SHIFT	16
-#define  IOCSR_MBUF_SEND_BUF_SHIFT	32
-#define  IOCSR_MBUF_SEND_H32_MASK	0xFFFFFFFF00000000ULL
-
-#define LOONGARCH_IOCSR_ANY_SEND	0x1158
-#define  IOCSR_ANY_SEND_BLOCKING	BIT_ULL(31)
-#define  IOCSR_ANY_SEND_CPU_SHIFT	16
-#define  IOCSR_ANY_SEND_MASK_SHIFT	27
-#define  IOCSR_ANY_SEND_BUF_SHIFT	32
-#define  IOCSR_ANY_SEND_H32_MASK	0xFFFFFFFF00000000ULL
-
-/* Register offset and bit definition for CSR access */
-#define LOONGARCH_IOCSR_TIMER_CFG       0x1060
-#define LOONGARCH_IOCSR_TIMER_TICK      0x1070
-#define  IOCSR_TIMER_CFG_RESERVED       (_ULCAST_(1) << 63)
-#define  IOCSR_TIMER_CFG_PERIODIC       (_ULCAST_(1) << 62)
-#define  IOCSR_TIMER_CFG_EN             (_ULCAST_(1) << 61)
-#define  IOCSR_TIMER_MASK		0x0ffffffffffffULL
-#define  IOCSR_TIMER_INITVAL_RST        (_ULCAST_(0xffff) << 48)
-
-#define LOONGARCH_IOCSR_EXTIOI_NODEMAP_BASE	0x14a0
-#define LOONGARCH_IOCSR_EXTIOI_IPMAP_BASE	0x14c0
-#define LOONGARCH_IOCSR_EXTIOI_EN_BASE		0x1600
-#define LOONGARCH_IOCSR_EXTIOI_BOUNCE_BASE	0x1680
-#define LOONGARCH_IOCSR_EXTIOI_ISR_BASE		0x1800
-#define LOONGARCH_IOCSR_EXTIOI_ROUTE_BASE	0x1c00
-#define IOCSR_EXTIOI_VECTOR_NUM			256
-
 #ifndef __ASSEMBLY__
 
 static __always_inline u64 drdtime(void)
@@ -1145,18 +1067,6 @@ static inline unsigned int get_csr_cpuid(void)
 	return csr_read32(LOONGARCH_CSR_CPUID);
 }
 
-static inline void csr_any_send(unsigned int addr, unsigned int data,
-				unsigned int data_mask, unsigned int cpu)
-{
-	uint64_t val = 0;
-
-	val = IOCSR_ANY_SEND_BLOCKING | addr;
-	val |= (cpu << IOCSR_ANY_SEND_CPU_SHIFT);
-	val |= (data_mask << IOCSR_ANY_SEND_MASK_SHIFT);
-	val |= ((uint64_t)data << IOCSR_ANY_SEND_BUF_SHIFT);
-	iocsr_write64(val, LOONGARCH_IOCSR_ANY_SEND);
-}
-
 static inline unsigned int read_csr_excode(void)
 {
 	return (csr_read32(LOONGARCH_CSR_ESTAT) & CSR_ESTAT_EXC) >> CSR_ESTAT_EXC_SHIFT;
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index d1a9bb77145f..ecf2b2d2fae5 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -6,6 +6,7 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/loongson/iocsr.h>
 #include <linux/ptrace.h>
 #include <linux/smp.h>
 #include <linux/stddef.h>
@@ -273,13 +274,13 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
 	if (c->options & LOONGARCH_CPU_IOCSR)
 		return;
 
-	*vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
-	*cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
+	*vendor = iocsr_read64(LOONGSON_IOCSR_VENDOR);
+	*cpuname = iocsr_read64(LOONGSON_IOCSR_CPUNAME);
 
 	if (!__cpu_full_name[cpu])
 		__cpu_full_name[cpu] = cpu_full_name;
 
-	config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
+	config = iocsr_read32(LOONGSON_IOCSR_FEATURES);
 	if (config & IOCSRF_CSRIPI)
 		c->options |= LOONGARCH_CPU_CSRIPI;
 	if (config & IOCSRF_EXTIOI)
diff --git a/arch/loongarch/kernel/relocate_kernel.S b/arch/loongarch/kernel/relocate_kernel.S
index 84e6de2fd973..ce40ba6b5975 100644
--- a/arch/loongarch/kernel/relocate_kernel.S
+++ b/arch/loongarch/kernel/relocate_kernel.S
@@ -5,6 +5,7 @@
  * Copyright (C) 2022 Loongson Technology Corporation Limited
  */
 
+#include <linux/loongson/iocsr.h>
 #include <linux/kexec.h>
 
 #include <asm/asm.h>
@@ -88,14 +89,14 @@ SYM_CODE_END(relocate_new_kernel)
 #ifdef CONFIG_SMP
 /*
  * Other CPUs should wait until code is relocated and
- * then start at the entry point from LOONGARCH_IOCSR_MBUF0.
+ * then start at the entry point from LOONGSON_IOCSR_MBUF0.
  */
 SYM_CODE_START(kexec_smp_wait)
 	UNWIND_HINT_UNDEFINED
 1:	li.w		t0, 0x100			/* wait for init loop */
 2:	addi.w		t0, t0, -1			/* limit mailbox access */
 	bnez		t0, 2b
-	li.w		t1, LOONGARCH_IOCSR_MBUF0
+	li.w		t1, LOONGSON_IOCSR_MBUF0
 	iocsrrd.w	s0, t1				/* check PC as an indicator */
 	beqz		s0, 1b
 	iocsrrd.d	s0, t1				/* get PC via mailbox */
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index 4adbbef3450a..120865985376 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq_work.h>
+#include <linux/loongson/iocsr.h>
 #include <linux/profile.h>
 #include <linux/seq_file.h>
 #include <linux/smp.h>
@@ -164,14 +165,14 @@ static void csr_mail_send(uint64_t data, int cpu, int mailbox)
 	val |= (IOCSR_MBUF_SEND_BOX_HI(mailbox) << IOCSR_MBUF_SEND_BOX_SHIFT);
 	val |= (cpu << IOCSR_MBUF_SEND_CPU_SHIFT);
 	val |= (data & IOCSR_MBUF_SEND_H32_MASK);
-	iocsr_write64(val, LOONGARCH_IOCSR_MBUF_SEND);
+	iocsr_write64(val, LOONGSON_IOCSR_MBUF_SEND);
 
 	/* Send low 32 bits */
 	val = IOCSR_MBUF_SEND_BLOCKING;
 	val |= (IOCSR_MBUF_SEND_BOX_LO(mailbox) << IOCSR_MBUF_SEND_BOX_SHIFT);
 	val |= (cpu << IOCSR_MBUF_SEND_CPU_SHIFT);
 	val |= (data << IOCSR_MBUF_SEND_BUF_SHIFT);
-	iocsr_write64(val, LOONGARCH_IOCSR_MBUF_SEND);
+	iocsr_write64(val, LOONGSON_IOCSR_MBUF_SEND);
 };
 
 static u32 ipi_read_clear(int cpu)
@@ -179,9 +180,9 @@ static u32 ipi_read_clear(int cpu)
 	u32 action;
 
 	/* Load the ipi register to figure out what we're supposed to do */
-	action = iocsr_read32(LOONGARCH_IOCSR_IPI_STATUS);
+	action = iocsr_read32(LOONGSON_IOCSR_IPI_STATUS);
 	/* Clear the ipi register to clear the interrupt */
-	iocsr_write32(action, LOONGARCH_IOCSR_IPI_CLEAR);
+	iocsr_write32(action, LOONGSON_IOCSR_IPI_CLEAR);
 	wbflush();
 
 	return action;
@@ -193,7 +194,7 @@ static void ipi_write_action(int cpu, u32 action)
 
 	val = IOCSR_IPI_SEND_BLOCKING | action;
 	val |= (cpu << IOCSR_IPI_SEND_CPU_SHIFT);
-	iocsr_write32(val, LOONGARCH_IOCSR_IPI_SEND);
+	iocsr_write32(val, LOONGSON_IOCSR_IPI_SEND);
 }
 
 static void loongson_send_ipi_single(int cpu, unsigned int action)
@@ -322,7 +323,7 @@ void __init loongson_smp_setup(void)
 	cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
 
 	pv_ipi_init();
-	iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
+	iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_EN);
 	pr_info("Detected %i available CPU(s)\n", loongson_sysconf.nr_cpus);
 }
 
@@ -370,7 +371,7 @@ void loongson_init_secondary(void)
 
 	change_csr_ecfg(ECFG0_IM, imask);
 
-	iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
+	iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_EN);
 
 #ifdef CONFIG_NUMA
 	numa_add_cpu(cpu);
@@ -385,7 +386,7 @@ void loongson_init_secondary(void)
 void loongson_smp_finish(void)
 {
 	local_irq_enable();
-	iocsr_write64(0, LOONGARCH_IOCSR_MBUF0);
+	iocsr_write64(0, LOONGSON_IOCSR_MBUF0);
 	pr_info("CPU#%d finished\n", smp_processor_id());
 }
 
@@ -435,12 +436,12 @@ void __noreturn arch_cpu_idle_dead(void)
 	__smp_mb();
 	do {
 		__asm__ __volatile__("idle 0\n\t");
-		addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0);
+		addr = iocsr_read64(LOONGSON_IOCSR_MBUF0);
 	} while (addr == 0);
 
 	local_irq_disable();
 	init_fn = (void *)TO_CACHE(addr);
-	iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR);
+	iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_CLEAR);
 
 	init_fn();
 	BUG();
@@ -460,7 +461,7 @@ static int loongson_ipi_suspend(void)
 
 static void loongson_ipi_resume(void)
 {
-	iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
+	iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_EN);
 }
 
 static struct syscore_ops loongson_ipi_syscore_ops = {
diff --git a/drivers/cpufreq/loongson3_cpufreq.c b/drivers/cpufreq/loongson3_cpufreq.c
index 6b5e6798d9a2..11d5f1ba3040 100644
--- a/drivers/cpufreq/loongson3_cpufreq.c
+++ b/drivers/cpufreq/loongson3_cpufreq.c
@@ -10,6 +10,7 @@
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/loongson/iocsr.h>
 #include <linux/platform_device.h>
 #include <linux/units.h>
 
@@ -182,7 +183,7 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext
 
 	mutex_lock(&cpufreq_mutex[package]);
 
-	last.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
+	last.value = iocsr_read32(LOONGSON_IOCSR_SMCMBX);
 	if (!last.complete) {
 		mutex_unlock(&cpufreq_mutex[package]);
 		return -EPERM;
@@ -195,12 +196,12 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext
 	msg.extra	= extra;
 	msg.complete	= 0;
 
-	iocsr_write32(msg.value, LOONGARCH_IOCSR_SMCMBX);
-	iocsr_write32(iocsr_read32(LOONGARCH_IOCSR_MISC_FUNC) | IOCSR_MISC_FUNC_SOFT_INT,
-		      LOONGARCH_IOCSR_MISC_FUNC);
+	iocsr_write32(msg.value, LOONGSON_IOCSR_SMCMBX);
+	iocsr_write32(iocsr_read32(LOONGSON_IOCSR_MISC_FUNC) | IOCSR_MISC_FUNC_SOFT_INT,
+		      LOONGSON_IOCSR_MISC_FUNC);
 
 	for (retries = 0; retries < 10000; retries++) {
-		msg.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
+		msg.value = iocsr_read32(LOONGSON_IOCSR_SMCMBX);
 		if (msg.complete)
 			break;
 
diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c
index 0f6e465dd309..2452c6cc0aa1 100644
--- a/drivers/irqchip/irq-loongarch-avec.c
+++ b/drivers/irqchip/irq-loongarch-avec.c
@@ -10,6 +10,7 @@
 #include <linux/irqchip.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
+#include <linux/loongson/iocsr.h>
 #include <linux/kernel.h>
 #include <linux/msi.h>
 #include <linux/radix-tree.h>
@@ -378,9 +379,9 @@ static int __init avecintc_init(struct irq_domain *parent)
 				  "irqchip/loongarch/avecintc:starting",
 				  avecintc_cpu_online, avecintc_cpu_offline);
 #endif
-	value = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
+	value = iocsr_read64(LOONGSON_IOCSR_MISC_FUNC);
 	value |= IOCSR_MISC_FUNC_AVEC_EN;
-	iocsr_write64(value, LOONGARCH_IOCSR_MISC_FUNC);
+	iocsr_write64(value, LOONGSON_IOCSR_MISC_FUNC);
 
 	return ret;
 
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
index e24db71a8783..6e81bf27914f 100644
--- a/drivers/irqchip/irq-loongson-eiointc.c
+++ b/drivers/irqchip/irq-loongson-eiointc.c
@@ -13,6 +13,7 @@
 #include <linux/irqchip.h>
 #include <linux/irqdomain.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/loongson/iocsr.h>
 #include <linux/kernel.h>
 #include <linux/syscore_ops.h>
 #include <asm/numa.h>
@@ -52,9 +53,9 @@ static void eiointc_enable(void)
 {
 	uint64_t misc;
 
-	misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
+	misc = iocsr_read64(LOONGSON_IOCSR_MISC_FUNC);
 	misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
-	iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
+	iocsr_write64(misc, LOONGSON_IOCSR_MISC_FUNC);
 }
 
 static int cpu_to_eio_node(int cpu)
diff --git a/include/linux/loongson/iocsr.h b/include/linux/loongson/iocsr.h
new file mode 100644
index 000000000000..6654a904bcbe
--- /dev/null
+++ b/include/linux/loongson/iocsr.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
+ * Copyright (C) 2024, Jiaxun Yang <jiaxun.yang@flygoat.com>
+ */
+
+#ifndef _LOONGSON_IOCSR_H
+#define _LOONGSON_IOCSR_H
+
+#include <linux/bits.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_LOONGARCH
+#include <asm/loongarch.h>
+#endif
+
+#define LOONGSON_IOCSR_FEATURES	0x8
+#define  IOCSRF_TEMP			BIT_ULL(0)
+#define  IOCSRF_NODECNT			BIT_ULL(1)
+#define  IOCSRF_MSI			BIT_ULL(2)
+#define  IOCSRF_EXTIOI			BIT_ULL(3)
+#define  IOCSRF_CSRIPI			BIT_ULL(4)
+#define  IOCSRF_FREQCSR			BIT_ULL(5)
+#define  IOCSRF_FREQSCALE		BIT_ULL(6)
+#define  IOCSRF_DVFSV1			BIT_ULL(7)
+#define  IOCSRF_EIODECODE		BIT_ULL(9)
+#define  IOCSRF_FLATMODE		BIT_ULL(10)
+#define  IOCSRF_VM			BIT_ULL(11)
+#define  IOCSRF_AVEC			BIT_ULL(15)
+
+#define LOONGSON_IOCSR_VENDOR		0x10
+
+#define LOONGSON_IOCSR_CPUNAME		0x20
+
+#define LOONGSON_IOCSR_NODECNT		0x408
+
+#define LOONGSON_IOCSR_MISC_FUNC	0x420
+#define  IOCSR_MISC_FUNC_SOFT_INT	BIT_ULL(10)
+#define  IOCSR_MISC_FUNC_TIMER_RESET	BIT_ULL(21)
+#define  IOCSR_MISC_FUNC_EXT_IOI_EN	BIT_ULL(48)
+#define  IOCSR_MISC_FUNC_AVEC_EN	BIT_ULL(51)
+
+#define LOONGSON_IOCSR_CPUTEMP		0x428
+
+#define LOONGSON_IOCSR_SMCMBX		0x51c
+
+/* PerCore CSR, only accessible by local cores */
+#define LOONGSON_IOCSR_IPI_STATUS	0x1000
+#define LOONGSON_IOCSR_IPI_EN		0x1004
+#define LOONGSON_IOCSR_IPI_SET		0x1008
+#define LOONGSON_IOCSR_IPI_CLEAR	0x100c
+#define LOONGSON_IOCSR_MBUF0		0x1020
+#define LOONGSON_IOCSR_MBUF1		0x1028
+#define LOONGSON_IOCSR_MBUF2		0x1030
+#define LOONGSON_IOCSR_MBUF3		0x1038
+
+#define LOONGSON_IOCSR_IPI_SEND	0x1040
+#define  IOCSR_IPI_SEND_IP_SHIFT	0
+#define  IOCSR_IPI_SEND_CPU_SHIFT	16
+#define  IOCSR_IPI_SEND_BLOCKING	BIT(31)
+
+#define LOONGSON_IOCSR_MBUF_SEND	0x1048
+#define  IOCSR_MBUF_SEND_BLOCKING	BIT_ULL(31)
+#define  IOCSR_MBUF_SEND_BOX_SHIFT	2
+#define  IOCSR_MBUF_SEND_BOX_LO(box)	(box << 1)
+#define  IOCSR_MBUF_SEND_BOX_HI(box)	((box << 1) + 1)
+#define  IOCSR_MBUF_SEND_CPU_SHIFT	16
+#define  IOCSR_MBUF_SEND_BUF_SHIFT	32
+#define  IOCSR_MBUF_SEND_H32_MASK	0xFFFFFFFF00000000ULL
+
+#define LOONGSON_IOCSR_ANY_SEND	0x1158
+#define  IOCSR_ANY_SEND_BLOCKING	BIT_ULL(31)
+#define  IOCSR_ANY_SEND_CPU_SHIFT	16
+#define  IOCSR_ANY_SEND_MASK_SHIFT	27
+#define  IOCSR_ANY_SEND_BUF_SHIFT	32
+#define  IOCSR_ANY_SEND_H32_MASK	0xFFFFFFFF00000000ULL
+
+/* Register offset and bit definition for CSR access */
+#define LOONGSON_IOCSR_TIMER_CFG       0x1060
+#define LOONGSON_IOCSR_TIMER_TICK      0x1070
+#define  IOCSR_TIMER_CFG_RESERVED       (_ULCAST_(1) << 63)
+#define  IOCSR_TIMER_CFG_PERIODIC       (_ULCAST_(1) << 62)
+#define  IOCSR_TIMER_CFG_EN             (_ULCAST_(1) << 61)
+#define  IOCSR_TIMER_MASK		0x0ffffffffffffULL
+#define  IOCSR_TIMER_INITVAL_RST        (_ULCAST_(0xffff) << 48)
+
+#define LOONGSON_IOCSR_EXTIOI_NODEMAP_BASE	0x14a0
+#define LOONGSON_IOCSR_EXTIOI_IPMAP_BASE	0x14c0
+#define LOONGSON_IOCSR_EXTIOI_EN_BASE		0x1600
+#define LOONGSON_IOCSR_EXTIOI_BOUNCE_BASE	0x1680
+#define LOONGSON_IOCSR_EXTIOI_ISR_BASE		0x1800
+#define LOONGSON_IOCSR_EXTIOI_ROUTE_BASE	0x1c00
+#define IOCSR_EXTIOI_VECTOR_NUM			256
+
+#ifndef __ASSEMBLY__
+static inline void csr_any_send(unsigned int addr, unsigned int data,
+				unsigned int data_mask, unsigned int cpu)
+{
+	uint64_t val = 0;
+
+	val = IOCSR_ANY_SEND_BLOCKING | addr;
+	val |= (cpu << IOCSR_ANY_SEND_CPU_SHIFT);
+	val |= (data_mask << IOCSR_ANY_SEND_MASK_SHIFT);
+	val |= ((uint64_t)data << IOCSR_ANY_SEND_BUF_SHIFT);
+	iocsr_write64(val, LOONGSON_IOCSR_ANY_SEND);
+}
+#endif
+
+#endif
+

-- 
2.46.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/4] MIPS: Loongson64: Use shared IOCSR header
  2024-09-12 20:55 [PATCH v2 0/4] LoongArch, MIPS: Unify Loongson IOCSR handling Jiaxun Yang
                   ` (2 preceding siblings ...)
  2024-09-12 20:55 ` [PATCH v2 3/4] LoongArch: Extract IOCSR definitions to standalone header Jiaxun Yang
@ 2024-09-12 20:55 ` Jiaxun Yang
  3 siblings, 0 replies; 9+ messages in thread
From: Jiaxun Yang @ 2024-09-12 20:55 UTC (permalink / raw)
  To: Huacai Chen, WANG Xuerui, Rafael J. Wysocki, Viresh Kumar,
	Thomas Gleixner, Thomas Bogendoerfer
  Cc: loongarch, linux-kernel, linux-pm, linux-mips, kvm, Jiaxun Yang

MIPS and LoongArch Loongson CPUs are sharing definition of
IOCSR registers, so it makes sense to use the same header
as well.

Align function names in loongson_regs.h with it's loongarch
equivalent and fix up macro names everywhere.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 .../include/asm/mach-loongson64/loongson_regs.h    | 58 ++++++----------------
 arch/mips/kvm/vz.c                                 |  2 +-
 arch/mips/loongson64/smp.c                         | 44 ++++++++--------
 drivers/platform/mips/cpu_hwmon.c                  |  7 ++-
 include/linux/loongson/iocsr.h                     |  5 +-
 5 files changed, 46 insertions(+), 70 deletions(-)

diff --git a/arch/mips/include/asm/mach-loongson64/loongson_regs.h b/arch/mips/include/asm/mach-loongson64/loongson_regs.h
index fec767507604..d8af16796dbe 100644
--- a/arch/mips/include/asm/mach-loongson64/loongson_regs.h
+++ b/arch/mips/include/asm/mach-loongson64/loongson_regs.h
@@ -5,12 +5,13 @@
 #ifndef _LOONGSON_REGS_H_
 #define _LOONGSON_REGS_H_
 
-#include <linux/types.h>
 #include <linux/bits.h>
+#include <linux/types.h>
 
 #include <asm/mipsregs.h>
 #include <asm/cpu.h>
 
+#ifndef __ASSEMBLY__
 static inline bool cpu_has_cfg(void)
 {
 	return ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G);
@@ -33,6 +34,7 @@ static inline u32 read_cpucfg(u32 reg)
 		);
 	return __res;
 }
+#endif
 
 /* Bit Domains for CFG registers */
 #define LOONGSON_CFG0	0x0
@@ -131,6 +133,7 @@ static inline u32 read_cpucfg(u32 reg)
 #define LOONGSON_CFG7_GCCAEQRP	BIT(0)
 #define LOONGSON_CFG7_UCAWINP	BIT(1)
 
+#ifndef __ASSEMBLY__
 static inline bool cpu_has_csr(void)
 {
 	if (cpu_has_cfg())
@@ -139,7 +142,10 @@ static inline bool cpu_has_csr(void)
 	return false;
 }
 
-static inline u32 csr_readl(u32 reg)
+#define cpu_has_iocsr()	cpu_has_csr()
+
+/* For MIPS/Loongson IOCSR and Core CSR are accessed same way */
+static inline u32 csr_read32(u32 reg)
 {
 	u32 __res;
 
@@ -158,7 +164,7 @@ static inline u32 csr_readl(u32 reg)
 	return __res;
 }
 
-static inline u64 csr_readq(u32 reg)
+static inline u64 csr_read64(u32 reg)
 {
 	u64 __res;
 
@@ -177,7 +183,7 @@ static inline u64 csr_readq(u32 reg)
 	return __res;
 }
 
-static inline void csr_writel(u32 val, u32 reg)
+static inline void csr_write32(u32 val, u32 reg)
 {
 	/* WRCSR reg, val */
 	__asm__ __volatile__(
@@ -193,7 +199,7 @@ static inline void csr_writel(u32 val, u32 reg)
 		);
 }
 
-static inline void csr_writeq(u64 val, u32 reg)
+static inline void csr_write64(u64 val, u32 reg)
 {
 	/* DWRCSR reg, val */
 	__asm__ __volatile__(
@@ -209,43 +215,10 @@ static inline void csr_writeq(u64 val, u32 reg)
 		);
 }
 
-/* Public CSR Register can also be accessed with regular addresses */
-#define CSR_PUBLIC_MMIO_BASE 0x1fe00000
-
-#define MMIO_CSR(x)		(void *)TO_UNCAC(CSR_PUBLIC_MMIO_BASE + x)
-
-#define LOONGSON_CSR_FEATURES	0x8
-#define LOONGSON_CSRF_TEMP	BIT(0)
-#define LOONGSON_CSRF_NODECNT	BIT(1)
-#define LOONGSON_CSRF_MSI	BIT(2)
-#define LOONGSON_CSRF_EXTIOI	BIT(3)
-#define LOONGSON_CSRF_IPI	BIT(4)
-#define LOONGSON_CSRF_FREQ	BIT(5)
-
-#define LOONGSON_CSR_VENDOR	0x10 /* Vendor name string, should be "Loongson" */
-#define LOONGSON_CSR_CPUNAME	0x20 /* Processor name string */
-#define LOONGSON_CSR_NODECNT	0x408
-#define LOONGSON_CSR_CPUTEMP	0x428
-
-/* PerCore CSR, only accessible by local cores */
-#define LOONGSON_CSR_IPI_STATUS	0x1000
-#define LOONGSON_CSR_IPI_EN	0x1004
-#define LOONGSON_CSR_IPI_SET	0x1008
-#define LOONGSON_CSR_IPI_CLEAR	0x100c
-#define LOONGSON_CSR_IPI_SEND	0x1040
-#define CSR_IPI_SEND_IP_SHIFT	0
-#define CSR_IPI_SEND_CPU_SHIFT	16
-#define CSR_IPI_SEND_BLOCK	BIT(31)
-
-#define LOONGSON_CSR_MAIL_BUF0		0x1020
-#define LOONGSON_CSR_MAIL_SEND		0x1048
-#define CSR_MAIL_SEND_BLOCK		BIT_ULL(31)
-#define CSR_MAIL_SEND_BOX_LOW(box)	(box << 1)
-#define CSR_MAIL_SEND_BOX_HIGH(box)	((box << 1) + 1)
-#define CSR_MAIL_SEND_BOX_SHIFT		2
-#define CSR_MAIL_SEND_CPU_SHIFT		16
-#define CSR_MAIL_SEND_BUF_SHIFT		32
-#define CSR_MAIL_SEND_H32_MASK		0xFFFFFFFF00000000ULL
+#define iocsr_read32(reg)	csr_read32(reg)
+#define iocsr_read64(reg)	csr_read64(reg)
+#define iocsr_write32(val, reg)	csr_write32(val, reg)
+#define iocsr_write64(val, reg)	csr_write64(val, reg)
 
 static inline u64 drdtime(void)
 {
@@ -264,5 +237,6 @@ static inline u64 drdtime(void)
 		);
 	return val;
 }
+#endif
 
 #endif
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index 99d5a71e4300..4964c1922b23 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -2977,7 +2977,7 @@ static int kvm_vz_hardware_enable(void)
 #ifdef CONFIG_CPU_LOONGSON64
 	/* Control guest CCA attribute */
 	if (cpu_has_csr())
-		csr_writel(csr_readl(0xffffffec) | 0x1, 0xffffffec);
+		csr_write32(csr_read32(0xffffffec) | 0x1, 0xffffffec);
 #endif
 
 	return 0;
diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c
index 147acd972a07..0cf03377edf0 100644
--- a/arch/mips/loongson64/smp.c
+++ b/arch/mips/loongson64/smp.c
@@ -7,6 +7,7 @@
 #include <irq.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
+#include <linux/loongson/iocsr.h>
 #include <linux/sched.h>
 #include <linux/sched/hotplug.h>
 #include <linux/sched/task_stack.h>
@@ -19,7 +20,6 @@
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 #include <loongson.h>
-#include <loongson_regs.h>
 #include <workarounds.h>
 
 #include "smp.h"
@@ -45,19 +45,19 @@ static void csr_mail_send(uint64_t data, int cpu, int mailbox)
 {
 	uint64_t val;
 
-	/* send high 32 bits */
-	val = CSR_MAIL_SEND_BLOCK;
-	val |= (CSR_MAIL_SEND_BOX_HIGH(mailbox) << CSR_MAIL_SEND_BOX_SHIFT);
-	val |= (cpu << CSR_MAIL_SEND_CPU_SHIFT);
-	val |= (data & CSR_MAIL_SEND_H32_MASK);
-	csr_writeq(val, LOONGSON_CSR_MAIL_SEND);
-
-	/* send low 32 bits */
-	val = CSR_MAIL_SEND_BLOCK;
-	val |= (CSR_MAIL_SEND_BOX_LOW(mailbox) << CSR_MAIL_SEND_BOX_SHIFT);
-	val |= (cpu << CSR_MAIL_SEND_CPU_SHIFT);
-	val |= (data << CSR_MAIL_SEND_BUF_SHIFT);
-	csr_writeq(val, LOONGSON_CSR_MAIL_SEND);
+	/* Send high 32 bits */
+	val = IOCSR_MBUF_SEND_BLOCKING;
+	val |= (IOCSR_MBUF_SEND_BOX_HI(mailbox) << IOCSR_MBUF_SEND_BOX_SHIFT);
+	val |= (cpu << IOCSR_MBUF_SEND_CPU_SHIFT);
+	val |= (data & IOCSR_MBUF_SEND_H32_MASK);
+	iocsr_write64(val, LOONGSON_IOCSR_MBUF_SEND);
+
+	/* Send low 32 bits */
+	val = IOCSR_MBUF_SEND_BLOCKING;
+	val |= (IOCSR_MBUF_SEND_BOX_LO(mailbox) << IOCSR_MBUF_SEND_BOX_SHIFT);
+	val |= (cpu << IOCSR_MBUF_SEND_CPU_SHIFT);
+	val |= (data << IOCSR_MBUF_SEND_BUF_SHIFT);
+	iocsr_write64(val, LOONGSON_IOCSR_MBUF_SEND);
 };
 
 static u32 csr_ipi_read_clear(int cpu)
@@ -65,9 +65,9 @@ static u32 csr_ipi_read_clear(int cpu)
 	u32 action;
 
 	/* Load the ipi register to figure out what we're supposed to do */
-	action = csr_readl(LOONGSON_CSR_IPI_STATUS);
+	action = iocsr_read32(LOONGSON_IOCSR_IPI_STATUS);
 	/* Clear the ipi register to clear the interrupt */
-	csr_writel(action, LOONGSON_CSR_IPI_CLEAR);
+	iocsr_write32(action, LOONGSON_IOCSR_IPI_CLEAR);
 
 	return action;
 }
@@ -77,22 +77,22 @@ static void csr_ipi_write_action(int cpu, u32 action)
 	unsigned int irq = 0;
 
 	while ((irq = ffs(action))) {
-		uint32_t val = CSR_IPI_SEND_BLOCK;
+		uint32_t val = IOCSR_IPI_SEND_BLOCKING;
 		val |= (irq - 1);
-		val |= (cpu << CSR_IPI_SEND_CPU_SHIFT);
-		csr_writel(val, LOONGSON_CSR_IPI_SEND);
+		val |= (cpu << IOCSR_IPI_SEND_CPU_SHIFT);
+		iocsr_write32(val, LOONGSON_IOCSR_IPI_SEND);
 		action &= ~BIT(irq - 1);
 	}
 }
 
 static void csr_ipi_write_enable(int cpu)
 {
-	csr_writel(0xffffffff, LOONGSON_CSR_IPI_EN);
+	iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_EN);
 }
 
 static void csr_ipi_clear_buf(int cpu)
 {
-	csr_writeq(0, LOONGSON_CSR_MAIL_BUF0);
+	iocsr_write64(0, LOONGSON_IOCSR_MBUF0);
 }
 
 static void csr_ipi_write_buf(int cpu, struct task_struct *idle)
@@ -169,7 +169,7 @@ static void legacy_ipi_write_buf(int cpu, struct task_struct *idle)
 
 static void csr_ipi_probe(void)
 {
-	if (cpu_has_csr() && csr_readl(LOONGSON_CSR_FEATURES) & LOONGSON_CSRF_IPI) {
+	if (cpu_has_iocsr() && iocsr_read32(LOONGSON_IOCSR_FEATURES) & IOCSRF_CSRIPI) {
 		ipi_read_clear = csr_ipi_read_clear;
 		ipi_write_action = csr_ipi_write_action;
 		ipi_write_enable = csr_ipi_write_enable;
diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c
index 2ac2f31090f9..9b0b39a39d13 100644
--- a/drivers/platform/mips/cpu_hwmon.c
+++ b/drivers/platform/mips/cpu_hwmon.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/err.h>
+#include <linux/loongson/iocsr.h>
 #include <linux/module.h>
 #include <linux/reboot.h>
 #include <linux/jiffies.h>
@@ -9,7 +10,6 @@
 #include <loongson.h>
 #include <boot_param.h>
 #include <loongson_hwmon.h>
-#include <loongson_regs.h>
 
 static int csr_temp_enable;
 
@@ -24,7 +24,7 @@ int loongson3_cpu_temp(int cpu)
 	u32 reg, prid_rev;
 
 	if (csr_temp_enable) {
-		reg = (csr_readl(LOONGSON_CSR_CPUTEMP) & 0xff);
+		reg = (iocsr_read32(LOONGSON_IOCSR_CPUTEMP) & 0xff);
 		goto out;
 	}
 
@@ -136,8 +136,7 @@ static int __init loongson_hwmon_init(void)
 	pr_info("Loongson Hwmon Enter...\n");
 
 	if (cpu_has_csr())
-		csr_temp_enable = csr_readl(LOONGSON_CSR_FEATURES) &
-				  LOONGSON_CSRF_TEMP;
+		csr_temp_enable = iocsr_read32(LOONGSON_IOCSR_FEATURES) & IOCSRF_TEMP;
 
 	if (!csr_temp_enable && !loongson_chiptemp[0])
 		return -ENODEV;
diff --git a/include/linux/loongson/iocsr.h b/include/linux/loongson/iocsr.h
index 6654a904bcbe..15e70e6e132e 100644
--- a/include/linux/loongson/iocsr.h
+++ b/include/linux/loongson/iocsr.h
@@ -10,9 +10,12 @@
 #include <linux/bits.h>
 #include <linux/types.h>
 
-#ifdef CONFIG_LOONGARCH
+#if defined(CONFIG_LOONGARCH)
 #include <asm/loongarch.h>
 #endif
+#if defined(CONFIG_MIPS) && defined(CONFIG_MACH_LOONGSON64)
+#include <loongson_regs.h>
+#endif
 
 #define LOONGSON_IOCSR_FEATURES	0x8
 #define  IOCSRF_TEMP			BIT_ULL(0)

-- 
2.46.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/4] LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common
  2024-09-12 20:55 ` [PATCH v2 2/4] LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common Jiaxun Yang
@ 2024-09-12 20:59   ` Jiaxun Yang
  2024-09-13  8:48     ` Huacai Chen
  0 siblings, 1 reply; 9+ messages in thread
From: Jiaxun Yang @ 2024-09-12 20:59 UTC (permalink / raw)
  To: Huacai Chen, Xuerui Wang, Rafael J. Wysocki, Viresh Kumar,
	Thomas Gleixner, Thomas Bogendoerfer
  Cc: loongarch, linux-kernel, linux-pm, linux-mips@vger.kernel.org,
	kvm



在2024年9月12日九月 下午9:55,Jiaxun Yang写道:
[...]
> +
> +	if (c->options & LOONGARCH_CPU_IOCSR)
> +		return;
Oops, typo here, there should be a not :-(

Huacai, if the series is ok for you please fix this when applying
the patch. I only tested against NEMU so didn't catch this :-(

Thanks
- Jiaxun

> +
> +	*vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
> +	*cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
> +
> +	if (!__cpu_full_name[cpu])
> +		__cpu_full_name[cpu] = cpu_full_name;
> +
> +	config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
> +	if (config & IOCSRF_CSRIPI)
> +		c->options |= LOONGARCH_CPU_CSRIPI;
> +	if (config & IOCSRF_EXTIOI)
> +		c->options |= LOONGARCH_CPU_EXTIOI;
> +	if (config & IOCSRF_FREQSCALE)
> +		c->options |= LOONGARCH_CPU_SCALEFREQ;
> +	if (config & IOCSRF_FLATMODE)
> +		c->options |= LOONGARCH_CPU_FLATMODE;
> +	if (config & IOCSRF_EIODECODE)
> +		c->options |= LOONGARCH_CPU_EIODECODE;
> +	if (config & IOCSRF_AVEC)
> +		c->options |= LOONGARCH_CPU_AVECINT;
> +	if (config & IOCSRF_VM)
> +		c->options |= LOONGARCH_CPU_HYPERVISOR;
>  }
> 
>  #ifdef CONFIG_64BIT
>
> -- 
> 2.46.0

-- 
- Jiaxun

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG
  2024-09-12 20:55 ` [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG Jiaxun Yang
@ 2024-09-13  8:46   ` Huacai Chen
  2024-09-13  9:10     ` Jiaxun Yang
  0 siblings, 1 reply; 9+ messages in thread
From: Huacai Chen @ 2024-09-13  8:46 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: WANG Xuerui, Rafael J. Wysocki, Viresh Kumar, Thomas Gleixner,
	Thomas Bogendoerfer, loongarch, linux-kernel, linux-pm,
	linux-mips, kvm

Hi, Jiaxun,

On Fri, Sep 13, 2024 at 4:56 AM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>
> Probe ISA level, TLB, IOCSR information from CPUCFG to
> improve kernel resilience to different core implementations.
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
>  arch/loongarch/include/asm/cpu.h       |  4 +++
>  arch/loongarch/include/asm/loongarch.h |  3 +-
>  arch/loongarch/kernel/cpu-probe.c      | 54 ++++++++++++++++++++++++----------
>  3 files changed, 44 insertions(+), 17 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h
> index 843f9c4ec980..251a15439cff 100644
> --- a/arch/loongarch/include/asm/cpu.h
> +++ b/arch/loongarch/include/asm/cpu.h
> @@ -100,6 +100,8 @@ enum cpu_type_enum {
>  #define CPU_FEATURE_HYPERVISOR         25      /* CPU has hypervisor (running in VM) */
>  #define CPU_FEATURE_PTW                        26      /* CPU has hardware page table walker */
>  #define CPU_FEATURE_AVECINT            27      /* CPU has avec interrupt */
> +#define CPU_FEATURE_IOCSR              28      /* CPU has IOCSR */
> +#define CPU_FEATURE_LSPW               29      /* CPU has LSPW */
I don't see LSPW being used, so just remove it now?

>
>  #define LOONGARCH_CPU_CPUCFG           BIT_ULL(CPU_FEATURE_CPUCFG)
>  #define LOONGARCH_CPU_LAM              BIT_ULL(CPU_FEATURE_LAM)
> @@ -129,5 +131,7 @@ enum cpu_type_enum {
>  #define LOONGARCH_CPU_HYPERVISOR       BIT_ULL(CPU_FEATURE_HYPERVISOR)
>  #define LOONGARCH_CPU_PTW              BIT_ULL(CPU_FEATURE_PTW)
>  #define LOONGARCH_CPU_AVECINT          BIT_ULL(CPU_FEATURE_AVECINT)
> +#define LOONGARCH_CPU_IOCSR            BIT_ULL(CPU_FEATURE_IOCSR)
> +#define LOONGARCH_CPU_LSPW             BIT_ULL(CPU_FEATURE_LSPW)
>
>  #endif /* _ASM_CPU_H */
> diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
> index 631d249b3ef2..23af28f00c3c 100644
> --- a/arch/loongarch/include/asm/loongarch.h
> +++ b/arch/loongarch/include/asm/loongarch.h
> @@ -60,8 +60,7 @@
>  #define  CPUCFG0_PRID                  GENMASK(31, 0)
>
>  #define LOONGARCH_CPUCFG1              0x1
> -#define  CPUCFG1_ISGR32                        BIT(0)
> -#define  CPUCFG1_ISGR64                        BIT(1)
> +#define  CPUCFG1_ISA                   GENMASK(1, 0)
>  #define  CPUCFG1_PAGING                        BIT(2)
>  #define  CPUCFG1_IOCSR                 BIT(3)
>  #define  CPUCFG1_PABITS                        GENMASK(11, 4)
> diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
> index 14f0449f5452..5dc8ca3c4387 100644
> --- a/arch/loongarch/kernel/cpu-probe.c
> +++ b/arch/loongarch/kernel/cpu-probe.c
> @@ -92,11 +92,29 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
>         unsigned long asid_mask;
>
>         c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
> -                    LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
> +                    LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
>
>         elf_hwcap = HWCAP_LOONGARCH_CPUCFG;
>
>         config = read_cpucfg(LOONGARCH_CPUCFG1);
> +
> +       switch (config & CPUCFG1_ISA) {
> +       case 0:
> +               set_isa(c, LOONGARCH_CPU_ISA_LA32R);
> +               break;
> +       case 1:
> +               set_isa(c, LOONGARCH_CPU_ISA_LA32S);
> +               break;
> +       case 2:
> +               set_isa(c, LOONGARCH_CPU_ISA_LA64);
> +               break;
> +       default:
> +               pr_warn("Warning: unknown ISA level\n");
> +       }
> +       if (config & CPUCFG1_PAGING)
> +               c->options |= LOONGARCH_CPU_TLB;
> +       if (config & CPUCFG1_IOCSR)
> +               c->options |= LOONGARCH_CPU_IOCSR;
>         if (config & CPUCFG1_UAL) {
>                 c->options |= LOONGARCH_CPU_UAL;
>                 elf_hwcap |= HWCAP_LOONGARCH_UAL;
> @@ -157,6 +175,8 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
>                 elf_hwcap |= HWCAP_LOONGARCH_LBT_MIPS;
>         }
>  #endif
> +       if (config & CPUCFG2_LSPW)
> +               c->options |= LOONGARCH_CPU_LSPW;
>
>         config = read_cpucfg(LOONGARCH_CPUCFG6);
>         if (config & CPUCFG6_PMP)
> @@ -222,6 +242,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
>  {
>         uint64_t *vendor = (void *)(&cpu_full_name[VENDOR_OFFSET]);
>         uint64_t *cpuname = (void *)(&cpu_full_name[CPUNAME_OFFSET]);
> +       const char *core_name = "Unknown";
>
>         if (!__cpu_full_name[cpu])
>                 __cpu_full_name[cpu] = cpu_full_name;
> @@ -232,40 +253,43 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
>         switch (c->processor_id & PRID_SERIES_MASK) {
>         case PRID_SERIES_LA132:
>                 c->cputype = CPU_LOONGSON32;
> -               set_isa(c, LOONGARCH_CPU_ISA_LA32S);
>                 __cpu_family[cpu] = "Loongson-32bit";
> -               pr_info("32-bit Loongson Processor probed (LA132 Core)\n");
> +               core_name = "LA132";
>                 break;
>         case PRID_SERIES_LA264:
>                 c->cputype = CPU_LOONGSON64;
> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>                 __cpu_family[cpu] = "Loongson-64bit";
> -               pr_info("64-bit Loongson Processor probed (LA264 Core)\n");
> +               core_name = "LA264";
>                 break;
>         case PRID_SERIES_LA364:
>                 c->cputype = CPU_LOONGSON64;
> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>                 __cpu_family[cpu] = "Loongson-64bit";
> -               pr_info("64-bit Loongson Processor probed (LA364 Core)\n");
> +               core_name = "LA364";
>                 break;
>         case PRID_SERIES_LA464:
>                 c->cputype = CPU_LOONGSON64;
> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>                 __cpu_family[cpu] = "Loongson-64bit";
> -               pr_info("64-bit Loongson Processor probed (LA464 Core)\n");
> +               core_name = "LA464";
>                 break;
>         case PRID_SERIES_LA664:
>                 c->cputype = CPU_LOONGSON64;
> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>                 __cpu_family[cpu] = "Loongson-64bit";
> -               pr_info("64-bit Loongson Processor probed (LA664 Core)\n");
> +               core_name = "LA664";
>                 break;
>         default: /* Default to 64 bit */
> -               c->cputype = CPU_LOONGSON64;
> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
> -               __cpu_family[cpu] = "Loongson-64bit";
> -               pr_info("64-bit Loongson Processor probed (Unknown Core)\n");
> +               if (c->isa_level & LOONGARCH_CPU_ISA_LA64) {
> +                       c->cputype = CPU_LOONGSON64;
> +                       __cpu_family[cpu] = "Loongson-64bit";
> +               } else if (c->isa_level & LOONGARCH_CPU_ISA_LA32S) {
> +                       c->cputype = CPU_LOONGSON32;
> +                       __cpu_family[cpu] = "Loongson-32bit";
> +               } else if (c->isa_level & LOONGARCH_CPU_ISA_LA32R) {
> +                       c->cputype = CPU_LOONGSON32;
> +                       __cpu_family[cpu] = "Loongson-32bit Reduced";
> +               }
I prefer to move this part before the switch-case of PRID (and it is
better to convert to a switch-case too), then the switch-case of PRID
can be only used for probing core-name.

Huacai

>         }
> +
> +       pr_info("%s Processor probed (%s Core)\n", __cpu_family[cpu], core_name);
>  }
>
>  #ifdef CONFIG_64BIT
>
> --
> 2.46.0
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/4] LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common
  2024-09-12 20:59   ` Jiaxun Yang
@ 2024-09-13  8:48     ` Huacai Chen
  0 siblings, 0 replies; 9+ messages in thread
From: Huacai Chen @ 2024-09-13  8:48 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: Xuerui Wang, Rafael J. Wysocki, Viresh Kumar, Thomas Gleixner,
	Thomas Bogendoerfer, loongarch, linux-kernel, linux-pm,
	linux-mips@vger.kernel.org, kvm

Hi, Jiaxun,

On Fri, Sep 13, 2024 at 4:59 AM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>
>
>
> 在2024年9月12日九月 下午9:55,Jiaxun Yang写道:
> [...]
> > +
> > +     if (c->options & LOONGARCH_CPU_IOCSR)
> > +             return;
> Oops, typo here, there should be a not :-(
>
> Huacai, if the series is ok for you please fix this when applying
> the patch. I only tested against NEMU so didn't catch this :-(
Since the first patch can also be improved, you can improve this one
by yourself. And from my point of view the two patches can be combined
to one.

Huacai

>
> Thanks
> - Jiaxun
>
> > +
> > +     *vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
> > +     *cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
> > +
> > +     if (!__cpu_full_name[cpu])
> > +             __cpu_full_name[cpu] = cpu_full_name;
> > +
> > +     config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
> > +     if (config & IOCSRF_CSRIPI)
> > +             c->options |= LOONGARCH_CPU_CSRIPI;
> > +     if (config & IOCSRF_EXTIOI)
> > +             c->options |= LOONGARCH_CPU_EXTIOI;
> > +     if (config & IOCSRF_FREQSCALE)
> > +             c->options |= LOONGARCH_CPU_SCALEFREQ;
> > +     if (config & IOCSRF_FLATMODE)
> > +             c->options |= LOONGARCH_CPU_FLATMODE;
> > +     if (config & IOCSRF_EIODECODE)
> > +             c->options |= LOONGARCH_CPU_EIODECODE;
> > +     if (config & IOCSRF_AVEC)
> > +             c->options |= LOONGARCH_CPU_AVECINT;
> > +     if (config & IOCSRF_VM)
> > +             c->options |= LOONGARCH_CPU_HYPERVISOR;
> >  }
> >
> >  #ifdef CONFIG_64BIT
> >
> > --
> > 2.46.0
>
> --
> - Jiaxun

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG
  2024-09-13  8:46   ` Huacai Chen
@ 2024-09-13  9:10     ` Jiaxun Yang
  0 siblings, 0 replies; 9+ messages in thread
From: Jiaxun Yang @ 2024-09-13  9:10 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Xuerui Wang, Rafael J. Wysocki, Viresh Kumar, Thomas Gleixner,
	Thomas Bogendoerfer, loongarch, linux-kernel, linux-pm,
	linux-mips@vger.kernel.org, kvm



在2024年9月13日九月 上午9:46,Huacai Chen写道:
> Hi, Jiaxun,
>
> On Fri, Sep 13, 2024 at 4:56 AM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>>
>> Probe ISA level, TLB, IOCSR information from CPUCFG to
>> improve kernel resilience to different core implementations.
>>
>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> ---
>>  arch/loongarch/include/asm/cpu.h       |  4 +++
>>  arch/loongarch/include/asm/loongarch.h |  3 +-
>>  arch/loongarch/kernel/cpu-probe.c      | 54 ++++++++++++++++++++++++----------
>>  3 files changed, 44 insertions(+), 17 deletions(-)
>>
>> diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h
>> index 843f9c4ec980..251a15439cff 100644
>> --- a/arch/loongarch/include/asm/cpu.h
>> +++ b/arch/loongarch/include/asm/cpu.h
>> @@ -100,6 +100,8 @@ enum cpu_type_enum {
>>  #define CPU_FEATURE_HYPERVISOR         25      /* CPU has hypervisor (running in VM) */
>>  #define CPU_FEATURE_PTW                        26      /* CPU has hardware page table walker */
>>  #define CPU_FEATURE_AVECINT            27      /* CPU has avec interrupt */
>> +#define CPU_FEATURE_IOCSR              28      /* CPU has IOCSR */
>> +#define CPU_FEATURE_LSPW               29      /* CPU has LSPW */
> I don't see LSPW being used, so just remove it now?

I’m going to submit a page table walker for CPU without SPW later on :-)

I’m fine with adding that later.

Thanks
- Jiaxun

>
>>
>>  #define LOONGARCH_CPU_CPUCFG           BIT_ULL(CPU_FEATURE_CPUCFG)
>>  #define LOONGARCH_CPU_LAM              BIT_ULL(CPU_FEATURE_LAM)
>> @@ -129,5 +131,7 @@ enum cpu_type_enum {
>>  #define LOONGARCH_CPU_HYPERVISOR       BIT_ULL(CPU_FEATURE_HYPERVISOR)
>>  #define LOONGARCH_CPU_PTW              BIT_ULL(CPU_FEATURE_PTW)
>>  #define LOONGARCH_CPU_AVECINT          BIT_ULL(CPU_FEATURE_AVECINT)
>> +#define LOONGARCH_CPU_IOCSR            BIT_ULL(CPU_FEATURE_IOCSR)
>> +#define LOONGARCH_CPU_LSPW             BIT_ULL(CPU_FEATURE_LSPW)
>>
>>  #endif /* _ASM_CPU_H */
>> diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
>> index 631d249b3ef2..23af28f00c3c 100644
>> --- a/arch/loongarch/include/asm/loongarch.h
>> +++ b/arch/loongarch/include/asm/loongarch.h
>> @@ -60,8 +60,7 @@
>>  #define  CPUCFG0_PRID                  GENMASK(31, 0)
>>
>>  #define LOONGARCH_CPUCFG1              0x1
>> -#define  CPUCFG1_ISGR32                        BIT(0)
>> -#define  CPUCFG1_ISGR64                        BIT(1)
>> +#define  CPUCFG1_ISA                   GENMASK(1, 0)
>>  #define  CPUCFG1_PAGING                        BIT(2)
>>  #define  CPUCFG1_IOCSR                 BIT(3)
>>  #define  CPUCFG1_PABITS                        GENMASK(11, 4)
>> diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
>> index 14f0449f5452..5dc8ca3c4387 100644
>> --- a/arch/loongarch/kernel/cpu-probe.c
>> +++ b/arch/loongarch/kernel/cpu-probe.c
>> @@ -92,11 +92,29 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
>>         unsigned long asid_mask;
>>
>>         c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
>> -                    LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
>> +                    LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
>>
>>         elf_hwcap = HWCAP_LOONGARCH_CPUCFG;
>>
>>         config = read_cpucfg(LOONGARCH_CPUCFG1);
>> +
>> +       switch (config & CPUCFG1_ISA) {
>> +       case 0:
>> +               set_isa(c, LOONGARCH_CPU_ISA_LA32R);
>> +               break;
>> +       case 1:
>> +               set_isa(c, LOONGARCH_CPU_ISA_LA32S);
>> +               break;
>> +       case 2:
>> +               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>> +               break;
>> +       default:
>> +               pr_warn("Warning: unknown ISA level\n");
>> +       }
>> +       if (config & CPUCFG1_PAGING)
>> +               c->options |= LOONGARCH_CPU_TLB;
>> +       if (config & CPUCFG1_IOCSR)
>> +               c->options |= LOONGARCH_CPU_IOCSR;
>>         if (config & CPUCFG1_UAL) {
>>                 c->options |= LOONGARCH_CPU_UAL;
>>                 elf_hwcap |= HWCAP_LOONGARCH_UAL;
>> @@ -157,6 +175,8 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
>>                 elf_hwcap |= HWCAP_LOONGARCH_LBT_MIPS;
>>         }
>>  #endif
>> +       if (config & CPUCFG2_LSPW)
>> +               c->options |= LOONGARCH_CPU_LSPW;
>>
>>         config = read_cpucfg(LOONGARCH_CPUCFG6);
>>         if (config & CPUCFG6_PMP)
>> @@ -222,6 +242,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
>>  {
>>         uint64_t *vendor = (void *)(&cpu_full_name[VENDOR_OFFSET]);
>>         uint64_t *cpuname = (void *)(&cpu_full_name[CPUNAME_OFFSET]);
>> +       const char *core_name = "Unknown";
>>
>>         if (!__cpu_full_name[cpu])
>>                 __cpu_full_name[cpu] = cpu_full_name;
>> @@ -232,40 +253,43 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
>>         switch (c->processor_id & PRID_SERIES_MASK) {
>>         case PRID_SERIES_LA132:
>>                 c->cputype = CPU_LOONGSON32;
>> -               set_isa(c, LOONGARCH_CPU_ISA_LA32S);
>>                 __cpu_family[cpu] = "Loongson-32bit";
>> -               pr_info("32-bit Loongson Processor probed (LA132 Core)\n");
>> +               core_name = "LA132";
>>                 break;
>>         case PRID_SERIES_LA264:
>>                 c->cputype = CPU_LOONGSON64;
>> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>>                 __cpu_family[cpu] = "Loongson-64bit";
>> -               pr_info("64-bit Loongson Processor probed (LA264 Core)\n");
>> +               core_name = "LA264";
>>                 break;
>>         case PRID_SERIES_LA364:
>>                 c->cputype = CPU_LOONGSON64;
>> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>>                 __cpu_family[cpu] = "Loongson-64bit";
>> -               pr_info("64-bit Loongson Processor probed (LA364 Core)\n");
>> +               core_name = "LA364";
>>                 break;
>>         case PRID_SERIES_LA464:
>>                 c->cputype = CPU_LOONGSON64;
>> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>>                 __cpu_family[cpu] = "Loongson-64bit";
>> -               pr_info("64-bit Loongson Processor probed (LA464 Core)\n");
>> +               core_name = "LA464";
>>                 break;
>>         case PRID_SERIES_LA664:
>>                 c->cputype = CPU_LOONGSON64;
>> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>>                 __cpu_family[cpu] = "Loongson-64bit";
>> -               pr_info("64-bit Loongson Processor probed (LA664 Core)\n");
>> +               core_name = "LA664";
>>                 break;
>>         default: /* Default to 64 bit */
>> -               c->cputype = CPU_LOONGSON64;
>> -               set_isa(c, LOONGARCH_CPU_ISA_LA64);
>> -               __cpu_family[cpu] = "Loongson-64bit";
>> -               pr_info("64-bit Loongson Processor probed (Unknown Core)\n");
>> +               if (c->isa_level & LOONGARCH_CPU_ISA_LA64) {
>> +                       c->cputype = CPU_LOONGSON64;
>> +                       __cpu_family[cpu] = "Loongson-64bit";
>> +               } else if (c->isa_level & LOONGARCH_CPU_ISA_LA32S) {
>> +                       c->cputype = CPU_LOONGSON32;
>> +                       __cpu_family[cpu] = "Loongson-32bit";
>> +               } else if (c->isa_level & LOONGARCH_CPU_ISA_LA32R) {
>> +                       c->cputype = CPU_LOONGSON32;
>> +                       __cpu_family[cpu] = "Loongson-32bit Reduced";
>> +               }
> I prefer to move this part before the switch-case of PRID (and it is
> better to convert to a switch-case too), then the switch-case of PRID
> can be only used for probing core-name.
>
> Huacai
>
>>         }
>> +
>> +       pr_info("%s Processor probed (%s Core)\n", __cpu_family[cpu], core_name);
>>  }
>>
>>  #ifdef CONFIG_64BIT
>>
>> --
>> 2.46.0
>>

-- 
- Jiaxun

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-09-13  9:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-12 20:55 [PATCH v2 0/4] LoongArch, MIPS: Unify Loongson IOCSR handling Jiaxun Yang
2024-09-12 20:55 ` [PATCH v2 1/4] LoongArch: Probe more CPU features from CPUCFG Jiaxun Yang
2024-09-13  8:46   ` Huacai Chen
2024-09-13  9:10     ` Jiaxun Yang
2024-09-12 20:55 ` [PATCH v2 2/4] LoongArch: cpu-probe: Move IOCSR probing out of cpu_probe_common Jiaxun Yang
2024-09-12 20:59   ` Jiaxun Yang
2024-09-13  8:48     ` Huacai Chen
2024-09-12 20:55 ` [PATCH v2 3/4] LoongArch: Extract IOCSR definitions to standalone header Jiaxun Yang
2024-09-12 20:55 ` [PATCH v2 4/4] MIPS: Loongson64: Use shared IOCSR header Jiaxun Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).