Skip to content

Commit 3aefb2e

Browse files
riscv: implement Zicbom-based CMO instructions + the t-head variant
This series is based on the alternatives changes done in my svpbmt series and thus also depends on Atish's isa-extension parsing series. It implements using the cache-management instructions from the Zicbom- extension to handle cache flush, etc actions on platforms needing them. SoCs using cpu cores from T-Head like the Allwinne D1 implement a different set of cache instructions. But while they are different, instructions they provide the same functionality, so a variant can easly hook into the existing alternatives mechanism on those. [Palmer: Some minor fixups, including a RISCV_ISA_ZICBOM dependency on MMU that's probably not strictly necessary. The Zicbom support will trip up sparse for users that have new toolchains, I just sent a patch.] Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/linux-sparse/[email protected]/T/#u * palmer/riscv-zicbom: riscv: implement cache-management errata for T-Head SoCs riscv: Add support for non-coherent devices using zicbom extension dt-bindings: riscv: document cbom-block-size of: also handle dma-noncoherent in of_dma_is_coherent()
2 parents 8f2f74b + d20ec75 commit 3aefb2e

File tree

15 files changed

+297
-9
lines changed

15 files changed

+297
-9
lines changed

Documentation/devicetree/bindings/riscv/cpus.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ properties:
6363
- riscv,sv48
6464
- riscv,none
6565

66+
riscv,cbom-block-size:
67+
$ref: /schemas/types.yaml#/definitions/uint32
68+
description:
69+
The blocksize in bytes for the Zicbom cache operations.
70+
6671
riscv,isa:
6772
description:
6873
Identifies the specific RISC-V instruction set architecture

arch/riscv/Kconfig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ config RISCV
113113
select MODULES_USE_ELF_RELA if MODULES
114114
select MODULE_SECTIONS if MODULES
115115
select OF
116+
select OF_DMA_DEFAULT_COHERENT
116117
select OF_EARLY_FLATTREE
117118
select OF_IRQ
118119
select PCI_DOMAINS_GENERIC if PCI
@@ -218,6 +219,14 @@ config PGTABLE_LEVELS
218219
config LOCKDEP_SUPPORT
219220
def_bool y
220221

222+
config RISCV_DMA_NONCOHERENT
223+
bool
224+
select ARCH_HAS_DMA_PREP_COHERENT
225+
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
226+
select ARCH_HAS_SYNC_DMA_FOR_CPU
227+
select ARCH_HAS_SETUP_DMA_OPS
228+
select DMA_DIRECT_REMAP
229+
221230
source "arch/riscv/Kconfig.socs"
222231
source "arch/riscv/Kconfig.erratas"
223232

@@ -392,6 +401,28 @@ config RISCV_ISA_SVPBMT
392401

393402
If you don't know what to do here, say Y.
394403

404+
config CC_HAS_ZICBOM
405+
bool
406+
default y if 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
407+
default y if 32BIT && $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
408+
409+
config RISCV_ISA_ZICBOM
410+
bool "Zicbom extension support for non-coherent DMA operation"
411+
depends on CC_HAS_ZICBOM
412+
depends on !XIP_KERNEL && MMU
413+
select RISCV_DMA_NONCOHERENT
414+
select RISCV_ALTERNATIVE
415+
default y
416+
help
417+
Adds support to dynamically detect the presence of the ZICBOM
418+
extension (Cache Block Management Operations) and enable its
419+
usage.
420+
421+
The Zicbom extension can be used to handle for example
422+
non-coherent DMA support on devices that need it.
423+
424+
If you don't know what to do here, say Y.
425+
395426
config FPU
396427
bool "FPU support"
397428
default y

arch/riscv/Kconfig.erratas

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,15 @@ config ERRATA_THEAD_PBMT
5555

5656
If you don't know what to do here, say "Y".
5757

58+
config ERRATA_THEAD_CMO
59+
bool "Apply T-Head cache management errata"
60+
depends on ERRATA_THEAD
61+
select RISCV_DMA_NONCOHERENT
62+
default y
63+
help
64+
This will apply the cache management errata to handle the
65+
non-standard handling on non-coherent operations on T-Head SoCs.
66+
67+
If you don't know what to do here, say "Y".
68+
5869
endmenu # "CPU errata selection"

arch/riscv/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
5656
toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei)
5757
riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
5858

59+
# Check if the toolchain supports Zicbom extension
60+
toolchain-supports-zicbom := $(call cc-option-yn, -march=$(riscv-march-y)_zicbom)
61+
riscv-march-$(toolchain-supports-zicbom) := $(riscv-march-y)_zicbom
62+
5963
KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
6064
KBUILD_AFLAGS += -march=$(riscv-march-y)
6165

arch/riscv/errata/thead/errata.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ static bool errata_probe_pbmt(unsigned int stage,
2727
return false;
2828
}
2929

