diff options
author | Justin Chen <justin.chen@broadcom.com> | 2016-12-07 20:16:26 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2017-01-03 10:34:46 -0500 |
commit | ef462f3b64e9fb0c8e1cd5d60f5bd7f13ac2156d (patch) | |
tree | 173a0ccbec594be974a620d2bf23c90d506beaaa | |
parent | 0014dea6b71ae3e0384c3358f632b4728c3d432e (diff) |
MIPS: Add cacheinfo support
Add cacheinfo support for MIPS architectures.
Use information from the cpuinfo_mips struct to populate the
cacheinfo struct. This allows an architecture agnostic approach,
however this also means if cache information is not properly
populated within the cpuinfo_mips struct, there is nothing
we can do. (I.E. c-r3k.c)
Signed-off-by: Justin Chen <justin.chen@broadcom.com>
Cc: f.fainelli@gmail.com
Cc: linux-mips@linux-mips.org
Cc: bcm-kernel-feedback-list@broadcom.com
Patchwork: https://patchwork.linux-mips.org/patch/14650/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/kernel/cacheinfo.c | 85 |
2 files changed, 86 insertions, 1 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 4a603a3ea657..904a9c48553a 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds | |||
7 | obj-y += cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \ | 7 | obj-y += cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \ |
8 | process.o prom.o ptrace.o reset.o setup.o signal.o \ | 8 | process.o prom.o ptrace.o reset.o setup.o signal.o \ |
9 | syscall.o time.o topology.o traps.o unaligned.o watch.o \ | 9 | syscall.o time.o topology.o traps.o unaligned.o watch.o \ |
10 | vdso.o | 10 | vdso.o cacheinfo.o |
11 | 11 | ||
12 | ifdef CONFIG_FUNCTION_TRACER | 12 | ifdef CONFIG_FUNCTION_TRACER |
13 | CFLAGS_REMOVE_ftrace.o = -pg | 13 | CFLAGS_REMOVE_ftrace.o = -pg |
diff --git a/arch/mips/kernel/cacheinfo.c b/arch/mips/kernel/cacheinfo.c new file mode 100644 index 000000000000..a92bbbae969b --- /dev/null +++ b/arch/mips/kernel/cacheinfo.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * MIPS cacheinfo support | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | #include <linux/cacheinfo.h> | ||
17 | |||
18 | /* Populates leaf and increments to next leaf */ | ||
19 | #define populate_cache(cache, leaf, c_level, c_type) \ | ||
20 | leaf->type = c_type; \ | ||
21 | leaf->level = c_level; \ | ||
22 | leaf->coherency_line_size = c->cache.linesz; \ | ||
23 | leaf->number_of_sets = c->cache.sets; \ | ||
24 | leaf->ways_of_associativity = c->cache.ways; \ | ||
25 | leaf->size = c->cache.linesz * c->cache.sets * \ | ||
26 | c->cache.ways; \ | ||
27 | leaf++; | ||
28 | |||
29 | static int __init_cache_level(unsigned int cpu) | ||
30 | { | ||
31 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
32 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
33 | int levels = 0, leaves = 0; | ||
34 | |||
35 | /* | ||
36 | * If Dcache is not set, we assume the cache structures | ||
37 | * are not properly initialized. | ||
38 | */ | ||
39 | if (c->dcache.waysize) | ||
40 | levels += 1; | ||
41 | else | ||
42 | return -ENOENT; | ||
43 | |||
44 | |||
45 | leaves += (c->icache.waysize) ? 2 : 1; | ||
46 | |||
47 | if (c->scache.waysize) { | ||
48 | levels++; | ||
49 | leaves++; | ||
50 | } | ||
51 | |||
52 | if (c->tcache.waysize) { | ||
53 | levels++; | ||
54 | leaves++; | ||
55 | } | ||
56 | |||
57 | this_cpu_ci->num_levels = levels; | ||
58 | this_cpu_ci->num_leaves = leaves; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int __populate_cache_leaves(unsigned int cpu) | ||
63 | { | ||
64 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
65 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
66 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; | ||
67 | |||
68 | if (c->icache.waysize) { | ||
69 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_DATA); | ||
70 | populate_cache(icache, this_leaf, 1, CACHE_TYPE_INST); | ||
71 | } else { | ||
72 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_UNIFIED); | ||
73 | } | ||
74 | |||
75 | if (c->scache.waysize) | ||
76 | populate_cache(scache, this_leaf, 2, CACHE_TYPE_UNIFIED); | ||
77 | |||
78 | if (c->tcache.waysize) | ||
79 | populate_cache(tcache, this_leaf, 3, CACHE_TYPE_UNIFIED); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) | ||
85 | DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) | ||