Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support
@ 2014-07-14  9:32 Paul Burton
  2014-07-14  9:32 ` Paul Burton
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

This series introduces support for the Memory Accessibility Attribute
Registers introduced with MIPSr5. These registers control whether
speculative accesses are allowed to regions of memory. Allowing
speculative memory accesses is a requirement for current hardware MSA
implementations to be able to handle non-128b aligned vector loads &
stores, which are something userland may legitimately assume will work.

The series needs Markos' "MIPS: cpu-info: Change the cpu options
variable to unsigned long long" patch to be applied first.

Paul Burton (4):
  MIPS: define MAAR register accessors & bits
  MIPS: detect presence of MAARs
  MIPS: initialise MAARs
  MIPS: Malta: initialise MAARs

 arch/mips/include/asm/cpu-features.h |   3 +
 arch/mips/include/asm/cpu.h          |   1 +
 arch/mips/include/asm/maar.h         | 109 +++++++++++++++++++++++++++++++++++
 arch/mips/include/asm/mipsregs.h     |  12 ++++
 arch/mips/kernel/cpu-probe.c         |   2 +
 arch/mips/mm/init.c                  |  33 +++++++++++
 arch/mips/mti-malta/malta-memory.c   |  26 +++++++++
 7 files changed, 186 insertions(+)
 create mode 100644 arch/mips/include/asm/maar.h

-- 
2.0.1

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

* [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support
  2014-07-14  9:32 [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support Paul Burton
@ 2014-07-14  9:32 ` Paul Burton
  2014-07-14  9:32 ` [PATCH 1/4] MIPS: define MAAR register accessors & bits Paul Burton
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

This series introduces support for the Memory Accessibility Attribute
Registers introduced with MIPSr5. These registers control whether
speculative accesses are allowed to regions of memory. Allowing
speculative memory accesses is a requirement for current hardware MSA
implementations to be able to handle non-128b aligned vector loads &
stores, which are something userland may legitimately assume will work.

The series needs Markos' "MIPS: cpu-info: Change the cpu options
variable to unsigned long long" patch to be applied first.

Paul Burton (4):
  MIPS: define MAAR register accessors & bits
  MIPS: detect presence of MAARs
  MIPS: initialise MAARs
  MIPS: Malta: initialise MAARs

 arch/mips/include/asm/cpu-features.h |   3 +
 arch/mips/include/asm/cpu.h          |   1 +
 arch/mips/include/asm/maar.h         | 109 +++++++++++++++++++++++++++++++++++
 arch/mips/include/asm/mipsregs.h     |  12 ++++
 arch/mips/kernel/cpu-probe.c         |   2 +
 arch/mips/mm/init.c                  |  33 +++++++++++
 arch/mips/mti-malta/malta-memory.c   |  26 +++++++++
 7 files changed, 186 insertions(+)
 create mode 100644 arch/mips/include/asm/maar.h

-- 
2.0.1

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

* [PATCH 1/4] MIPS: define MAAR register accessors & bits
  2014-07-14  9:32 [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support Paul Burton
  2014-07-14  9:32 ` Paul Burton
@ 2014-07-14  9:32 ` Paul Burton
  2014-07-14  9:32   ` Paul Burton
  2014-07-14  9:32 ` [PATCH 2/4] MIPS: detect presence of MAARs Paul Burton
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Add accessor macros for the Memory Accessibility Attribute Registers
(MAARs), the bits contained within the MAARs & the Config5.MRP bit
indicating their presence. The only current use of the MAARs is to
enable speculative accesses to regions of memory. Besides the potential
performance benefits of speculative accesses, they are a requirement
for the P5600 core to handle non-128b-aligned MSA vector loads & stores
rather than generating an address error.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/include/asm/mipsregs.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 98e9754..b21f5a3 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -652,6 +652,7 @@
 
 #define MIPS_CONF5_NF		(_ULCAST_(1) << 0)
 #define MIPS_CONF5_UFR		(_ULCAST_(1) << 2)
+#define MIPS_CONF5_MRP		(_ULCAST_(1) << 3)
 #define MIPS_CONF5_MSAEN	(_ULCAST_(1) << 27)
 #define MIPS_CONF5_EVA		(_ULCAST_(1) << 28)
 #define MIPS_CONF5_CV		(_ULCAST_(1) << 29)
@@ -668,6 +669,12 @@
 #define MIPS_CONF7_IAR		(_ULCAST_(1) << 10)
 #define MIPS_CONF7_AR		(_ULCAST_(1) << 16)
 
+/* MAAR bit definitions */
+#define MIPS_MAAR_ADDR		((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)
+#define MIPS_MAAR_ADDR_SHIFT	12
+#define MIPS_MAAR_S		(_ULCAST_(1) << 1)
+#define MIPS_MAAR_V		(_ULCAST_(1) << 0)
+
 /*  EntryHI bit definition */
 #define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10)
 
@@ -1044,6 +1051,11 @@ do {									\
 #define write_c0_config6(val)	__write_32bit_c0_register($16, 6, val)
 #define write_c0_config7(val)	__write_32bit_c0_register($16, 7, val)
 
+#define read_c0_maar()		__read_ulong_c0_register($17, 1)
+#define write_c0_maar(val)	__write_ulong_c0_register($17, 1, val)
+#define read_c0_maari()		__read_32bit_c0_register($17, 2)
+#define write_c0_maari(val)	__write_32bit_c0_register($17, 2, val)
+
 /*
  * The WatchLo register.  There may be up to 8 of them.
  */
-- 
2.0.1

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

* [PATCH 1/4] MIPS: define MAAR register accessors & bits
  2014-07-14  9:32 ` [PATCH 1/4] MIPS: define MAAR register accessors & bits Paul Burton
