aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2014-07-14 05:32:15 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-08-01 18:06:46 -0400
commitab9988a3dafb8c94c2a19637fb00f7d1db799347 (patch)
tree6c564bb08c92d79fcad07b8add4c555842ba3246
parent1f6c52ff7225789d20c1d69883f263d502b7eda7 (diff)
MIPS: Initialise MAARs
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> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7331/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/include/asm/maar.h109
-rw-r--r--arch/mips/mm/init.c33
2 files changed, 142 insertions, 0 deletions
diff --git a/arch/mips/include/asm/maar.h b/arch/mips/include/asm/maar.h
new file mode 100644
index 000000000000..6c62b0f899c0
--- /dev/null
+++ b/arch/mips/include/asm/maar.h
@@ -0,0 +1,109 @@
1/*
2 * Copyright (C) 2014 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __MIPS_ASM_MIPS_MAAR_H__
12#define __MIPS_ASM_MIPS_MAAR_H__
13
14#include <asm/hazards.h>
15#include <asm/mipsregs.h>
16
17/**
18 * platform_maar_init() - perform platform-level MAAR configuration
19 * @num_pairs: The number of MAAR pairs present in the system.
20 *
21 * Platforms should implement this function such that it configures as many
22 * MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns
23 * the number that were used. Any further MAARs will be configured to be
24 * invalid. The default implementation of this function will simply indicate
25 * that it has configured 0 MAAR pairs.
26 *
27 * Return: The number of MAAR pairs configured.
28 */
29unsigned __weak platform_maar_init(unsigned num_pairs);
30
31/**
32 * write_maar_pair() - write to a pair of MAARs
33 * @idx: The index of the pair (ie. use MAARs idx*2 & (idx*2)+1).
34 * @lower: The lowest address that the MAAR pair will affect. Must be
35 * aligned to a 2^16 byte boundary.
36 * @upper: The highest address that the MAAR pair will affect. Must be
37 * aligned to one byte before a 2^16 byte boundary.
38 * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The
39 * MIPS_MAAR_V attribute will automatically be set.
40 *
41 * Program the pair of MAAR registers specified by idx to apply the attributes
42 * specified by attrs to the range of addresses from lower to higher.
43 */
44static inline void write_maar_pair(unsigned idx, phys_addr_t lower,
45 phys_addr_t upper, unsigned attrs)
46{
47 /* Addresses begin at bit 16, but are shifted right 4 bits */
48 BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4)));
49 BUG_ON(((upper & 0xffff) != 0xffff)
50 || ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4)));
51
52 /* Automatically set MIPS_MAAR_V */
53 attrs |= MIPS_MAAR_V;
54
55 /* Write the upper address & attributes (only MIPS_MAAR_V matters) */
56 write_c0_maari(idx << 1);
57 back_to_back_c0_hazard();
58 write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs);
59 back_to_back_c0_hazard();
60
61 /* Write the lower address & attributes */
62 write_c0_maari((idx << 1) | 0x1);
63 back_to_back_c0_hazard();
64 write_c0_maar((lower >> 4) | attrs);
65 back_to_back_c0_hazard();
66}
67
68/**
69 * struct maar_config - MAAR configuration data
70 * @lower: The lowest address that the MAAR pair will affect. Must be
71 * aligned to a 2^16 byte boundary.
72 * @upper: The highest address that the MAAR pair will affect. Must be
73 * aligned to one byte before a 2^16 byte boundary.
74 * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The
75 * MIPS_MAAR_V attribute will automatically be set.
76 *
77 * Describes the configuration of a pair of Memory Accessibility Attribute
78 * Registers - applying attributes from attrs to the range of physical
79 * addresses from lower to upper inclusive.
80 */
81struct maar_config {
82 phys_addr_t lower;
83 phys_addr_t upper;
84 unsigned attrs;
85};
86
87/**
88 * maar_config() - configure MAARs according to provided data
89 * @cfg: Pointer to an array of struct maar_config.
90 * @num_cfg: The number of structs in the cfg array.
91 * @num_pairs: The number of MAAR pairs present in the system.
92 *
93 * Configures as many MAARs as are present and specified in the cfg
94 * array with the values taken from the cfg array.
95 *
96 * Return: The number of MAAR pairs configured.
97 */
98static inline unsigned maar_config(const struct maar_config *cfg,
99 unsigned num_cfg, unsigned num_pairs)
100{
101 unsigned i;
102
103 for (i = 0; i < min(num_cfg, num_pairs); i++)
104 write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs);
105
106 return i;
107}
108
109#endif /* __MIPS_ASM_MIPS_MAAR_H__ */
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 6e4413330e36..571aab064936 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)
325#endif 325#endif
326} 326}
327 327
328unsigned __weak platform_maar_init(unsigned num_maars)
329{
330 return 0;
331}
332
333static void maar_init(void)
334{
335 unsigned num_maars, used, i;
336
337 if (!cpu_has_maar)
338 return;
339
340 /* Detect the number of MAARs */
341 write_c0_maari(~0);
342 back_to_back_c0_hazard();
343 num_maars = read_c0_maari() + 1;
344
345 /* MAARs should be in pairs */
346 WARN_ON(num_maars % 2);
347
348 /* Configure the required MAARs */
349 used = platform_maar_init(num_maars / 2);
350
351 /* Disable any further MAARs */
352 for (i = (used * 2); i < num_maars; i++) {
353 write_c0_maari(i);
354 back_to_back_c0_hazard();
355 write_c0_maar(0);
356 back_to_back_c0_hazard();
357 }
358}
359
328void __init mem_init(void) 360void __init mem_init(void)
329{ 361{
330#ifdef CONFIG_HIGHMEM 362#ifdef CONFIG_HIGHMEM
@@ -337,6 +369,7 @@ void __init mem_init(void)
337#endif 369#endif
338 high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); 370 high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
339 371
372 maar_init();
340 free_all_bootmem(); 373 free_all_bootmem();
341 setup_zero_pages(); /* Setup zeroed pages. */ 374 setup_zero_pages(); /* Setup zeroed pages. */
342 mem_init_free_highmem(); 375 mem_init_free_highmem();