linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michal Simek <michal.simek@xilinx.com>
To: linux-kernel@vger.kernel.org, monstr@monstr.eu,
	michal.simek@xilinx.com, git@xilinx.com, arnd@arndb.de
Cc: Stefan Asserhall <stefan.asserhall@xilinx.com>,
	Allison Randal <allison@lohutok.net>,
	Enrico Weigelt <info@metux.net>,
	Kate Stewart <kstewart@linuxfoundation.org>,
	Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>,
	Thomas Gleixner <tglx@linutronix.de>
Subject: [PATCH 2/7] microblaze: Make cpuinfo structure SMP aware
Date: Wed, 12 Feb 2020 16:42:24 +0100	[thread overview]
Message-ID: <f6bca66fa1c0c4f7321bbac3906fdf87652285d1.1581522136.git.michal.simek@xilinx.com> (raw)
In-Reply-To: <cover.1581522136.git.michal.simek@xilinx.com>

From: Stefan Asserhall <stefan.asserhall@xilinx.com>

Define struct cpuinfo per cpu and also fill it based on information from DT
or PVR.

Signed-off-by: Stefan Asserhall <stefan.asserhall@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/microblaze/include/asm/cpuinfo.h |   2 +-
 arch/microblaze/kernel/cpu/cache.c    | 154 +++++++++++--------
 arch/microblaze/kernel/cpu/cpuinfo.c  |  38 +++--
 arch/microblaze/kernel/cpu/mb.c       | 207 ++++++++++++++------------
 arch/microblaze/mm/consistent.c       |   8 +-
 5 files changed, 236 insertions(+), 173 deletions(-)

diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h
index 786ffa669bf1..b8b04cd0095d 100644
--- a/arch/microblaze/include/asm/cpuinfo.h
+++ b/arch/microblaze/include/asm/cpuinfo.h
@@ -84,7 +84,7 @@ struct cpuinfo {
 	u32 pvr_user2;
 };
 
-extern struct cpuinfo cpuinfo;
+DECLARE_PER_CPU(struct cpuinfo, cpu_info);
 
 /* fwd declarations of the various CPUinfo populators */
 void setup_cpuinfo(void);
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index dcba53803fa5..818152e37375 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -12,6 +12,7 @@
 
 #include <asm/cacheflush.h>
 #include <linux/cache.h>
+#include <linux/smp.h>
 #include <asm/cpuinfo.h>
 #include <asm/pvr.h>
 
@@ -158,6 +159,8 @@ do {									\
 
 static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -166,15 +169,15 @@ static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.icache_line_length, cpuinfo.icache_size);
+			cpuinfo->icache_line_length, cpuinfo->icache_size);
 
 	local_irq_save(flags);
 	__disable_icache_msr();
 
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo->icache_line_length, wic);
 #else
-	for (i = start; i < end; i += cpuinfo.icache_line_length)
+	for (i = start; i < end; i += cpuinfo->icache_line_length)
 		__asm__ __volatile__ ("wic	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -185,6 +188,8 @@ static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
 static void __flush_icache_range_nomsr_irq(unsigned long start,
 				unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -193,15 +198,15 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.icache_line_length, cpuinfo.icache_size);
+			cpuinfo->icache_line_length, cpuinfo->icache_size);
 
 	local_irq_save(flags);
 	__disable_icache_nomsr();
 
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo->icache_line_length, wic);
 #else
-	for (i = start; i < end; i += cpuinfo.icache_line_length)
+	for (i = start; i < end; i += cpuinfo->icache_line_length)
 		__asm__ __volatile__ ("wic	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -213,6 +218,8 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
 static void __flush_icache_range_noirq(unsigned long start,
 				unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
@@ -220,11 +227,11 @@ static void __flush_icache_range_noirq(unsigned long start,
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.icache_line_length, cpuinfo.icache_size);
+			cpuinfo->icache_line_length, cpuinfo->icache_size);
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo->icache_line_length, wic);
 #else