@ 2014-07-14  9:32   ` Paul Burton
  0 siblings, 0 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Add accessor macros for the Memory Accessibility Attribute Registers
(MAARs), the bits contained within the MAARs & the Config5.MRP bit
indicating their presence. The only current use of the MAARs is to
enable speculative accesses to regions of memory. Besides the potential
performance benefits of speculative accesses, they are a requirement
for the P5600 core to handle non-128b-aligned MSA vector loads & stores
rather than generating an address error.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/include/asm/mipsregs.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 98e9754..b21f5a3 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -652,6 +652,7 @@
 
 #define MIPS_CONF5_NF		(_ULCAST_(1) << 0)
 #define MIPS_CONF5_UFR		(_ULCAST_(1) << 2)
+#define MIPS_CONF5_MRP		(_ULCAST_(1) << 3)
 #define MIPS_CONF5_MSAEN	(_ULCAST_(1) << 27)
 #define MIPS_CONF5_EVA		(_ULCAST_(1) << 28)
 #define MIPS_CONF5_CV		(_ULCAST_(1) << 29)
@@ -668,6 +669,12 @@
 #define MIPS_CONF7_IAR		(_ULCAST_(1) << 10)
 #define MIPS_CONF7_AR		(_ULCAST_(1) << 16)
 
+/* MAAR bit definitions */
+#define MIPS_MAAR_ADDR		((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)
+#define MIPS_MAAR_ADDR_SHIFT	12
+#define MIPS_MAAR_S		(_ULCAST_(1) << 1)
+#define MIPS_MAAR_V		(_ULCAST_(1) << 0)
+
 /*  EntryHI bit definition */
 #define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10)
 
@@ -1044,6 +1051,11 @@ do {									\
 #define write_c0_config6(val)	__write_32bit_c0_register($16, 6, val)
 #define write_c0_config7(val)	__write_32bit_c0_register($16, 7, val)
 
+#define read_c0_maar()		__read_ulong_c0_register($17, 1)
+#define write_c0_maar(val)	__write_ulong_c0_register($17, 1, val)
+#define read_c0_maari()		__read_32bit_c0_register($17, 2)
+#define write_c0_maari(val)	__write_32bit_c0_register($17, 2, val)
+
 /*
  * The WatchLo register.  There may be up to 8 of them.
  */
-- 
2.0.1

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

* [PATCH 2/4] MIPS: detect presence of MAARs
  2014-07-14  9:32 [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support Paul Burton
  2014-07-14  9:32 ` Paul Burton
  2014-07-14  9:32 ` [PATCH 1/4] MIPS: define MAAR register accessors & bits Paul Burton
@ 2014-07-14  9:32 ` Paul Burton
  2014-07-14  9:32   ` Paul Burton
  2014-07-14  9:32 ` [PATCH 3/4] MIPS: initialise MAARs Paul Burton
  2014-07-14  9:32 ` [PATCH 4/4] MIPS: Malta: " Paul Burton
  4 siblings, 1 reply; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Detect the presence of MAAR using the MRP bit in Config5, and record
that presence using a CPU option bit. A cpu_has_maar macro will then
allow code to conditionalise upon the presence of MAARs.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/include/asm/cpu-features.h | 3 +++
 arch/mips/include/asm/cpu.h          | 1 +
 arch/mips/kernel/cpu-probe.c         | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index c7d8c99..2101618 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -29,6 +29,9 @@
 #ifndef cpu_has_eva
 #define cpu_has_eva		(cpu_data[0].options & MIPS_CPU_EVA)
 #endif
+#ifndef cpu_has_maar
+#define cpu_has_maar		(cpu_data[0].options & MIPS_CPU_MAAR)
+#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 3b8d993..000bb9e 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -363,6 +363,7 @@ enum cpu_type_enum {
 #define MIPS_CPU_TLBINV		0x02000000ull /* CPU supports TLBINV/F */
 #define MIPS_CPU_SEGMENTS	0x04000000ull /* CPU supports Segmentation Control registers */
 #define MIPS_CPU_EVA		0x80000000ull /* CPU supports Enhanced Virtual Addressing */
+#define MIPS_CPU_MAAR		0x200000000ull /* MAAR(I) registers are present */
 
 /*
  * CPU ASE encodings
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index d74f957..e818547 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -389,6 +389,8 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
 
 	if (config5 & MIPS_CONF5_EVA)
 		c->options |= MIPS_CPU_EVA;
+	if (config5 & MIPS_CONF5_MRP)
+		c->options |= MIPS_CPU_MAAR;
 
 	return config5 & MIPS_CONF_M;
 }
-- 
2.0.1

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

* [PATCH 2/4] MIPS: detect presence of MAARs
  2014-07-14  9:32 ` [PATCH 2/4] MIPS: detect presence of MAARs Paul Burton
