Skip to content

Commit ec0c2d5

Browse files
committed
Merge tag 'for-linus' of https://github.com/openrisc/linux
Pull OpenRISC updates from Stafford Horne: - Support for cacheinfo API to expose OpenRISC cache info via sysfs, this also translated to some cleanups to OpenRISC cache flush and invalidate API's - Documentation updates for new mailing list and toolchain binaries * tag 'for-linus' of https://github.com/openrisc/linux: Documentation: openrisc: Update toolchain binaries URL Documentation: openrisc: Update mailing list openrisc: Add cacheinfo support openrisc: Introduce new utility functions to flush and invalidate caches openrisc: Refactor struct cpuinfo_or1k to reduce duplication
2 parents a16ebe5 + 66ffd2f commit ec0c2d5

File tree

11 files changed

+214
-93
lines changed

11 files changed

+214
-93
lines changed

Documentation/arch/openrisc/openrisc_port.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k).
77

88
For information about OpenRISC processors and ongoing development:
99

10-
======= =============================
10+
======= ==============================
1111
website https://openrisc.io
12-
email openrisc@lists.librecores.org
13-
======= =============================
12+
email linux-openrisc@vger.kernel.org
13+
======= ==============================
1414

1515
---------------------------------------------------------------------
1616

@@ -27,11 +27,11 @@ Toolchain binaries can be obtained from openrisc.io or our github releases page.
2727
Instructions for building the different toolchains can be found on openrisc.io
2828
or Stafford's toolchain build and release scripts.
2929

30-
========== =================================================
31-
binaries https://github.com/openrisc/or1k-gcc/releases
30+
========== ==========================================================
31+
binaries https://github.com/stffrdhrn/or1k-toolchain-build/releases
3232
toolchains https://openrisc.io/software
3333
building https://github.com/stffrdhrn/or1k-toolchain-build
34-
========== =================================================
34+
========== ==========================================================
3535

3636
2) Building
3737

Documentation/translations/zh_CN/arch/openrisc/openrisc_port.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ OpenRISC 1000系列(或1k)。
1717

1818
关于OpenRISC处理器和正在进行中的开发的信息:
1919

20-
======= =============================
20+
======= ==============================
2121
网站 https://openrisc.io
22-
邮箱 openrisc@lists.librecores.org
23-
======= =============================
22+
邮箱 linux-openrisc@vger.kernel.org
23+
======= ==============================
2424

2525
---------------------------------------------------------------------
2626

@@ -36,11 +36,11 @@ OpenRISC工具链和Linux的构建指南
3636
工具链的构建指南可以在openrisc.io或Stafford的工具链构建和发布脚本
3737
中找到。
3838

39-
====== =================================================
40-
二进制 https://github.com/openrisc/or1k-gcc/releases
39+
====== ==========================================================
40+
二进制 https://github.com/stffrdhrn/or1k-toolchain-build/releases
4141
工具链 https://openrisc.io/software
4242
构建 https://github.com/stffrdhrn/or1k-toolchain-build
43-
====== =================================================
43+
====== ==========================================================
4444

4545
2) 构建
4646

Documentation/translations/zh_TW/arch/openrisc/openrisc_port.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ OpenRISC 1000系列(或1k)。
1717

1818
關於OpenRISC處理器和正在進行中的開發的信息:
1919

20-
======= =============================
20+
======= ==============================
2121
網站 https://openrisc.io
22-
郵箱 openrisc@lists.librecores.org
23-
======= =============================
22+
郵箱 linux-openrisc@vger.kernel.org
23+
======= ==============================
2424

2525
---------------------------------------------------------------------
2626

@@ -36,11 +36,11 @@ OpenRISC工具鏈和Linux的構建指南
3636
工具鏈的構建指南可以在openrisc.io或Stafford的工具鏈構建和發佈腳本
3737
中找到。
3838

39-
====== =================================================
40-
二進制 https://github.com/openrisc/or1k-gcc/releases
39+
====== ==========================================================
40+
二進制 https://github.com/stffrdhrn/or1k-toolchain-build/releases
4141
工具鏈 https://openrisc.io/software
4242
構建 https://github.com/stffrdhrn/or1k-toolchain-build
43-
====== =================================================
43+
====== ==========================================================
4444

4545
2) 構建
4646

arch/openrisc/include/asm/cacheflush.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
*/
2424
extern void local_dcache_page_flush(struct page *page);
2525
extern void local_icache_page_inv(struct page *page);
26+
extern void local_dcache_range_flush(unsigned long start, unsigned long end);
27+
extern void local_dcache_range_inv(unsigned long start, unsigned long end);
28+
extern void local_icache_range_inv(unsigned long start, unsigned long end);
2629

2730
/*
2831
* Data cache flushing always happen on the local cpu. Instruction cache
@@ -38,6 +41,20 @@ extern void local_icache_page_inv(struct page *page);
3841
extern void smp_icache_page_inv(struct page *page);
3942
#endif /* CONFIG_SMP */
4043

