Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/openrisc/kernel/cacheinfo.c
26439 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* OpenRISC cacheinfo support
4
*
5
* Based on work done for MIPS and LoongArch. All original copyrights
6
* apply as per the original source declaration.
7
*
8
* OpenRISC implementation:
9
* Copyright (C) 2025 Sahil Siddiq <[email protected]>
10
*/
11
12
#include <linux/cacheinfo.h>
13
#include <asm/cpuinfo.h>
14
#include <asm/spr.h>
15
#include <asm/spr_defs.h>
16
17
static inline void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
18
unsigned int level, struct cache_desc *cache, int cpu)
19
{
20
this_leaf->type = type;
21
this_leaf->level = level;
22
this_leaf->coherency_line_size = cache->block_size;
23
this_leaf->number_of_sets = cache->sets;
24
this_leaf->ways_of_associativity = cache->ways;
25
this_leaf->size = cache->size;
26
cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map);
27
}
28
29
int init_cache_level(unsigned int cpu)
30
{
31
struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
32
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
33
int leaves = 0, levels = 0;
34
unsigned long upr = mfspr(SPR_UPR);
35
unsigned long iccfgr, dccfgr;
36
37
if (!(upr & SPR_UPR_UP)) {
38
printk(KERN_INFO
39
"-- no UPR register... unable to detect configuration\n");
40
return -ENOENT;
41
}
42
43
if (cpu_cache_is_present(SPR_UPR_DCP)) {
44
dccfgr = mfspr(SPR_DCCFGR);
45
cpuinfo->dcache.ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
46
cpuinfo->dcache.sets = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
47
cpuinfo->dcache.block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >> 7);
48
cpuinfo->dcache.size =
49
cpuinfo->dcache.sets * cpuinfo->dcache.ways * cpuinfo->dcache.block_size;
50
leaves += 1;
51
printk(KERN_INFO
52
"-- dcache: %d bytes total, %d bytes/line, %d set(s), %d way(s)\n",
53
cpuinfo->dcache.size, cpuinfo->dcache.block_size,
54
cpuinfo->dcache.sets, cpuinfo->dcache.ways);
55
} else
56
printk(KERN_INFO "-- dcache disabled\n");
57
58
if (cpu_cache_is_present(SPR_UPR_ICP)) {
59
iccfgr = mfspr(SPR_ICCFGR);
60
cpuinfo->icache.ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
61
cpuinfo->icache.sets = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
62
cpuinfo->icache.block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7);
63
cpuinfo->icache.size =
64
cpuinfo->icache.sets * cpuinfo->icache.ways * cpuinfo->icache.block_size;
65
leaves += 1;
66
printk(KERN_INFO
67
"-- icache: %d bytes total, %d bytes/line, %d set(s), %d way(s)\n",
68
cpuinfo->icache.size, cpuinfo->icache.block_size,
69
cpuinfo->icache.sets, cpuinfo->icache.ways);
70
} else
71
printk(KERN_INFO "-- icache disabled\n");
72
73
if (!leaves)
74
return -ENOENT;
75
76
levels = 1;
77
78
this_cpu_ci->num_leaves = leaves;
79
this_cpu_ci->num_levels = levels;
80
81
return 0;
82
}
83
84
int populate_cache_leaves(unsigned int cpu)
85
{
86
struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
87
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
88
struct cacheinfo *this_leaf = this_cpu_ci->info_list;
89
int level = 1;
90
91
if (cpu_cache_is_present(SPR_UPR_DCP)) {
92
ci_leaf_init(this_leaf, CACHE_TYPE_DATA, level, &cpuinfo->dcache, cpu);
93
this_leaf->attributes = ((mfspr(SPR_DCCFGR) & SPR_DCCFGR_CWS) >> 8) ?
94
CACHE_WRITE_BACK : CACHE_WRITE_THROUGH;
95
this_leaf++;
96
}
97
98
if (cpu_cache_is_present(SPR_UPR_ICP))
99
ci_leaf_init(this_leaf, CACHE_TYPE_INST, level, &cpuinfo->icache, cpu);
100
101
this_cpu_ci->cpu_map_populated = true;
102
103
return 0;
104
}
105
106