@ 2014-07-14  9:32   ` Paul Burton
  0 siblings, 0 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Detect the presence of MAAR using the MRP bit in Config5, and record
that presence using a CPU option bit. A cpu_has_maar macro will then
allow code to conditionalise upon the presence of MAARs.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/include/asm/cpu-features.h | 3 +++
 arch/mips/include/asm/cpu.h          | 1 +
 arch/mips/kernel/cpu-probe.c         | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index c7d8c99..2101618 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -29,6 +29,9 @@
 #ifndef cpu_has_eva
 #define cpu_has_eva		(cpu_data[0].options & MIPS_CPU_EVA)
 #endif
+#ifndef cpu_has_maar
+#define cpu_has_maar		(cpu_data[0].options & MIPS_CPU_MAAR)
+#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 3b8d993..000bb9e 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -363,6 +363,7 @@ enum cpu_type_enum {
 #define MIPS_CPU_TLBINV		0x02000000ull /* CPU supports TLBINV/F */
 #define MIPS_CPU_SEGMENTS	0x04000000ull /* CPU supports Segmentation Control registers */
 #define MIPS_CPU_EVA		0x80000000ull /* CPU supports Enhanced Virtual Addressing */
+#define MIPS_CPU_MAAR		0x200000000ull /* MAAR(I) registers are present */
 
 /*
  * CPU ASE encodings
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index d74f957..e818547 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -389,6 +389,8 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
 
 	if (config5 & MIPS_CONF5_EVA)
 		c->options |= MIPS_CPU_EVA;
+	if (config5 & MIPS_CONF5_MRP)
+		c->options |= MIPS_CPU_MAAR;
 
 	return config5 & MIPS_CONF_M;
 }
-- 
2.0.1

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

* [PATCH 3/4] MIPS: initialise MAARs
  2014-07-14  9:32 [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support Paul Burton
                   ` (2 preceding siblings ...)
  2014-07-14  9:32 ` [PATCH 2/4] MIPS: detect presence of MAARs Paul Burton
@ 2014-07-14  9:32 ` Paul Burton
  2014-07-14  9:32   ` Paul Burton
  2014-07-14  9:32 ` [PATCH 4/4] MIPS: Malta: " Paul Burton
  4 siblings, 1 reply; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Add initialisation for Memory Accessibility Attribute Registers. Generic
code cannot know the platform-specific requirements with regards to
speculative accesses, so it simply calls a platform_maar_init function
which platforms with MAARs are expected to implement by calling the
provided write_maar_pair function & returning the number of MAAR pairs
used. A weak default implementation will simply use no MAAR pairs. Any
present but unused MAAR pairs are then marked invalid, effectively
disabling them.