44+
/*
45+
* Even if the actual block size is larger than L1_CACHE_BYTES, paddr
46+
* can be incremented by L1_CACHE_BYTES. When paddr is written to the
47+
* invalidate register, the entire cache line encompassing this address
48+
* is invalidated. Each subsequent reference to the same cache line will
49+
* not affect the invalidation process.
50+
*/
51+
#define local_dcache_block_flush(addr) \
52+
local_dcache_range_flush(addr, addr + L1_CACHE_BYTES)
53+
#define local_dcache_block_inv(addr) \
54+
local_dcache_range_inv(addr, addr + L1_CACHE_BYTES)
55+
#define local_icache_block_inv(addr) \
56+
local_icache_range_inv(addr, addr + L1_CACHE_BYTES)
57+
4158
/*
4259
* Synchronizes caches. Whenever a cpu writes executable code to memory, this
4360
* should be called to make sure the processor sees the newly written code.

arch/openrisc/include/asm/cpuinfo.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,31 @@
1515
#ifndef __ASM_OPENRISC_CPUINFO_H
1616
#define __ASM_OPENRISC_CPUINFO_H
1717

18+
#include <asm/spr.h>
19+
#include <asm/spr_defs.h>
20+
21+
struct cache_desc {
22+
u32 size;
23+
u32 sets;
24+
u32 block_size;
25+
u32 ways;
26+
};
27+
1828
struct cpuinfo_or1k {
1929
u32 clock_frequency;
2030

21-
u32 icache_size;
22-
u32 icache_block_size;
23-
u32 icache_ways;
24-
25-
u32 dcache_size;
26-
u32 dcache_block_size;
27-
u32 dcache_ways;
31+
struct cache_desc icache;
32+
struct cache_desc dcache;
2833

2934
u16 coreid;
3035
};
3136

3237
extern struct cpuinfo_or1k cpuinfo_or1k[NR_CPUS];
3338
extern void setup_cpuinfo(void);
3439

40+
/*
41+
* Check if the cache component exists.
42+
*/
43+
extern bool cpu_cache_is_present(const unsigned int cache_type);
44+
3545
#endif /* __ASM_OPENRISC_CPUINFO_H */

arch/openrisc/kernel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extra-y := vmlinux.lds
77

88
obj-y := head.o setup.o or32_ksyms.o process.o dma.o \
99
traps.o time.o irq.o entry.o ptrace.o signal.o \
10-
sys_call_table.o unwinder.o
10+
sys_call_table.o unwinder.o cacheinfo.o
1111

1212
obj-$(CONFIG_SMP) += smp.o sync-timer.o
1313
obj-$(CONFIG_STACKTRACE) += stacktrace.o

arch/openrisc/kernel/cacheinfo.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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 <sahilcdq@proton.me>
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+
}

arch/openrisc/kernel/dma.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@
1717
#include <linux/pagewalk.h>
1818

1919
#include <asm/cpuinfo.h>
20+
#include <asm/cacheflush.h>
2021
#include <asm/spr_defs.h>
2122
#include <asm/tlbflush.h>
2223

2324
static int
2425
page_set_nocache(pte_t *pte, unsigned long addr,
2526
unsigned long next, struct mm_walk *walk)
2627
{
27-
unsigned long cl;
28-
struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
29-
3028
pte_val(*pte) |= _PAGE_CI;
3129

3230
/*
@@ -36,8 +34,7 @@ page_set_nocache(pte_t *pte, unsigned long addr,
3634
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
3735

3836
/* Flush page out of dcache */
39-
for (cl = __pa(addr); cl < __pa(next); cl += cpuinfo->dcache_block_size)
40-
mtspr(SPR_DCBFR, cl);
37+
local_dcache_range_flush(__pa(addr), __pa(next));
4138

4239
return 0;
4340
}
@@ -98,21 +95,14 @@ void arch_dma_clear_uncached(void *cpu_addr, size_t size)
9895
void arch_sync_dma_for_device(phys_addr_t addr, size_t size,
9996
enum dma_data_direction dir)
10097
{
101-
unsigned long cl;
102-
struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
103-
10498
switch (dir) {
10599
case DMA_TO_DEVICE:
106100
/* Flush the dcache for the requested range */
107-
for (cl = addr; cl < addr + size;
108-
cl += cpuinfo->dcache_block_size)
109-
mtspr(SPR_DCBFR, cl);
101+
local_dcache_range_flush(addr, addr + size);
110102
break;
111103
case DMA_FROM_DEVICE:
112104
/* Invalidate the dcache for the requested range */
113-
for (cl = addr; cl < addr + size;
114-
cl += cpuinfo->dcache_block_size)
115-
mtspr(SPR_DCBIR, cl);
105+
local_dcache_range_inv(addr, addr + size);
116106
break;
117107
default:
118108
/*

0 commit comments

Comments
 (0)