30+
static bool errata_probe_cmo(unsigned int stage,
31+
unsigned long arch_id, unsigned long impid)
32+
{
33+
#ifdef CONFIG_ERRATA_THEAD_CMO
34+
if (arch_id != 0 || impid != 0)
35+
return false;
36+
37+
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
38+
return false;
39+
40+
riscv_noncoherent_supported();
41+
return true;
42+
#else
43+
return false;
44+
#endif
45+
}
46+
3047
static u32 thead_errata_probe(unsigned int stage,
3148
unsigned long archid, unsigned long impid)
3249
{
@@ -35,6 +52,9 @@ static u32 thead_errata_probe(unsigned int stage,
3552
if (errata_probe_pbmt(stage, archid, impid))
3653
cpu_req_errata |= (1U << ERRATA_THEAD_PBMT);
3754

55+
if (errata_probe_cmo(stage, archid, impid))
56+
cpu_req_errata |= (1U << ERRATA_THEAD_CMO);
57+
3858
return cpu_req_errata;
3959
}
4060

arch/riscv/include/asm/cache.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
1313

14+
#ifdef CONFIG_RISCV_DMA_NONCOHERENT
15+
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
16+
#endif
17+
1418
/*
1519
* RISC-V requires the stack pointer to be 16-byte aligned, so ensure that
1620
* the flat loader aligns it accordingly.

arch/riscv/include/asm/cacheflush.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
4242

4343
#endif /* CONFIG_SMP */
4444

45+
#ifdef CONFIG_RISCV_ISA_ZICBOM
46+
void riscv_init_cbom_blocksize(void);
47+
#else
48+
static inline void riscv_init_cbom_blocksize(void) { }
49+
#endif
50+
51+
#ifdef CONFIG_RISCV_DMA_NONCOHERENT
52+
void riscv_noncoherent_supported(void);
53+
#endif
54+
4555
/*
4656
* Bits in sys_riscv_flush_icache()'s flags argument.
4757
*/

arch/riscv/include/asm/errata_list.h

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616

1717
#ifdef CONFIG_ERRATA_THEAD
1818
#define ERRATA_THEAD_PBMT 0
19-
#define ERRATA_THEAD_NUMBER 1
19+
#define ERRATA_THEAD_CMO 1
20+
#define ERRATA_THEAD_NUMBER 2
2021
#endif
2122

2223
#define CPUFEATURE_SVPBMT 0
23-
#define CPUFEATURE_NUMBER 1
24+
#define CPUFEATURE_ZICBOM 1
25+
#define CPUFEATURE_NUMBER 2
2426

2527
#ifdef __ASSEMBLY__
2628

@@ -87,6 +89,59 @@ asm volatile(ALTERNATIVE( \
8789
#define ALT_THEAD_PMA(_val)
8890
#endif
8991

92+
/*
93+
* dcache.ipa rs1 (invalidate, physical address)
94+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
95+
* 0000001 01010 rs1 000 00000 0001011
96+
* dache.iva rs1 (invalida, virtual address)
97+
* 0000001 00110 rs1 000 00000 0001011
98+
*
99+
* dcache.cpa rs1 (clean, physical address)
100+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
101+
* 0000001 01001 rs1 000 00000 0001011
102+
* dcache.cva rs1 (clean, virtual address)
103+
* 0000001 00100 rs1 000 00000 0001011
104+
*
105+
* dcache.cipa rs1 (clean then invalidate, physical address)
106+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
107+
* 0000001 01011 rs1 000 00000 0001011
108+
* dcache.civa rs1 (... virtual address)
109+
* 0000001 00111 rs1 000 00000 0001011
110+
*
111+
* sync.s (make sure all cache operations finished)
112+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
113+
* 0000000 11001 00000 000 00000 0001011
114+
*/
115+
#define THEAD_inval_A0 ".long 0x0265000b"
116+
#define THEAD_clean_A0 ".long 0x0245000b"
117+
#define THEAD_flush_A0 ".long 0x0275000b"
118+
#define THEAD_SYNC_S ".long 0x0190000b"
119+
120+
#define ALT_CMO_OP(_op, _start, _size, _cachesize) \
121+
asm volatile(ALTERNATIVE_2( \
122+
__nops(6), \
123+
"mv a0, %1\n\t" \
124+
"j 2f\n\t" \
125+
"3:\n\t" \
126+
"cbo." __stringify(_op) " (a0)\n\t" \
127+
"add a0, a0, %0\n\t" \
128+
"2:\n\t" \
129+
"bltu a0, %2, 3b\n\t" \
130+
"nop", 0, CPUFEATURE_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
131+
"mv a0, %1\n\t" \
132+
"j 2f\n\t" \
133+
"3:\n\t" \
134+
THEAD_##_op##_A0 "\n\t" \
135+
"add a0, a0, %0\n\t" \
136+
"2:\n\t" \
137+
"bltu a0, %2, 3b\n\t" \
138+
THEAD_SYNC_S, THEAD_VENDOR_ID, \
139+
ERRATA_THEAD_CMO, CONFIG_ERRATA_THEAD_CMO) \
140+
: : "r"(_cachesize), \
141+
"r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \
142+
"r"((unsigned long)(_start) + (_size)) \
143+
: "a0")
144+
90145
#endif /* __ASSEMBLY__ */
91146

92147
#endif

arch/riscv/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ extern unsigned long elf_hwcap;
5454
enum riscv_isa_ext_id {
5555
RISCV_ISA_EXT_SSCOFPMF = RISCV_ISA_EXT_BASE,
5656
RISCV_ISA_EXT_SVPBMT,
57+
RISCV_ISA_EXT_ZICBOM,
5758
RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
5859
};
5960

arch/riscv/kernel/cpu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
9393
static struct riscv_isa_ext_data isa_ext_arr[] = {
9494
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
9595
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
96+
__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
9697
__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
9798
};
9899

0 commit comments

Comments
 (0)