The end result of this patch is that MAARs are all marked invalid, until
platforms implement the platform_maar_init function.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/include/asm/maar.h | 109 +++++++++++++++++++++++++++++++++++++++++++
 arch/mips/mm/init.c          |  33 +++++++++++++
 2 files changed, 142 insertions(+)
 create mode 100644 arch/mips/include/asm/maar.h

diff --git a/arch/mips/include/asm/maar.h b/arch/mips/include/asm/maar.h
new file mode 100644
index 0000000..6c62b0f
--- /dev/null
+++ b/arch/mips/include/asm/maar.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_MIPS_MAAR_H__
+#define __MIPS_ASM_MIPS_MAAR_H__
+
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+
+/**
+ * platform_maar_init() - perform platform-level MAAR configuration
+ * @num_pairs:	The number of MAAR pairs present in the system.
+ *
+ * Platforms should implement this function such that it configures as many
+ * MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns
+ * the number that were used. Any further MAARs will be configured to be
+ * invalid. The default implementation of this function will simply indicate
+ * that it has configured 0 MAAR pairs.
+ *
+ * Return:	The number of MAAR pairs configured.
+ */
+unsigned __weak platform_maar_init(unsigned num_pairs);
+
+/**
+ * write_maar_pair() - write to a pair of MAARs
+ * @idx:	The index of the pair (ie. use MAARs idx*2 & (idx*2)+1).
+ * @lower:	The lowest address that the MAAR pair will affect. Must be
+ *		aligned to a 2^16 byte boundary.
+ * @upper:	The highest address that the MAAR pair will affect. Must be
+ *		aligned to one byte before a 2^16 byte boundary.
+ * @attrs:	The accessibility attributes to program, eg. MIPS_MAAR_S. The
+ *		MIPS_MAAR_V attribute will automatically be set.
+ *
+ * Program the pair of MAAR registers specified by idx to apply the attributes
+ * specified by attrs to the range of addresses from lower to higher.
+ */
+static inline void write_maar_pair(unsigned idx, phys_addr_t lower,
+				   phys_addr_t upper, unsigned attrs)
+{
+	/* Addresses begin at bit 16, but are shifted right 4 bits */
+	BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4)));
+	BUG_ON(((upper & 0xffff) != 0xffff)
+		|| ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4)));
+
+	/* Automatically set MIPS_MAAR_V */
+	attrs |= MIPS_MAAR_V;
+
+	/* Write the upper address & attributes (only MIPS_MAAR_V matters) */
+	write_c0_maari(idx << 1);
+	back_to_back_c0_hazard();
+	write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs);
+	back_to_back_c0_hazard();
+
+	/* Write the lower address & attributes */
+	write_c0_maari((idx << 1) | 0x1);
+	back_to_back_c0_hazard();
+	write_c0_maar((lower >> 4) | attrs);
+	back_to_back_c0_hazard();
+}
+
+/**
+ * struct maar_config - MAAR configuration data
+ * @lower:	The lowest address that the MAAR pair will affect. Must be
+ *		aligned to a 2^16 byte boundary.
+ * @upper:	The highest address that the MAAR pair will affect. Must be
+ *		aligned to one byte before a 2^16 byte boundary.
+ * @attrs:	The accessibility attributes to program, eg. MIPS_MAAR_S. The
+ *		MIPS_MAAR_V attribute will automatically be set.
+ *
+ * Describes the configuration of a pair of Memory Accessibility Attribute
+ * Registers - applying attributes from attrs to the range of physical
+ * addresses from lower to upper inclusive.
+ */
+struct maar_config {
+	phys_addr_t lower;
+	phys_addr_t upper;
+	unsigned attrs;
+};
+
+/**
+ * maar_config() - configure MAARs according to provided data
+ * @cfg:	Pointer to an array of struct maar_config.
+ * @num_cfg:	The number of structs in the cfg array.
+ * @num_pairs:	The number of MAAR pairs present in the system.
+ *
+ * Configures as many MAARs as are present and specified in the cfg
+ * array with the values taken from the cfg array.
+ *
+ * Return:	The number of MAAR pairs configured.
+ */
+static inline unsigned maar_config(const struct maar_config *cfg,
+				   unsigned num_cfg, unsigned num_pairs)
+{
+	unsigned i;
+
+	for (i = 0; i < min(num_cfg, num_pairs); i++)
+		write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs);
+
+	return i;
+}
+
+#endif /* __MIPS_ASM_MIPS_MAAR_H__ */
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 6e44133..571aab0 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -325,6 +325,38 @@ static inline void mem_init_free_highmem(void)
 #endif
 }
 
