diff options
author | Greentime Hu <greentime@andestech.com> | 2017-10-24 03:40:25 -0400 |
---|---|---|
committer | Greentime Hu <greentime@andestech.com> | 2018-02-21 21:44:32 -0500 |
commit | 7de9cf474083bfbba469f72dc208f7b51747632d (patch) | |
tree | 45e8f3f41c736e8a6abc0995aaf5ab8d86bea917 /arch/nds32/kernel | |
parent | 664eec400bf8f3ab4d41279d6fb674a66ff3ba94 (diff) |
nds32: Cache and TLB routines
This patch contains cache and TLB maintenance functions.
Signed-off-by: Vincent Chen <vincentc@andestech.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/nds32/kernel')
-rw-r--r-- | arch/nds32/kernel/cacheinfo.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/nds32/kernel/cacheinfo.c b/arch/nds32/kernel/cacheinfo.c new file mode 100644 index 000000000000..0a7bc696dd55 --- /dev/null +++ b/arch/nds32/kernel/cacheinfo.c | |||
@@ -0,0 +1,49 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (C) 2005-2017 Andes Technology Corporation | ||
3 | |||
4 | #include <linux/bitops.h> | ||
5 | #include <linux/cacheinfo.h> | ||
6 | #include <linux/cpu.h> | ||
7 | |||
8 | static void ci_leaf_init(struct cacheinfo *this_leaf, | ||
9 | enum cache_type type, unsigned int level) | ||
10 | { | ||
11 | char cache_type = (type & CACHE_TYPE_INST ? ICACHE : DCACHE); | ||
12 | |||
13 | this_leaf->level = level; | ||
14 | this_leaf->type = type; | ||
15 | this_leaf->coherency_line_size = CACHE_LINE_SIZE(cache_type); | ||
16 | this_leaf->number_of_sets = CACHE_SET(cache_type);; | ||
17 | this_leaf->ways_of_associativity = CACHE_WAY(cache_type); | ||
18 | this_leaf->size = this_leaf->number_of_sets * | ||
19 | this_leaf->coherency_line_size * this_leaf->ways_of_associativity; | ||
20 | #if defined(CONFIG_CPU_DCACHE_WRITETHROUGH) | ||
21 | this_leaf->attributes = CACHE_WRITE_THROUGH; | ||
22 | #else | ||
23 | this_leaf->attributes = CACHE_WRITE_BACK; | ||
24 | #endif | ||
25 | } | ||
26 | |||
27 | int init_cache_level(unsigned int cpu) | ||
28 | { | ||
29 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
30 | |||
31 | /* Only 1 level and I/D cache seperate. */ | ||
32 | this_cpu_ci->num_levels = 1; | ||
33 | this_cpu_ci->num_leaves = 2; | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | int populate_cache_leaves(unsigned int cpu) | ||
38 | { | ||
39 | unsigned int level, idx; | ||
40 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
41 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; | ||
42 | |||
43 | for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && | ||
44 | idx < this_cpu_ci->num_leaves; idx++, level++) { | ||
45 | ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); | ||
46 | ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); | ||
47 | } | ||
48 | return 0; | ||
49 | } | ||