-	for (i = start; i < end; i += cpuinfo.icache_line_length)
+	for (i = start; i < end; i += cpuinfo->icache_line_length)
 		__asm__ __volatile__ ("wic	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -232,6 +239,8 @@ static void __flush_icache_range_noirq(unsigned long start,
 
 static void __flush_icache_all_msr_irq(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -241,11 +250,10 @@ static void __flush_icache_all_msr_irq(void)
 	local_irq_save(flags);
 	__disable_icache_msr();
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+	CACHE_ALL_LOOP(cpuinfo->icache_size, cpuinfo->icache_line_length, wic);
 #else
-	for (i = 0; i < cpuinfo.icache_size;
-		 i += cpuinfo.icache_line_length)
-			__asm__ __volatile__ ("wic	%0, r0;" \
+	for (i = 0; i < cpuinfo->icache_size; i += cpuinfo->icache_line_length)
+		__asm__ __volatile__ ("wic	%0, r0;" \
 					: : "r" (i));
 #endif
 	__enable_icache_msr();
@@ -254,6 +262,8 @@ static void __flush_icache_all_msr_irq(void)
 
 static void __flush_icache_all_nomsr_irq(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -263,11 +273,10 @@ static void __flush_icache_all_nomsr_irq(void)
 	local_irq_save(flags);
 	__disable_icache_nomsr();
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+	CACHE_ALL_LOOP(cpuinfo->icache_size, cpuinfo->icache_line_length, wic);
 #else
-	for (i = 0; i < cpuinfo.icache_size;
-		 i += cpuinfo.icache_line_length)
-			__asm__ __volatile__ ("wic	%0, r0;" \
+	for (i = 0; i < cpuinfo->icache_size; i += cpuinfo->icache_line_length)
+		__asm__ __volatile__ ("wic	%0, r0;" \
 					: : "r" (i));
 #endif
 	__enable_icache_nomsr();
@@ -276,22 +285,25 @@ static void __flush_icache_all_nomsr_irq(void)
 
 static void __flush_icache_all_noirq(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
 	pr_debug("%s\n", __func__);
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+	CACHE_ALL_LOOP(cpuinfo->icache_size, cpuinfo->icache_line_length, wic);
 #else
-	for (i = 0; i < cpuinfo.icache_size;
-		 i += cpuinfo.icache_line_length)
-			__asm__ __volatile__ ("wic	%0, r0;" \
+	for (i = 0; i < cpuinfo->icache_size; i += cpuinfo->icache_line_length)
+		__asm__ __volatile__ ("wic	%0, r0;" \
 					: : "r" (i));
 #endif
 }
 
 static void __invalidate_dcache_all_msr_irq(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -301,11 +313,10 @@ static void __invalidate_dcache_all_msr_irq(void)
 	local_irq_save(flags);
 	__disable_dcache_msr();
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
+	CACHE_ALL_LOOP(cpuinfo->dcache_size, cpuinfo->dcache_line_length, wdc);
 #else
-	for (i = 0; i < cpuinfo.dcache_size;
-		 i += cpuinfo.dcache_line_length)
-			__asm__ __volatile__ ("wdc	%0, r0;" \
+	for (i = 0; i < cpuinfo->dcache_size; i += cpuinfo->dcache_line_length)
+		__asm__ __volatile__ ("wdc	%0, r0;" \
 					: : "r" (i));
 #endif
 	__enable_dcache_msr();
@@ -314,6 +325,8 @@ static void __invalidate_dcache_all_msr_irq(void)
 
 static void __invalidate_dcache_all_nomsr_irq(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -323,11 +336,10 @@ static void __invalidate_dcache_all_nomsr_irq(void)
 	local_irq_save(flags);
 	__disable_dcache_nomsr();
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
+	CACHE_ALL_LOOP(cpuinfo->dcache_size, cpuinfo->dcache_line_length, wdc);
 #else
-	for (i = 0; i < cpuinfo.dcache_size;
-		 i += cpuinfo.dcache_line_length)
-			__asm__ __volatile__ ("wdc	%0, r0;" \
+	for (i = 0; i < cpuinfo->dcache_size; i += cpuinfo->dcache_line_length)
+		__asm__ __volatile__ ("wdc	%0, r0;" \
 					: : "r" (i));
 #endif
 	__enable_dcache_nomsr();
@@ -336,16 +348,17 @@ static void __invalidate_dcache_all_nomsr_irq(void)
 
 static void __invalidate_dcache_all_noirq_wt(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
 	pr_debug("%s\n", __func__);
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
+	CACHE_ALL_LOOP(cpuinfo->dcache_size, cpuinfo->dcache_line_length, wdc);
 #else
-	for (i = 0; i < cpuinfo.dcache_size;
-		 i += cpuinfo.dcache_line_length)
-			__asm__ __volatile__ ("wdc	%0, r0;" \
+	for (i = 0; i < cpuinfo->dcache_size; i += cpuinfo->dcache_line_length)
+		__asm__ __volatile__ ("wdc	%0, r0;" \
 					: : "r" (i));
 #endif
 }
@@ -359,17 +372,18 @@ static void __invalidate_dcache_all_noirq_wt(void)
  */
 static void __invalidate_dcache_all_wb(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
 	pr_debug("%s\n", __func__);
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+	CACHE_ALL_LOOP(cpuinfo->dcache_size, cpuinfo->dcache_line_length,
 					wdc);
 #else
-	for (i = 0; i < cpuinfo.dcache_size;
-		 i += cpuinfo.dcache_line_length)
-			__asm__ __volatile__ ("wdc	%0, r0;" \
+	for (i = 0; i < cpuinfo->dcache_size; i += cpuinfo->dcache_line_length)
+		__asm__ __volatile__ ("wdc	%0, r0;" \
 					: : "r" (i));
 #endif
 }
@@ -377,6 +391,8 @@ static void __invalidate_dcache_all_wb(void)
 static void __invalidate_dcache_range_wb(unsigned long start,
 						unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
@@ -384,11 +400,11 @@ static void __invalidate_dcache_range_wb(unsigned long start,
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+			cpuinfo->dcache_line_length, cpuinfo->dcache_size);
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
+	CACHE_RANGE_LOOP_2(start, end, cpuinfo->dcache_line_length, wdc.clear);
 #else
-	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+	for (i = start; i < end; i += cpuinfo->dcache_line_length)
 		__asm__ __volatile__ ("wdc.clear	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -397,18 +413,20 @@ static void __invalidate_dcache_range_wb(unsigned long start,
 static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
 							unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+			cpuinfo->dcache_line_length, cpuinfo->dcache_size);
 
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo->dcache_line_length, wdc);
 #else
-	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+	for (i = start; i < end; i += cpuinfo->dcache_line_length)
 		__asm__ __volatile__ ("wdc	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -417,6 +435,8 @@ static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
 static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
 							unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -424,15 +444,15 @@ static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+			cpuinfo->dcache_line_length, cpuinfo->dcache_size);
 
 	local_irq_save(flags);
 	__disable_dcache_msr();
 
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo->dcache_line_length, wdc);
 #else
-	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+	for (i = start; i < end; i += cpuinfo->dcache_line_length)
 		__asm__ __volatile__ ("wdc	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -444,6 +464,8 @@ static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
 static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
 							unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 	unsigned long flags;
 #ifndef ASM_LOOP
 	int i;
@@ -452,15 +474,15 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+			cpuinfo->dcache_line_length, cpuinfo->dcache_size);
 
 	local_irq_save(flags);
 	__disable_dcache_nomsr();
 
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo->dcache_line_length, wdc);
 #else
-	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+	for (i = start; i < end; i += cpuinfo->dcache_line_length)
 		__asm__ __volatile__ ("wdc	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -471,23 +493,26 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
 
 static void __flush_dcache_all_wb(void)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
 	pr_debug("%s\n", __func__);
 #ifdef ASM_LOOP
-	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+	CACHE_ALL_LOOP(cpuinfo->dcache_size, cpuinfo->dcache_line_length,
 				wdc.flush);
 #else
-	for (i = 0; i < cpuinfo.dcache_size;
-		 i += cpuinfo.dcache_line_length)
-			__asm__ __volatile__ ("wdc.flush	%0, r0;" \
+	for (i = 0; i < cpuinfo->dcache_size; i += cpuinfo->dcache_line_length)
+		__asm__ __volatile__ ("wdc.flush	%0, r0;" \
 					: : "r" (i));
 #endif
 }
 
 static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
 {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 #ifndef ASM_LOOP
 	int i;
 #endif
@@ -495,11 +520,11 @@ static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
-			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+			cpuinfo->dcache_line_length, cpuinfo->dcache_size);
 #ifdef ASM_LOOP
-	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
+	CACHE_RANGE_LOOP_2(start, end, cpuinfo->dcache_line_length, wdc.flush);
 #else
-	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+	for (i = start; i < end; i += cpuinfo->dcache_line_length)
 		__asm__ __volatile__ ("wdc.flush	%0, r0;"	\
 				: : "r" (i));
 #endif
@@ -608,16 +633,19 @@ static const struct scache wt_nomsr_noirq = {
 
 void microblaze_cache_init(void)
 {
-	if (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) {
-		if (cpuinfo.dcache_wb) {
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
+
+	if (cpuinfo->use_instr & PVR2_USE_MSR_INSTR) {
+		if (cpuinfo->dcache_wb) {
 			pr_info("wb_msr\n");
 			mbc = (struct scache *)&wb_msr;
-			if (cpuinfo.ver_code <= CPUVER_7_20_D) {
+			if (cpuinfo->ver_code <= CPUVER_7_20_D) {
 				/* MS: problem with signal handling - hw bug */
 				pr_info("WB won't work properly\n");
 			}
 		} else {
-			if (cpuinfo.ver_code >= CPUVER_7_20_A) {
+			if (cpuinfo->ver_code >= CPUVER_7_20_A) {
 				pr_info("wt_msr_noirq\n");
 				mbc = (struct scache *)&wt_msr_noirq;
 			} else {
@@ -626,15 +654,15 @@ void microblaze_cache_init(void)
 			}
 		}
 	} else {
-		if (cpuinfo.dcache_wb) {
+		if (cpuinfo->dcache_wb) {
 			pr_info("wb_nomsr\n");
 			mbc = (struct scache *)&wb_nomsr;
-			if (cpuinfo.ver_code <= CPUVER_7_20_D) {
+			if (cpuinfo->ver_code <= CPUVER_7_20_D) {
 				/* MS: problem with signal handling - hw bug */
 				pr_info("WB won't work properly\n");
 			}
 		} else {
-			if (cpuinfo.ver_code >= CPUVER_7_20_A) {
+			if (cpuinfo->ver_code >= CPUVER_7_20_A) {
 				pr_info("wt_nomsr_noirq\n");
 				mbc = (struct scache *)&wt_nomsr_noirq;
 			} else {
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index cd9b4450763b..e2b87f136ba8 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2013-2020 Xilinx, Inc. All rights reserved.
  * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
  * Copyright (C) 2007-2009 PetaLogix
  * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
@@ -10,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/init.h>
+#include <linux/smp.h>
 #include <asm/cpuinfo.h>
 #include <asm/pvr.h>
 
@@ -56,7 +58,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
 };
 
 /*
- * FIXME Not sure if the actual key is defined by Xilinx in the PVR
+ * The actual key is defined by Xilinx in the PVR
  */
 const struct family_string_key family_string_lookup[] = {
 	{"virtex2", 0x4},
@@ -85,37 +87,40 @@ const struct family_string_key family_string_lookup[] = {
 	{NULL, 0},
 };
 
-struct cpuinfo cpuinfo;
-static struct device_node *cpu;
+DEFINE_PER_CPU(struct cpuinfo, cpu_info);
 
 void __init setup_cpuinfo(void)
 {
-	cpu = of_get_cpu_node(0, NULL);
+	struct device_node *cpu;
+	unsigned int cpu_id = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu_id);
+
+	cpu = of_get_cpu_node(cpu_id, NULL);
 	if (!cpu)
 		pr_err("You don't have cpu or are missing cpu reg property!!!\n");
 
-	pr_info("%s: initialising\n", __func__);
+	pr_info("%s: initialising cpu %d\n", __func__, cpu_id);
 
 	switch (cpu_has_pvr()) {
 	case 0:
 		pr_warn("%s: No PVR support. Using static CPU info from FDT\n",
 			__func__);
-		set_cpuinfo_static(&cpuinfo, cpu);
+		set_cpuinfo_static(cpuinfo, cpu);
 		break;
 /* FIXME I found weird behavior with MB 7.00.a/b 7.10.a
  * please do not use FULL PVR with MMU */
 	case 1:
 		pr_info("%s: Using full CPU PVR support\n",
 			__func__);
-		set_cpuinfo_static(&cpuinfo, cpu);
-		set_cpuinfo_pvr_full(&cpuinfo, cpu);
+		set_cpuinfo_static(cpuinfo, cpu);
+		set_cpuinfo_pvr_full(cpuinfo, cpu);
 		break;
 	default:
 		pr_warn("%s: Unsupported PVR setting\n", __func__);
-		set_cpuinfo_static(&cpuinfo, cpu);
+		set_cpuinfo_static(cpuinfo, cpu);
 	}
 
-	if (cpuinfo.mmu_privins)
+	if (cpuinfo->mmu_privins)
 		pr_warn("%s: Stream instructions enabled"
 			" - USERSPACE CAN LOCK THIS KERNEL!\n", __func__);
 
@@ -125,17 +130,24 @@ void __init setup_cpuinfo(void)
 void __init setup_cpuinfo_clk(void)
 {
 	struct clk *clk;
+	struct device_node *cpu;
+	unsigned int cpu_id = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu_id);
+
+	cpu = of_get_cpu_node(cpu_id, NULL);
+	if (!cpu)
+		pr_err("You don't have cpu or are missing cpu reg property!!!\n");
 
 	clk = of_clk_get(cpu, 0);
 	if (IS_ERR(clk)) {
 		pr_err("ERROR: CPU CCF input clock not found\n");
 		/* take timebase-frequency from DTS */
-		cpuinfo.cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+		cpuinfo->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
 	} else {
-		cpuinfo.cpu_clock_freq = clk_get_rate(clk);
+		cpuinfo->cpu_clock_freq = clk_get_rate(clk);
 	}
 
-	if (!cpuinfo.cpu_clock_freq) {
+	if (!cpuinfo->cpu_clock_freq) {
 		pr_err("ERROR: CPU clock frequency not setup\n");
 		BUG();
 	}
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
index 9581d194d9e4..7a6fc13f925a 100644
--- a/arch/microblaze/kernel/cpu/mb.c
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -1,6 +1,7 @@
 /*
  * CPU-version specific code
  *
+ * Copyright (C) 2013-2020 Xilinx, Inc. All rights reserved
  * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
  * Copyright (C) 2006-2009 PetaLogix
  *
@@ -27,117 +28,135 @@
 
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
-	char *fpga_family = "Unknown";
-	char *cpu_ver = "Unknown";
-	int i;
-
-	/* Denormalised to get the fpga family string */
-	for (i = 0; family_string_lookup[i].s != NULL; i++) {
-		if (cpuinfo.fpga_family_code == family_string_lookup[i].k) {
-			fpga_family = (char *)family_string_lookup[i].s;
-			break;
+	unsigned int cpu;
+
+	for_each_online_cpu(cpu) {
+		struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
+		char *fpga_family = "Unknown";
+		char *cpu_ver = "Unknown";
+		int i;
+
+		/* Denormalised to get the fpga family string */
+		for (i = 0; family_string_lookup[i].s != NULL; i++) {
+			if (cpuinfo->fpga_family_code ==
+			    family_string_lookup[i].k) {
+				fpga_family = (char *)family_string_lookup[i].s;
+				break;
+			}
 		}
-	}
 
-	/* Denormalised to get the hw version string */
-	for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
-		if (cpuinfo.ver_code == cpu_ver_lookup[i].k) {
-			cpu_ver = (char *)cpu_ver_lookup[i].s;
-			break;
+		/* Denormalised to get the hw version string */
+		for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+			if (cpuinfo->ver_code == cpu_ver_lookup[i].k) {
+				cpu_ver = (char *)cpu_ver_lookup[i].s;
+				break;
+			}
 		}
-	}
 
-	seq_printf(m,
-		   "CPU-Family:	MicroBlaze\n"
-		   "FPGA-Arch:	%s\n"
-		   "CPU-Ver:	%s, %s endian\n"
-		   "CPU-MHz:	%d.%02d\n"
-		   "BogoMips:	%lu.%02lu\n",
-		   fpga_family,
-		   cpu_ver,
-		   cpuinfo.endian ? "little" : "big",
-		   cpuinfo.cpu_clock_freq / 1000000,
-		   cpuinfo.cpu_clock_freq % 1000000,
-		   loops_per_jiffy / (500000 / HZ),
-		   (loops_per_jiffy / (5000 / HZ)) % 100);
-
-	seq_printf(m,
-		   "HW:\n Shift:\t\t%s\n"
-		   " MSR:\t\t%s\n"
-		   " PCMP:\t\t%s\n"
-		   " DIV:\t\t%s\n",
-		   (cpuinfo.use_instr & PVR0_USE_BARREL_MASK) ? "yes" : "no",
-		   (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) ? "yes" : "no",
-		   (cpuinfo.use_instr & PVR2_USE_PCMP_INSTR) ? "yes" : "no",
-		   (cpuinfo.use_instr & PVR0_USE_DIV_MASK) ? "yes" : "no");
-
-	seq_printf(m, " MMU:\t\t%x\n", cpuinfo.mmu);
-
-	seq_printf(m,
-		   " MUL:\t\t%s\n"
-		   " FPU:\t\t%s\n",
-		   (cpuinfo.use_mult & PVR2_USE_MUL64_MASK) ? "v2" :
-		   (cpuinfo.use_mult & PVR0_USE_HW_MUL_MASK) ? "v1" : "no",
-		   (cpuinfo.use_fpu & PVR2_USE_FPU2_MASK) ? "v2" :
-		   (cpuinfo.use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no");
-
-	seq_printf(m,
-		   " Exc:\t\t%s%s%s%s%s%s%s%s\n",
-		   (cpuinfo.use_exc & PVR2_OPCODE_0x0_ILL_MASK) ? "op0x0 " : "",
-		   (cpuinfo.use_exc & PVR2_UNALIGNED_EXC_MASK) ? "unal " : "",
-		   (cpuinfo.use_exc & PVR2_ILL_OPCODE_EXC_MASK) ? "ill " : "",
-		   (cpuinfo.use_exc & PVR2_IOPB_BUS_EXC_MASK) ? "iopb " : "",
-		   (cpuinfo.use_exc & PVR2_DOPB_BUS_EXC_MASK) ? "dopb " : "",
-		   (cpuinfo.use_exc & PVR2_DIV_ZERO_EXC_MASK) ? "zero " : "",
-		   (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "",
-		   (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : "");
-
-	seq_printf(m,
-		   "Stream-insns:\t%sprivileged\n",
-		   cpuinfo.mmu_privins ? "un" : "");
-
-	if (cpuinfo.use_icache)
 		seq_printf(m,
-			   "Icache:\t\t%ukB\tline length:\t%dB\n",
-			   cpuinfo.icache_size >> 10,
-			   cpuinfo.icache_line_length);
-	else
-		seq_puts(m, "Icache:\t\tno\n");
+			"Processor:	%u\n"
+			"CPU-Family:	MicroBlaze\n"
+			"FPGA-Arch:	%s\n"
+			"CPU-Ver:	%s, %s endian\n"
+			"CPU-MHz:	%d.%02d\n"
+			"BogoMips:	%lu.%02lu\n",
+			cpu,
+			fpga_family,
+			cpu_ver,
+			cpuinfo->endian ? "little" : "big",
+			cpuinfo->cpu_clock_freq / 1000000,
+			cpuinfo->cpu_clock_freq % 1000000,
+			loops_per_jiffy / (500000 / HZ),
+			(loops_per_jiffy / (5000 / HZ)) % 100);
+
+		seq_printf(m,
+			"HW:\n Shift:\t\t%s\n"
+			" MSR:\t\t%s\n"
+			" PCMP:\t\t%s\n"
+			" DIV:\t\t%s\n",
+			(cpuinfo->use_instr & PVR0_USE_BARREL_MASK) ?
+			"yes" : "no",
+			(cpuinfo->use_instr & PVR2_USE_MSR_INSTR) ?
+			"yes" : "no",
+			(cpuinfo->use_instr & PVR2_USE_PCMP_INSTR) ?
+			"yes" : "no",
+			(cpuinfo->use_instr & PVR0_USE_DIV_MASK) ?
+			"yes" : "no");
+
+		seq_printf(m, " MMU:\t\t%x\n", cpuinfo->mmu);
+
+		seq_printf(m,
+			" MUL:\t\t%s\n"
+			" FPU:\t\t%s\n",
+			(cpuinfo->use_mult & PVR2_USE_MUL64_MASK) ? "v2" :
+			(cpuinfo->use_mult & PVR0_USE_HW_MUL_MASK) ?
+			"v1" : "no",
+			(cpuinfo->use_fpu & PVR2_USE_FPU2_MASK) ? "v2" :
+			(cpuinfo->use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no");
+
+		seq_printf(m,
+			" Exc:\t\t%s%s%s%s%s%s%s%s\n",
+			(cpuinfo->use_exc & PVR2_OPCODE_0x0_ILL_MASK) ?
+			"op0x0 " : "",
+			(cpuinfo->use_exc & PVR2_UNALIGNED_EXC_MASK) ?
+			"unal " : "",
+			(cpuinfo->use_exc & PVR2_ILL_OPCODE_EXC_MASK) ?
+			"ill " : "",
+			(cpuinfo->use_exc & PVR2_IOPB_BUS_EXC_MASK) ?
+			"iopb " : "",
+			(cpuinfo->use_exc & PVR2_DOPB_BUS_EXC_MASK) ?
+			"dopb " : "",
+			(cpuinfo->use_exc & PVR2_DIV_ZERO_EXC_MASK) ?
+			"zero " : "",
+			(cpuinfo->use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "",
+			(cpuinfo->use_exc & PVR2_USE_FSL_EXC) ? "fsl " : "");
 
-	if (cpuinfo.use_dcache) {
 		seq_printf(m,
-			   "Dcache:\t\t%ukB\tline length:\t%dB\n",
-			   cpuinfo.dcache_size >> 10,
-			   cpuinfo.dcache_line_length);
-		seq_puts(m, "Dcache-Policy:\t");
-		if (cpuinfo.dcache_wb)
-			seq_puts(m, "write-back\n");
+			"Stream-insns:\t%sprivileged\n",
+			cpuinfo->mmu_privins ? "un" : "");
+
+		if (cpuinfo->use_icache)
+			seq_printf(m,
+				"Icache:\t\t%ukB\tline length:\t%dB\n",
+				cpuinfo->icache_size >> 10,
+				cpuinfo->icache_line_length);
 		else
-			seq_puts(m, "write-through\n");
-	} else {
-		seq_puts(m, "Dcache:\t\tno\n");
-	}
+			seq_puts(m, "Icache:\t\tno\n");
+
+		if (cpuinfo->use_dcache) {
+			seq_printf(m,
+				"Dcache:\t\t%ukB\tline length:\t%dB\n",
+				cpuinfo->dcache_size >> 10,
+				cpuinfo->dcache_line_length);
+			seq_puts(m, "Dcache-Policy:\t");
+			if (cpuinfo->dcache_wb)
+				seq_puts(m, "write-back\n");
+			else
+				seq_puts(m, "write-through\n");
+		} else {
+			seq_puts(m, "Dcache:\t\tno\n");
+		}
 
-	seq_printf(m,
-		   "HW-Debug:\t%s\n",
-		   cpuinfo.hw_debug ? "yes" : "no");
+		seq_printf(m,
+			"HW-Debug:\t%s\n",
+			cpuinfo->hw_debug ? "yes" : "no");
 
-	seq_printf(m,
-		   "PVR-USR1:\t%02x\n"
-		   "PVR-USR2:\t%08x\n",
-		   cpuinfo.pvr_user1,
-		   cpuinfo.pvr_user2);
+		seq_printf(m,
+			"PVR-USR1:\t%02x\n"
+			"PVR-USR2:\t%08x\n",
+			cpuinfo->pvr_user1,
+			cpuinfo->pvr_user2);
 
-	seq_printf(m, "Page size:\t%lu\n", PAGE_SIZE);
+		seq_printf(m, "Page size:\t%lu\n", PAGE_SIZE);
+		seq_puts(m, "\n");
+	}
 
 	return 0;
 }
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-	int i = *pos;
-
-	return i < NR_CPUS ? (void *) (i + 1) : NULL;
+	return *pos < 1 ? (void *) 1 : NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c
index 8c5f0c332d8b..ddccc2a29fbf 100644
--- a/arch/microblaze/mm/consistent.c
+++ b/arch/microblaze/mm/consistent.c
@@ -35,7 +35,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
  * I have to use dcache values because I can't relate on ram size:
  */
 #ifdef CONFIG_XILINX_UNCACHED_SHADOW
-#define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
+#define UNCACHED_SHADOW_MASK (cpuinfo->dcache_high - cpuinfo->dcache_base + 1)
 #else
 #define UNCACHED_SHADOW_MASK 0
 #endif /* CONFIG_XILINX_UNCACHED_SHADOW */
@@ -43,9 +43,11 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 void *uncached_kernel_address(void *ptr)
 {
 	unsigned long addr = (unsigned long)ptr;
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 
 	addr |= UNCACHED_SHADOW_MASK;
-	if (addr > cpuinfo.dcache_base && addr < cpuinfo.dcache_high)
+	if (addr > cpuinfo->dcache_base && addr < cpuinfo->dcache_high)
 		pr_warn("ERROR: Your cache coherent area is CACHED!!!\n");
 	return (void *)addr;
 }
@@ -53,6 +55,8 @@ void *uncached_kernel_address(void *ptr)
 void *cached_kernel_address(void *ptr)
 {
 	unsigned long addr = (unsigned long)ptr;
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo *cpuinfo = per_cpu_ptr(&cpu_info, cpu);
 
 	return (void *)(addr & ~UNCACHED_SHADOW_MASK);
 }
-- 
2.25.0


  parent reply	other threads:[~2020-02-12 15:42 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-12 15:42 [PATCH 0/7] microblaze: Define SMP safe operations Michal Simek
2020-02-12 15:42 ` [PATCH 1/7] microblaze: timer: Don't use cpu timer setting Michal Simek
2020-02-12 15:42 ` Michal Simek [this message]
2020-02-12 20:42   ` [PATCH 2/7] microblaze: Make cpuinfo structure SMP aware Arnd Bergmann
2020-02-12 15:42 ` [PATCH 3/7] microblaze: Define SMP safe bit operations Michal Simek
2020-02-12 15:53   ` Peter Zijlstra
2020-02-13  8:42     ` Michal Simek
2020-02-13  9:01       ` Stefan Asserhall
2020-02-13  9:11         ` Peter Zijlstra
2020-02-13  9:24           ` Stefan Asserhall
2020-02-12 15:42 ` [PATCH 4/7] microblaze: Add SMP implementation of xchg and cmpxchg Michal Simek
2020-02-12 15:42 ` [PATCH 5/7] microblaze: Remove disabling IRQ while pte_update() run Michal Simek
2020-02-12 15:42 ` [PATCH 6/7] microblaze: Implement architecture spinlock Michal Simek
2020-02-12 15:47   ` Peter Zijlstra
2020-02-13  7:51     ` Michal Simek
2020-02-13  8:00       ` Peter Zijlstra
2020-02-12 15:42 ` [PATCH 7/7] microblaze: Do atomic operations by using exclusive ops Michal Simek
2020-02-12 15:55   ` Peter Zijlstra
2020-02-13  8:06     ` Michal Simek
2020-02-13  8:58       ` Peter Zijlstra
2020-02-13  9:16         ` Peter Zijlstra
2020-02-13 10:04           ` Will Deacon
2020-02-13 10:14             ` Stefan Asserhall
2020-02-13 10:20               ` Will Deacon
2020-02-13 10:15             ` Peter Zijlstra
2020-02-13 11:34         ` Boqun Feng
2020-02-13 11:38           ` Boqun Feng
2020-02-13 13:51             ` Andrea Parri
2020-02-13 14:01               ` Andrea Parri
2020-02-12 16:08 ` [PATCH 0/7] microblaze: Define SMP safe operations Peter Zijlstra
2020-02-12 16:38   ` Peter Zijlstra
2020-02-13  7:49   ` Michal Simek
2020-02-13  8:11     ` Peter Zijlstra
2020-02-13  8:12       ` Michal Simek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f6bca66fa1c0c4f7321bbac3906fdf87652285d1.1581522136.git.michal.simek@xilinx.com \
    --to=michal.simek@xilinx.com \
    --cc=allison@lohutok.net \
    --cc=arnd@arndb.de \
    --cc=git@xilinx.com \
    --cc=info@metux.net \
    --cc=kstewart@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=monstr@monstr.eu \
    --cc=shubhrajyoti.datta@xilinx.com \
    --cc=stefan.asserhall@xilinx.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).