+unsigned __weak platform_maar_init(unsigned num_maars)
+{
+	return 0;
+}
+
+static void maar_init(void)
+{
+	unsigned num_maars, used, i;
+
+	if (!cpu_has_maar)
+		return;
+
+	/* Detect the number of MAARs */
+	write_c0_maari(~0);
+	back_to_back_c0_hazard();
+	num_maars = read_c0_maari() + 1;
+
+	/* MAARs should be in pairs */
+	WARN_ON(num_maars % 2);
+
+	/* Configure the required MAARs */
+	used = platform_maar_init(num_maars / 2);
+
+	/* Disable any further MAARs */
+	for (i = (used * 2); i < num_maars; i++) {
+		write_c0_maari(i);
+		back_to_back_c0_hazard();
+		write_c0_maar(0);
+		back_to_back_c0_hazard();
+	}
+}
+
 void __init mem_init(void)
 {
 #ifdef CONFIG_HIGHMEM
@@ -337,6 +369,7 @@ void __init mem_init(void)
 #endif
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
+	maar_init();
 	free_all_bootmem();
 	setup_zero_pages();	/* Setup zeroed pages.  */
 	mem_init_free_highmem();
-- 
2.0.1

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

* [PATCH 3/4] MIPS: initialise MAARs
  2014-07-14  9:32 ` [PATCH 3/4] MIPS: initialise MAARs Paul Burton
@ 2014-07-14  9:32   ` Paul Burton
  0 siblings, 0 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Add initialisation for Memory Accessibility Attribute Registers. Generic
code cannot know the platform-specific requirements with regards to
speculative accesses, so it simply calls a platform_maar_init function
which platforms with MAARs are expected to implement by calling the
provided write_maar_pair function & returning the number of MAAR pairs
used. A weak default implementation will simply use no MAAR pairs. Any
present but unused MAAR pairs are then marked invalid, effectively
disabling them.

The end result of this patch is that MAARs are all marked invalid, until
platforms implement the platform_maar_init function.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/include/asm/maar.h | 109 +++++++++++++++++++++++++++++++++++++++++++
 arch/mips/mm/init.c          |  33 +++++++++++++
 2 files changed, 142 insertions(+)
 create mode 100644 arch/mips/include/asm/maar.h

diff --git a/arch/mips/include/asm/maar.h b/arch/mips/include/asm/maar.h
new file mode 100644
index 0000000..6c62b0f
--- /dev/null
+++ b/arch/mips/include/asm/maar.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_MIPS_MAAR_H__
+#define __MIPS_ASM_MIPS_MAAR_H__
+
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+
+/**
+ * platform_maar_init() - perform platform-level MAAR configuration
+ * @num_pairs:	The number of MAAR pairs present in the system.
+ *
+ * Platforms should implement this function such that it configures as many
+ * MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns
+ * the number that were used. Any further MAARs will be configured to be
+ * invalid. The default implementation of this function will simply indicate
+ * that it has configured 0 MAAR pairs.
+ *
+ * Return:	The number of MAAR pairs configured.
+ */
+unsigned __weak platform_maar_init(unsigned num_pairs);
+
+/**
+ * write_maar_pair() - write to a pair of MAARs
+ * @idx:	The index of the pair (ie. use MAARs idx*2 & (idx*2)+1).
+ * @lower:	The lowest address that the MAAR pair will affect. Must be
+ *		aligned to a 2^16 byte boundary.
+ * @upper:	The highest address that the MAAR pair will affect. Must be
+ *		aligned to one byte before a 2^16 byte boundary.
+ * @attrs:	The accessibility attributes to program, eg. MIPS_MAAR_S. The
+ *		MIPS_MAAR_V attribute will automatically be set.
+ *
+ * Program the pair of MAAR registers specified by idx to apply the attributes
+ * specified by attrs to the range of addresses from lower to higher.
+ */
+static inline void write_maar_pair(unsigned idx, phys_addr_t lower,
+				   phys_addr_t upper, unsigned attrs)
+{
+	/* Addresses begin at bit 16, but are shifted right 4 bits */
+	BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4)));
+	BUG_ON(((upper & 0xffff) != 0xffff)
+		|| ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4)));
+
+	/* Automatically set MIPS_MAAR_V */
+	attrs |= MIPS_MAAR_V;
+
+	/* Write the upper address & attributes (only MIPS_MAAR_V matters) */
+	write_c0_maari(idx << 1);
+	back_to_back_c0_hazard();
+	write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs);
+	back_to_back_c0_hazard();
+
+	/* Write the lower address & attributes */
+	write_c0_maari((idx << 1) | 0x1);
+	back_to_back_c0_hazard();
+	write_c0_maar((lower >> 4) | attrs);
+	back_to_back_c0_hazard();
+}
+
+/**
+ * struct maar_config - MAAR configuration data
+ * @lower:	The lowest address that the MAAR pair will affect. Must be
+ *		aligned to a 2^16 byte boundary.
+ * @upper:	The highest address that the MAAR pair will affect. Must be
+ *		aligned to one byte before a 2^16 byte boundary.
+ * @attrs:	The accessibility attributes to program, eg. MIPS_MAAR_S. The
+ *		MIPS_MAAR_V attribute will automatically be set.
+ *
+ * Describes the configuration of a pair of Memory Accessibility Attribute
+ * Registers - applying attributes from attrs to the range of physical
+ * addresses from lower to upper inclusive.
+ */
+struct maar_config {
+	phys_addr_t lower;
+	phys_addr_t upper;
+	unsigned attrs;
+};
+
+/**
+ * maar_config() - configure MAARs according to provided data
+ * @cfg:	Pointer to an array of struct maar_config.
+ * @num_cfg:	The number of structs in the cfg array.
+ * @num_pairs:	The number of MAAR pairs present in the system.
+ *
+ * Configures as many MAARs as are present and specified in the cfg
+ * array with the values taken from the cfg array.
+ *
+ * Return:	The number of MAAR pairs configured.
+ */
+static inline unsigned maar_config(const struct maar_config *cfg,
+				   unsigned num_cfg, unsigned num_pairs)
+{
+	unsigned i;
+
+	for (i = 0; i < min(num_cfg, num_pairs); i++)
+		write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs);
+
+	return i;
+}
+
+#endif /* __MIPS_ASM_MIPS_MAAR_H__ */
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 6e44133..571aab0 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -325,6 +325,38 @@ static inline void mem_init_free_highmem(void)
 #endif
 }
 
