All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] MIPS: dump_tlb improvements
@ 2015-05-19  8:50 ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips
  Cc: James Hogan, Maciej W. Rozycki, Steven J. Hill, David Daney

This patchset improves dump_tlb.c to use proper hazard macros (for which
new macros are added for tlb reads), and to take into account the global
bit, the EHINV invalid bit, RI & XI bits, and XPA.

Patch 1 also adds a MIPS specific SysRq operation ('x') to dump the TLBs
on running CPUs. This is mainly for debug purposes, however I've
included it for completeness as an RFC patch, in case others find it
helpful.

Patches 2 & 4 add and make use of tlbr related hazard macros (which are
technically distinct, though identically implemented, to tlbw hazards).

Patch 3 adds EntryLo defines used in later patches (particularly patch
6).

Patches 5-8 improve the TLB entry matching so as to more closely match
which entries hardware treats as matching (taking the global and EHINV
bits into account), and does some refactoring while at it.

Patches 9-10 improve the TLB printing to handle RI & XI bits (which show
up in the physical address at the moment), and XPA (where the top of the
physical address needs to be read from EntryLo registers with mfhc0).

Changes in v2:
- New patch 3 (Maceij) including reordered MIPS_ENTRYLO_RI/XI
  definitions from patch 7 of v1 (patch 9 in v2).
- New patch 6 (Maciej), using mipsregs.h EntryLo bit definitions.
- Patch 7: Check both global bits and add comment (Ralf).
- Patch 7: Fix typo s/absense/absence/ (Maciej).
- Patch 7: Use MIPS_ENTRYLO_G definition (Maciej).
- Patch 7: Update r3k_dump_tlb.c too (Maciej - please test).
- Dropped patch 9 (v1) (a typo which Ralf has already got upstream).

James Hogan (10):
  MIPS: Add SysRq operation to dump TLBs on all CPUs
  MIPS: hazards: Add hazard macros for tlb read
  MIPS: mipsregs.h: Add EntryLo bit definitions
  MIPS: dump_tlb: Use tlbr hazard macros
  MIPS: dump_tlb: Refactor TLB matching
  MIPS: dump_tlb: Make use of EntryLo bit definitions
  MIPS: dump_tlb: Take global bit into account
  MIPS: dump_tlb: Take EHINV bit into account
  MIPS: dump_tlb: Take RI/XI bits into account
  MIPS: dump_tlb: Take XPA into account

 arch/mips/include/asm/hazards.h  |  52 ++++++++++++++++++
 arch/mips/include/asm/mipsregs.h |  22 ++++++++
 arch/mips/kernel/Makefile        |   1 +
 arch/mips/kernel/sysrq.c         |  77 +++++++++++++++++++++++++++
 arch/mips/lib/dump_tlb.c         | 110 +++++++++++++++++++++++++--------------
 arch/mips/lib/r3k_dump_tlb.c     |  13 ++---
 drivers/tty/sysrq.c              |   1 +
 7 files changed, 231 insertions(+), 45 deletions(-)
 create mode 100644 arch/mips/kernel/sysrq.c

Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
-- 
2.3.6

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

* [PATCH v2 00/10] MIPS: dump_tlb improvements
@ 2015-05-19  8:50 ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips
  Cc: James Hogan, Maciej W. Rozycki, Steven J. Hill, David Daney

This patchset improves dump_tlb.c to use proper hazard macros (for which
new macros are added for tlb reads), and to take into account the global
bit, the EHINV invalid bit, RI & XI bits, and XPA.

Patch 1 also adds a MIPS specific SysRq operation ('x') to dump the TLBs
on running CPUs. This is mainly for debug purposes, however I've
included it for completeness as an RFC patch, in case others find it
helpful.

Patches 2 & 4 add and make use of tlbr related hazard macros (which are
technically distinct, though identically implemented, to tlbw hazards).

Patch 3 adds EntryLo defines used in later patches (particularly patch
6).

Patches 5-8 improve the TLB entry matching so as to more closely match
which entries hardware treats as matching (taking the global and EHINV
bits into account), and does some refactoring while at it.

Patches 9-10 improve the TLB printing to handle RI & XI bits (which show
up in the physical address at the moment), and XPA (where the top of the
physical address needs to be read from EntryLo registers with mfhc0).

Changes in v2:
- New patch 3 (Maceij) including reordered MIPS_ENTRYLO_RI/XI
  definitions from patch 7 of v1 (patch 9 in v2).
- New patch 6 (Maciej), using mipsregs.h EntryLo bit definitions.
- Patch 7: Check both global bits and add comment (Ralf).
- Patch 7: Fix typo s/absense/absence/ (Maciej).
- Patch 7: Use MIPS_ENTRYLO_G definition (Maciej).
- Patch 7: Update r3k_dump_tlb.c too (Maciej - please test).
- Dropped patch 9 (v1) (a typo which Ralf has already got upstream).

James Hogan (10):
  MIPS: Add SysRq operation to dump TLBs on all CPUs
  MIPS: hazards: Add hazard macros for tlb read
  MIPS: mipsregs.h: Add EntryLo bit definitions
  MIPS: dump_tlb: Use tlbr hazard macros
  MIPS: dump_tlb: Refactor TLB matching
  MIPS: dump_tlb: Make use of EntryLo bit definitions
  MIPS: dump_tlb: Take global bit into account
  MIPS: dump_tlb: Take EHINV bit into account
  MIPS: dump_tlb: Take RI/XI bits into account
  MIPS: dump_tlb: Take XPA into account

 arch/mips/include/asm/hazards.h  |  52 ++++++++++++++++++
 arch/mips/include/asm/mipsregs.h |  22 ++++++++
 arch/mips/kernel/Makefile        |   1 +
 arch/mips/kernel/sysrq.c         |  77 +++++++++++++++++++++++++++
 arch/mips/lib/dump_tlb.c         | 110 +++++++++++++++++++++++++--------------
 arch/mips/lib/r3k_dump_tlb.c     |  13 ++---
 drivers/tty/sysrq.c              |   1 +
 7 files changed, 231 insertions(+), 45 deletions(-)
 create mode 100644 arch/mips/kernel/sysrq.c

Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
-- 
2.3.6

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

* [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Add a MIPS specific SysRq operation to dump the TLB entries on all CPUs,
using the 'x' trigger key.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
This was mainly for debug purposes, however I've included it for
completeness as an RFC patch, in case others find it helpful.
---
 arch/mips/kernel/Makefile |  1 +
 arch/mips/kernel/sysrq.c  | 77 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/sysrq.c       |  1 +
 3 files changed, 79 insertions(+)
 create mode 100644 arch/mips/kernel/sysrq.c

diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index d3d2ff2d76dc..a2debcbedb6d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o
 
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
+obj-$(CONFIG_MAGIC_SYSRQ)	+= sysrq.o
 
 obj-$(CONFIG_64BIT)		+= cpu-bugs64.o
 
diff --git a/arch/mips/kernel/sysrq.c b/arch/mips/kernel/sysrq.c
new file mode 100644
index 000000000000..5b539f5fc9d9
--- /dev/null
+++ b/arch/mips/kernel/sysrq.c
@@ -0,0 +1,77 @@
+/*
+ * MIPS specific sysrq operations.
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/sysrq.h>
+#include <linux/workqueue.h>
+
+#include <asm/cpu-features.h>
+#include <asm/mipsregs.h>
+#include <asm/tlbdebug.h>
+
+/*
+ * Dump TLB entries on all CPUs.
+ */
+
+static DEFINE_SPINLOCK(show_lock);
+
+static void sysrq_tlbdump_single(void *dummy)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned long flags;
+
+	spin_lock_irqsave(&show_lock, flags);
+
+	pr_info("CPU%d:\n", smp_processor_id());
+	pr_info("Index	: %0x\n", read_c0_index());
+	pr_info("Pagemask: %0x\n", read_c0_pagemask());
+	pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
+	pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
+	pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
+	pr_info("Wired   : %0x\n", read_c0_wired());
+	pr_info("Pagegrain: %0x\n", read_c0_pagegrain());
+	if (cpu_has_htw) {
+		pr_info("PWField : %0*lx\n", field, read_c0_pwfield());
+		pr_info("PWSize  : %0*lx\n", field, read_c0_pwsize());
+		pr_info("PWCtl   : %0x\n", read_c0_pwctl());
+	}
+	pr_info("\n");
+	dump_tlb_all();
+	pr_info("\n");
+
+	spin_unlock_irqrestore(&show_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static void sysrq_tlbdump_othercpus(struct work_struct *dummy)
+{
+	smp_call_function(sysrq_tlbdump_single, NULL, 0);
+}
+
+static DECLARE_WORK(sysrq_tlbdump, sysrq_tlbdump_othercpus);
+#endif
+
+static void sysrq_handle_tlbdump(int key)
+{
+	sysrq_tlbdump_single(NULL);
+#ifdef CONFIG_SMP
+	schedule_work(&sysrq_tlbdump);
+#endif
+}
+
+static struct sysrq_key_op sysrq_tlbdump_op = {
+	.handler        = sysrq_handle_tlbdump,
+	.help_msg       = "show-tlbs(x)",
+	.action_msg     = "Show TLB entries",
+	.enable_mask	= SYSRQ_ENABLE_DUMP,
+};
+
+static int __init mips_sysrq_init(void)
+{
+	return register_sysrq_key('x', &sysrq_tlbdump_op);
+}
+arch_initcall(mips_sysrq_init);
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 843f2cdc280b..8ba52e56bb8b 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -463,6 +463,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
 	/* v: May be registered for frame buffer console restore */
 	NULL,				/* v */
 	&sysrq_showstate_blocked_op,	/* w */
+	/* x: May be registered on mips for TLB dump */
 	/* x: May be registered on ppc/powerpc for xmon */
 	/* x: May be registered on sparc64 for global PMU dump */
 	NULL,				/* x */
-- 
2.3.6

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

* [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Add a MIPS specific SysRq operation to dump the TLB entries on all CPUs,
using the 'x' trigger key.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
This was mainly for debug purposes, however I've included it for
completeness as an RFC patch, in case others find it helpful.
---
 arch/mips/kernel/Makefile |  1 +
 arch/mips/kernel/sysrq.c  | 77 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/sysrq.c       |  1 +
 3 files changed, 79 insertions(+)
 create mode 100644 arch/mips/kernel/sysrq.c

diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index d3d2ff2d76dc..a2debcbedb6d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o
 
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
+obj-$(CONFIG_MAGIC_SYSRQ)	+= sysrq.o
 
 obj-$(CONFIG_64BIT)		+= cpu-bugs64.o
 
diff --git a/arch/mips/kernel/sysrq.c b/arch/mips/kernel/sysrq.c
new file mode 100644
index 000000000000..5b539f5fc9d9
--- /dev/null
+++ b/arch/mips/kernel/sysrq.c
@@ -0,0 +1,77 @@
+/*
+ * MIPS specific sysrq operations.
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/sysrq.h>
+#include <linux/workqueue.h>
+
+#include <asm/cpu-features.h>
+#include <asm/mipsregs.h>
+#include <asm/tlbdebug.h>
+
+/*
+ * Dump TLB entries on all CPUs.
+ */
+
+static DEFINE_SPINLOCK(show_lock);
+
+static void sysrq_tlbdump_single(void *dummy)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned long flags;
+
+	spin_lock_irqsave(&show_lock, flags);
+
+	pr_info("CPU%d:\n", smp_processor_id());
+	pr_info("Index	: %0x\n", read_c0_index());
+	pr_info("Pagemask: %0x\n", read_c0_pagemask());
+	pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
+	pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
+	pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
+	pr_info("Wired   : %0x\n", read_c0_wired());
+	pr_info("Pagegrain: %0x\n", read_c0_pagegrain());
+	if (cpu_has_htw) {
+		pr_info("PWField : %0*lx\n", field, read_c0_pwfield());
+		pr_info("PWSize  : %0*lx\n", field, read_c0_pwsize());
+		pr_info("PWCtl   : %0x\n", read_c0_pwctl());
+	}
+	pr_info("\n");
+	dump_tlb_all();
+	pr_info("\n");
+
+	spin_unlock_irqrestore(&show_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static void sysrq_tlbdump_othercpus(struct work_struct *dummy)
+{
+	smp_call_function(sysrq_tlbdump_single, NULL, 0);
+}
+
+static DECLARE_WORK(sysrq_tlbdump, sysrq_tlbdump_othercpus);
+#endif
+
+static void sysrq_handle_tlbdump(int key)
+{
+	sysrq_tlbdump_single(NULL);
+#ifdef CONFIG_SMP
+	schedule_work(&sysrq_tlbdump);
+#endif
+}
+
+static struct sysrq_key_op sysrq_tlbdump_op = {
+	.handler        = sysrq_handle_tlbdump,
+	.help_msg       = "show-tlbs(x)",
+	.action_msg     = "Show TLB entries",
+	.enable_mask	= SYSRQ_ENABLE_DUMP,
+};
+
+static int __init mips_sysrq_init(void)
+{
+	return register_sysrq_key('x', &sysrq_tlbdump_op);
+}
+arch_initcall(mips_sysrq_init);
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 843f2cdc280b..8ba52e56bb8b 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -463,6 +463,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
 	/* v: May be registered for frame buffer console restore */
 	NULL,				/* v */
 	&sysrq_showstate_blocked_op,	/* w */
+	/* x: May be registered on mips for TLB dump */
 	/* x: May be registered on ppc/powerpc for xmon */
 	/* x: May be registered on sparc64 for global PMU dump */
 	NULL,				/* x */
-- 
2.3.6

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

* [PATCH v2 02/10] MIPS: hazards: Add hazard macros for tlb read
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Add hazard macros to <asm/hazards.h> for the following hazards around
tlbr (TLB read) instructions, which are used in TLB dumping code and
some KVM TLB management code:

- mtc0_tlbr_hazard
  Between mtc0 (Index) and tlbr. This is copied from mtc0_tlbw_hazard in
  all cases on the assumption that tlbr always has similar data user
  timings to tlbw.

- tlb_read_hazard
  Between tlbr and mfc0 (various TLB registers). This is copied from
  tlbw_use_hazard in all cases on the assumption that tlbr has similar
  data writer characteristics to tlbw, and mfc0 has similar data user
  characteristics to loads and stores.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Looking at r4000 manual, its tlbr had similar data user timings to tlbw,
and mfc0 had similar data writer timings to loads and stores. Are there
particular other cores that should be checked too?
---
 arch/mips/include/asm/hazards.h | 52 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index 4087b47ad1cb..7b99efd31074 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -31,9 +31,15 @@
 #define __mtc0_tlbw_hazard						\
 	___ehb
 
+#define __mtc0_tlbr_hazard						\
+	___ehb
+
 #define __tlbw_use_hazard						\
 	___ehb
 
+#define __tlb_read_hazard						\
+	___ehb
+
 #define __tlb_probe_hazard						\
 	___ehb
 
@@ -80,12 +86,23 @@ do {									\
 	___ssnop;							\
 	___ehb
 
+#define __mtc0_tlbr_hazard						\
+	___ssnop;							\
+	___ssnop;							\
+	___ehb
+
 #define __tlbw_use_hazard						\
 	___ssnop;							\
 	___ssnop;							\
 	___ssnop;							\
 	___ehb
 
+#define __tlb_read_hazard						\
+	___ssnop;							\
+	___ssnop;							\
+	___ssnop;							\
+	___ehb
+
 #define __tlb_probe_hazard						\
 	___ssnop;							\
 	___ssnop;							\
@@ -147,8 +164,12 @@ do {									\
 
 #define __mtc0_tlbw_hazard
 
+#define __mtc0_tlbr_hazard
+
 #define __tlbw_use_hazard
 
+#define __tlb_read_hazard
+
 #define __tlb_probe_hazard
 
 #define __irq_enable_hazard
@@ -166,8 +187,12 @@ do {									\
  */
 #define __mtc0_tlbw_hazard
 
+#define __mtc0_tlbr_hazard
+
 #define __tlbw_use_hazard
 
+#define __tlb_read_hazard
+
 #define __tlb_probe_hazard
 
 #define __irq_enable_hazard
@@ -196,11 +221,20 @@ do {									\
 	nop;								\
 	nop
 
+#define __mtc0_tlbr_hazard						\
+	nop;								\
+	nop
+
 #define __tlbw_use_hazard						\
 	nop;								\
 	nop;								\
 	nop
 
+#define __tlb_read_hazard						\
+	nop;								\
+	nop;								\
+	nop
+
 #define __tlb_probe_hazard						\
 	nop;								\
 	nop;								\
@@ -267,7 +301,9 @@ do {									\
 #define _ssnop ___ssnop
 #define	_ehb ___ehb
 #define mtc0_tlbw_hazard __mtc0_tlbw_hazard
+#define mtc0_tlbr_hazard __mtc0_tlbr_hazard
 #define tlbw_use_hazard __tlbw_use_hazard
+#define tlb_read_hazard __tlb_read_hazard
 #define tlb_probe_hazard __tlb_probe_hazard
 #define irq_enable_hazard __irq_enable_hazard
 #define irq_disable_hazard __irq_disable_hazard
@@ -300,6 +336,14 @@ do {									\
 } while (0)
 
 
+#define mtc0_tlbr_hazard()						\
+do {									\
+	__asm__ __volatile__(						\
+	__stringify(__mtc0_tlbr_hazard)					\
+	);								\
+} while (0)
+
+
 #define tlbw_use_hazard()						\
 do {									\
 	__asm__ __volatile__(						\
@@ -308,6 +352,14 @@ do {									\
 } while (0)
 
 
+#define tlb_read_hazard()						\
+do {									\
+	__asm__ __volatile__(						\
+	__stringify(__tlb_read_hazard)					\
+	);								\
+} while (0)
+
+
 #define tlb_probe_hazard()						\
 do {									\
 	__asm__ __volatile__(						\
-- 
2.3.6

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

* [PATCH v2 02/10] MIPS: hazards: Add hazard macros for tlb read
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Add hazard macros to <asm/hazards.h> for the following hazards around
tlbr (TLB read) instructions, which are used in TLB dumping code and
some KVM TLB management code:

- mtc0_tlbr_hazard
  Between mtc0 (Index) and tlbr. This is copied from mtc0_tlbw_hazard in
  all cases on the assumption that tlbr always has similar data user
  timings to tlbw.

- tlb_read_hazard
  Between tlbr and mfc0 (various TLB registers). This is copied from
  tlbw_use_hazard in all cases on the assumption that tlbr has similar
  data writer characteristics to tlbw, and mfc0 has similar data user
  characteristics to loads and stores.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Looking at r4000 manual, its tlbr had similar data user timings to tlbw,
and mfc0 had similar data writer timings to loads and stores. Are there
particular other cores that should be checked too?
---
 arch/mips/include/asm/hazards.h | 52 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index 4087b47ad1cb..7b99efd31074 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -31,9 +31,15 @@
 #define __mtc0_tlbw_hazard						\
 	___ehb
 
+#define __mtc0_tlbr_hazard						\
+	___ehb
+
 #define __tlbw_use_hazard						\
 	___ehb
 
+#define __tlb_read_hazard						\
+	___ehb
+
 #define __tlb_probe_hazard						\
 	___ehb
 
@@ -80,12 +86,23 @@ do {									\
 	___ssnop;							\
 	___ehb
 
+#define __mtc0_tlbr_hazard						\
+	___ssnop;							\
+	___ssnop;							\
+	___ehb
+
 #define __tlbw_use_hazard						\
 	___ssnop;							\
 	___ssnop;							\
 	___ssnop;							\
 	___ehb
 
+#define __tlb_read_hazard						\
+	___ssnop;							\
+	___ssnop;							\
+	___ssnop;							\
+	___ehb
+
 #define __tlb_probe_hazard						\
 	___ssnop;							\
 	___ssnop;							\
@@ -147,8 +164,12 @@ do {									\
 
 #define __mtc0_tlbw_hazard
 
+#define __mtc0_tlbr_hazard
+
 #define __tlbw_use_hazard
 
+#define __tlb_read_hazard
+
 #define __tlb_probe_hazard
 
 #define __irq_enable_hazard
@@ -166,8 +187,12 @@ do {									\
  */
 #define __mtc0_tlbw_hazard
 
+#define __mtc0_tlbr_hazard
+
 #define __tlbw_use_hazard
 
+#define __tlb_read_hazard
+
 #define __tlb_probe_hazard
 
 #define __irq_enable_hazard
@@ -196,11 +221,20 @@ do {									\
 	nop;								\
 	nop
 
+#define __mtc0_tlbr_hazard						\
+	nop;								\
+	nop
+
 #define __tlbw_use_hazard						\
 	nop;								\
 	nop;								\
 	nop
 
+#define __tlb_read_hazard						\
+	nop;								\
+	nop;								\
+	nop
+
 #define __tlb_probe_hazard						\
 	nop;								\
 	nop;								\
@@ -267,7 +301,9 @@ do {									\
 #define _ssnop ___ssnop
 #define	_ehb ___ehb
 #define mtc0_tlbw_hazard __mtc0_tlbw_hazard
+#define mtc0_tlbr_hazard __mtc0_tlbr_hazard
 #define tlbw_use_hazard __tlbw_use_hazard
+#define tlb_read_hazard __tlb_read_hazard
 #define tlb_probe_hazard __tlb_probe_hazard
 #define irq_enable_hazard __irq_enable_hazard
 #define irq_disable_hazard __irq_disable_hazard
@@ -300,6 +336,14 @@ do {									\
 } while (0)
 
 
+#define mtc0_tlbr_hazard()						\
+do {									\
+	__asm__ __volatile__(						\
+	__stringify(__mtc0_tlbr_hazard)					\
+	);								\
+} while (0)
+
+
 #define tlbw_use_hazard()						\
 do {									\
 	__asm__ __volatile__(						\
@@ -308,6 +352,14 @@ do {									\
 } while (0)
 
 
+#define tlb_read_hazard()						\
+do {									\
+	__asm__ __volatile__(						\
+	__stringify(__tlb_read_hazard)					\
+	);								\
+} while (0)
+
+
 #define tlb_probe_hazard()						\
 do {									\
 	__asm__ __volatile__(						\
-- 
2.3.6

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

* [PATCH v2 03/10] MIPS: mipsregs.h: Add EntryLo bit definitions
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Maciej W. Rozycki

Add definitions for EntryLo register bits in mipsregs.h. The R4000
compatible ones are prefixed MIPS_ENTRYLO_ and the R3000 compatible ones
are prefixed R3K_ENTRYLO_.

These will be used in later patches.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- New patch (Maceij) including reordered MIPS_ENTRYLO_RI/XI definitions
  from patch 7.
---
 arch/mips/include/asm/mipsregs.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 764e2756b54d..3b5a145af659 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -589,6 +589,28 @@
 /*  EntryHI bit definition */
 #define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10)
 
+/* R3000 EntryLo bit definitions */
+#define R3K_ENTRYLO_G		(_ULCAST_(1) << 8)
+#define R3K_ENTRYLO_V		(_ULCAST_(1) << 9)
+#define R3K_ENTRYLO_D		(_ULCAST_(1) << 10)
+#define R3K_ENTRYLO_N		(_ULCAST_(1) << 11)
+
+/* R4000 compatible EntryLo bit definitions */
+#define MIPS_ENTRYLO_G		(_ULCAST_(1) << 0)
+#define MIPS_ENTRYLO_V		(_ULCAST_(1) << 1)
+#define MIPS_ENTRYLO_D		(_ULCAST_(1) << 2)
+#define MIPS_ENTRYLO_C_SHIFT	3
+#define MIPS_ENTRYLO_C		(_ULCAST_(7) << MIPS_ENTRYLO_C_SHIFT)
+#ifdef CONFIG_64BIT
+/* as read by dmfc0 */
+#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 62)
+#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 63)
+#else
+/* as read by mfc0 */
+#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 30)
+#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 31)
+#endif
+
 /* CMGCRBase bit definitions */
 #define MIPS_CMGCRB_BASE	11
 #define MIPS_CMGCRF_BASE	(~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
-- 
2.3.6

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

* [PATCH v2 03/10] MIPS: mipsregs.h: Add EntryLo bit definitions
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Maciej W. Rozycki

Add definitions for EntryLo register bits in mipsregs.h. The R4000
compatible ones are prefixed MIPS_ENTRYLO_ and the R3000 compatible ones
are prefixed R3K_ENTRYLO_.

These will be used in later patches.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- New patch (Maceij) including reordered MIPS_ENTRYLO_RI/XI definitions
  from patch 7.
---
 arch/mips/include/asm/mipsregs.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 764e2756b54d..3b5a145af659 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -589,6 +589,28 @@
 /*  EntryHI bit definition */
 #define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10)
 
+/* R3000 EntryLo bit definitions */
+#define R3K_ENTRYLO_G		(_ULCAST_(1) << 8)
+#define R3K_ENTRYLO_V		(_ULCAST_(1) << 9)
+#define R3K_ENTRYLO_D		(_ULCAST_(1) << 10)
+#define R3K_ENTRYLO_N		(_ULCAST_(1) << 11)
+
+/* R4000 compatible EntryLo bit definitions */
+#define MIPS_ENTRYLO_G		(_ULCAST_(1) << 0)
+#define MIPS_ENTRYLO_V		(_ULCAST_(1) << 1)
+#define MIPS_ENTRYLO_D		(_ULCAST_(1) << 2)
+#define MIPS_ENTRYLO_C_SHIFT	3
+#define MIPS_ENTRYLO_C		(_ULCAST_(7) << MIPS_ENTRYLO_C_SHIFT)
+#ifdef CONFIG_64BIT
+/* as read by dmfc0 */
+#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 62)
+#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 63)
+#else
+/* as read by mfc0 */
+#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 30)
+#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 31)
+#endif
+
 /* CMGCRBase bit definitions */
 #define MIPS_CMGCRB_BASE	11
 #define MIPS_CMGCRF_BASE	(~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
-- 
2.3.6

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

* [PATCH v2 04/10] MIPS: dump_tlb: Use tlbr hazard macros
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Use the new tlb read hazard macros from <asm/hazards.h> rather than the
local BARRIER() macro which uses 7 ops regardless of the kernel
configuration.

We use mtc0_tlbr_hazard for the hazard between mtc0 to the index
register and the tlbr, and tlb_read_hazard for the hazard between the
tlbr and the mfc0 of the TLB registers written by tlbr.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 32b9f21bfd85..a62dfacb60f7 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 
+#include <asm/hazards.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -40,12 +41,6 @@ static inline const char *msk2str(unsigned int mask)
 	return "";
 }
 
-#define BARRIER()					\
-	__asm__ __volatile__(				\
-		".set\tnoreorder\n\t"			\
-		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
-		".set\treorder");
-
 static void dump_tlb(int first, int last)
 {
 	unsigned long s_entryhi, entryhi, asid;
@@ -59,9 +54,9 @@ static void dump_tlb(int first, int last)
 
 	for (i = first; i <= last; i++) {
 		write_c0_index(i);
-		BARRIER();
+		mtc0_tlbr_hazard();
 		tlb_read();
-		BARRIER();
+		tlb_read_hazard();
 		pagemask = read_c0_pagemask();
 		entryhi	 = read_c0_entryhi();
 		entrylo0 = read_c0_entrylo0();
-- 
2.3.6

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

* [PATCH v2 04/10] MIPS: dump_tlb: Use tlbr hazard macros
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Use the new tlb read hazard macros from <asm/hazards.h> rather than the
local BARRIER() macro which uses 7 ops regardless of the kernel
configuration.

We use mtc0_tlbr_hazard for the hazard between mtc0 to the index
register and the tlbr, and tlb_read_hazard for the hazard between the
tlbr and the mfc0 of the TLB registers written by tlbr.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 32b9f21bfd85..a62dfacb60f7 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 
+#include <asm/hazards.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -40,12 +41,6 @@ static inline const char *msk2str(unsigned int mask)
 	return "";
 }
 
-#define BARRIER()					\
-	__asm__ __volatile__(				\
-		".set\tnoreorder\n\t"			\
-		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
-		".set\treorder");
-
 static void dump_tlb(int first, int last)
 {
 	unsigned long s_entryhi, entryhi, asid;
@@ -59,9 +54,9 @@ static void dump_tlb(int first, int last)
 
 	for (i = first; i <= last; i++) {
 		write_c0_index(i);
-		BARRIER();
+		mtc0_tlbr_hazard();
 		tlb_read();
-		BARRIER();
+		tlb_read_hazard();
 		pagemask = read_c0_pagemask();
 		entryhi	 = read_c0_entryhi();
 		entrylo0 = read_c0_entrylo0();
-- 
2.3.6

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

* [PATCH v2 05/10] MIPS: dump_tlb: Refactor TLB matching
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Refactor the TLB matching code in dump_tlb() slightly so that the
conditions which can cause a TLB entry to be skipped can be more easily
extended. This should prevent the match condition getting unwieldy once
it is updated to take further conditions into account.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 65 ++++++++++++++++++++++++++----------------------
 1 file changed, 35 insertions(+), 30 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index a62dfacb60f7..17d05caa776d 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -46,6 +46,11 @@ static void dump_tlb(int first, int last)
 	unsigned long s_entryhi, entryhi, asid;
 	unsigned long long entrylo0, entrylo1;
 	unsigned int s_index, s_pagemask, pagemask, c0, c1, i;
+#ifdef CONFIG_32BIT
+	int width = 8;
+#else
+	int width = 11;
+#endif
 
 	s_pagemask = read_c0_pagemask();
 	s_entryhi = read_c0_entryhi();
@@ -62,38 +67,38 @@ static void dump_tlb(int first, int last)
 		entrylo0 = read_c0_entrylo0();
 		entrylo1 = read_c0_entrylo1();
 
-		/* Unused entries have a virtual address of CKSEG0.  */
-		if ((entryhi & ~0x1ffffUL) != CKSEG0
-		    && (entryhi & 0xff) == asid) {
-#ifdef CONFIG_32BIT
-			int width = 8;
-#else
-			int width = 11;
-#endif
-			/*
-			 * Only print entries in use
-			 */
-			printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
+		/*
+		 * Prior to tlbinv, unused entries have a virtual address of
+		 * CKSEG0.
+		 */
+		if ((entryhi & ~0x1ffffUL) == CKSEG0)
+			continue;
+		if ((entryhi & 0xff) != asid)
+			continue;
 
-			c0 = (entrylo0 >> 3) & 7;
-			c1 = (entrylo1 >> 3) & 7;
+		/*
+		 * Only print entries in use
+		 */
+		printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 
-			printk("va=%0*lx asid=%02lx\n",
-			       width, (entryhi & ~0x1fffUL),
-			       entryhi & 0xff);
-			printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
-			       width,
-			       (entrylo0 << 6) & PAGE_MASK, c0,
-			       (entrylo0 & 4) ? 1 : 0,
-			       (entrylo0 & 2) ? 1 : 0,
-			       (entrylo0 & 1) ? 1 : 0);
-			printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
-			       width,
-			       (entrylo1 << 6) & PAGE_MASK, c1,
-			       (entrylo1 & 4) ? 1 : 0,
-			       (entrylo1 & 2) ? 1 : 0,
-			       (entrylo1 & 1) ? 1 : 0);
-		}
+		c0 = (entrylo0 >> 3) & 7;
+		c1 = (entrylo1 >> 3) & 7;
+
+		printk("va=%0*lx asid=%02lx\n",
+		       width, (entryhi & ~0x1fffUL),
+		       entryhi & 0xff);
+		printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
+		       width,
+		       (entrylo0 << 6) & PAGE_MASK, c0,
+		       (entrylo0 & 4) ? 1 : 0,
+		       (entrylo0 & 2) ? 1 : 0,
+		       (entrylo0 & 1) ? 1 : 0);
+		printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
+		       width,
+		       (entrylo1 << 6) & PAGE_MASK, c1,
+		       (entrylo1 & 4) ? 1 : 0,
+		       (entrylo1 & 2) ? 1 : 0,
+		       (entrylo1 & 1) ? 1 : 0);
 	}
 	printk("\n");
 
-- 
2.3.6

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

* [PATCH v2 05/10] MIPS: dump_tlb: Refactor TLB matching
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

Refactor the TLB matching code in dump_tlb() slightly so that the
conditions which can cause a TLB entry to be skipped can be more easily
extended. This should prevent the match condition getting unwieldy once
it is updated to take further conditions into account.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 65 ++++++++++++++++++++++++++----------------------
 1 file changed, 35 insertions(+), 30 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index a62dfacb60f7..17d05caa776d 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -46,6 +46,11 @@ static void dump_tlb(int first, int last)
 	unsigned long s_entryhi, entryhi, asid;
 	unsigned long long entrylo0, entrylo1;
 	unsigned int s_index, s_pagemask, pagemask, c0, c1, i;
+#ifdef CONFIG_32BIT
+	int width = 8;
+#else
+	int width = 11;
+#endif
 
 	s_pagemask = read_c0_pagemask();
 	s_entryhi = read_c0_entryhi();
@@ -62,38 +67,38 @@ static void dump_tlb(int first, int last)
 		entrylo0 = read_c0_entrylo0();
 		entrylo1 = read_c0_entrylo1();
 
-		/* Unused entries have a virtual address of CKSEG0.  */
-		if ((entryhi & ~0x1ffffUL) != CKSEG0
-		    && (entryhi & 0xff) == asid) {
-#ifdef CONFIG_32BIT
-			int width = 8;
-#else
-			int width = 11;
-#endif
-			/*
-			 * Only print entries in use
-			 */
-			printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
+		/*
+		 * Prior to tlbinv, unused entries have a virtual address of
+		 * CKSEG0.
+		 */
+		if ((entryhi & ~0x1ffffUL) == CKSEG0)
+			continue;
+		if ((entryhi & 0xff) != asid)
+			continue;
 
-			c0 = (entrylo0 >> 3) & 7;
-			c1 = (entrylo1 >> 3) & 7;
+		/*
+		 * Only print entries in use
+		 */
+		printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 
-			printk("va=%0*lx asid=%02lx\n",
-			       width, (entryhi & ~0x1fffUL),
-			       entryhi & 0xff);
-			printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
-			       width,
-			       (entrylo0 << 6) & PAGE_MASK, c0,
-			       (entrylo0 & 4) ? 1 : 0,
-			       (entrylo0 & 2) ? 1 : 0,
-			       (entrylo0 & 1) ? 1 : 0);
-			printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
-			       width,
-			       (entrylo1 << 6) & PAGE_MASK, c1,
-			       (entrylo1 & 4) ? 1 : 0,
-			       (entrylo1 & 2) ? 1 : 0,
-			       (entrylo1 & 1) ? 1 : 0);
-		}
+		c0 = (entrylo0 >> 3) & 7;
+		c1 = (entrylo1 >> 3) & 7;
+
+		printk("va=%0*lx asid=%02lx\n",
+		       width, (entryhi & ~0x1fffUL),
+		       entryhi & 0xff);
+		printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
+		       width,
+		       (entrylo0 << 6) & PAGE_MASK, c0,
+		       (entrylo0 & 4) ? 1 : 0,
+		       (entrylo0 & 2) ? 1 : 0,
+		       (entrylo0 & 1) ? 1 : 0);
+		printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
+		       width,
+		       (entrylo1 << 6) & PAGE_MASK, c1,
+		       (entrylo1 & 4) ? 1 : 0,
+		       (entrylo1 & 2) ? 1 : 0,
+		       (entrylo1 & 1) ? 1 : 0);
 	}
 	printk("\n");
 
-- 
2.3.6

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

* [PATCH v2 06/10] MIPS: dump_tlb: Make use of EntryLo bit definitions
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Maciej W. Rozycki

Make use of recently added EntryLo bit definitions in mipsregs.h when
dumping TLB contents.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- New patch (Maciej).
---
 arch/mips/lib/dump_tlb.c     | 16 ++++++++--------
 arch/mips/lib/r3k_dump_tlb.c |  8 ++++----
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 17d05caa776d..f02cc554d720 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -81,8 +81,8 @@ static void dump_tlb(int first, int last)
 		 */
 		printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 
-		c0 = (entrylo0 >> 3) & 7;
-		c1 = (entrylo1 >> 3) & 7;
+		c0 = (entrylo0 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
+		c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
 
 		printk("va=%0*lx asid=%02lx\n",
 		       width, (entryhi & ~0x1fffUL),
@@ -90,15 +90,15 @@ static void dump_tlb(int first, int last)
 		printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
 		       width,
 		       (entrylo0 << 6) & PAGE_MASK, c0,
-		       (entrylo0 & 4) ? 1 : 0,
-		       (entrylo0 & 2) ? 1 : 0,
-		       (entrylo0 & 1) ? 1 : 0);
+		       (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
+		       (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
+		       (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
 		printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
 		       width,
 		       (entrylo1 << 6) & PAGE_MASK, c1,
-		       (entrylo1 & 4) ? 1 : 0,
-		       (entrylo1 & 2) ? 1 : 0,
-		       (entrylo1 & 1) ? 1 : 0);
+		       (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
+		       (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
+		       (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
 	}
 	printk("\n");
 
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index 975a13855116..e210f04b2bc3 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -47,10 +47,10 @@ static void dump_tlb(int first, int last)
 			       entryhi & PAGE_MASK,
 			       entryhi & ASID_MASK,
 			       entrylo0 & PAGE_MASK,
-			       (entrylo0 & (1 << 11)) ? 1 : 0,
-			       (entrylo0 & (1 << 10)) ? 1 : 0,
-			       (entrylo0 & (1 << 9)) ? 1 : 0,
-			       (entrylo0 & (1 << 8)) ? 1 : 0);
+			       (entrylo0 & R3K_ENTRYLO_N) ? 1 : 0,
+			       (entrylo0 & R3K_ENTRYLO_D) ? 1 : 0,
+			       (entrylo0 & R3K_ENTRYLO_V) ? 1 : 0,
+			       (entrylo0 & R3K_ENTRYLO_G) ? 1 : 0);
 		}
 	}
 	printk("\n");
-- 
2.3.6

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

* [PATCH v2 06/10] MIPS: dump_tlb: Make use of EntryLo bit definitions
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Maciej W. Rozycki

Make use of recently added EntryLo bit definitions in mipsregs.h when
dumping TLB contents.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- New patch (Maciej).
---
 arch/mips/lib/dump_tlb.c     | 16 ++++++++--------
 arch/mips/lib/r3k_dump_tlb.c |  8 ++++----
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 17d05caa776d..f02cc554d720 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -81,8 +81,8 @@ static void dump_tlb(int first, int last)
 		 */
 		printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 
-		c0 = (entrylo0 >> 3) & 7;
-		c1 = (entrylo1 >> 3) & 7;
+		c0 = (entrylo0 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
+		c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
 
 		printk("va=%0*lx asid=%02lx\n",
 		       width, (entryhi & ~0x1fffUL),
@@ -90,15 +90,15 @@ static void dump_tlb(int first, int last)
 		printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
 		       width,
 		       (entrylo0 << 6) & PAGE_MASK, c0,
-		       (entrylo0 & 4) ? 1 : 0,
-		       (entrylo0 & 2) ? 1 : 0,
-		       (entrylo0 & 1) ? 1 : 0);
+		       (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
+		       (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
+		       (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
 		printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
 		       width,
 		       (entrylo1 << 6) & PAGE_MASK, c1,
-		       (entrylo1 & 4) ? 1 : 0,
-		       (entrylo1 & 2) ? 1 : 0,
-		       (entrylo1 & 1) ? 1 : 0);
+		       (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
+		       (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
+		       (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
 	}
 	printk("\n");
 
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index 975a13855116..e210f04b2bc3 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -47,10 +47,10 @@ static void dump_tlb(int first, int last)
 			       entryhi & PAGE_MASK,
 			       entryhi & ASID_MASK,
 			       entrylo0 & PAGE_MASK,
-			       (entrylo0 & (1 << 11)) ? 1 : 0,
-			       (entrylo0 & (1 << 10)) ? 1 : 0,
-			       (entrylo0 & (1 << 9)) ? 1 : 0,
-			       (entrylo0 & (1 << 8)) ? 1 : 0);
+			       (entrylo0 & R3K_ENTRYLO_N) ? 1 : 0,
+			       (entrylo0 & R3K_ENTRYLO_D) ? 1 : 0,
+			       (entrylo0 & R3K_ENTRYLO_V) ? 1 : 0,
+			       (entrylo0 & R3K_ENTRYLO_G) ? 1 : 0);
 		}
 	}
 	printk("\n");
-- 
2.3.6

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

* [PATCH v2 07/10] MIPS: dump_tlb: Take global bit into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Maciej W. Rozycki

The TLB only matches the ASID when the global bit isn't set, so
dump_tlb() shouldn't really be skipping global entries just because the
ASID doesn't match. Fix the condition to read the TLB entry's global bit
from EntryLo0. Note that after a TLB read the global bits in both
EntryLo registers reflect the same global bit in the TLB entry.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- Check both global bits and add comment (Ralf).
- Fix typo s/absense/absence/ (Maciej).
- Use MIPS_ENTRYLO_G definition (Maciej).
- Update r3k_dump_tlb.c too (Maciej - please test).
---
 arch/mips/lib/dump_tlb.c     | 10 +++++++++-
 arch/mips/lib/r3k_dump_tlb.c |  5 +++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index f02cc554d720..995c393e3342 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -73,7 +73,15 @@ static void dump_tlb(int first, int last)
 		 */
 		if ((entryhi & ~0x1ffffUL) == CKSEG0)
 			continue;
-		if ((entryhi & 0xff) != asid)
+		/*
+		 * ASID takes effect in absence of G (global) bit.
+		 * We check both G bits, even though architecturally they should
+		 * match one another, because some revisions of the SB1 core may
+		 * leave only a single G bit set after a machine check exception
+		 * due to duplicate TLB entry.
+		 */
+		if (!((entrylo0 | entrylo1) & MIPS_ENTRYLO_G) &&
+		    (entryhi & 0xff) != asid)
 			continue;
 
 		/*
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index e210f04b2bc3..1335e4394e33 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -35,8 +35,9 @@ static void dump_tlb(int first, int last)
 		entrylo0 = read_c0_entrylo0();
 
 		/* Unused entries have a virtual address of KSEG0.  */
-		if ((entryhi & PAGE_MASK) != KSEG0
-		    && (entryhi & ASID_MASK) == asid) {
+		if ((entryhi & PAGE_MASK) != KSEG0 &&
+		    (entrylo0 & R3K_ENTRYLO_G ||
+		     (entryhi & ASID_MASK) == asid)) {
 			/*
 			 * Only print entries in use
 			 */
-- 
2.3.6

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

* [PATCH v2 07/10] MIPS: dump_tlb: Take global bit into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Maciej W. Rozycki

The TLB only matches the ASID when the global bit isn't set, so
dump_tlb() shouldn't really be skipping global entries just because the
ASID doesn't match. Fix the condition to read the TLB entry's global bit
from EntryLo0. Note that after a TLB read the global bits in both
EntryLo registers reflect the same global bit in the TLB entry.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- Check both global bits and add comment (Ralf).
- Fix typo s/absense/absence/ (Maciej).
- Use MIPS_ENTRYLO_G definition (Maciej).
- Update r3k_dump_tlb.c too (Maciej - please test).
---
 arch/mips/lib/dump_tlb.c     | 10 +++++++++-
 arch/mips/lib/r3k_dump_tlb.c |  5 +++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index f02cc554d720..995c393e3342 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -73,7 +73,15 @@ static void dump_tlb(int first, int last)
 		 */
 		if ((entryhi & ~0x1ffffUL) == CKSEG0)
 			continue;
-		if ((entryhi & 0xff) != asid)
+		/*
+		 * ASID takes effect in absence of G (global) bit.
+		 * We check both G bits, even though architecturally they should
+		 * match one another, because some revisions of the SB1 core may
+		 * leave only a single G bit set after a machine check exception
+		 * due to duplicate TLB entry.
+		 */
+		if (!((entrylo0 | entrylo1) & MIPS_ENTRYLO_G) &&
+		    (entryhi & 0xff) != asid)
 			continue;
 
 		/*
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index e210f04b2bc3..1335e4394e33 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -35,8 +35,9 @@ static void dump_tlb(int first, int last)
 		entrylo0 = read_c0_entrylo0();
 
 		/* Unused entries have a virtual address of KSEG0.  */
-		if ((entryhi & PAGE_MASK) != KSEG0
-		    && (entryhi & ASID_MASK) == asid) {
+		if ((entryhi & PAGE_MASK) != KSEG0 &&
+		    (entrylo0 & R3K_ENTRYLO_G ||
+		     (entryhi & ASID_MASK) == asid)) {
 			/*
 			 * Only print entries in use
 			 */
-- 
2.3.6

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

* [PATCH v2 08/10] MIPS: dump_tlb: Take EHINV bit into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

The EHINV bit in EntryHi allows a TLB entry to be properly marked
invalid so that EntryHi doesn't have to be set to a unique value to
avoid machine check exceptions due to multiple matching entries.

Unfortunately dump_tlb() doesn't take this into account so it will print
all the uninteresting invalid TLB entries if the current ASID happens to
be 00. Therefore add a condition to skip entries which are marked
invalid with the EHINV bit.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 995c393e3342..3bcdd53c832f 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -67,6 +67,9 @@ static void dump_tlb(int first, int last)
 		entrylo0 = read_c0_entrylo0();
 		entrylo1 = read_c0_entrylo1();
 
+		/* EHINV bit marks entire entry as invalid */
+		if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV)
+			continue;
 		/*
 		 * Prior to tlbinv, unused entries have a virtual address of
 		 * CKSEG0.
-- 
2.3.6

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

* [PATCH v2 08/10] MIPS: dump_tlb: Take EHINV bit into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan

The EHINV bit in EntryHi allows a TLB entry to be properly marked
invalid so that EntryHi doesn't have to be set to a unique value to
avoid machine check exceptions due to multiple matching entries.

Unfortunately dump_tlb() doesn't take this into account so it will print
all the uninteresting invalid TLB entries if the current ASID happens to
be 00. Therefore add a condition to skip entries which are marked
invalid with the EHINV bit.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 995c393e3342..3bcdd53c832f 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -67,6 +67,9 @@ static void dump_tlb(int first, int last)
 		entrylo0 = read_c0_entrylo0();
 		entrylo1 = read_c0_entrylo1();
 
+		/* EHINV bit marks entire entry as invalid */
+		if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV)
+			continue;
 		/*
 		 * Prior to tlbinv, unused entries have a virtual address of
 		 * CKSEG0.
-- 
2.3.6

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

* [PATCH v2 09/10] MIPS: dump_tlb: Take RI/XI bits into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, David Daney

The RI/XI bits when present are above the PFN field in the EntryLo
registers, at bits 63,62 when read with dmfc0, and bits 31,30 when read
with mfc0. This makes them appear as part of the physical address, since
the other bits are masked with PAGE_MASK, for example:

Index: 253 pgmask=16kb va=77b18000 asid=75
        [pa=1000744000 c=5 d=1 v=1 g=0] [pa=100134c000 c=5 d=1 v=1 g=0]

The physical addresses have bit 36 set, which corresponds to bit 30 of
EntryLo1, the XI bit.

Explicitly mask off the RI and XI bits from the printed physical
address, and print the RI and XI bits separately if they exist, giving
output more like this:

Index: 226 pgmask=16kb va=77be0000 asid=79
        [ri=0 xi=1 pa=01288000 c=5 d=1 v=1 g=0] [ri=0 xi=0 pa=010e4000 c=5 d=0 v=1 g=0]

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- mipsregs.h definitions for XI/RI bits moved to new patch 3 with other
  definitions.
---
 arch/mips/lib/dump_tlb.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 3bcdd53c832f..1fefd38aba08 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -44,7 +44,7 @@ static inline const char *msk2str(unsigned int mask)
 static void dump_tlb(int first, int last)
 {
 	unsigned long s_entryhi, entryhi, asid;
-	unsigned long long entrylo0, entrylo1;
+	unsigned long long entrylo0, entrylo1, pa;
 	unsigned int s_index, s_pagemask, pagemask, c0, c1, i;
 #ifdef CONFIG_32BIT
 	int width = 8;
@@ -98,15 +98,28 @@ static void dump_tlb(int first, int last)
 		printk("va=%0*lx asid=%02lx\n",
 		       width, (entryhi & ~0x1fffUL),
 		       entryhi & 0xff);
-		printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
-		       width,
-		       (entrylo0 << 6) & PAGE_MASK, c0,
+		/* RI/XI are in awkward places, so mask them off separately */
+		pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		pa = (pa << 6) & PAGE_MASK;
+		printk("\t[");
+		if (cpu_has_rixi)
+			printk("ri=%d xi=%d ",
+			       (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0,
+			       (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
+		printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",
+		       width, pa, c0,
 		       (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
-		printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
-		       width,
-		       (entrylo1 << 6) & PAGE_MASK, c1,
+		/* RI/XI are in awkward places, so mask them off separately */
+		pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		pa = (pa << 6) & PAGE_MASK;
+		if (cpu_has_rixi)
+			printk("ri=%d xi=%d ",
+			       (entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0,
+			       (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
+		printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
+		       width, pa, c1,
 		       (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
-- 
2.3.6

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

* [PATCH v2 09/10] MIPS: dump_tlb: Take RI/XI bits into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, David Daney

The RI/XI bits when present are above the PFN field in the EntryLo
registers, at bits 63,62 when read with dmfc0, and bits 31,30 when read
with mfc0. This makes them appear as part of the physical address, since
the other bits are masked with PAGE_MASK, for example:

Index: 253 pgmask=16kb va=77b18000 asid=75
        [pa=1000744000 c=5 d=1 v=1 g=0] [pa=100134c000 c=5 d=1 v=1 g=0]

The physical addresses have bit 36 set, which corresponds to bit 30 of
EntryLo1, the XI bit.

Explicitly mask off the RI and XI bits from the printed physical
address, and print the RI and XI bits separately if they exist, giving
output more like this:

Index: 226 pgmask=16kb va=77be0000 asid=79
        [ri=0 xi=1 pa=01288000 c=5 d=1 v=1 g=0] [ri=0 xi=0 pa=010e4000 c=5 d=0 v=1 g=0]

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
---
Changes in v2:
- mipsregs.h definitions for XI/RI bits moved to new patch 3 with other
  definitions.
---
 arch/mips/lib/dump_tlb.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 3bcdd53c832f..1fefd38aba08 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -44,7 +44,7 @@ static inline const char *msk2str(unsigned int mask)
 static void dump_tlb(int first, int last)
 {
 	unsigned long s_entryhi, entryhi, asid;
-	unsigned long long entrylo0, entrylo1;
+	unsigned long long entrylo0, entrylo1, pa;
 	unsigned int s_index, s_pagemask, pagemask, c0, c1, i;
 #ifdef CONFIG_32BIT
 	int width = 8;
@@ -98,15 +98,28 @@ static void dump_tlb(int first, int last)
 		printk("va=%0*lx asid=%02lx\n",
 		       width, (entryhi & ~0x1fffUL),
 		       entryhi & 0xff);
-		printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
-		       width,
-		       (entrylo0 << 6) & PAGE_MASK, c0,
+		/* RI/XI are in awkward places, so mask them off separately */
+		pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		pa = (pa << 6) & PAGE_MASK;
+		printk("\t[");
+		if (cpu_has_rixi)
+			printk("ri=%d xi=%d ",
+			       (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0,
+			       (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
+		printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",
+		       width, pa, c0,
 		       (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
-		printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
-		       width,
-		       (entrylo1 << 6) & PAGE_MASK, c1,
+		/* RI/XI are in awkward places, so mask them off separately */
+		pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		pa = (pa << 6) & PAGE_MASK;
+		if (cpu_has_rixi)
+			printk("ri=%d xi=%d ",
+			       (entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0,
+			       (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
+		printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
+		       width, pa, c1,
 		       (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
-- 
2.3.6

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

* [PATCH v2 10/10] MIPS: dump_tlb: Take XPA into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Steven J. Hill

XPA extends the physical addresses on MIPS32, including the EntryLo
registers. Update dump_tlb() to concatenate the PFNX field from the high
end of the EntryLo registers (as read by mfhc0).

The width of physical and virtual addresses are also separated to show
only 8 nibbles of virtual but 11 nibbles of physical with XPA.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 1fefd38aba08..167f35634709 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -47,9 +47,13 @@ static void dump_tlb(int first, int last)
 	unsigned long long entrylo0, entrylo1, pa;
 	unsigned int s_index, s_pagemask, pagemask, c0, c1, i;
 #ifdef CONFIG_32BIT
-	int width = 8;
+	bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA);
+	int pwidth = xpa ? 11 : 8;
+	int vwidth = 8;
 #else
-	int width = 11;
+	bool xpa = false;
+	int pwidth = 11;
+	int vwidth = 11;
 #endif
 
 	s_pagemask = read_c0_pagemask();
@@ -96,10 +100,12 @@ static void dump_tlb(int first, int last)
 		c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
 
 		printk("va=%0*lx asid=%02lx\n",
-		       width, (entryhi & ~0x1fffUL),
+		       vwidth, (entryhi & ~0x1fffUL),
 		       entryhi & 0xff);
 		/* RI/XI are in awkward places, so mask them off separately */
 		pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		if (xpa)
+			pa |= (unsigned long long)readx_c0_entrylo0() << 30;
 		pa = (pa << 6) & PAGE_MASK;
 		printk("\t[");
 		if (cpu_has_rixi)
@@ -107,19 +113,21 @@ static void dump_tlb(int first, int last)
 			       (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0,
 			       (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
 		printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",
-		       width, pa, c0,
+		       pwidth, pa, c0,
 		       (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
 		/* RI/XI are in awkward places, so mask them off separately */
 		pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		if (xpa)
+			pa |= (unsigned long long)readx_c0_entrylo1() << 30;
 		pa = (pa << 6) & PAGE_MASK;
 		if (cpu_has_rixi)
 			printk("ri=%d xi=%d ",
 			       (entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0,
 			       (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
 		printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
-		       width, pa, c1,
+		       pwidth, pa, c1,
 		       (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
-- 
2.3.6

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

* [PATCH v2 10/10] MIPS: dump_tlb: Take XPA into account
@ 2015-05-19  8:50   ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-05-19  8:50 UTC (permalink / raw)
  To: Ralf Baechle, linux-mips; +Cc: James Hogan, Steven J. Hill

XPA extends the physical addresses on MIPS32, including the EntryLo
registers. Update dump_tlb() to concatenate the PFNX field from the high
end of the EntryLo registers (as read by mfhc0).

The width of physical and virtual addresses are also separated to show
only 8 nibbles of virtual but 11 nibbles of physical with XPA.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: linux-mips@linux-mips.org
---
 arch/mips/lib/dump_tlb.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 1fefd38aba08..167f35634709 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -47,9 +47,13 @@ static void dump_tlb(int first, int last)
 	unsigned long long entrylo0, entrylo1, pa;
 	unsigned int s_index, s_pagemask, pagemask, c0, c1, i;
 #ifdef CONFIG_32BIT
-	int width = 8;
+	bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA);
+	int pwidth = xpa ? 11 : 8;
+	int vwidth = 8;
 #else
-	int width = 11;
+	bool xpa = false;
+	int pwidth = 11;
+	int vwidth = 11;
 #endif
 
 	s_pagemask = read_c0_pagemask();
@@ -96,10 +100,12 @@ static void dump_tlb(int first, int last)
 		c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
 
 		printk("va=%0*lx asid=%02lx\n",
-		       width, (entryhi & ~0x1fffUL),
+		       vwidth, (entryhi & ~0x1fffUL),
 		       entryhi & 0xff);
 		/* RI/XI are in awkward places, so mask them off separately */
 		pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		if (xpa)
+			pa |= (unsigned long long)readx_c0_entrylo0() << 30;
 		pa = (pa << 6) & PAGE_MASK;
 		printk("\t[");
 		if (cpu_has_rixi)
@@ -107,19 +113,21 @@ static void dump_tlb(int first, int last)
 			       (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0,
 			       (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
 		printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",
-		       width, pa, c0,
+		       pwidth, pa, c0,
 		       (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
 		/* RI/XI are in awkward places, so mask them off separately */
 		pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+		if (xpa)
+			pa |= (unsigned long long)readx_c0_entrylo1() << 30;
 		pa = (pa << 6) & PAGE_MASK;
 		if (cpu_has_rixi)
 			printk("ri=%d xi=%d ",
 			       (entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0,
 			       (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
 		printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
-		       width, pa, c1,
+		       pwidth, pa, c1,
 		       (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
 		       (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
-- 
2.3.6

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

* Re: [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs
  2015-05-19  8:50   ` James Hogan
  (?)
@ 2015-05-24 21:21   ` Joshua Kinard
  2015-05-26 11:58     ` Maciej W. Rozycki
  -1 siblings, 1 reply; 32+ messages in thread
From: Joshua Kinard @ 2015-05-24 21:21 UTC (permalink / raw)
  To: James Hogan, Ralf Baechle, linux-mips

On 05/19/2015 04:50, James Hogan wrote:
> Add a MIPS specific SysRq operation to dump the TLB entries on all CPUs,
> using the 'x' trigger key.

Thought: Would it make sense to split apart the data such that one SysRq key
dumps the CP0 registers of all CPUs, and another dumps the TLB info?


> +/*
> + * Dump TLB entries on all CPUs.
> + */
> +
> +static DEFINE_SPINLOCK(show_lock);
> +
> +static void sysrq_tlbdump_single(void *dummy)
> +{
> +	const int field = 2 * sizeof(unsigned long);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&show_lock, flags);
> +
> +	pr_info("CPU%d:\n", smp_processor_id());
> +	pr_info("Index	: %0x\n", read_c0_index());
> +	pr_info("Pagemask: %0x\n", read_c0_pagemask());
> +	pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
> +	pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
> +	pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
> +	pr_info("Wired   : %0x\n", read_c0_wired());
> +	pr_info("Pagegrain: %0x\n", read_c0_pagegrain());
> +	if (cpu_has_htw) {
> +		pr_info("PWField : %0*lx\n", field, read_c0_pwfield());
> +		pr_info("PWSize  : %0*lx\n", field, read_c0_pwsize());
> +		pr_info("PWCtl   : %0x\n", read_c0_pwctl());
> +	}
> +	pr_info("\n");
> +	dump_tlb_all();
> +	pr_info("\n");
> +
> +	spin_unlock_irqrestore(&show_lock, flags);
> +}

The older CPUs, like the R10000 don't have a PageGrain register I believe (at
least R10K doesn't),  Does that need to be stuffed behind a conditional?  Also,
R10K (and newer?) CPUs have a FrameMask CP0 register ($21).  Linux currently
scribbles a 0 to the writable bits, though, so I'm not sure if it matters.

--J

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

* Re: [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs
  2015-05-24 21:21   ` Joshua Kinard
@ 2015-05-26 11:58     ` Maciej W. Rozycki
  2015-05-27 13:09       ` Maciej W. Rozycki
  2015-07-14  9:27         ` James Hogan
  0 siblings, 2 replies; 32+ messages in thread
From: Maciej W. Rozycki @ 2015-05-26 11:58 UTC (permalink / raw)
  To: Joshua Kinard, James Hogan; +Cc: Ralf Baechle, linux-mips

On Sun, 24 May 2015, Joshua Kinard wrote:

> > Add a MIPS specific SysRq operation to dump the TLB entries on all CPUs,
> > using the 'x' trigger key.
> 
> Thought: Would it make sense to split apart the data such that one SysRq key
> dumps the CP0 registers of all CPUs, and another dumps the TLB info?

 That would be a large separate project, probing a CPU for its implemented 
CP0 registers is a complex matter.

 I did it for GDB and a bare-iron debug stub a few years ago and back then 
there were IIRC 53 register subsets already defined for MIPS architecture 
processors, wired to various, sometimes overlapping feature bits of CP0 
Config registers, and now there are more.  Plus legacy processors require 
fixed register maps according to CP0.PRId.

 James, I think what you proposed is good enough for TLB diagnostics (I'm 
not sure if dumping EntryLo0 and EntryLo1 registers has any use, but it 
surely does not hurt either).

> > +	pr_info("CPU%d:\n", smp_processor_id());
> > +	pr_info("Index	: %0x\n", read_c0_index());
> > +	pr_info("Pagemask: %0x\n", read_c0_pagemask());
> > +	pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
> > +	pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
> > +	pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
> > +	pr_info("Wired   : %0x\n", read_c0_wired());
> > +	pr_info("Pagegrain: %0x\n", read_c0_pagegrain());

 Please capitalise these consistently: PageMask and PageGrain.

> The older CPUs, like the R10000 don't have a PageGrain register I believe (at
> least R10K doesn't),  Does that need to be stuffed behind a conditional?  Also,
> R10K (and newer?) CPUs have a FrameMask CP0 register ($21).  Linux currently
> scribbles a 0 to the writable bits, though, so I'm not sure if it matters.

 First of all I suggest that this part is split off into separate small 
helper functions within dump_tlb.c and r3k_dump_tlb.c.  This code is not 
performance-critical, so the overhead of an extra function call isn't of 
a concern.

 Then R3k processors have Index, EntryHi and EntryLo (rather than 
EntryLo0) registers only; some Toshiba processors have Wired too (cf. 
`r3k_have_wired_reg').

 And for the R4k-style TLB the PageGrain register does need to be probed 
for.  I think including FrameMask would be good too, that shouldn't be 
difficult (switch on `current_cpu_type'?).

  Maciej

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

* Re: [PATCH v2 02/10] MIPS: hazards: Add hazard macros for tlb read
  2015-05-19  8:50   ` James Hogan
  (?)
@ 2015-05-26 12:36   ` Maciej W. Rozycki
  2015-05-26 12:53     ` Ralf Baechle
  -1 siblings, 1 reply; 32+ messages in thread
From: Maciej W. Rozycki @ 2015-05-26 12:36 UTC (permalink / raw)
  To: James Hogan; +Cc: Ralf Baechle, linux-mips

On Tue, 19 May 2015, James Hogan wrote:

> - tlb_read_hazard
>   Between tlbr and mfc0 (various TLB registers). This is copied from
>   tlbw_use_hazard in all cases on the assumption that tlbr has similar
>   data writer characteristics to tlbw, and mfc0 has similar data user
>   characteristics to loads and stores.

 Be careful with this assumption, it does not stand for R4600/R4700 and 
R5000 processors (4 vs 3 intervening instructions), you need an extra NOP 
for them.  Likewise there is a difference with the 5K (1 vs 0 intervening 
instructions), but it's already buried in our pessimistic barrier that 
assumes 4 intervening instructions.

  Maciej

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

* Re: [PATCH v2 02/10] MIPS: hazards: Add hazard macros for tlb read
  2015-05-26 12:36   ` Maciej W. Rozycki
@ 2015-05-26 12:53     ` Ralf Baechle
  2015-05-26 13:25       ` Maciej W. Rozycki
  0 siblings, 1 reply; 32+ messages in thread
From: Ralf Baechle @ 2015-05-26 12:53 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: James Hogan, linux-mips

On Tue, May 26, 2015 at 01:36:37PM +0100, Maciej W. Rozycki wrote:

> > - tlb_read_hazard
> >   Between tlbr and mfc0 (various TLB registers). This is copied from
> >   tlbw_use_hazard in all cases on the assumption that tlbr has similar
> >   data writer characteristics to tlbw, and mfc0 has similar data user
> >   characteristics to loads and stores.
> 
>  Be careful with this assumption, it does not stand for R4600/R4700 and 
> R5000 processors (4 vs 3 intervening instructions), you need an extra NOP 
> for them.  Likewise there is a difference with the 5K (1 vs 0 intervening 
> instructions), but it's already buried in our pessimistic barrier that 
> assumes 4 intervening instructions.

The TLB write hazard is 4 cycles on the 8 stage R4000 pipeline but 2 cycles
on the R4600 pipeline.  We handle this in a particularly non-obvious but
optimized way by exploiting the fact that the R4000 pipeline kills two
instructions following the branch delay slot like:

	.set	noreorder
	MTC0	$reg, c0_sometlbregister
	B	1f
1:	 NOP
	TLBW

where the branch-nop sequence will cost 4 cycles on the R4000's eight-stage
pipeline but only two on the R4600 pipeline.

  Ralf

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

* Re: [PATCH v2 02/10] MIPS: hazards: Add hazard macros for tlb read
  2015-05-26 12:53     ` Ralf Baechle
@ 2015-05-26 13:25       ` Maciej W. Rozycki
  2015-05-26 13:32         ` Ralf Baechle
  0 siblings, 1 reply; 32+ messages in thread
From: Maciej W. Rozycki @ 2015-05-26 13:25 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: James Hogan, linux-mips

On Tue, 26 May 2015, Ralf Baechle wrote:

> > > - tlb_read_hazard
> > >   Between tlbr and mfc0 (various TLB registers). This is copied from
> > >   tlbw_use_hazard in all cases on the assumption that tlbr has similar
> > >   data writer characteristics to tlbw, and mfc0 has similar data user
> > >   characteristics to loads and stores.
> > 
> >  Be careful with this assumption, it does not stand for R4600/R4700 and 
> > R5000 processors (4 vs 3 intervening instructions), you need an extra NOP 
> > for them.  Likewise there is a difference with the 5K (1 vs 0 intervening 
> > instructions), but it's already buried in our pessimistic barrier that 
> > assumes 4 intervening instructions.
> 
> The TLB write hazard is 4 cycles on the 8 stage R4000 pipeline but 2 cycles
> on the R4600 pipeline.

 I misinterpreted the numbers in the table for the R4600/R4700/R5000, 
sorry.  It gives pipeline stage numbers rather than instruction counts, 
unlike the 5K and some other tables.

 The difference is still there however: for TLBW_/use it's (3 - 2 - 1) => 
0 and for TLBR/MFC0 it's (4 - 2 - 1) => 1 (there's a one-cycle slip for 
TLBW_ instructions causing it).  We use 3 NOPs for this variant, so it'll 
be covered.

>  We handle this in a particularly non-obvious but
> optimized way by exploiting the fact that the R4000 pipeline kills two
> instructions following the branch delay slot like:
> 
> 	.set	noreorder
> 	MTC0	$reg, c0_sometlbregister
> 	B	1f
> 1:	 NOP
> 	TLBW
> 
> where the branch-nop sequence will cost 4 cycles on the R4000's eight-stage
> pipeline but only two on the R4600 pipeline.

 And this code is where?  ISTR seeing it before, but now all I can see in 
<asm/hazards.h> for the R4k and friends is:

#define __tlbw_use_hazard						\
	nop;								\
	nop;								\
	nop

It does not cover the 4-instruction hazard of the original R4000 even, so 
it looks like it has to be fixed, perhaps by using code like you quoted.

  Maciej

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

* Re: [PATCH v2 02/10] MIPS: hazards: Add hazard macros for tlb read
  2015-05-26 13:25       ` Maciej W. Rozycki
@ 2015-05-26 13:32         ` Ralf Baechle
  0 siblings, 0 replies; 32+ messages in thread
From: Ralf Baechle @ 2015-05-26 13:32 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: James Hogan, linux-mips

On Tue, May 26, 2015 at 02:25:52PM +0100, Maciej W. Rozycki wrote:

> > > > - tlb_read_hazard
> > > >   Between tlbr and mfc0 (various TLB registers). This is copied from
> > > >   tlbw_use_hazard in all cases on the assumption that tlbr has similar
> > > >   data writer characteristics to tlbw, and mfc0 has similar data user
> > > >   characteristics to loads and stores.
> > > 
> > >  Be careful with this assumption, it does not stand for R4600/R4700 and 
> > > R5000 processors (4 vs 3 intervening instructions), you need an extra NOP 
> > > for them.  Likewise there is a difference with the 5K (1 vs 0 intervening 
> > > instructions), but it's already buried in our pessimistic barrier that 
> > > assumes 4 intervening instructions.
> > 
> > The TLB write hazard is 4 cycles on the 8 stage R4000 pipeline but 2 cycles
> > on the R4600 pipeline.
> 
>  I misinterpreted the numbers in the table for the R4600/R4700/R5000, 
> sorry.  It gives pipeline stage numbers rather than instruction counts, 
> unlike the 5K and some other tables.
> 
>  The difference is still there however: for TLBW_/use it's (3 - 2 - 1) => 
> 0 and for TLBR/MFC0 it's (4 - 2 - 1) => 1 (there's a one-cycle slip for 
> TLBW_ instructions causing it).  We use 3 NOPs for this variant, so it'll 
> be covered.
> 
> >  We handle this in a particularly non-obvious but
> > optimized way by exploiting the fact that the R4000 pipeline kills two
> > instructions following the branch delay slot like:
> > 
> > 	.set	noreorder
> > 	MTC0	$reg, c0_sometlbregister
> > 	B	1f
> > 1:	 NOP
> > 	TLBW
> > 
> > where the branch-nop sequence will cost 4 cycles on the R4000's eight-stage
> > pipeline but only two on the R4600 pipeline.
> 
>  And this code is where?  ISTR seeing it before, but now all I can see in 
> <asm/hazards.h> for the R4k and friends is:
> 
> #define __tlbw_use_hazard						\
> 	nop;								\
> 	nop;								\
> 	nop
> 
> It does not cover the 4-instruction hazard of the original R4000 even, so 
> it looks like it has to be fixed, perhaps by using code like you quoted.

Sorry for reciting kernel code from memory :-) I haven't checked a current
kernel before posting.  If it's been removed then this there might be a
bug or at least something that can be optimized for the R4000/R4000.

  Ralf

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

* Re: [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs
  2015-05-26 11:58     ` Maciej W. Rozycki
@ 2015-05-27 13:09       ` Maciej W. Rozycki
  2015-07-14  9:27         ` James Hogan
  1 sibling, 0 replies; 32+ messages in thread
From: Maciej W. Rozycki @ 2015-05-27 13:09 UTC (permalink / raw)
  To: James Hogan; +Cc: Ralf Baechle, Joshua Kinard, linux-mips

On Tue, 26 May 2015, Maciej W. Rozycki wrote:

>  James, I think what you proposed is good enough for TLB diagnostics (I'm 
> not sure if dumping EntryLo0 and EntryLo1 registers has any use, but it 
> surely does not hurt either).

 And BTW, please update Documentation/sysrq.txt accordingly!

  Maciej

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

* Re: [PATCH v2 03/10] MIPS: mipsregs.h: Add EntryLo bit definitions
  2015-05-19  8:50   ` James Hogan
  (?)
@ 2015-05-28 23:47   ` Maciej W. Rozycki
  -1 siblings, 0 replies; 32+ messages in thread
From: Maciej W. Rozycki @ 2015-05-28 23:47 UTC (permalink / raw)
  To: James Hogan; +Cc: Ralf Baechle, linux-mips

On Tue, 19 May 2015, James Hogan wrote:

> Add definitions for EntryLo register bits in mipsregs.h. The R4000
> compatible ones are prefixed MIPS_ENTRYLO_ and the R3000 compatible ones
> are prefixed R3K_ENTRYLO_.

 I think the convention for macros in <asm/mipsregs.h> has been to omit 
the MIPS_ prefix for generic definitions.  The prefix is meant for MIPS32 
and MIPS64 architecture processor properties.  The bits in EntryLo0/1 have 
been like this since forever, with the exception of the R3k/R6k/R8k 
oddballs.  So I think they can be treated as generic.  Of course the R3K_ 
prefix is right with R3k-specific definitions.

 OTOH, the EntryHi.EHINV bit has only been added with (non-legacy) MIPS 
architecture processors, so MIPS_ENTRYHI_EHINV is the right choice 
(although its placement is unfortunate, buried within the "Bits in the 
MIPS32/64 PRA coprocessor 0 config registers 1 and above." section).

> diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
> index 764e2756b54d..3b5a145af659 100644
> --- a/arch/mips/include/asm/mipsregs.h
> +++ b/arch/mips/include/asm/mipsregs.h
> @@ -589,6 +589,28 @@
>  /*  EntryHI bit definition */
>  #define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10)
>  
> +/* R3000 EntryLo bit definitions */
> +#define R3K_ENTRYLO_G		(_ULCAST_(1) << 8)
> +#define R3K_ENTRYLO_V		(_ULCAST_(1) << 9)
> +#define R3K_ENTRYLO_D		(_ULCAST_(1) << 10)
> +#define R3K_ENTRYLO_N		(_ULCAST_(1) << 11)
> +
> +/* R4000 compatible EntryLo bit definitions */
> +#define MIPS_ENTRYLO_G		(_ULCAST_(1) << 0)
> +#define MIPS_ENTRYLO_V		(_ULCAST_(1) << 1)
> +#define MIPS_ENTRYLO_D		(_ULCAST_(1) << 2)
> +#define MIPS_ENTRYLO_C_SHIFT	3
> +#define MIPS_ENTRYLO_C		(_ULCAST_(7) << MIPS_ENTRYLO_C_SHIFT)

 Please drop the MIPS_ prefix here then, e.g.:

#define ENTRYLO_G		(_ULCAST_(1) << 0)

> +#ifdef CONFIG_64BIT
> +/* as read by dmfc0 */
> +#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 62)
> +#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 63)
> +#else
> +/* as read by mfc0 */
> +#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 30)
> +#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 31)
> +#endif
> +

 These do need to keep the prefix however, because these have only been 
added with MIPS32/MIPS64 processors.  This also means they need its own 
explanatory heading.

 And then put the generic (or R4k) bits first, followed by the R3k bits, 
followed by the MIPS32/64 bits.  See how it's been done for the Status 
register (disregard the odd ST0_ prefix, it's another legacy) and the 
Config register.

 Like with MIPS_ENTRYHI_EHINV I think the placement of these new additions 
is also unfortunate.  No need for you to fix the former, unless you're 
keen to, but with this new stuff I suggest that you put it right at the 
top, to keep the definitions grouped by the function (MMU in this case) 
and roughly in the numeric order by register ID.  So that'll be 
immediately before stuff for PageMask.

 Thanks for your patience and sorry to be a pain, but this file has had a 
tendency to become a mess.  Maybe we need to put a note explaining the 
rules at the top.

  Maciej

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

* Re: [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs
@ 2015-07-14  9:27         ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-07-14  9:27 UTC (permalink / raw)
  To: Maciej W. Rozycki, Joshua Kinard; +Cc: Ralf Baechle, linux-mips

[-- Attachment #1: Type: text/plain, Size: 2707 bytes --]

On 26/05/15 12:58, Maciej W. Rozycki wrote:
> On Sun, 24 May 2015, Joshua Kinard wrote:
> 
>>> Add a MIPS specific SysRq operation to dump the TLB entries on all CPUs,
>>> using the 'x' trigger key.
>>
>> Thought: Would it make sense to split apart the data such that one SysRq key
>> dumps the CP0 registers of all CPUs, and another dumps the TLB info?
> 
>  That would be a large separate project, probing a CPU for its implemented 
> CP0 registers is a complex matter.
> 
>  I did it for GDB and a bare-iron debug stub a few years ago and back then 
> there were IIRC 53 register subsets already defined for MIPS architecture 
> processors, wired to various, sometimes overlapping feature bits of CP0 
> Config registers, and now there are more.  Plus legacy processors require 
> fixed register maps according to CP0.PRId.
> 
>  James, I think what you proposed is good enough for TLB diagnostics (I'm 
> not sure if dumping EntryLo0 and EntryLo1 registers has any use, but it 
> surely does not hurt either).
> 
>>> +	pr_info("CPU%d:\n", smp_processor_id());
>>> +	pr_info("Index	: %0x\n", read_c0_index());
>>> +	pr_info("Pagemask: %0x\n", read_c0_pagemask());
>>> +	pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
>>> +	pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
>>> +	pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
>>> +	pr_info("Wired   : %0x\n", read_c0_wired());
>>> +	pr_info("Pagegrain: %0x\n", read_c0_pagegrain());
> 
>  Please capitalise these consistently: PageMask and PageGrain.
> 
>> The older CPUs, like the R10000 don't have a PageGrain register I believe (at
>> least R10K doesn't),  Does that need to be stuffed behind a conditional?  Also,
>> R10K (and newer?) CPUs have a FrameMask CP0 register ($21).  Linux currently
>> scribbles a 0 to the writable bits, though, so I'm not sure if it matters.
> 
>  First of all I suggest that this part is split off into separate small 
> helper functions within dump_tlb.c and r3k_dump_tlb.c.  This code is not 
> performance-critical, so the overhead of an extra function call isn't of 
> a concern.
> 
>  Then R3k processors have Index, EntryHi and EntryLo (rather than 
> EntryLo0) registers only; some Toshiba processors have Wired too (cf. 
> `r3k_have_wired_reg').
> 
>  And for the R4k-style TLB the PageGrain register does need to be probed 
> for.  I think including FrameMask would be good too, that shouldn't be 
> difficult (switch on `current_cpu_type'?).

Thanks for all the feedback Joshua and Maciej, and sorry for the delay
getting back to this. I think I've addressed it all now, so I'll submit
a second patchset soon.

Cheers
James


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs
@ 2015-07-14  9:27         ` James Hogan
  0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2015-07-14  9:27 UTC (permalink / raw)
  To: Maciej W. Rozycki, Joshua Kinard; +Cc: Ralf Baechle, linux-mips

[-- Attachment #1: Type: text/plain, Size: 2707 bytes --]

On 26/05/15 12:58, Maciej W. Rozycki wrote:
> On Sun, 24 May 2015, Joshua Kinard wrote:
> 
>>> Add a MIPS specific SysRq operation to dump the TLB entries on all CPUs,
>>> using the 'x' trigger key.
>>
>> Thought: Would it make sense to split apart the data such that one SysRq key
>> dumps the CP0 registers of all CPUs, and another dumps the TLB info?
> 
>  That would be a large separate project, probing a CPU for its implemented 
> CP0 registers is a complex matter.
> 
>  I did it for GDB and a bare-iron debug stub a few years ago and back then 
> there were IIRC 53 register subsets already defined for MIPS architecture 
> processors, wired to various, sometimes overlapping feature bits of CP0 
> Config registers, and now there are more.  Plus legacy processors require 
> fixed register maps according to CP0.PRId.
> 
>  James, I think what you proposed is good enough for TLB diagnostics (I'm 
> not sure if dumping EntryLo0 and EntryLo1 registers has any use, but it 
> surely does not hurt either).
> 
>>> +	pr_info("CPU%d:\n", smp_processor_id());
>>> +	pr_info("Index	: %0x\n", read_c0_index());
>>> +	pr_info("Pagemask: %0x\n", read_c0_pagemask());
>>> +	pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
>>> +	pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
>>> +	pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
>>> +	pr_info("Wired   : %0x\n", read_c0_wired());
>>> +	pr_info("Pagegrain: %0x\n", read_c0_pagegrain());
> 
>  Please capitalise these consistently: PageMask and PageGrain.
> 
>> The older CPUs, like the R10000 don't have a PageGrain register I believe (at
>> least R10K doesn't),  Does that need to be stuffed behind a conditional?  Also,
>> R10K (and newer?) CPUs have a FrameMask CP0 register ($21).  Linux currently
>> scribbles a 0 to the writable bits, though, so I'm not sure if it matters.
> 
>  First of all I suggest that this part is split off into separate small 
> helper functions within dump_tlb.c and r3k_dump_tlb.c.  This code is not 
> performance-critical, so the overhead of an extra function call isn't of 
> a concern.
> 
>  Then R3k processors have Index, EntryHi and EntryLo (rather than 
> EntryLo0) registers only; some Toshiba processors have Wired too (cf. 
> `r3k_have_wired_reg').
> 
>  And for the R4k-style TLB the PageGrain register does need to be probed 
> for.  I think including FrameMask would be good too, that shouldn't be 
> difficult (switch on `current_cpu_type'?).

Thanks for all the feedback Joshua and Maciej, and sorry for the delay
getting back to this. I think I've addressed it all now, so I'll submit
a second patchset soon.

Cheers
James


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

end of thread, other threads:[~2015-07-14  9:27 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-19  8:50 [PATCH v2 00/10] MIPS: dump_tlb improvements James Hogan
2015-05-19  8:50 ` James Hogan
2015-05-19  8:50 ` [PATCH RFC v2 01/10] MIPS: Add SysRq operation to dump TLBs on all CPUs James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-24 21:21   ` Joshua Kinard
2015-05-26 11:58     ` Maciej W. Rozycki
2015-05-27 13:09       ` Maciej W. Rozycki
2015-07-14  9:27       ` James Hogan
2015-07-14  9:27         ` James Hogan
2015-05-19  8:50 ` [PATCH v2 02/10] MIPS: hazards: Add hazard macros for tlb read James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-26 12:36   ` Maciej W. Rozycki
2015-05-26 12:53     ` Ralf Baechle
2015-05-26 13:25       ` Maciej W. Rozycki
2015-05-26 13:32         ` Ralf Baechle
2015-05-19  8:50 ` [PATCH v2 03/10] MIPS: mipsregs.h: Add EntryLo bit definitions James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-28 23:47   ` Maciej W. Rozycki
2015-05-19  8:50 ` [PATCH v2 04/10] MIPS: dump_tlb: Use tlbr hazard macros James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-19  8:50 ` [PATCH v2 05/10] MIPS: dump_tlb: Refactor TLB matching James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-19  8:50 ` [PATCH v2 06/10] MIPS: dump_tlb: Make use of EntryLo bit definitions James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-19  8:50 ` [PATCH v2 07/10] MIPS: dump_tlb: Take global bit into account James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-19  8:50 ` [PATCH v2 08/10] MIPS: dump_tlb: Take EHINV " James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-19  8:50 ` [PATCH v2 09/10] MIPS: dump_tlb: Take RI/XI bits " James Hogan
2015-05-19  8:50   ` James Hogan
2015-05-19  8:50 ` [PATCH v2 10/10] MIPS: dump_tlb: Take XPA " James Hogan
2015-05-19  8:50   ` James Hogan

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.