All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Add support for the proAptiv core
@ 2013-11-07 17:08 ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Markos Chandras

Hi,

The following patchset adds support for the proAptiv core.

The proAptiv Multiprocessing System is a power efficient multi-core
microprocessor for use in system-on-chip (SoC) applications.
The proAptiv Multiprocessing System combines a deep pipeline
with multi-issue out of order execution for improved computational
throughput. The proAptiv Multiprocessing System can contain one to
six MIPS32r3 proAptiv cores, system level coherence
manager with L2 cache, optional coherent I/O port, and optional
floating point unit.

http://www.imgtec.com/mips/mips-proaptiv.asp

Leonid Yegoshin (4):
  MIPS: Add missing bits for Config registers
  MIPS: Add support for the proAptiv cores
  MIPS: mm: Use the TLBINVF instruction to flush the VTLB
  MIPS: Add support for FTLBs

Markos Chandras (1):
  MIPS: mm: Move UNIQUE_ENTRYHI macro to a header file

Steven J. Hill (1):
  MIPS: Add debugfs file to print the segmentation control registers

 arch/mips/include/asm/cpu-features.h |   7 +++
 arch/mips/include/asm/cpu-info.h     |   3 +
 arch/mips/include/asm/cpu-type.h     |   1 +
 arch/mips/include/asm/cpu.h          |   6 +-
 arch/mips/include/asm/mipsregs.h     |  84 +++++++++++++++++++++++++-
 arch/mips/include/asm/page.h         |  25 ++++++++
 arch/mips/include/asm/tlb.h          |   4 ++
 arch/mips/kernel/Makefile            |   1 +
 arch/mips/kernel/cpu-probe.c         | 101 ++++++++++++++++++++++++++++++--
 arch/mips/kernel/genex.S             |   1 +
 arch/mips/kernel/idle.c              |   1 +
 arch/mips/kernel/segment.c           | 110 +++++++++++++++++++++++++++++++++++
 arch/mips/kernel/spram.c             |   1 +
 arch/mips/kernel/traps.c             |  31 ++++++++++
 arch/mips/mm/c-r4k.c                 |   1 +
 arch/mips/mm/init.c                  |   2 -
 arch/mips/mm/sc-mips.c               |   1 +
 arch/mips/mm/tlb-r4k.c               |  48 ++++++++++-----
 arch/mips/mm/tlbex.c                 |   1 +
 arch/mips/oprofile/op_model_mipsxx.c |   4 ++
 20 files changed, 406 insertions(+), 27 deletions(-)
 create mode 100644 arch/mips/kernel/segment.c

-- 
1.8.4

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

* [PATCH 0/6] Add support for the proAptiv core
@ 2013-11-07 17:08 ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Markos Chandras

Hi,

The following patchset adds support for the proAptiv core.

The proAptiv Multiprocessing System is a power efficient multi-core
microprocessor for use in system-on-chip (SoC) applications.
The proAptiv Multiprocessing System combines a deep pipeline
with multi-issue out of order execution for improved computational
throughput. The proAptiv Multiprocessing System can contain one to
six MIPS32r3 proAptiv cores, system level coherence
manager with L2 cache, optional coherent I/O port, and optional
floating point unit.

http://www.imgtec.com/mips/mips-proaptiv.asp

Leonid Yegoshin (4):
  MIPS: Add missing bits for Config registers
  MIPS: Add support for the proAptiv cores
  MIPS: mm: Use the TLBINVF instruction to flush the VTLB
  MIPS: Add support for FTLBs

Markos Chandras (1):
  MIPS: mm: Move UNIQUE_ENTRYHI macro to a header file

Steven J. Hill (1):
  MIPS: Add debugfs file to print the segmentation control registers

 arch/mips/include/asm/cpu-features.h |   7 +++
 arch/mips/include/asm/cpu-info.h     |   3 +
 arch/mips/include/asm/cpu-type.h     |   1 +
 arch/mips/include/asm/cpu.h          |   6 +-
 arch/mips/include/asm/mipsregs.h     |  84 +++++++++++++++++++++++++-
 arch/mips/include/asm/page.h         |  25 ++++++++
 arch/mips/include/asm/tlb.h          |   4 ++
 arch/mips/kernel/Makefile            |   1 +
 arch/mips/kernel/cpu-probe.c         | 101 ++++++++++++++++++++++++++++++--
 arch/mips/kernel/genex.S             |   1 +
 arch/mips/kernel/idle.c              |   1 +
 arch/mips/kernel/segment.c           | 110 +++++++++++++++++++++++++++++++++++
 arch/mips/kernel/spram.c             |   1 +
 arch/mips/kernel/traps.c             |  31 ++++++++++
 arch/mips/mm/c-r4k.c                 |   1 +
 arch/mips/mm/init.c                  |   2 -
 arch/mips/mm/sc-mips.c               |   1 +
 arch/mips/mm/tlb-r4k.c               |  48 ++++++++++-----
 arch/mips/mm/tlbex.c                 |   1 +
 arch/mips/oprofile/op_model_mipsxx.c |   4 ++
 20 files changed, 406 insertions(+), 27 deletions(-)
 create mode 100644 arch/mips/kernel/segment.c

-- 
1.8.4

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

* [PATCH 1/6] MIPS: Add missing bits for Config registers
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/mipsregs.h | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index e033141..412fe99 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -573,7 +573,9 @@
 #define MIPS_CONF1_IA		(_ULCAST_(7) << 16)
 #define MIPS_CONF1_IL		(_ULCAST_(7) << 19)
 #define MIPS_CONF1_IS		(_ULCAST_(7) << 22)
-#define MIPS_CONF1_TLBS		(_ULCAST_(63)<< 25)
+#define MIPS_CONF1_TLBS_SHIFT   (25)
+#define MIPS_CONF1_TLBS_SIZE    (6)
+#define MIPS_CONF1_TLBS         (_ULCAST_(63) << MIPS_CONF1_TLBS_SHIFT)
 
 #define MIPS_CONF2_SA		(_ULCAST_(15)<<	 0)
 #define MIPS_CONF2_SL		(_ULCAST_(15)<<	 4)
@@ -587,21 +589,53 @@
 #define MIPS_CONF3_TL		(_ULCAST_(1) <<	 0)
 #define MIPS_CONF3_SM		(_ULCAST_(1) <<	 1)
 #define MIPS_CONF3_MT		(_ULCAST_(1) <<	 2)
+#define MIPS_CONF3_CDMM		(_ULCAST_(1) <<	 3)
 #define MIPS_CONF3_SP		(_ULCAST_(1) <<	 4)
 #define MIPS_CONF3_VINT		(_ULCAST_(1) <<	 5)
 #define MIPS_CONF3_VEIC		(_ULCAST_(1) <<	 6)
 #define MIPS_CONF3_LPA		(_ULCAST_(1) <<	 7)
+#define MIPS_CONF3_ITL		(_ULCAST_(1) <<	 8)
+#define MIPS_CONF3_CTXTC	(_ULCAST_(1) <<	 9)
 #define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
 #define MIPS_CONF3_DSP2P	(_ULCAST_(1) << 11)
 #define MIPS_CONF3_RXI		(_ULCAST_(1) << 12)
 #define MIPS_CONF3_ULRI		(_ULCAST_(1) << 13)
 #define MIPS_CONF3_ISA		(_ULCAST_(3) << 14)
 #define MIPS_CONF3_ISA_OE	(_ULCAST_(1) << 16)
+#define MIPS_CONF3_MCU		(_ULCAST_(1) << 17)
+#define MIPS_CONF3_MMAR		(_ULCAST_(7) << 18)
+#define MIPS_CONF3_IPLW		(_ULCAST_(3) << 21)
 #define MIPS_CONF3_VZ		(_ULCAST_(1) << 23)
-
+#define MIPS_CONF3_PW		(_ULCAST_(1) << 24)
+#define MIPS_CONF3_SC		(_ULCAST_(1) << 25)
+#define MIPS_CONF3_BI		(_ULCAST_(1) << 26)
+#define MIPS_CONF3_BP		(_ULCAST_(1) << 27)
+#define MIPS_CONF3_MSA		(_ULCAST_(1) << 28)
+#define MIPS_CONF3_CMGCR	(_ULCAST_(1) << 29)
+#define MIPS_CONF3_BPG		(_ULCAST_(1) << 30)
+
+#define MIPS_CONF4_MMUSIZEEXT_SHIFT	(0)
 #define MIPS_CONF4_MMUSIZEEXT	(_ULCAST_(255) << 0)
+#define MIPS_CONF4_FTLBSETS_SHIFT	(0)
+#define MIPS_CONF4_FTLBSETS_SHIFT	(0)
+#define MIPS_CONF4_FTLBSETS	(_ULCAST_(15) << MIPS_CONF4_FTLBSETS_SHIFT)
+#define MIPS_CONF4_FTLBWAYS_SHIFT	(4)
+#define MIPS_CONF4_FTLBWAYS	(_ULCAST_(15) << MIPS_CONF4_FTLBWAYS_SHIFT)
+#define MIPS_CONF4_FTLBPAGESIZE_SHIFT	(8)
+/* bits 10:8 in FTLB-only configurations */
+#define MIPS_CONF4_FTLBPAGESIZE (_ULCAST_(7) << MIPS_CONF4_FTLBPAGESIZE_SHIFT)
+/* bits 12:8 in VTLB-FTLB only configurations */
+#define MIPS_CONF4_VFTLBPAGESIZE (_ULCAST_(31) << MIPS_CONF4_FTLBPAGESIZE_SHIFT)
 #define MIPS_CONF4_MMUEXTDEF	(_ULCAST_(3) << 14)
 #define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
+#define MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT	(_ULCAST_(2) << 14)
+#define MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT	(_ULCAST_(3) << 14)
+#define MIPS_CONF4_KSCREXIST	(_ULCAST_(255) << 16)
+#define MIPS_CONF4_VTLBSIZEEXT_SHIFT	(24)
+#define MIPS_CONF4_VTLBSIZEEXT	(_ULCAST_(15) << MIPS_CONF4_VTLBSIZEEXT_SHIFT)
+#define MIPS_CONF4_AE		(_ULCAST_(1) << 28)
+#define MIPS_CONF4_IE		(_ULCAST_(3) << 29)
+#define MIPS_CONF4_TLBINV	(_ULCAST_(2) << 29)
 
 #define MIPS_CONF5_NF		(_ULCAST_(1) << 0)
 #define MIPS_CONF5_UFR		(_ULCAST_(1) << 2)
@@ -616,6 +650,8 @@
 
 #define MIPS_CONF7_RPS		(_ULCAST_(1) << 2)
 