+unsigned __weak platform_maar_init(unsigned num_maars)
+{
+	return 0;
+}
+
+static void maar_init(void)
+{
+	unsigned num_maars, used, i;
+
+	if (!cpu_has_maar)
+		return;
+
+	/* Detect the number of MAARs */
+	write_c0_maari(~0);
+	back_to_back_c0_hazard();
+	num_maars = read_c0_maari() + 1;
+
+	/* MAARs should be in pairs */
+	WARN_ON(num_maars % 2);
+
+	/* Configure the required MAARs */
+	used = platform_maar_init(num_maars / 2);
+
+	/* Disable any further MAARs */
+	for (i = (used * 2); i < num_maars; i++) {
+		write_c0_maari(i);
+		back_to_back_c0_hazard();
+		write_c0_maar(0);
+		back_to_back_c0_hazard();
+	}
+}
+
 void __init mem_init(void)
 {
 #ifdef CONFIG_HIGHMEM
@@ -337,6 +369,7 @@ void __init mem_init(void)
 #endif
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
+	maar_init();
 	free_all_bootmem();
 	setup_zero_pages();	/* Setup zeroed pages.  */
 	mem_init_free_highmem();
-- 
2.0.1

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

* [PATCH 4/4] MIPS: Malta: initialise MAARs
  2014-07-14  9:32 [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support Paul Burton
                   ` (3 preceding siblings ...)
  2014-07-14  9:32 ` [PATCH 3/4] MIPS: initialise MAARs Paul Burton
@ 2014-07-14  9:32 ` Paul Burton
  2014-07-14  9:32   ` Paul Burton
  2014-07-14 11:33   ` Sergei Shtylyov
  4 siblings, 2 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Initialise the MAARs such that speculation is enabled for all physical
addresses outside of the I/O region.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/mti-malta/malta-memory.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index 6d97730..e96803d 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
+#include <asm/maar.h>
 #include <asm/sections.h>
 #include <asm/fw/fw.h>
 
@@ -164,3 +165,28 @@ void __init prom_free_prom_memory(void)
 				addr, addr + boot_mem_map.map[i].size);
 	}
 }
+
+unsigned platform_maar_init(unsigned num_pairs)
+{
+	phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1;
+	struct maar_config cfg[] = {
+		/* DRAM preceeding I/O */
+		{ 0x00000000, 0x0fffffff, MIPS_MAAR_S },
+
+		/* DRAM following I/O */
+		{ 0x20000000, mem_end, MIPS_MAAR_S },
+
+		/* DRAM alias in upper half of physical */
+		{ 0x80000000, 0x80000000 + mem_end, MIPS_MAAR_S },
+	};
+	unsigned i, num_cfg = ARRAY_SIZE(cfg);
+
+	/* If DRAM fits before I/O, drop the region following it */
+	if (physical_memsize <= 0x10000000) {
+		num_cfg--;
+		for (i = 1; i < num_cfg; i++)
+			cfg[i] = cfg[i + 1];
+	}
+
+	return maar_config(cfg, num_cfg, num_pairs);
+}
-- 
2.0.1

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

* [PATCH 4/4] MIPS: Malta: initialise MAARs
  2014-07-14  9:32 ` [PATCH 4/4] MIPS: Malta: " Paul Burton
@ 2014-07-14  9:32   ` Paul Burton
  2014-07-14 11:33   ` Sergei Shtylyov
  1 sibling, 0 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14  9:32 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Initialise the MAARs such that speculation is enabled for all physical
addresses outside of the I/O region.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/mti-malta/malta-memory.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index 6d97730..e96803d 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
+#include <asm/maar.h>
 #include <asm/sections.h>
 #include <asm/fw/fw.h>
 
@@ -164,3 +165,28 @@ void __init prom_free_prom_memory(void)
 				addr, addr + boot_mem_map.map[i].size);
 	}
 }
