mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 07:31:29 +00:00
89d77f71f4
* Support for runtime detection of the Svnapot extension. * Support for Zicboz when clearing pages. * We've moved to GENERIC_ENTRY. * Support for !MMU on rv32 systems. * The linear region is now mapped via huge pages. * Support for building relocatable kernels. * Support for the hwprobe interface. * Various fixes and cleanups throughout the tree. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmRL5rcTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYibpcD/0RnmO+N2OJxsJXf0KtHv4LlChAFaMZ mfcsU8lv8r3Rz1USJGyVoE57885R+iUw1664ic6Gj9Ll9/A+BDVyqlNeo1BZ7nnv 6hZawSh8XGMyCJoatjaCSMW6VKObsSpHXLoA0mxtj06w1XhtpUnzjv4SZQqBYxC2 7+/cfy6l3uGdSKQ0R402sF8PE+l3HthhO+Cw9NYHQZisAHEQrfFpXRnrovhs+vX0 aVxoWo8bmIhhNke2jh6dnGhfFfAs+UClbaKgZfe8af6feboo+Tal3+OibiEy1K1j hDQ3w/G5jAdwSqnNPdXzpk4srskUOhP9is8AG79vCasMxybQIBfZcc7/kLmmQX+2 xt1EoDVD/lSO1p+CWRautLXEsInWbpBYaSJie7WcR4SHe8S7/nomTDlwkJHx5cma mkSYHJKNwCbamDTI3gXg8nrScbxsRnJQsQUolFDwAeRz7AYVwtqVh8VxAWqAdU3q xUNKrUpCAzNC3d5GL7pmRfZrqjpQhuFXkHFSy85vaCPuckBu926OzxpKBmX4Kea1 qLYWfxv78bcwuY47FWJKcd97Ib63iBYDgarJxvrHrwDaHV2xjBOmdapNPUc2PswT a938enbYYnJHIbuSmbeNBPF4iF6nKUXshyfZu7tCZl6MzsXloUckGdm++j97Bpvr g6G3ZP6STSQBmw== =oxQd -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-6.4-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V updates from Palmer Dabbelt: - Support for runtime detection of the Svnapot extension - Support for Zicboz when clearing pages - We've moved to GENERIC_ENTRY - Support for !MMU on rv32 systems - The linear region is now mapped via huge pages - Support for building relocatable kernels - Support for the hwprobe interface - Various fixes and cleanups throughout the tree * tag 'riscv-for-linus-6.4-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (57 commits) RISC-V: hwprobe: Explicity check for -1 in vdso init RISC-V: hwprobe: There can only be one first riscv: Allow to downgrade paging mode from the command line dt-bindings: riscv: add sv57 mmu-type RISC-V: hwprobe: Remove __init on probe_vendor_features() riscv: Use --emit-relocs in order to move .rela.dyn in init riscv: Check relocations at compile time powerpc: Move script to check relocations at compile time in scripts/ riscv: Introduce CONFIG_RELOCATABLE riscv: Move .rela.dyn outside of init to avoid empty relocations riscv: Prepare EFI header for relocatable kernels riscv: Unconditionnally select KASAN_VMALLOC if KASAN riscv: Fix ptdump when KASAN is enabled riscv: Fix EFI stub usage of KASAN instrumented strcmp function riscv: Move DTB_EARLY_BASE_VA to the kernel address space riscv: Rework kasan population functions riscv: Split early and final KASAN population functions riscv: Use PUD/P4D/PGD pages for the linear mapping riscv: Move the linear mapping creation in its own function riscv: Get rid of riscv_pfn_base variable ...
111 lines
3.1 KiB
C
111 lines
3.1 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) 2017 SiFive
|
|
*/
|
|
|
|
#include <linux/cpu.h>
|
|
#include <linux/of.h>
|
|
#include <asm/cacheinfo.h>
|
|
|
|
static struct riscv_cacheinfo_ops *rv_cache_ops;
|
|
|
|
void riscv_set_cacheinfo_ops(struct riscv_cacheinfo_ops *ops)
|
|
{
|
|
rv_cache_ops = ops;
|
|
}
|
|
EXPORT_SYMBOL_GPL(riscv_set_cacheinfo_ops);
|
|
|
|
const struct attribute_group *
|
|
cache_get_priv_group(struct cacheinfo *this_leaf)
|
|
{
|
|
if (rv_cache_ops && rv_cache_ops->get_priv_group)
|
|
return rv_cache_ops->get_priv_group(this_leaf);
|
|
return NULL;
|
|
}
|
|
|
|
static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type)
|
|
{
|
|
/*
|
|
* Using raw_smp_processor_id() elides a preemptability check, but this
|
|
* is really indicative of a larger problem: the cacheinfo UABI assumes
|
|
* that cores have a homonogenous view of the cache hierarchy. That
|
|
* happens to be the case for the current set of RISC-V systems, but
|
|
* likely won't be true in general. Since there's no way to provide
|
|
* correct information for these systems via the current UABI we're
|
|
* just eliding the check for now.
|
|
*/
|
|
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(raw_smp_processor_id());
|
|
struct cacheinfo *this_leaf;
|
|
int index;
|
|
|
|
for (index = 0; index < this_cpu_ci->num_leaves; index++) {
|
|
this_leaf = this_cpu_ci->info_list + index;
|
|
if (this_leaf->level == level && this_leaf->type == type)
|
|
return this_leaf;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uintptr_t get_cache_size(u32 level, enum cache_type type)
|
|
{
|
|
struct cacheinfo *this_leaf = get_cacheinfo(level, type);
|
|
|
|
return this_leaf ? this_leaf->size : 0;
|
|
}
|
|
|
|
uintptr_t get_cache_geometry(u32 level, enum cache_type type)
|
|
{
|
|
struct cacheinfo *this_leaf = get_cacheinfo(level, type);
|
|
|
|
return this_leaf ? (this_leaf->ways_of_associativity << 16 |
|
|
this_leaf->coherency_line_size) :
|
|
0;
|
|
}
|
|
|
|
static void ci_leaf_init(struct cacheinfo *this_leaf,
|
|
struct device_node *node,
|
|
enum cache_type type, unsigned int level)
|
|
{
|
|
this_leaf->level = level;
|
|
this_leaf->type = type;
|
|
}
|
|
|
|
int populate_cache_leaves(unsigned int cpu)
|
|
{
|
|
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
|
|
struct cacheinfo *this_leaf = this_cpu_ci->info_list;
|
|
struct device_node *np = of_cpu_device_node_get(cpu);
|
|
struct device_node *prev = NULL;
|
|
int levels = 1, level = 1;
|
|
|
|
if (of_property_read_bool(np, "cache-size"))
|
|
ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
|
|
if (of_property_read_bool(np, "i-cache-size"))
|
|
ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
|
|
if (of_property_read_bool(np, "d-cache-size"))
|
|
ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
|
|
|
|
prev = np;
|
|
while ((np = of_find_next_cache_node(np))) {
|
|
of_node_put(prev);
|
|
prev = np;
|
|
if (!of_device_is_compatible(np, "cache"))
|
|
break;
|
|
if (of_property_read_u32(np, "cache-level", &level))
|
|
break;
|
|
if (level <= levels)
|
|
break;
|
|
if (of_property_read_bool(np, "cache-size"))
|
|
ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
|
|
if (of_property_read_bool(np, "i-cache-size"))
|
|
ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
|
|
if (of_property_read_bool(np, "d-cache-size"))
|
|
ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
|
|
levels = level;
|
|
}
|
|
of_node_put(np);
|
|
|
|
return 0;
|
|
}
|