+/*  EntryHI bit definition */
+#define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10)
 
 /*
  * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
-- 
1.8.4

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

* [PATCH 1/6] MIPS: Add missing bits for Config registers
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/mipsregs.h | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index e033141..412fe99 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -573,7 +573,9 @@
 #define MIPS_CONF1_IA		(_ULCAST_(7) << 16)
 #define MIPS_CONF1_IL		(_ULCAST_(7) << 19)
 #define MIPS_CONF1_IS		(_ULCAST_(7) << 22)
-#define MIPS_CONF1_TLBS		(_ULCAST_(63)<< 25)
+#define MIPS_CONF1_TLBS_SHIFT   (25)
+#define MIPS_CONF1_TLBS_SIZE    (6)
+#define MIPS_CONF1_TLBS         (_ULCAST_(63) << MIPS_CONF1_TLBS_SHIFT)
 
 #define MIPS_CONF2_SA		(_ULCAST_(15)<<	 0)
 #define MIPS_CONF2_SL		(_ULCAST_(15)<<	 4)
@@ -587,21 +589,53 @@
 #define MIPS_CONF3_TL		(_ULCAST_(1) <<	 0)
 #define MIPS_CONF3_SM		(_ULCAST_(1) <<	 1)
 #define MIPS_CONF3_MT		(_ULCAST_(1) <<	 2)
+#define MIPS_CONF3_CDMM		(_ULCAST_(1) <<	 3)
 #define MIPS_CONF3_SP		(_ULCAST_(1) <<	 4)
 #define MIPS_CONF3_VINT		(_ULCAST_(1) <<	 5)
 #define MIPS_CONF3_VEIC		(_ULCAST_(1) <<	 6)
 #define MIPS_CONF3_LPA		(_ULCAST_(1) <<	 7)
+#define MIPS_CONF3_ITL		(_ULCAST_(1) <<	 8)
+#define MIPS_CONF3_CTXTC	(_ULCAST_(1) <<	 9)
 #define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
 #define MIPS_CONF3_DSP2P	(_ULCAST_(1) << 11)
 #define MIPS_CONF3_RXI		(_ULCAST_(1) << 12)
 #define MIPS_CONF3_ULRI		(_ULCAST_(1) << 13)
 #define MIPS_CONF3_ISA		(_ULCAST_(3) << 14)
 #define MIPS_CONF3_ISA_OE	(_ULCAST_(1) << 16)
+#define MIPS_CONF3_MCU		(_ULCAST_(1) << 17)
+#define MIPS_CONF3_MMAR		(_ULCAST_(7) << 18)
+#define MIPS_CONF3_IPLW		(_ULCAST_(3) << 21)
 #define MIPS_CONF3_VZ		(_ULCAST_(1) << 23)
-
+#define MIPS_CONF3_PW		(_ULCAST_(1) << 24)
+#define MIPS_CONF3_SC		(_ULCAST_(1) << 25)
+#define MIPS_CONF3_BI		(_ULCAST_(1) << 26)
+#define MIPS_CONF3_BP		(_ULCAST_(1) << 27)
+#define MIPS_CONF3_MSA		(_ULCAST_(1) << 28)
+#define MIPS_CONF3_CMGCR	(_ULCAST_(1) << 29)
+#define MIPS_CONF3_BPG		(_ULCAST_(1) << 30)
+
+#define MIPS_CONF4_MMUSIZEEXT_SHIFT	(0)
 #define MIPS_CONF4_MMUSIZEEXT	(_ULCAST_(255) << 0)
+#define MIPS_CONF4_FTLBSETS_SHIFT	(0)
+#define MIPS_CONF4_FTLBSETS_SHIFT	(0)
+#define MIPS_CONF4_FTLBSETS	(_ULCAST_(15) << MIPS_CONF4_FTLBSETS_SHIFT)
+#define MIPS_CONF4_FTLBWAYS_SHIFT	(4)
+#define MIPS_CONF4_FTLBWAYS	(_ULCAST_(15) << MIPS_CONF4_FTLBWAYS_SHIFT)
+#define MIPS_CONF4_FTLBPAGESIZE_SHIFT	(8)
+/* bits 10:8 in FTLB-only configurations */
+#define MIPS_CONF4_FTLBPAGESIZE (_ULCAST_(7) << MIPS_CONF4_FTLBPAGESIZE_SHIFT)
+/* bits 12:8 in VTLB-FTLB only configurations */
+#define MIPS_CONF4_VFTLBPAGESIZE (_ULCAST_(31) << MIPS_CONF4_FTLBPAGESIZE_SHIFT)
 #define MIPS_CONF4_MMUEXTDEF	(_ULCAST_(3) << 14)
 #define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
+#define MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT	(_ULCAST_(2) << 14)
+#define MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT	(_ULCAST_(3) << 14)
+#define MIPS_CONF4_KSCREXIST	(_ULCAST_(255) << 16)
+#define MIPS_CONF4_VTLBSIZEEXT_SHIFT	(24)
+#define MIPS_CONF4_VTLBSIZEEXT	(_ULCAST_(15) << MIPS_CONF4_VTLBSIZEEXT_SHIFT)
+#define MIPS_CONF4_AE		(_ULCAST_(1) << 28)
+#define MIPS_CONF4_IE		(_ULCAST_(3) << 29)
+#define MIPS_CONF4_TLBINV	(_ULCAST_(2) << 29)
 
 #define MIPS_CONF5_NF		(_ULCAST_(1) << 0)
 #define MIPS_CONF5_UFR		(_ULCAST_(1) << 2)
@@ -616,6 +650,8 @@
 
 #define MIPS_CONF7_RPS		(_ULCAST_(1) << 2)
 
+/*  EntryHI bit definition */
+#define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10)
 
 /*
  * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
-- 
1.8.4

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

* [PATCH 2/6] MIPS: mm: Move UNIQUE_ENTRYHI macro to a header file
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Markos Chandras

The UNIQUE_ENTRYHI definition was duplicated whenever there
was the need to flush the TLB entries. We move this common
definition to a header file.

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/tlb.h | 2 ++
 arch/mips/mm/init.c         | 2 --
 arch/mips/mm/tlb-r4k.c      | 7 +------
 3 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/tlb.h b/arch/mips/include/asm/tlb.h
index c67842b..235367ce 100644
--- a/arch/mips/include/asm/tlb.h
+++ b/arch/mips/include/asm/tlb.h
@@ -18,6 +18,8 @@
  */
 #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
 
+#define UNIQUE_ENTRYHI(idx)	(CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
 #include <asm-generic/tlb.h>
 
 #endif /* __ASM_TLB_H */
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index e205ef5..6f44a31 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -171,8 +171,6 @@ void *kmap_coherent(struct page *page, unsigned long addr)
 	return (void*) vaddr;
 }
 
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
 void kunmap_coherent(void)
 {
 #ifndef CONFIG_MIPS_MT_SMTC
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index da3b0b9..363aa03 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -20,16 +20,11 @@
 #include <asm/bootinfo.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
+#include <asm/tlb.h>
 #include <asm/tlbmisc.h>
 
 extern void build_tlb_refill_handler(void);
 
-/*
- * Make sure all entries differ.  If they're not different
- * MIPS32 will take revenge ...
- */
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
 /* Atomicity and interruptability */
 #ifdef CONFIG_MIPS_MT_SMTC
 
-- 
1.8.4

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

* [PATCH 2/6] MIPS: mm: Move UNIQUE_ENTRYHI macro to a header file
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Markos Chandras

The UNIQUE_ENTRYHI definition was duplicated whenever there
was the need to flush the TLB entries. We move this common
definition to a header file.

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/tlb.h | 2 ++
 arch/mips/mm/init.c         | 2 --
 arch/mips/mm/tlb-r4k.c      | 7 +------
 3 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/tlb.h b/arch/mips/include/asm/tlb.h
index c67842b..235367ce 100644
--- a/arch/mips/include/asm/tlb.h
+++ b/arch/mips/include/asm/tlb.h
@@ -18,6 +18,8 @@
  */
 #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
 
+#define UNIQUE_ENTRYHI(idx)	(CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
 #include <asm-generic/tlb.h>
 
 #endif /* __ASM_TLB_H */
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index e205ef5..6f44a31 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -171,8 +171,6 @@ void *kmap_coherent(struct page *page, unsigned long addr)
 	return (void*) vaddr;
 }
 
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
 void kunmap_coherent(void)
 {
 #ifndef CONFIG_MIPS_MT_SMTC
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index da3b0b9..363aa03 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -20,16 +20,11 @@
 #include <asm/bootinfo.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
+#include <asm/tlb.h>
 #include <asm/tlbmisc.h>
 
 extern void build_tlb_refill_handler(void);
 
-/*
- * Make sure all entries differ.  If they're not different
- * MIPS32 will take revenge ...
- */
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
 /* Atomicity and interruptability */
 #ifdef CONFIG_MIPS_MT_SMTC
 
-- 
1.8.4

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

* [PATCH 3/6] MIPS: Add support for the proAptiv cores
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

The proAptiv Multiprocessing System is a power efficient multi-core
microprocessor for use in system-on-chip (SoC) applications.
The proAptiv Multiprocessing System combines a deep pipeline
with multi-issue out of order execution for improved computational
throughput. The proAptiv Multiprocessing System can contain one to
six MIPS32r3 proAptiv cores, system level coherence
manager with L2 cache, optional coherent I/O port, and optional
floating point unit.

Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/cpu-features.h |  3 +++
 arch/mips/include/asm/cpu-type.h     |  1 +
 arch/mips/include/asm/cpu.h          |  5 ++++-
 arch/mips/include/asm/tlb.h          |  4 +++-
 arch/mips/kernel/cpu-probe.c         | 15 +++++++++++++++
 arch/mips/kernel/idle.c              |  1 +
 arch/mips/kernel/spram.c             |  1 +
 arch/mips/kernel/traps.c             |  1 +
 arch/mips/mm/c-r4k.c                 |  1 +
 arch/mips/mm/sc-mips.c               |  1 +
 arch/mips/mm/tlbex.c                 |  1 +
 arch/mips/oprofile/op_model_mipsxx.c |  4 ++++
 12 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index d445d06..296606b 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -20,6 +20,9 @@
 #ifndef cpu_has_tlb
 #define cpu_has_tlb		(cpu_data[0].options & MIPS_CPU_TLB)
 #endif
+#ifndef cpu_has_tlbinv
+#define cpu_has_tlbinv		(cpu_data[0].options & MIPS_CPU_TLBINV)
+#endif
 
 /*
  * For the moment we don't consider R6000 and R8000 so we can assume that
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h
index 4a402cc..673f426 100644
--- a/arch/mips/include/asm/cpu-type.h
+++ b/arch/mips/include/asm/cpu-type.h
@@ -47,6 +47,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
 	case CPU_74K:
 	case CPU_M14KC:
 	case CPU_M14KEC:
+	case CPU_PROAPTIV:
 #endif
 
 #ifdef CONFIG_SYS_HAS_CPU_MIPS64_R1
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index d2035e1..ca5827c 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -111,6 +111,8 @@
 #define PRID_IMP_1074K		0x9a00
 #define PRID_IMP_M14KC		0x9c00
 #define PRID_IMP_M14KEC		0x9e00
+#define PRID_IMP_PROAPTIV_UP	0xa200
+#define PRID_IMP_PROAPTIV_MP	0xa300
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
@@ -289,7 +291,7 @@ enum cpu_type_enum {
 	CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
 	CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
 	CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
-	CPU_M14KEC,
+	CPU_M14KEC, CPU_PROAPTIV,
 
 	/*
 	 * MIPS64 class processors
@@ -348,6 +350,7 @@ enum cpu_type_enum {
 #define MIPS_CPU_PCI		0x00400000 /* CPU has Perf Ctr Int indicator */
 #define MIPS_CPU_RIXI		0x00800000 /* CPU has TLB Read/eXec Inhibit */
 #define MIPS_CPU_MICROMIPS	0x01000000 /* CPU has microMIPS capability */
+#define MIPS_CPU_TLBINV		0x02000000 /* CPU supports TLBINV/F */
 
 /*
  * CPU ASE encodings
diff --git a/arch/mips/include/asm/tlb.h b/arch/mips/include/asm/tlb.h
index 235367ce..4a23493 100644
--- a/arch/mips/include/asm/tlb.h
+++ b/arch/mips/include/asm/tlb.h
@@ -18,7 +18,9 @@
  */
 #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
 
-#define UNIQUE_ENTRYHI(idx)	(CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+#define UNIQUE_ENTRYHI(idx)						\
+		((CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) |		\
+		 (cpu_has_tlbinv ? MIPS_ENTRYHI_EHINV : 0))
 
 #include <asm-generic/tlb.h>
 
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index c814287..8168e29 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -286,6 +286,13 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
 	    && cpu_has_tlb)
 		c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
 
+	if (cpu_has_tlb) {
+		if (((config4 & MIPS_CONF4_IE) >> 29) == 2) {
+			c->options |= MIPS_CPU_TLBINV;
+			pr_info("TLBINV/F supported, config4=0x%0x\n", config4);
+		}
+	}
+
 	c->kscratch_mask = (config4 >> 16) & 0xff;
 
 	return config4 & MIPS_CONF_M;
@@ -739,6 +746,14 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 		c->cputype = CPU_74K;
 		__cpu_name[cpu] = "MIPS 1074Kc";
 		break;
+	case PRID_IMP_PROAPTIV_UP:
+		c->cputype = CPU_PROAPTIV;
+		__cpu_name[cpu] = "MIPS proAptiv";
+		break;
+	case PRID_IMP_PROAPTIV_MP:
+		c->cputype = CPU_PROAPTIV;
+		__cpu_name[cpu] = "MIPS proAptiv (multi)";
+		break;
 	}
 
 	spram_config();
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
index f7991d9..cb2c94f 100644
--- a/arch/mips/kernel/idle.c
+++ b/arch/mips/kernel/idle.c
@@ -184,6 +184,7 @@ void __init check_wait(void)
 	case CPU_24K:
 	case CPU_34K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		cpu_wait = r4k_wait;
 		if (read_c0_config7() & MIPS_CONF7_WII)
 			cpu_wait = r4k_wait_irqoff;
diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c
index 93f8681..fb72b80 100644
--- a/arch/mips/kernel/spram.c
+++ b/arch/mips/kernel/spram.c
@@ -206,6 +206,7 @@ void spram_config(void)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		config0 = read_c0_config();
 		/* FIXME: addresses are Malta specific */
 		if (config0 & (1<<24)) {
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f9c8746..cc20415 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1336,6 +1336,7 @@ static inline void parity_protection_init(void)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		{
 #define ERRCTL_PE	0x80000000
 #define ERRCTL_L2P	0x00800000
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 62ffd20..24b3a63 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1098,6 +1098,7 @@ static void probe_pcache(void)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		if (current_cpu_type() == CPU_74K)
 			alias_74k_erratum(c);
 		if ((read_c0_config7() & (1 << 16))) {
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 08d05ae..317c249 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -76,6 +76,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 	case CPU_BMIPS5000:
 		if (config2 & (1 << 12))
 			return 0;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 183f2b5..6fdfe1f 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -510,6 +510,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
 		switch (current_cpu_type()) {
 		case CPU_M14KC:
 		case CPU_74K:
+		case CPU_PROAPTIV:
 			break;
 
 		default:
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 3a2b6e9..3e28aaa 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -376,6 +376,10 @@ static int __init mipsxx_init(void)
 		op_model_mipsxx_ops.cpu_type = "mips/74K";
 		break;
 
+	case CPU_PROAPTIV:
+		op_model_mipsxx_ops.cpu_type = "mips/proAptiv";
+		break;
+
 	case CPU_5KC:
 		op_model_mipsxx_ops.cpu_type = "mips/5K";
 		break;
-- 
1.8.4

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

* [PATCH 3/6] MIPS: Add support for the proAptiv cores
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

The proAptiv Multiprocessing System is a power efficient multi-core
microprocessor for use in system-on-chip (SoC) applications.
The proAptiv Multiprocessing System combines a deep pipeline
with multi-issue out of order execution for improved computational
throughput. The proAptiv Multiprocessing System can contain one to
six MIPS32r3 proAptiv cores, system level coherence
manager with L2 cache, optional coherent I/O port, and optional
floating point unit.

Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/cpu-features.h |  3 +++
 arch/mips/include/asm/cpu-type.h     |  1 +
 arch/mips/include/asm/cpu.h          |  5 ++++-
 arch/mips/include/asm/tlb.h          |  4 +++-
 arch/mips/kernel/cpu-probe.c         | 15 +++++++++++++++
 arch/mips/kernel/idle.c              |  1 +
 arch/mips/kernel/spram.c             |  1 +
 arch/mips/kernel/traps.c             |  1 +
 arch/mips/mm/c-r4k.c                 |  1 +
 arch/mips/mm/sc-mips.c               |  1 +
 arch/mips/mm/tlbex.c                 |  1 +
 arch/mips/oprofile/op_model_mipsxx.c |  4 ++++
 12 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index d445d06..296606b 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -20,6 +20,9 @@
 #ifndef cpu_has_tlb
 #define cpu_has_tlb		(cpu_data[0].options & MIPS_CPU_TLB)
 #endif
+#ifndef cpu_has_tlbinv
+#define cpu_has_tlbinv		(cpu_data[0].options & MIPS_CPU_TLBINV)
+#endif
 
 /*
  * For the moment we don't consider R6000 and R8000 so we can assume that
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h
index 4a402cc..673f426 100644
--- a/arch/mips/include/asm/cpu-type.h
+++ b/arch/mips/include/asm/cpu-type.h
@@ -47,6 +47,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
 	case CPU_74K:
 	case CPU_M14KC:
 	case CPU_M14KEC:
+	case CPU_PROAPTIV:
 #endif
 
 #ifdef CONFIG_SYS_HAS_CPU_MIPS64_R1
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index d2035e1..ca5827c 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -111,6 +111,8 @@
 #define PRID_IMP_1074K		0x9a00
 #define PRID_IMP_M14KC		0x9c00
 #define PRID_IMP_M14KEC		0x9e00
+#define PRID_IMP_PROAPTIV_UP	0xa200
+#define PRID_IMP_PROAPTIV_MP	0xa300
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
@@ -289,7 +291,7 @@ enum cpu_type_enum {
 	CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
 	CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
 	CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
-	CPU_M14KEC,
+	CPU_M14KEC, CPU_PROAPTIV,
 
 	/*
 	 * MIPS64 class processors
@@ -348,6 +350,7 @@ enum cpu_type_enum {
 #define MIPS_CPU_PCI		0x00400000 /* CPU has Perf Ctr Int indicator */
 #define MIPS_CPU_RIXI		0x00800000 /* CPU has TLB Read/eXec Inhibit */
 #define MIPS_CPU_MICROMIPS	0x01000000 /* CPU has microMIPS capability */
+#define MIPS_CPU_TLBINV		0x02000000 /* CPU supports TLBINV/F */
 
 /*
  * CPU ASE encodings
diff --git a/arch/mips/include/asm/tlb.h b/arch/mips/include/asm/tlb.h
index 235367ce..4a23493 100644
--- a/arch/mips/include/asm/tlb.h
+++ b/arch/mips/include/asm/tlb.h
@@ -18,7 +18,9 @@
  */
 #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
 
-#define UNIQUE_ENTRYHI(idx)	(CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+#define UNIQUE_ENTRYHI(idx)						\
+		((CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) |		\
+		 (cpu_has_tlbinv ? MIPS_ENTRYHI_EHINV : 0))
 
 #include <asm-generic/tlb.h>
 
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index c814287..8168e29 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -286,6 +286,13 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
 	    && cpu_has_tlb)
 		c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
 
+	if (cpu_has_tlb) {
+		if (((config4 & MIPS_CONF4_IE) >> 29) == 2) {
+			c->options |= MIPS_CPU_TLBINV;
+			pr_info("TLBINV/F supported, config4=0x%0x\n", config4);
+		}
+	}
+
 	c->kscratch_mask = (config4 >> 16) & 0xff;
 
 	return config4 & MIPS_CONF_M;
@@ -739,6 +746,14 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 		c->cputype = CPU_74K;
 		__cpu_name[cpu] = "MIPS 1074Kc";
 		break;
+	case PRID_IMP_PROAPTIV_UP:
+		c->cputype = CPU_PROAPTIV;
+		__cpu_name[cpu] = "MIPS proAptiv";
+		break;
+	case PRID_IMP_PROAPTIV_MP:
+		c->cputype = CPU_PROAPTIV;
+		__cpu_name[cpu] = "MIPS proAptiv (multi)";
+		break;
 	}
 
 	spram_config();
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
index f7991d9..cb2c94f 100644
--- a/arch/mips/kernel/idle.c
+++ b/arch/mips/kernel/idle.c
@@ -184,6 +184,7 @@ void __init check_wait(void)
 	case CPU_24K:
 	case CPU_34K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		cpu_wait = r4k_wait;
 		if (read_c0_config7() & MIPS_CONF7_WII)
 			cpu_wait = r4k_wait_irqoff;
diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c
index 93f8681..fb72b80 100644
--- a/arch/mips/kernel/spram.c
+++ b/arch/mips/kernel/spram.c
@@ -206,6 +206,7 @@ void spram_config(void)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		config0 = read_c0_config();
 		/* FIXME: addresses are Malta specific */
 		if (config0 & (1<<24)) {
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f9c8746..cc20415 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1336,6 +1336,7 @@ static inline void parity_protection_init(void)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		{
 #define ERRCTL_PE	0x80000000
 #define ERRCTL_L2P	0x00800000
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 62ffd20..24b3a63 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1098,6 +1098,7 @@ static void probe_pcache(void)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 		if (current_cpu_type() == CPU_74K)
 			alias_74k_erratum(c);
 		if ((read_c0_config7() & (1 << 16))) {
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 08d05ae..317c249 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -76,6 +76,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+	case CPU_PROAPTIV:
 	case CPU_BMIPS5000:
 		if (config2 & (1 << 12))
 			return 0;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 183f2b5..6fdfe1f 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -510,6 +510,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
 		switch (current_cpu_type()) {
 		case CPU_M14KC:
 		case CPU_74K:
+		case CPU_PROAPTIV:
 			break;
 
 		default:
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 3a2b6e9..3e28aaa 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -376,6 +376,10 @@ static int __init mipsxx_init(void)
 		op_model_mipsxx_ops.cpu_type = "mips/74K";
 		break;
 
+	case CPU_PROAPTIV:
+		op_model_mipsxx_ops.cpu_type = "mips/proAptiv";
+		break;
+
 	case CPU_5KC:
 		op_model_mipsxx_ops.cpu_type = "mips/5K";
 		break;
-- 
1.8.4

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

* [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

The TLBINVF instruction can be used to flush the entire VTLB.
This eliminates the need for the TLBWI loop and improves performance.

Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/mipsregs.h | 13 +++++++++++++
 arch/mips/mm/tlb-r4k.c           | 18 ++++++++++++------
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 412fe99..9cd0e13 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -685,6 +685,19 @@ static inline int mm_insn_16bit(u16 insn)
 }
 
 /*
+ * TLB Invalidate Flush
+ */
+static inline void tlbinvf(void)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set noreorder\n\t"
+		".word 0x42000004\n\t" /* tlbinvf */
+		".set pop");
+}
+
+
+/*
  * Functions to access the R10000 performance counters.	 These are basically
  * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
  * performance counter number encoded into bits 1 ... 5 of the instruction.
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 363aa03..427dcac 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -83,13 +83,19 @@ void local_flush_tlb_all(void)
 	entry = read_c0_wired();
 
 	/* Blast 'em all away. */
-	while (entry < current_cpu_data.tlbsize) {
-		/* Make sure all entries differ. */
-		write_c0_entryhi(UNIQUE_ENTRYHI(entry));
-		write_c0_index(entry);
+	if (cpu_has_tlbinv && current_cpu_data.tlbsize) {
+		write_c0_index(0);
 		mtc0_tlbw_hazard();
-		tlb_write_indexed();
-		entry++;
+		tlbinvf();  /* invalidate VTLB */
+	} else {
+		while (entry < current_cpu_data.tlbsize) {
+			/* Make sure all entries differ. */
+			write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+			write_c0_index(entry);
+			mtc0_tlbw_hazard();
+			tlb_write_indexed();
+			entry++;
+		}
 	}
 	tlbw_use_hazard();
 	write_c0_entryhi(old_ctx);
-- 
1.8.4

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

* [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

The TLBINVF instruction can be used to flush the entire VTLB.
This eliminates the need for the TLBWI loop and improves performance.

Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/mipsregs.h | 13 +++++++++++++
 arch/mips/mm/tlb-r4k.c           | 18 ++++++++++++------
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 412fe99..9cd0e13 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -685,6 +685,19 @@ static inline int mm_insn_16bit(u16 insn)
 }
 
 /*
+ * TLB Invalidate Flush
+ */
+static inline void tlbinvf(void)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set noreorder\n\t"
+		".word 0x42000004\n\t" /* tlbinvf */
+		".set pop");
+}
+
+
+/*
  * Functions to access the R10000 performance counters.	 These are basically
  * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
  * performance counter number encoded into bits 1 ... 5 of the instruction.
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 363aa03..427dcac 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -83,13 +83,19 @@ void local_flush_tlb_all(void)
 	entry = read_c0_wired();
 
 	/* Blast 'em all away. */
-	while (entry < current_cpu_data.tlbsize) {
-		/* Make sure all entries differ. */
-		write_c0_entryhi(UNIQUE_ENTRYHI(entry));
-		write_c0_index(entry);
+	if (cpu_has_tlbinv && current_cpu_data.tlbsize) {
+		write_c0_index(0);
 		mtc0_tlbw_hazard();
-		tlb_write_indexed();
-		entry++;
+		tlbinvf();  /* invalidate VTLB */
+	} else {
+		while (entry < current_cpu_data.tlbsize) {
+			/* Make sure all entries differ. */
+			write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+			write_c0_index(entry);
+			mtc0_tlbw_hazard();
+			tlb_write_indexed();
+			entry++;
+		}
 	}
 	tlbw_use_hazard();
 	write_c0_entryhi(old_ctx);
-- 
1.8.4

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

* [PATCH 5/6] MIPS: Add support for FTLBs
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

The Fixed Page Size TLB (FTLB) is a set-associative dual entry TLB. Its
purpose is to reduce the number of TLB misses by increasing the effective
TLB size and keep the implementation complexity to minimum levels.
A supported core can have both VTLB and FTLB.

Reviewed-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/cpu-info.h |  3 ++
 arch/mips/include/asm/mipsregs.h |  2 +
 arch/mips/include/asm/page.h     | 25 ++++++++++++
 arch/mips/kernel/cpu-probe.c     | 86 ++++++++++++++++++++++++++++++++++++----
 arch/mips/kernel/genex.S         |  1 +
 arch/mips/kernel/traps.c         | 30 ++++++++++++++
 arch/mips/mm/tlb-r4k.c           | 29 ++++++++++----
 7 files changed, 162 insertions(+), 14 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 21c8e29..8f7adf0 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -52,6 +52,9 @@ struct cpuinfo_mips {
 	unsigned int		cputype;
 	int			isa_level;
 	int			tlbsize;
+	int			tlbsizevtlb;
+	int			tlbsizeftlbsets;
+	int			tlbsizeftlbways;
 	struct cache_desc	icache; /* Primary I-cache */
 	struct cache_desc	dcache; /* Primary D or combined I/D cache */
 	struct cache_desc	scache; /* Secondary cache */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 9cd0e13..303bb46 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -645,6 +645,8 @@
 #define MIPS_CONF5_K		(_ULCAST_(1) << 30)
 
 #define MIPS_CONF6_SYND		(_ULCAST_(1) << 13)
+/* proAptiv FTLB on/off bit */
+#define MIPS_CONF6_FTLBEN	(_ULCAST_(1) << 15)
 
 #define MIPS_CONF7_WII		(_ULCAST_(1) << 31)
 
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index f6be474..5e08bcc 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -11,6 +11,8 @@
 
 #include <spaces.h>
 #include <linux/const.h>
+#include <linux/kernel.h>
+#include <asm/mipsregs.h>
 
 /*
  * PAGE_SHIFT determines the page size
@@ -33,6 +35,29 @@
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK	(~((1 << PAGE_SHIFT) - 1))
 
+/*
+ * This is used for calculating the real page sizes
+ * for FTLB or VTLB + FTLB confugrations.
+ */
+static inline unsigned int page_size_ftlb(unsigned int mmuextdef)
+{
+	switch (mmuextdef) {
+	case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
+		if (PAGE_SIZE == (1 << 30))
+			return 5;
+		if (PAGE_SIZE == (1llu << 32))
+			return 6;
+		if (PAGE_SIZE > (256 << 10))
+			return 7; /* reserved */
+			/* fall through */
+	case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
+		return (PAGE_SHIFT - 10) / 2;
+	default:
+		panic("Invalid FTLB configuration with Conf4_mmuextdef=%d value\n",
+		      mmuextdef >> 14);
+	}
+}
+
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 #define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
 #define HPAGE_SIZE	(_AC(1,UL) << HPAGE_SHIFT)
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 8168e29..de364ac 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -163,6 +163,26 @@ static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
 static char unknown_isa[] = KERN_ERR \
 	"Unsupported ISA type, c0.config0: %d.";
 
+static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)
+{
+	unsigned int config6;
+	/*
+	 * Config6 is implementation dependent and it's currently only
+	 * used by proAptiv
+	 */
+	if (c->cputype == CPU_PROAPTIV) {
+		config6 = read_c0_config6();
+		if (enable) {
+			pr_info("Enabling FTLB support\n");
+			write_c0_config6(config6 | MIPS_CONF6_FTLBEN);
+		} else {
+			pr_info("Switching FTLB OFF\n");
+			write_c0_config6(config6 &  ~MIPS_CONF6_FTLBEN);
+		}
+		back_to_back_c0_hazard();
+	}
+}
+
 static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 {
 	unsigned int config0;
@@ -170,8 +190,13 @@ static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 
 	config0 = read_c0_config();
 
-	if (((config0 & MIPS_CONF_MT) >> 7) == 1)
+	/*
+	 * Look for Standard TLB or Dual VTLB and FTLB
+	 */
+	if ((((config0 & MIPS_CONF_MT) >> 7) == 1) ||
+	    (((config0 & MIPS_CONF_MT) >> 7) == 4))
 		c->options |= MIPS_CPU_TLB;
+
 	isa = (config0 & MIPS_CONF_AT) >> 13;
 	switch (isa) {
 	case 0:
@@ -226,8 +251,11 @@ static inline unsigned int decode_config1(struct cpuinfo_mips *c)
 		c->options |= MIPS_CPU_FPU;
 		c->options |= MIPS_CPU_32FPR;
 	}
-	if (cpu_has_tlb)
+	if (cpu_has_tlb) {
 		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
+		c->tlbsizevtlb = c->tlbsize;
+		c->tlbsizeftlbsets = 0;
+	}
 
 	return config1 & MIPS_CONF_M;
 }
@@ -279,18 +307,58 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
 static inline unsigned int decode_config4(struct cpuinfo_mips *c)
 {
 	unsigned int config4;
+	unsigned int newcf4;
+	unsigned int mmuextdef;
+	unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE;
 
 	config4 = read_c0_config4();
 
-	if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
-	    && cpu_has_tlb)
-		c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
-
 	if (cpu_has_tlb) {
 		if (((config4 & MIPS_CONF4_IE) >> 29) == 2) {
 			c->options |= MIPS_CPU_TLBINV;
 			pr_info("TLBINV/F supported, config4=0x%0x\n", config4);
 		}
+		mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
+		switch (mmuextdef) {
+		case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:
+			c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+			c->tlbsizevtlb = c->tlbsize;
+			pr_info("MMUSizeExt found, total TLB=%d\n", c->tlbsize);
+			break;
+		case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
+			c->tlbsizevtlb +=
+				((config4 & MIPS_CONF4_VTLBSIZEEXT) >>
+				  MIPS_CONF4_VTLBSIZEEXT_SHIFT) * 0x40;
+			c->tlbsize = c->tlbsizevtlb;
+			ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
+			/* fall through */
+		case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
+			newcf4 = (config4 & ~ftlb_page) |
+				(page_size_ftlb(mmuextdef) <<
+				 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
+			write_c0_config4(newcf4);
+			back_to_back_c0_hazard();
+			config4 = read_c0_config4();
+			if (config4 != newcf4) {
+				pr_err("PAGE_SIZE 0x%lx is not supported by FTLB (config4=0x%x)\n",
+				       PAGE_SIZE, config4);
+				/* Switch FTLB off */
+				set_ftlb_enable(c, 0);
+				pr_info("Total TLB(VTLB) in use: %d\n",
+					c->tlbsizevtlb);
+				break;
+			}
+			c->tlbsizeftlbsets = 1 <<
+				((config4 & MIPS_CONF4_FTLBSETS) >>
+				 MIPS_CONF4_FTLBSETS_SHIFT);
+			c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
+					      MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
+			c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
+			pr_info("V/FTLB found: VTLB=%d, FTLB sets=%d, ways=%d total TLB=%d\n",
+				c->tlbsizevtlb, c->tlbsizeftlbsets,
+				c->tlbsizeftlbways, c->tlbsize);
+			break;
+		}
 	}
 
 	c->kscratch_mask = (config4 >> 16) & 0xff;
@@ -319,6 +387,9 @@ static void decode_configs(struct cpuinfo_mips *c)
 
 	c->scache.flags = MIPS_CACHE_NOT_PRESENT;
 
+	/* Enable FTLB if present */
+	set_ftlb_enable(c, 1);
+
 	ok = decode_config0(c);			/* Read Config registers.  */
 	BUG_ON(!ok);				/* Arch spec violation!	 */
 	if (ok)
@@ -682,7 +753,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 
 static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 {
-	decode_configs(c);
 	switch (c->processor_id & PRID_IMP_MASK) {
 	case PRID_IMP_4KC:
 		c->cputype = CPU_4KC;
@@ -756,6 +826,8 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 		break;
 	}
 
+	decode_configs(c);
+
 	spram_config();
 }
 
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 72853aa..bf56ae1 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -476,6 +476,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
 	BUILD_HANDLER ov ov sti silent			/* #12 */
 	BUILD_HANDLER tr tr sti silent			/* #13 */
 	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
+	BUILD_HANDLER ftlb ftlb none silent		/* #16 */
 	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */
 #ifdef	CONFIG_HARDWARE_WATCHPOINTS
 	/*
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cc20415..7541855 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -78,6 +78,7 @@ extern asmlinkage void handle_cpu(void);
 extern asmlinkage void handle_ov(void);
 extern asmlinkage void handle_tr(void);
 extern asmlinkage void handle_fpe(void);
+extern asmlinkage void handle_ftlb(void);
 extern asmlinkage void handle_mdmx(void);
 extern asmlinkage void handle_watch(void);
 extern asmlinkage void handle_mt(void);
@@ -1447,6 +1448,34 @@ asmlinkage void cache_parity_error(void)
 	panic("Can't handle the cache error!");
 }
 
+asmlinkage void do_ftlb(void)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned int reg_val;
+
+	/* For the moment, report the problem and hang. */
+	if (cpu_has_mips_r2 &&
+	    ((current_cpu_data.processor_id && 0xff0000) == PRID_COMP_MIPS)) {
+		pr_err("FTLB error exception, cp0_ecc=0x%08x:\n",
+		       read_c0_ecc());
+		pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
+		reg_val = read_c0_cacheerr();
+		pr_err("c0_cacheerr == %08x\n", reg_val);
+
+		if ((reg_val & 0xc0000000) == 0xc0000000) {
+			pr_err("Decoded c0_cacheerr: FTLB parity error\n");
+		} else {
+			pr_err("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
+			       reg_val & (1<<30) ? "secondary" : "primary",
+			       reg_val & (1<<31) ? "data" : "insn");
+		}
+	} else {
+		pr_err("FTLB error exception\n");
+	}
+	/* Just print the cacheerr bits for now */
+	cache_parity_error();
+}
+
 /*
  * SDBBP EJTAG debug exception handler.
  * We skip the instruction and return to the next instruction.
@@ -1996,6 +2025,7 @@ void __init trap_init(void)
 	if (cpu_has_fpu && !cpu_has_nofpuex)
 		set_except_vector(15, handle_fpe);
 
+	set_except_vector(16, handle_ftlb);
 	set_except_vector(22, handle_mdmx);
 
 	if (cpu_has_mcheck)
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 427dcac..11f149c 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -72,7 +72,7 @@ void local_flush_tlb_all(void)
 {
 	unsigned long flags;
 	unsigned long old_ctx;
-	int entry;
+	int entry, ftlbhighset;
 
 	ENTER_CRITICAL(flags);
 	/* Save old context and create impossible VPN2 value */
@@ -83,10 +83,21 @@ void local_flush_tlb_all(void)
 	entry = read_c0_wired();
 
 	/* Blast 'em all away. */
-	if (cpu_has_tlbinv && current_cpu_data.tlbsize) {
-		write_c0_index(0);
-		mtc0_tlbw_hazard();
-		tlbinvf();  /* invalidate VTLB */
+	if (cpu_has_tlbinv) {
+		if (current_cpu_data.tlbsizevtlb) {
+			write_c0_index(0);
+			mtc0_tlbw_hazard();
+			tlbinvf();  /* invalidate VTLB */
+		}
+		ftlbhighset = current_cpu_data.tlbsizevtlb +
+			current_cpu_data.tlbsizeftlbsets;
+		for (entry = current_cpu_data.tlbsizevtlb;
+		     entry < ftlbhighset;
+		     entry++) {
+			write_c0_index(entry);
+			mtc0_tlbw_hazard();
+			tlbinvf();  /* invalide one FTLB set */
+		}
 	} else {
 		while (entry < current_cpu_data.tlbsize) {
 			/* Make sure all entries differ. */
@@ -134,7 +145,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		start = round_down(start, PAGE_SIZE << 1);
 		end = round_up(end, PAGE_SIZE << 1);
 		size = (end - start) >> (PAGE_SHIFT + 1);
-		if (size <= current_cpu_data.tlbsize/2) {
+		if (size <= (current_cpu_data.tlbsizeftlbsets ?
+			     current_cpu_data.tlbsize / 8 :
+			     current_cpu_data.tlbsize / 2)) {
 			int oldpid = read_c0_entryhi();
 			int newpid = cpu_asid(cpu, mm);
 
@@ -173,7 +186,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 	ENTER_CRITICAL(flags);
 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 	size = (size + 1) >> 1;
-	if (size <= current_cpu_data.tlbsize / 2) {
+	if (size <= (current_cpu_data.tlbsizeftlbsets ?
+		     current_cpu_data.tlbsize / 8 :
+		     current_cpu_data.tlbsize / 2)) {
 		int pid = read_c0_entryhi();
 
 		start &= (PAGE_MASK << 1);
-- 
1.8.4

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

* [PATCH 5/6] MIPS: Add support for FTLBs
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Leonid Yegoshin, Markos Chandras

From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>

The Fixed Page Size TLB (FTLB) is a set-associative dual entry TLB. Its
purpose is to reduce the number of TLB misses by increasing the effective
TLB size and keep the implementation complexity to minimum levels.
A supported core can have both VTLB and FTLB.

Reviewed-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/cpu-info.h |  3 ++
 arch/mips/include/asm/mipsregs.h |  2 +
 arch/mips/include/asm/page.h     | 25 ++++++++++++
 arch/mips/kernel/cpu-probe.c     | 86 ++++++++++++++++++++++++++++++++++++----
 arch/mips/kernel/genex.S         |  1 +
 arch/mips/kernel/traps.c         | 30 ++++++++++++++
 arch/mips/mm/tlb-r4k.c           | 29 ++++++++++----
 7 files changed, 162 insertions(+), 14 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 21c8e29..8f7adf0 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -52,6 +52,9 @@ struct cpuinfo_mips {
 	unsigned int		cputype;
 	int			isa_level;
 	int			tlbsize;
+	int			tlbsizevtlb;
+	int			tlbsizeftlbsets;
+	int			tlbsizeftlbways;
 	struct cache_desc	icache; /* Primary I-cache */
 	struct cache_desc	dcache; /* Primary D or combined I/D cache */
 	struct cache_desc	scache; /* Secondary cache */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 9cd0e13..303bb46 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -645,6 +645,8 @@
 #define MIPS_CONF5_K		(_ULCAST_(1) << 30)
 
 #define MIPS_CONF6_SYND		(_ULCAST_(1) << 13)
+/* proAptiv FTLB on/off bit */
+#define MIPS_CONF6_FTLBEN	(_ULCAST_(1) << 15)
 
 #define MIPS_CONF7_WII		(_ULCAST_(1) << 31)
 
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index f6be474..5e08bcc 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -11,6 +11,8 @@
 
 #include <spaces.h>
 #include <linux/const.h>
+#include <linux/kernel.h>
+#include <asm/mipsregs.h>
 
 /*
  * PAGE_SHIFT determines the page size
@@ -33,6 +35,29 @@
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK	(~((1 << PAGE_SHIFT) - 1))
 
+/*
+ * This is used for calculating the real page sizes
+ * for FTLB or VTLB + FTLB confugrations.
+ */
+static inline unsigned int page_size_ftlb(unsigned int mmuextdef)
+{
+	switch (mmuextdef) {
+	case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
+		if (PAGE_SIZE == (1 << 30))
+			return 5;
+		if (PAGE_SIZE == (1llu << 32))
+			return 6;
+		if (PAGE_SIZE > (256 << 10))
+			return 7; /* reserved */
+			/* fall through */
+	case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
+		return (PAGE_SHIFT - 10) / 2;
+	default:
+		panic("Invalid FTLB configuration with Conf4_mmuextdef=%d value\n",
+		      mmuextdef >> 14);
+	}
+}
+
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 #define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
 #define HPAGE_SIZE	(_AC(1,UL) << HPAGE_SHIFT)
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 8168e29..de364ac 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -163,6 +163,26 @@ static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
 static char unknown_isa[] = KERN_ERR \
 	"Unsupported ISA type, c0.config0: %d.";
 
+static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)
+{
+	unsigned int config6;
+	/*
+	 * Config6 is implementation dependent and it's currently only
+	 * used by proAptiv
+	 */
+	if (c->cputype == CPU_PROAPTIV) {
+		config6 = read_c0_config6();
+		if (enable) {
+			pr_info("Enabling FTLB support\n");
+			write_c0_config6(config6 | MIPS_CONF6_FTLBEN);
+		} else {
+			pr_info("Switching FTLB OFF\n");
+			write_c0_config6(config6 &  ~MIPS_CONF6_FTLBEN);
+		}
+		back_to_back_c0_hazard();
+	}
+}
+
 static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 {
 	unsigned int config0;
@@ -170,8 +190,13 @@ static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 
 	config0 = read_c0_config();
 
-	if (((config0 & MIPS_CONF_MT) >> 7) == 1)
+	/*
+	 * Look for Standard TLB or Dual VTLB and FTLB
+	 */
+	if ((((config0 & MIPS_CONF_MT) >> 7) == 1) ||
+	    (((config0 & MIPS_CONF_MT) >> 7) == 4))
 		c->options |= MIPS_CPU_TLB;
+
 	isa = (config0 & MIPS_CONF_AT) >> 13;
 	switch (isa) {
 	case 0:
@@ -226,8 +251,11 @@ static inline unsigned int decode_config1(struct cpuinfo_mips *c)
 		c->options |= MIPS_CPU_FPU;
 		c->options |= MIPS_CPU_32FPR;
 	}
-	if (cpu_has_tlb)
+	if (cpu_has_tlb) {
 		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
+		c->tlbsizevtlb = c->tlbsize;
+		c->tlbsizeftlbsets = 0;
+	}
 
 	return config1 & MIPS_CONF_M;
 }
@@ -279,18 +307,58 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
 static inline unsigned int decode_config4(struct cpuinfo_mips *c)
 {
 	unsigned int config4;
+	unsigned int newcf4;
+	unsigned int mmuextdef;
+	unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE;
 
 	config4 = read_c0_config4();
 
-	if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
-	    && cpu_has_tlb)
-		c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
-
 	if (cpu_has_tlb) {
 		if (((config4 & MIPS_CONF4_IE) >> 29) == 2) {
 			c->options |= MIPS_CPU_TLBINV;
 			pr_info("TLBINV/F supported, config4=0x%0x\n", config4);
 		}
+		mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
+		switch (mmuextdef) {
+		case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:
+			c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+			c->tlbsizevtlb = c->tlbsize;
+			pr_info("MMUSizeExt found, total TLB=%d\n", c->tlbsize);
+			break;
+		case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
+			c->tlbsizevtlb +=
+				((config4 & MIPS_CONF4_VTLBSIZEEXT) >>
+				  MIPS_CONF4_VTLBSIZEEXT_SHIFT) * 0x40;
+			c->tlbsize = c->tlbsizevtlb;
+			ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
+			/* fall through */
+		case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
+			newcf4 = (config4 & ~ftlb_page) |
+				(page_size_ftlb(mmuextdef) <<
+				 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
+			write_c0_config4(newcf4);
+			back_to_back_c0_hazard();
+			config4 = read_c0_config4();
+			if (config4 != newcf4) {
+				pr_err("PAGE_SIZE 0x%lx is not supported by FTLB (config4=0x%x)\n",
+				       PAGE_SIZE, config4);
+				/* Switch FTLB off */
+				set_ftlb_enable(c, 0);
+				pr_info("Total TLB(VTLB) in use: %d\n",
+					c->tlbsizevtlb);
+				break;
+			}
+			c->tlbsizeftlbsets = 1 <<
+				((config4 & MIPS_CONF4_FTLBSETS) >>
+				 MIPS_CONF4_FTLBSETS_SHIFT);
+			c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
+					      MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
+			c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
+			pr_info("V/FTLB found: VTLB=%d, FTLB sets=%d, ways=%d total TLB=%d\n",
+				c->tlbsizevtlb, c->tlbsizeftlbsets,
+				c->tlbsizeftlbways, c->tlbsize);
+			break;
+		}
 	}
 
 	c->kscratch_mask = (config4 >> 16) & 0xff;
@@ -319,6 +387,9 @@ static void decode_configs(struct cpuinfo_mips *c)
 
 	c->scache.flags = MIPS_CACHE_NOT_PRESENT;
 
+	/* Enable FTLB if present */
+	set_ftlb_enable(c, 1);
+
 	ok = decode_config0(c);			/* Read Config registers.  */
 	BUG_ON(!ok);				/* Arch spec violation!	 */
 	if (ok)
@@ -682,7 +753,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 
 static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 {
-	decode_configs(c);
 	switch (c->processor_id & PRID_IMP_MASK) {
 	case PRID_IMP_4KC:
 		c->cputype = CPU_4KC;
@@ -756,6 +826,8 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 		break;
 	}
 
+	decode_configs(c);
+
 	spram_config();
 }
 
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 72853aa..bf56ae1 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -476,6 +476,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
 	BUILD_HANDLER ov ov sti silent			/* #12 */
 	BUILD_HANDLER tr tr sti silent			/* #13 */
 	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
+	BUILD_HANDLER ftlb ftlb none silent		/* #16 */
 	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */
 #ifdef	CONFIG_HARDWARE_WATCHPOINTS
 	/*
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cc20415..7541855 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -78,6 +78,7 @@ extern asmlinkage void handle_cpu(void);
 extern asmlinkage void handle_ov(void);
 extern asmlinkage void handle_tr(void);
 extern asmlinkage void handle_fpe(void);
+extern asmlinkage void handle_ftlb(void);
 extern asmlinkage void handle_mdmx(void);
 extern asmlinkage void handle_watch(void);
 extern asmlinkage void handle_mt(void);
@@ -1447,6 +1448,34 @@ asmlinkage void cache_parity_error(void)
 	panic("Can't handle the cache error!");
 }
 
+asmlinkage void do_ftlb(void)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned int reg_val;
+
+	/* For the moment, report the problem and hang. */
+	if (cpu_has_mips_r2 &&
+	    ((current_cpu_data.processor_id && 0xff0000) == PRID_COMP_MIPS)) {
+		pr_err("FTLB error exception, cp0_ecc=0x%08x:\n",
+		       read_c0_ecc());
+		pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
+		reg_val = read_c0_cacheerr();
+		pr_err("c0_cacheerr == %08x\n", reg_val);
+
+		if ((reg_val & 0xc0000000) == 0xc0000000) {
+			pr_err("Decoded c0_cacheerr: FTLB parity error\n");
+		} else {
+			pr_err("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
+			       reg_val & (1<<30) ? "secondary" : "primary",
+			       reg_val & (1<<31) ? "data" : "insn");
+		}
+	} else {
+		pr_err("FTLB error exception\n");
+	}
+	/* Just print the cacheerr bits for now */
+	cache_parity_error();
+}
+
 /*
  * SDBBP EJTAG debug exception handler.
  * We skip the instruction and return to the next instruction.
@@ -1996,6 +2025,7 @@ void __init trap_init(void)
 	if (cpu_has_fpu && !cpu_has_nofpuex)
 		set_except_vector(15, handle_fpe);
 
+	set_except_vector(16, handle_ftlb);
 	set_except_vector(22, handle_mdmx);
 
 	if (cpu_has_mcheck)
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 427dcac..11f149c 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -72,7 +72,7 @@ void local_flush_tlb_all(void)
 {
 	unsigned long flags;
 	unsigned long old_ctx;
-	int entry;
+	int entry, ftlbhighset;
 
 	ENTER_CRITICAL(flags);
 	/* Save old context and create impossible VPN2 value */
@@ -83,10 +83,21 @@ void local_flush_tlb_all(void)
 	entry = read_c0_wired();
 
 	/* Blast 'em all away. */
-	if (cpu_has_tlbinv && current_cpu_data.tlbsize) {
-		write_c0_index(0);
-		mtc0_tlbw_hazard();
-		tlbinvf();  /* invalidate VTLB */
+	if (cpu_has_tlbinv) {
+		if (current_cpu_data.tlbsizevtlb) {
+			write_c0_index(0);
+			mtc0_tlbw_hazard();
+			tlbinvf();  /* invalidate VTLB */
+		}
+		ftlbhighset = current_cpu_data.tlbsizevtlb +
+			current_cpu_data.tlbsizeftlbsets;
+		for (entry = current_cpu_data.tlbsizevtlb;
+		     entry < ftlbhighset;
+		     entry++) {
+			write_c0_index(entry);
+			mtc0_tlbw_hazard();
+			tlbinvf();  /* invalide one FTLB set */
+		}
 	} else {
 		while (entry < current_cpu_data.tlbsize) {
 			/* Make sure all entries differ. */
@@ -134,7 +145,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		start = round_down(start, PAGE_SIZE << 1);
 		end = round_up(end, PAGE_SIZE << 1);
 		size = (end - start) >> (PAGE_SHIFT + 1);
-		if (size <= current_cpu_data.tlbsize/2) {
+		if (size <= (current_cpu_data.tlbsizeftlbsets ?
+			     current_cpu_data.tlbsize / 8 :
+			     current_cpu_data.tlbsize / 2)) {
 			int oldpid = read_c0_entryhi();
 			int newpid = cpu_asid(cpu, mm);
 
@@ -173,7 +186,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 	ENTER_CRITICAL(flags);
 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 	size = (size + 1) >> 1;
-	if (size <= current_cpu_data.tlbsize / 2) {
+	if (size <= (current_cpu_data.tlbsizeftlbsets ?
+		     current_cpu_data.tlbsize / 8 :
+		     current_cpu_data.tlbsize / 2)) {
 		int pid = read_c0_entryhi();
 
 		start &= (PAGE_MASK << 1);
-- 
1.8.4

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

* [PATCH 6/6] MIPS: Add debugfs file to print the segmentation control registers
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Steven J. Hill, Markos Chandras

From: "Steven J. Hill" <Steven.Hill@imgtec.com>

Add a new mips/segments debugfs file to print the 6 segmentation
control registers for supported cores. A sample from a proAptiv core
is given below:

Segment   Virtual    Size   Access Mode   Physical   Caching   EU
-------   -------    ----   -----------   --------   -------   --
   0      e0000000   512M      MK           UND         U       0
   1      c0000000   512M      MSK          UND         U       0
   2      a0000000   512M      UK           000         2       0
   3      80000000   512M      UK           000         3       0
   4      40000000    1G       MUSK         UND         U       1
   5      00000000    1G       MUSK         UND         U       1

Reviewed-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/cpu-features.h |   4 ++
 arch/mips/include/asm/cpu.h          |   1 +
 arch/mips/include/asm/mipsregs.h     |  29 +++++++++
 arch/mips/kernel/Makefile            |   1 +
 arch/mips/kernel/cpu-probe.c         |   2 +
 arch/mips/kernel/segment.c           | 110 +++++++++++++++++++++++++++++++++++
 6 files changed, 147 insertions(+)
 create mode 100644 arch/mips/kernel/segment.c

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 296606b..6e70b03 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -23,6 +23,10 @@
 #ifndef cpu_has_tlbinv
 #define cpu_has_tlbinv		(cpu_data[0].options & MIPS_CPU_TLBINV)
 #endif
+#ifndef cpu_has_segments
+#define cpu_has_segments	(cpu_data[0].options & MIPS_CPU_SEGMENTS)
+#endif
+
 
 /*
  * For the moment we don't consider R6000 and R8000 so we can assume that
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index ca5827c..9bb2abe 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -351,6 +351,7 @@ enum cpu_type_enum {
 #define MIPS_CPU_RIXI		0x00800000 /* CPU has TLB Read/eXec Inhibit */
 #define MIPS_CPU_MICROMIPS	0x01000000 /* CPU has microMIPS capability */
 #define MIPS_CPU_TLBINV		0x02000000 /* CPU supports TLBINV/F */
+#define MIPS_CPU_SEGMENTS	0x04000000 /* CPU supports Segmentation Control registers */
 
 /*
  * CPU ASE encodings
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 303bb46..cb57e07 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -666,6 +666,26 @@
 #define MIPS_FPIR_L		(_ULCAST_(1) << 21)
 #define MIPS_FPIR_F64		(_ULCAST_(1) << 22)
 
+/*
+ * Bits in the MIPS32 Memory Segmentation registers.
+ */
+#define MIPS_SEGCFG_PA_SHIFT	9
+#define MIPS_SEGCFG_PA		(_ULCAST_(127) << MIPS_SEGCFG_PA_SHIFT)
+#define MIPS_SEGCFG_AM_SHIFT	4
+#define MIPS_SEGCFG_AM		(_ULCAST_(7) << MIPS_SEGCFG_AM_SHIFT)
+#define MIPS_SEGCFG_EU_SHIFT	3
+#define MIPS_SEGCFG_EU		(_ULCAST_(1) << MIPS_SEGCFG_EU_SHIFT)
+#define MIPS_SEGCFG_C_SHIFT	0
+#define MIPS_SEGCFG_C		(_ULCAST_(7) << MIPS_SEGCFG_C_SHIFT)
+
+#define MIPS_SEGCFG_UUSK	_ULCAST_(7)
+#define MIPS_SEGCFG_USK		_ULCAST_(5)
+#define MIPS_SEGCFG_MUSUK	_ULCAST_(4)
+#define MIPS_SEGCFG_MUSK	_ULCAST_(3)
+#define MIPS_SEGCFG_MSK		_ULCAST_(2)
+#define MIPS_SEGCFG_MK		_ULCAST_(1)
+#define MIPS_SEGCFG_UK		_ULCAST_(0)
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -1153,6 +1173,15 @@ do {									\
 #define read_c0_ebase()		__read_32bit_c0_register($15, 1)
 #define write_c0_ebase(val)	__write_32bit_c0_register($15, 1, val)
 
+/* MIPSR3 */
+#define read_c0_segctl0()	__read_32bit_c0_register($5, 2)
+#define write_c0_segctl0(val)	__write_32bit_c0_register($5, 2, val)
+
+#define read_c0_segctl1()	__read_32bit_c0_register($5, 3)
+#define write_c0_segctl1(val)	__write_32bit_c0_register($5, 3, val)
+
+#define read_c0_segctl2()	__read_32bit_c0_register($5, 4)
+#define write_c0_segctl2(val)	__write_32bit_c0_register($5, 4, val)
 
 /* Cavium OCTEON (cnMIPS) */
 #define read_c0_cvmcount()	__read_ulong_c0_register($9, 6)
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 1c1b717..b95eb741 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CSRC_R4K)		+= csrc-r4k.o
 obj-$(CONFIG_CSRC_SB1250)	+= csrc-sb1250.o
 obj-$(CONFIG_SYNC_R4K)		+= sync-r4k.o
 
+obj-$(CONFIG_DEBUG_FS)		+= segment.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_MODULES)		+= mips_ksyms.o module.o
 obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index de364ac..beea299 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -300,6 +300,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
 		c->options |= MIPS_CPU_MICROMIPS;
 	if (config3 & MIPS_CONF3_VZ)
 		c->ases |= MIPS_ASE_VZ;
+	if (config3 & MIPS_CONF3_SC)
+		c->options |= MIPS_CPU_SEGMENTS;
 
 	return config3 & MIPS_CONF_M;
 }
diff --git a/arch/mips/kernel/segment.c b/arch/mips/kernel/segment.c
new file mode 100644
index 0000000..076ead2
--- /dev/null
+++ b/arch/mips/kernel/segment.c
@@ -0,0 +1,110 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ */
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+
+static void build_segment_config(char *str, unsigned int cfg)
+{
+	unsigned int am;
+	static const char * const am_str[] = {
+		"UK", "MK", "MSK", "MUSK", "MUSUK", "USK",
+		"RSRVD", "UUSK"};
+
+	/* Segment access mode. */
+	am = (cfg & MIPS_SEGCFG_AM) >> MIPS_SEGCFG_AM_SHIFT;
+	str += sprintf(str, "%-5s", am_str[am]);
+
+	/*
+	 * Access modes MK, MSK and MUSK are mapped segments. Therefore
+	 * there is no direct physical address mapping.
+	 */
+	if ((am == 0) || (am > 3)) {
+		str += sprintf(str, "         %03lx",
+			((cfg & MIPS_SEGCFG_PA) >> MIPS_SEGCFG_PA_SHIFT));
+		str += sprintf(str, "         %01ld",
+			((cfg & MIPS_SEGCFG_C) >> MIPS_SEGCFG_C_SHIFT));
+	} else {
+		str += sprintf(str, "         UND");
+		str += sprintf(str, "         U");
+	}
+
+	/* Exception configuration. */
+	str += sprintf(str, "       %01ld\n",
+		((cfg & MIPS_SEGCFG_EU) >> MIPS_SEGCFG_EU_SHIFT));
+}
+
+static int show_segments(struct seq_file *m, void *v)
+{
+	unsigned int segcfg;
+	char str[42];
+
+	seq_puts(m, "Segment   Virtual    Size   Access Mode   Physical   Caching   EU\n");
+	seq_puts(m, "-------   -------    ----   -----------   --------   -------   --\n");
+
+	segcfg = read_c0_segctl0();
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   0      e0000000   512M      %s", str);
+
+	segcfg >>= 16;
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   1      c0000000   512M      %s", str);
+
+	segcfg = read_c0_segctl1();
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   2      a0000000   512M      %s", str);
+
+	segcfg >>= 16;
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   3      80000000   512M      %s", str);
+
+	segcfg = read_c0_segctl2();
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   4      40000000    1G       %s", str);
+
+	segcfg >>= 16;
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   5      00000000    1G       %s\n", str);
+
+	return 0;
+}
+
+static int segments_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, show_segments, NULL);
+}
+
+static const struct file_operations segments_fops = {
+	.open		= segments_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init segments_info(void)
+{
+	extern struct dentry *mips_debugfs_dir;
+	struct dentry *segments;
+
+	if (cpu_has_segments) {
+		if (!mips_debugfs_dir)
+			return -ENODEV;
+
+		segments = debugfs_create_file("segments", S_IRUGO,
+					       mips_debugfs_dir, NULL,
+					       &segments_fops);
+		if (!segments)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+device_initcall(segments_info);
-- 
1.8.4

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

* [PATCH 6/6] MIPS: Add debugfs file to print the segmentation control registers
@ 2013-11-07 17:08   ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-07 17:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Steven J. Hill, Markos Chandras

From: "Steven J. Hill" <Steven.Hill@imgtec.com>

Add a new mips/segments debugfs file to print the 6 segmentation
control registers for supported cores. A sample from a proAptiv core
is given below:

Segment   Virtual    Size   Access Mode   Physical   Caching   EU
-------   -------    ----   -----------   --------   -------   --
   0      e0000000   512M      MK           UND         U       0
   1      c0000000   512M      MSK          UND         U       0
   2      a0000000   512M      UK           000         2       0
   3      80000000   512M      UK           000         3       0
   4      40000000    1G       MUSK         UND         U       1
   5      00000000    1G       MUSK         UND         U       1

Reviewed-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 arch/mips/include/asm/cpu-features.h |   4 ++
 arch/mips/include/asm/cpu.h          |   1 +
 arch/mips/include/asm/mipsregs.h     |  29 +++++++++
 arch/mips/kernel/Makefile            |   1 +
 arch/mips/kernel/cpu-probe.c         |   2 +
 arch/mips/kernel/segment.c           | 110 +++++++++++++++++++++++++++++++++++
 6 files changed, 147 insertions(+)
 create mode 100644 arch/mips/kernel/segment.c

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 296606b..6e70b03 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -23,6 +23,10 @@
 #ifndef cpu_has_tlbinv
 #define cpu_has_tlbinv		(cpu_data[0].options & MIPS_CPU_TLBINV)
 #endif
+#ifndef cpu_has_segments
+#define cpu_has_segments	(cpu_data[0].options & MIPS_CPU_SEGMENTS)
+#endif
+
 
 /*
  * For the moment we don't consider R6000 and R8000 so we can assume that
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index ca5827c..9bb2abe 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -351,6 +351,7 @@ enum cpu_type_enum {
 #define MIPS_CPU_RIXI		0x00800000 /* CPU has TLB Read/eXec Inhibit */
 #define MIPS_CPU_MICROMIPS	0x01000000 /* CPU has microMIPS capability */
 #define MIPS_CPU_TLBINV		0x02000000 /* CPU supports TLBINV/F */
+#define MIPS_CPU_SEGMENTS	0x04000000 /* CPU supports Segmentation Control registers */
 
 /*
  * CPU ASE encodings
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 303bb46..cb57e07 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -666,6 +666,26 @@
 #define MIPS_FPIR_L		(_ULCAST_(1) << 21)
 #define MIPS_FPIR_F64		(_ULCAST_(1) << 22)
 
+/*
+ * Bits in the MIPS32 Memory Segmentation registers.
+ */
+#define MIPS_SEGCFG_PA_SHIFT	9
+#define MIPS_SEGCFG_PA		(_ULCAST_(127) << MIPS_SEGCFG_PA_SHIFT)
+#define MIPS_SEGCFG_AM_SHIFT	4
+#define MIPS_SEGCFG_AM		(_ULCAST_(7) << MIPS_SEGCFG_AM_SHIFT)
+#define MIPS_SEGCFG_EU_SHIFT	3
+#define MIPS_SEGCFG_EU		(_ULCAST_(1) << MIPS_SEGCFG_EU_SHIFT)
+#define MIPS_SEGCFG_C_SHIFT	0
+#define MIPS_SEGCFG_C		(_ULCAST_(7) << MIPS_SEGCFG_C_SHIFT)
+
+#define MIPS_SEGCFG_UUSK	_ULCAST_(7)
+#define MIPS_SEGCFG_USK		_ULCAST_(5)
+#define MIPS_SEGCFG_MUSUK	_ULCAST_(4)
+#define MIPS_SEGCFG_MUSK	_ULCAST_(3)
+#define MIPS_SEGCFG_MSK		_ULCAST_(2)
+#define MIPS_SEGCFG_MK		_ULCAST_(1)
+#define MIPS_SEGCFG_UK		_ULCAST_(0)
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -1153,6 +1173,15 @@ do {									\
 #define read_c0_ebase()		__read_32bit_c0_register($15, 1)
 #define write_c0_ebase(val)	__write_32bit_c0_register($15, 1, val)
 
+/* MIPSR3 */
+#define read_c0_segctl0()	__read_32bit_c0_register($5, 2)
+#define write_c0_segctl0(val)	__write_32bit_c0_register($5, 2, val)
+
+#define read_c0_segctl1()	__read_32bit_c0_register($5, 3)
+#define write_c0_segctl1(val)	__write_32bit_c0_register($5, 3, val)
+
+#define read_c0_segctl2()	__read_32bit_c0_register($5, 4)
+#define write_c0_segctl2(val)	__write_32bit_c0_register($5, 4, val)
 
 /* Cavium OCTEON (cnMIPS) */
 #define read_c0_cvmcount()	__read_ulong_c0_register($9, 6)
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 1c1b717..b95eb741 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CSRC_R4K)		+= csrc-r4k.o
 obj-$(CONFIG_CSRC_SB1250)	+= csrc-sb1250.o
 obj-$(CONFIG_SYNC_R4K)		+= sync-r4k.o
 
+obj-$(CONFIG_DEBUG_FS)		+= segment.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_MODULES)		+= mips_ksyms.o module.o
 obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index de364ac..beea299 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -300,6 +300,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
 		c->options |= MIPS_CPU_MICROMIPS;
 	if (config3 & MIPS_CONF3_VZ)
 		c->ases |= MIPS_ASE_VZ;
+	if (config3 & MIPS_CONF3_SC)
+		c->options |= MIPS_CPU_SEGMENTS;
 
 	return config3 & MIPS_CONF_M;
 }
diff --git a/arch/mips/kernel/segment.c b/arch/mips/kernel/segment.c
new file mode 100644
index 0000000..076ead2
--- /dev/null
+++ b/arch/mips/kernel/segment.c
@@ -0,0 +1,110 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ */
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+
+static void build_segment_config(char *str, unsigned int cfg)
+{
+	unsigned int am;
+	static const char * const am_str[] = {
+		"UK", "MK", "MSK", "MUSK", "MUSUK", "USK",
+		"RSRVD", "UUSK"};
+
+	/* Segment access mode. */
+	am = (cfg & MIPS_SEGCFG_AM) >> MIPS_SEGCFG_AM_SHIFT;
+	str += sprintf(str, "%-5s", am_str[am]);
+
+	/*
+	 * Access modes MK, MSK and MUSK are mapped segments. Therefore
+	 * there is no direct physical address mapping.
+	 */
+	if ((am == 0) || (am > 3)) {
+		str += sprintf(str, "         %03lx",
+			((cfg & MIPS_SEGCFG_PA) >> MIPS_SEGCFG_PA_SHIFT));
+		str += sprintf(str, "         %01ld",
+			((cfg & MIPS_SEGCFG_C) >> MIPS_SEGCFG_C_SHIFT));
+	} else {
+		str += sprintf(str, "         UND");
+		str += sprintf(str, "         U");
+	}
+
+	/* Exception configuration. */
+	str += sprintf(str, "       %01ld\n",
+		((cfg & MIPS_SEGCFG_EU) >> MIPS_SEGCFG_EU_SHIFT));
+}
+
+static int show_segments(struct seq_file *m, void *v)
+{
+	unsigned int segcfg;
+	char str[42];
+
+	seq_puts(m, "Segment   Virtual    Size   Access Mode   Physical   Caching   EU\n");
+	seq_puts(m, "-------   -------    ----   -----------   --------   -------   --\n");
+
+	segcfg = read_c0_segctl0();
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   0      e0000000   512M      %s", str);
+
+	segcfg >>= 16;
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   1      c0000000   512M      %s", str);
+
+	segcfg = read_c0_segctl1();
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   2      a0000000   512M      %s", str);
+
+	segcfg >>= 16;
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   3      80000000   512M      %s", str);
+
+	segcfg = read_c0_segctl2();
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   4      40000000    1G       %s", str);
+
+	segcfg >>= 16;
+	build_segment_config(str, segcfg);
+	seq_printf(m, "   5      00000000    1G       %s\n", str);
+
+	return 0;
+}
+
+static int segments_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, show_segments, NULL);
+}
+
+static const struct file_operations segments_fops = {
+	.open		= segments_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init segments_info(void)
+{
+	extern struct dentry *mips_debugfs_dir;
+	struct dentry *segments;
+
+	if (cpu_has_segments) {
+		if (!mips_debugfs_dir)
+			return -ENODEV;
+
+		segments = debugfs_create_file("segments", S_IRUGO,
+					       mips_debugfs_dir, NULL,
+					       &segments_fops);
+		if (!segments)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+device_initcall(segments_info);
-- 
1.8.4

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

* Re: [PATCH 3/6] MIPS: Add support for the proAptiv cores
  2013-11-07 17:08   ` Markos Chandras
  (?)
@ 2013-11-11 19:59   ` David Daney
  2013-11-12  9:41       ` Markos Chandras
  -1 siblings, 1 reply; 23+ messages in thread
From: David Daney @ 2013-11-11 19:59 UTC (permalink / raw)
  To: Markos Chandras; +Cc: linux-mips, Leonid Yegoshin

On 11/07/2013 09:08 AM, Markos Chandras wrote:
> From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>
> The proAptiv Multiprocessing System is a power efficient multi-core
> microprocessor for use in system-on-chip (SoC) applications.
> The proAptiv Multiprocessing System combines a deep pipeline
> with multi-issue out of order execution for improved computational
> throughput. The proAptiv Multiprocessing System can contain one to
> six MIPS32r3 proAptiv cores, system level coherence
> manager with L2 cache, optional coherent I/O port, and optional
> floating point unit.
>
> Reviewed-by: Paul Burton <paul.burton@imgtec.com>
> Reviewed-by: James Hogan <james.hogan@imgtec.com>
> Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>


This patch is a big collection of small unrelated changes.

Can you break it up so that there is one patch per change?

o Add new identifiers
o Probe for them.
o Add new cpu-features.
o tlb.h change.
o All the places you add 'case CPU_PROAPTIV'

Plus...
> ---
>   arch/mips/include/asm/cpu-features.h |  3 +++
>   arch/mips/include/asm/cpu-type.h     |  1 +
>   arch/mips/include/asm/cpu.h          |  5 ++++-
>   arch/mips/include/asm/tlb.h          |  4 +++-
>   arch/mips/kernel/cpu-probe.c         | 15 +++++++++++++++
>   arch/mips/kernel/idle.c              |  1 +
>   arch/mips/kernel/spram.c             |  1 +
>   arch/mips/kernel/traps.c             |  1 +
>   arch/mips/mm/c-r4k.c                 |  1 +
>   arch/mips/mm/sc-mips.c               |  1 +
>   arch/mips/mm/tlbex.c                 |  1 +
>   arch/mips/oprofile/op_model_mipsxx.c |  4 ++++
>   12 files changed, 36 insertions(+), 2 deletions(-)
>
[...]
> diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
> index c814287..8168e29 100644
> --- a/arch/mips/kernel/cpu-probe.c
> +++ b/arch/mips/kernel/cpu-probe.c
> @@ -286,6 +286,13 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
>   	    && cpu_has_tlb)
>   		c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
>
> +	if (cpu_has_tlb) {
> +		if (((config4 & MIPS_CONF4_IE) >> 29) == 2) {
> +			c->options |= MIPS_CPU_TLBINV;
> +			pr_info("TLBINV/F supported, config4=0x%0x\n", config4);

... The probing functions don't print messages, so don't add this pr_info().


> +		}
> +	}
> +

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

* Re: [PATCH 1/6] MIPS: Add missing bits for Config registers
  2013-11-07 17:08   ` Markos Chandras
  (?)
@ 2013-11-11 20:00   ` David Daney
  -1 siblings, 0 replies; 23+ messages in thread
From: David Daney @ 2013-11-11 20:00 UTC (permalink / raw)
  To: Markos Chandras; +Cc: linux-mips, Leonid Yegoshin

On 11/07/2013 09:08 AM, Markos Chandras wrote:
> From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>
> Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>

This seems good to me.

Acked-by: David Daney <david.daney@cavium.com>


> ---
>   arch/mips/include/asm/mipsregs.h | 40 ++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 38 insertions(+), 2 deletions(-)
>

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

* Re: [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB
  2013-11-07 17:08   ` Markos Chandras
  (?)
@ 2013-11-11 20:10   ` David Daney
  2013-11-11 20:55       ` Leonid Yegoshin
  2013-11-12  9:40       ` Markos Chandras
  -1 siblings, 2 replies; 23+ messages in thread
From: David Daney @ 2013-11-11 20:10 UTC (permalink / raw)
  To: Markos Chandras; +Cc: linux-mips, Leonid Yegoshin

On 11/07/2013 09:08 AM, Markos Chandras wrote:
> From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>
> The TLBINVF instruction can be used to flush the entire VTLB.
> This eliminates the need for the TLBWI loop and improves performance.
>
> Reviewed-by: Paul Burton <paul.burton@imgtec.com>
> Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>


This should be split into two patches.  One for each file.

Also...

> ---
>   arch/mips/include/asm/mipsregs.h | 13 +++++++++++++
>   arch/mips/mm/tlb-r4k.c           | 18 ++++++++++++------
>   2 files changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
> index 412fe99..9cd0e13 100644
> --- a/arch/mips/include/asm/mipsregs.h
> +++ b/arch/mips/include/asm/mipsregs.h
> @@ -685,6 +685,19 @@ static inline int mm_insn_16bit(u16 insn)
>   }
>
>   /*
> + * TLB Invalidate Flush
> + */
> +static inline void tlbinvf(void)
> +{
> +	__asm__ __volatile__(
> +		".set push\n\t"
> +		".set noreorder\n\t"

... Why do you need noreorder here?

> +		".word 0x42000004\n\t" /* tlbinvf */
> +		".set pop");
> +}
> +
> +
> +/*
>    * Functions to access the R10000 performance counters.	 These are basically
>    * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
>    * performance counter number encoded into bits 1 ... 5 of the instruction.
> diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
> index 363aa03..427dcac 100644
> --- a/arch/mips/mm/tlb-r4k.c
> +++ b/arch/mips/mm/tlb-r4k.c
> @@ -83,13 +83,19 @@ void local_flush_tlb_all(void)
>   	entry = read_c0_wired();
>
>   	/* Blast 'em all away. */
> -	while (entry < current_cpu_data.tlbsize) {
> -		/* Make sure all entries differ. */
> -		write_c0_entryhi(UNIQUE_ENTRYHI(entry));
> -		write_c0_index(entry);
> +	if (cpu_has_tlbinv && current_cpu_data.tlbsize) {
> +		write_c0_index(0);
>   		mtc0_tlbw_hazard();
> -		tlb_write_indexed();
> -		entry++;
> +		tlbinvf();  /* invalidate VTLB */
> +	} else {
> +		while (entry < current_cpu_data.tlbsize) {
> +			/* Make sure all entries differ. */
> +			write_c0_entryhi(UNIQUE_ENTRYHI(entry));
> +			write_c0_index(entry);
> +			mtc0_tlbw_hazard();
> +			tlb_write_indexed();
> +			entry++;
> +		}
>   	}
>   	tlbw_use_hazard();
>   	write_c0_entryhi(old_ctx);
>

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

* Re: [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB
@ 2013-11-11 20:55       ` Leonid Yegoshin
  0 siblings, 0 replies; 23+ messages in thread
From: Leonid Yegoshin @ 2013-11-11 20:55 UTC (permalink / raw)
  To: David Daney; +Cc: Markos Chandras, linux-mips

On 11/11/2013 12:10 PM, David Daney wrote:
> On 11/07/2013 09:08 AM, Markos Chandras wrote:
>> From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>>
>> The TLBINVF instruction can be used to flush the entire VTLB.
>> This eliminates the need for the TLBWI loop and improves performance.
>>
>> Reviewed-by: Paul Burton <paul.burton@imgtec.com>
>> Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
>
>
> This should be split into two patches.  One for each file.
>
> Also...
>
>> ---
>>   arch/mips/include/asm/mipsregs.h | 13 +++++++++++++
>>   arch/mips/mm/tlb-r4k.c           | 18 ++++++++++++------
>>   2 files changed, 25 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/mips/include/asm/mipsregs.h 
>> b/arch/mips/include/asm/mipsregs.h
>> index 412fe99..9cd0e13 100644
>> --- a/arch/mips/include/asm/mipsregs.h
>> +++ b/arch/mips/include/asm/mipsregs.h
>> @@ -685,6 +685,19 @@ static inline int mm_insn_16bit(u16 insn)
>>   }
>>
>>   /*
>> + * TLB Invalidate Flush
>> + */
>> +static inline void tlbinvf(void)
>> +{
>> +    __asm__ __volatile__(
>> +        ".set push\n\t"
>> +        ".set noreorder\n\t"
>
> ... Why do you need noreorder here?

Historically. Just copied a worked stuff right before this function and 
doesn't bother "why it is needed in other functions".

>
>> +        ".word 0x42000004\n\t" /* tlbinvf */
>> +        ".set pop");
>> +}
>> +
>> +
>> +/*
>>    * Functions to access the R10000 performance counters. These are 
>> basically
>>    * mfc0 and mtc0 instructions from and to coprocessor register with 
>> a 5-bit
>>    * performance counter number encoded into bits 1 ... 5 of the 
>> instruction.
>> diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
>> index 363aa03..427dcac 100644
>> --- a/arch/mips/mm/tlb-r4k.c
>> +++ b/arch/mips/mm/tlb-r4k.c
>> @@ -83,13 +83,19 @@ void local_flush_tlb_all(void)
>>       entry = read_c0_wired();
>>
>>       /* Blast 'em all away. */
>> -    while (entry < current_cpu_data.tlbsize) {
>> -        /* Make sure all entries differ. */
>> -        write_c0_entryhi(UNIQUE_ENTRYHI(entry));
>> -        write_c0_index(entry);
>> +    if (cpu_has_tlbinv && current_cpu_data.tlbsize) {
>> +        write_c0_index(0);
>>           mtc0_tlbw_hazard();
>> -        tlb_write_indexed();
>> -        entry++;
>> +        tlbinvf();  /* invalidate VTLB */
>> +    } else {
>> +        while (entry < current_cpu_data.tlbsize) {
>> +            /* Make sure all entries differ. */
>> +            write_c0_entryhi(UNIQUE_ENTRYHI(entry));
>> +            write_c0_index(entry);
>> +            mtc0_tlbw_hazard();
>> +            tlb_write_indexed();
>> +            entry++;
>> +        }
>>       }
>>       tlbw_use_hazard();
>>       write_c0_entryhi(old_ctx);
>>
>

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

* Re: [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB
@ 2013-11-11 20:55       ` Leonid Yegoshin
  0 siblings, 0 replies; 23+ messages in thread
From: Leonid Yegoshin @ 2013-11-11 20:55 UTC (permalink / raw)
  To: David Daney; +Cc: Markos Chandras, linux-mips

On 11/11/2013 12:10 PM, David Daney wrote:
> On 11/07/2013 09:08 AM, Markos Chandras wrote:
>> From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>>
>> The TLBINVF instruction can be used to flush the entire VTLB.
>> This eliminates the need for the TLBWI loop and improves performance.
>>
>> Reviewed-by: Paul Burton <paul.burton@imgtec.com>
>> Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
>
>
> This should be split into two patches.  One for each file.
>
> Also...
>
>> ---
>>   arch/mips/include/asm/mipsregs.h | 13 +++++++++++++
>>   arch/mips/mm/tlb-r4k.c           | 18 ++++++++++++------
>>   2 files changed, 25 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/mips/include/asm/mipsregs.h 
>> b/arch/mips/include/asm/mipsregs.h
>> index 412fe99..9cd0e13 100644
>> --- a/arch/mips/include/asm/mipsregs.h
>> +++ b/arch/mips/include/asm/mipsregs.h
>> @@ -685,6 +685,19 @@ static inline int mm_insn_16bit(u16 insn)
>>   }
>>
>>   /*
>> + * TLB Invalidate Flush
>> + */
>> +static inline void tlbinvf(void)
>> +{
>> +    __asm__ __volatile__(
>> +        ".set push\n\t"
>> +        ".set noreorder\n\t"
>
> ... Why do you need noreorder here?

Historically. Just copied a worked stuff right before this function and 
doesn't bother "why it is needed in other functions".

>
>> +        ".word 0x42000004\n\t" /* tlbinvf */
>> +        ".set pop");
>> +}
>> +
>> +
>> +/*
>>    * Functions to access the R10000 performance counters. These are 
>> basically
>>    * mfc0 and mtc0 instructions from and to coprocessor register with 
>> a 5-bit
>>    * performance counter number encoded into bits 1 ... 5 of the 
>> instruction.
>> diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
>> index 363aa03..427dcac 100644
>> --- a/arch/mips/mm/tlb-r4k.c
>> +++ b/arch/mips/mm/tlb-r4k.c
>> @@ -83,13 +83,19 @@ void local_flush_tlb_all(void)
>>       entry = read_c0_wired();
>>
>>       /* Blast 'em all away. */
>> -    while (entry < current_cpu_data.tlbsize) {
>> -        /* Make sure all entries differ. */
>> -        write_c0_entryhi(UNIQUE_ENTRYHI(entry));
>> -        write_c0_index(entry);
>> +    if (cpu_has_tlbinv && current_cpu_data.tlbsize) {
>> +        write_c0_index(0);
>>           mtc0_tlbw_hazard();
>> -        tlb_write_indexed();
>> -        entry++;
>> +        tlbinvf();  /* invalidate VTLB */
>> +    } else {
>> +        while (entry < current_cpu_data.tlbsize) {
>> +            /* Make sure all entries differ. */
>> +            write_c0_entryhi(UNIQUE_ENTRYHI(entry));
>> +            write_c0_index(entry);
>> +            mtc0_tlbw_hazard();
>> +            tlb_write_indexed();
>> +            entry++;
>> +        }
>>       }
>>       tlbw_use_hazard();
>>       write_c0_entryhi(old_ctx);
>>
>

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

* Re: [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB
@ 2013-11-12  9:40       ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-12  9:40 UTC (permalink / raw)
  To: David Daney; +Cc: linux-mips, Leonid Yegoshin

On 11/11/2013 08:10 PM, David Daney wrote:
> On 11/07/2013 09:08 AM, Markos Chandras wrote:
>> From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>>
>> The TLBINVF instruction can be used to flush the entire VTLB.
>> This eliminates the need for the TLBWI loop and improves performance.
>>
>> Reviewed-by: Paul Burton <paul.burton@imgtec.com>
>> Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
>
>
> This should be split into two patches.  One for each file.
>
> Also...

Hi David,

But it is a single functional change. I believe it makes sense
to have it in a single commit.

-- 
markos

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

* Re: [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB
@ 2013-11-12  9:40       ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-12  9:40 UTC (permalink / raw)
  To: David Daney; +Cc: linux-mips, Leonid Yegoshin

On 11/11/2013 08:10 PM, David Daney wrote:
> On 11/07/2013 09:08 AM, Markos Chandras wrote:
>> From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>>
>> The TLBINVF instruction can be used to flush the entire VTLB.
>> This eliminates the need for the TLBWI loop and improves performance.
>>
>> Reviewed-by: Paul Burton <paul.burton@imgtec.com>
>> Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
>> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
>
>
> This should be split into two patches.  One for each file.
>
> Also...

Hi David,

But it is a single functional change. I believe it makes sense
to have it in a single commit.

-- 
markos

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

* Re: [PATCH 3/6] MIPS: Add support for the proAptiv cores
@ 2013-11-12  9:41       ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-12  9:41 UTC (permalink / raw)
  To: David Daney; +Cc: linux-mips, Leonid Yegoshin

On 11/11/2013 07:59 PM, David Daney wrote:
>
> This patch is a big collection of small unrelated changes.
>
> Can you break it up so that there is one patch per change?
>
> o Add new identifiers
> o Probe for them.
> o Add new cpu-features.
> o tlb.h change.
> o All the places you add 'case CPU_PROAPTIV'
>

Hi David,

Ok thanks I will split this patch into smaller patches.

> [...]
>> diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
>> index c814287..8168e29 100644
>> --- a/arch/mips/kernel/cpu-probe.c
>> +++ b/arch/mips/kernel/cpu-probe.c
>> @@ -286,6 +286,13 @@ static inline unsigned int decode_config4(struct
>> cpuinfo_mips *c)
>>           && cpu_has_tlb)
>>           c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
>>
>> +    if (cpu_has_tlb) {
>> +        if (((config4 & MIPS_CONF4_IE) >> 29) == 2) {
>> +            c->options |= MIPS_CPU_TLBINV;
>> +            pr_info("TLBINV/F supported, config4=0x%0x\n", config4);
>
> ... The probing functions don't print messages, so don't add this
> pr_info().

Ok will do

Thanks for the review

-- 
markos

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

* Re: [PATCH 3/6] MIPS: Add support for the proAptiv cores
@ 2013-11-12  9:41       ` Markos Chandras
  0 siblings, 0 replies; 23+ messages in thread
From: Markos Chandras @ 2013-11-12  9:41 UTC (permalink / raw)
  To: David Daney; +Cc: linux-mips, Leonid Yegoshin

On 11/11/2013 07:59 PM, David Daney wrote:
>
> This patch is a big collection of small unrelated changes.
>
> Can you break it up so that there is one patch per change?
>
> o Add new identifiers
> o Probe for them.
> o Add new cpu-features.
> o tlb.h change.
> o All the places you add 'case CPU_PROAPTIV'
>

Hi David,

Ok thanks I will split this patch into smaller patches.

> [...]
>> diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
>> index c814287..8168e29 100644
>> --- a/arch/mips/kernel/cpu-probe.c
>> +++ b/arch/mips/kernel/cpu-probe.c
>> @@ -286,6 +286,13 @@ static inline unsigned int decode_config4(struct
>> cpuinfo_mips *c)
>>           && cpu_has_tlb)
>>           c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
>>
>> +    if (cpu_has_tlb) {
>> +        if (((config4 & MIPS_CONF4_IE) >> 29) == 2) {
>> +            c->options |= MIPS_CPU_TLBINV;
>> +            pr_info("TLBINV/F supported, config4=0x%0x\n", config4);
>
> ... The probing functions don't print messages, so don't add this
> pr_info().

Ok will do

Thanks for the review

-- 
markos

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

end of thread, other threads:[~2013-11-12  9:42 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-07 17:08 [PATCH 0/6] Add support for the proAptiv core Markos Chandras
2013-11-07 17:08 ` Markos Chandras
2013-11-07 17:08 ` [PATCH 1/6] MIPS: Add missing bits for Config registers Markos Chandras
2013-11-07 17:08   ` Markos Chandras
2013-11-11 20:00   ` David Daney
2013-11-07 17:08 ` [PATCH 2/6] MIPS: mm: Move UNIQUE_ENTRYHI macro to a header file Markos Chandras
2013-11-07 17:08   ` Markos Chandras
2013-11-07 17:08 ` [PATCH 3/6] MIPS: Add support for the proAptiv cores Markos Chandras
2013-11-07 17:08   ` Markos Chandras
2013-11-11 19:59   ` David Daney
2013-11-12  9:41     ` Markos Chandras
2013-11-12  9:41       ` Markos Chandras
2013-11-07 17:08 ` [PATCH 4/6] MIPS: mm: Use the TLBINVF instruction to flush the VTLB Markos Chandras
2013-11-07 17:08   ` Markos Chandras
2013-11-11 20:10   ` David Daney
2013-11-11 20:55     ` Leonid Yegoshin
2013-11-11 20:55       ` Leonid Yegoshin
2013-11-12  9:40     ` Markos Chandras
2013-11-12  9:40       ` Markos Chandras
2013-11-07 17:08 ` [PATCH 5/6] MIPS: Add support for FTLBs Markos Chandras
2013-11-07 17:08   ` Markos Chandras
2013-11-07 17:08 ` [PATCH 6/6] MIPS: Add debugfs file to print the segmentation control registers Markos Chandras
2013-11-07 17:08   ` Markos Chandras

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.