+
+unsigned platform_maar_init(unsigned num_pairs)
+{
+	phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1;
+	struct maar_config cfg[] = {
+		/* DRAM preceeding I/O */
+		{ 0x00000000, 0x0fffffff, MIPS_MAAR_S },
+
+		/* DRAM following I/O */
+		{ 0x20000000, mem_end, MIPS_MAAR_S },
+
+		/* DRAM alias in upper half of physical */
+		{ 0x80000000, 0x80000000 + mem_end, MIPS_MAAR_S },
+	};
+	unsigned i, num_cfg = ARRAY_SIZE(cfg);
+
+	/* If DRAM fits before I/O, drop the region following it */
+	if (physical_memsize <= 0x10000000) {
+		num_cfg--;
+		for (i = 1; i < num_cfg; i++)
+			cfg[i] = cfg[i + 1];
+	}
+
+	return maar_config(cfg, num_cfg, num_pairs);
+}
-- 
2.0.1

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

* Re: [PATCH 4/4] MIPS: Malta: initialise MAARs
  2014-07-14  9:32 ` [PATCH 4/4] MIPS: Malta: " Paul Burton
  2014-07-14  9:32   ` Paul Burton
@ 2014-07-14 11:33   ` Sergei Shtylyov
  2014-07-14 11:37     ` [PATCH v2 " Paul Burton
  1 sibling, 1 reply; 13+ messages in thread
From: Sergei Shtylyov @ 2014-07-14 11:33 UTC (permalink / raw)
  To: Paul Burton, linux-mips

Hello.

On 07/14/2014 01:32 PM, Paul Burton wrote:

> Initialise the MAARs such that speculation is enabled for all physical
> addresses outside of the I/O region.

> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> ---
>   arch/mips/mti-malta/malta-memory.c | 26 ++++++++++++++++++++++++++
>   1 file changed, 26 insertions(+)

> diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
> index 6d97730..e96803d 100644
> --- a/arch/mips/mti-malta/malta-memory.c
> +++ b/arch/mips/mti-malta/malta-memory.c
[...]
> @@ -164,3 +165,28 @@ void __init prom_free_prom_memory(void)
>   				addr, addr + boot_mem_map.map[i].size);
>   	}
>   }
> +
> +unsigned platform_maar_init(unsigned num_pairs)
> +{
> +	phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1;
> +	struct maar_config cfg[] = {
> +		/* DRAM preceeding I/O */

    Perhaps "preceding"?

WBR, Sergei

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

* [PATCH v2 4/4] MIPS: Malta: initialise MAARs
  2014-07-14 11:33   ` Sergei Shtylyov
@ 2014-07-14 11:37     ` Paul Burton
  2014-07-14 11:37       ` Paul Burton
  0 siblings, 1 reply; 13+ messages in thread
From: Paul Burton @ 2014-07-14 11:37 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Initialise the MAARs such that speculation is enabled for all physical
addresses outside of the I/O region.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
Changes in v2:
  - s/preceeding/preceding/
---
 arch/mips/mti-malta/malta-memory.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index 6d97730..0c35dee0 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
+#include <asm/maar.h>
 #include <asm/sections.h>
 #include <asm/fw/fw.h>
 
@@ -164,3 +165,28 @@ void __init prom_free_prom_memory(void)
 				addr, addr + boot_mem_map.map[i].size);
 	}
 }
+
+unsigned platform_maar_init(unsigned num_pairs)
+{
+	phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1;
+	struct maar_config cfg[] = {
+		/* DRAM preceding I/O */
+		{ 0x00000000, 0x0fffffff, MIPS_MAAR_S },
+
+		/* DRAM following I/O */
+		{ 0x20000000, mem_end, MIPS_MAAR_S },
+
+		/* DRAM alias in upper half of physical */
+		{ 0x80000000, 0x80000000 + mem_end, MIPS_MAAR_S },
+	};
+	unsigned i, num_cfg = ARRAY_SIZE(cfg);
+
+	/* If DRAM fits before I/O, drop the region following it */
+	if (physical_memsize <= 0x10000000) {
+		num_cfg--;
+		for (i = 1; i < num_cfg; i++)
+			cfg[i] = cfg[i + 1];
+	}
+
+	return maar_config(cfg, num_cfg, num_pairs);
+}
-- 
2.0.1

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

* [PATCH v2 4/4] MIPS: Malta: initialise MAARs
  2014-07-14 11:37     ` [PATCH v2 " Paul Burton
@ 2014-07-14 11:37       ` Paul Burton
  0 siblings, 0 replies; 13+ messages in thread
From: Paul Burton @ 2014-07-14 11:37 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton

Initialise the MAARs such that speculation is enabled for all physical
addresses outside of the I/O region.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
Changes in v2:
  - s/preceeding/preceding/
---
 arch/mips/mti-malta/malta-memory.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index 6d97730..0c35dee0 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
+#include <asm/maar.h>
 #include <asm/sections.h>
 #include <asm/fw/fw.h>
 
@@ -164,3 +165,28 @@ void __init prom_free_prom_memory(void)
 				addr, addr + boot_mem_map.map[i].size);
 	}
 }
+
+unsigned platform_maar_init(unsigned num_pairs)
+{
+	phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1;
+	struct maar_config cfg[] = {
+		/* DRAM preceding I/O */
+		{ 0x00000000, 0x0fffffff, MIPS_MAAR_S },
+
+		/* DRAM following I/O */
+		{ 0x20000000, mem_end, MIPS_MAAR_S },
+
+		/* DRAM alias in upper half of physical */
+		{ 0x80000000, 0x80000000 + mem_end, MIPS_MAAR_S },
+	};
+	unsigned i, num_cfg = ARRAY_SIZE(cfg);
+
+	/* If DRAM fits before I/O, drop the region following it */
+	if (physical_memsize <= 0x10000000) {
+		num_cfg--;
+		for (i = 1; i < num_cfg; i++)
+			cfg[i] = cfg[i + 1];
+	}
+
+	return maar_config(cfg, num_cfg, num_pairs);
+}
-- 
2.0.1

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

end of thread, other threads:[~2014-07-14 11:38 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-14  9:32 [PATCH 0/4] Memory Accessibility Attribute Register (MAAR) support Paul Burton
2014-07-14  9:32 ` Paul Burton
2014-07-14  9:32 ` [PATCH 1/4] MIPS: define MAAR register accessors & bits Paul Burton
2014-07-14  9:32   ` Paul Burton
2014-07-14  9:32 ` [PATCH 2/4] MIPS: detect presence of MAARs Paul Burton
2014-07-14  9:32   ` Paul Burton
2014-07-14  9:32 ` [PATCH 3/4] MIPS: initialise MAARs Paul Burton
2014-07-14  9:32   ` Paul Burton
2014-07-14  9:32 ` [PATCH 4/4] MIPS: Malta: " Paul Burton
2014-07-14  9:32   ` Paul Burton
2014-07-14 11:33   ` Sergei Shtylyov
2014-07-14 11:37     ` [PATCH v2 " Paul Burton
2014-07-14 11:37       ` Paul Burton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox