Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -526,5 +526,6 @@ config RISCV_NO_MTVAL_ON_FP_TRAP
to handle FP exceptions.

rsource "Kconfig.isa"
rsource "core/Kconfig"

endmenu
2 changes: 2 additions & 0 deletions arch/riscv/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ if(CONFIG_GEN_SW_ISR_TABLE)
zephyr_linker_sources(RODATA swi_tables.ld)
endif()
endif()

add_subdirectory_ifdef(CONFIG_XUANTIE xuantie)
11 changes: 11 additions & 0 deletions arch/riscv/core/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# RISC-V cores configuration options

# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
# SPDX-License-Identifier: Apache-2.0

config XUANTIE
bool
help
This option signifies the use of a CPU of the XuanTie RISC-V family

rsource "xuantie/Kconfig"
8 changes: 8 additions & 0 deletions arch/riscv/core/xuantie/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/cache.h)

zephyr_library()

zephyr_library_sources_ifdef(CONFIG_CACHE_XTHEADCMO cache_xtheadcmo.c)
zephyr_library_sources_ifdef(CONFIG_CACHE_XTHEADCMO_E907 cache_xtheadcmo_e907.c)
48 changes: 48 additions & 0 deletions arch/riscv/core/xuantie/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
# SPDX-License-Identifier: Apache-2.0

config XUANTIE_E907
bool
select XUANTIE
select GEN_IRQ_VECTOR_TABLE
select INCLUDE_RESET_VECTOR
select RISCV_HAS_CLIC
select RISCV_MACHINE_TIMER
select RISCV_PRIVILEGED
select RISCV_ISA_RV32I
select RISCV_ISA_EXT_M
select RISCV_ISA_EXT_A
select RISCV_ISA_EXT_C
select RISCV_ISA_EXT_ZICSR
select RISCV_ISA_EXT_ZIFENCEI
select RISCV_VECTORED_MODE

if XUANTIE

config CACHE_XTHEADCMO
bool
default y
select CACHE_MANAGEMENT
select CPU_HAS_ICACHE
help
This option enables cache support for XuanTie family of CPUs using the XTHeadCmo extension

if CACHE_XTHEADCMO

config DCACHE_LINE_SIZE
default 32

config ICACHE_LINE_SIZE
default 32

config CACHE_XTHEADCMO_E907
bool
default y
depends on XUANTIE_E907
select CPU_HAS_DCACHE
help
This option enables the additional XTHeadCmo cache functions for the E907 cores

endif # CACHE_XTHEADCMO

endif # XUANTIE
203 changes: 203 additions & 0 deletions arch/riscv/core/xuantie/cache_xtheadcmo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/*
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/cache.h>

int arch_dcache_invd_all(void)
{
__asm__ volatile (
"fence\n"
/* th.dcache.iall */
".insn 0x20000B\n"
"fence\n"
);

return 0;
}

static void arch_cache_invalidate_dcache_line(uintptr_t address_in)
{
register uintptr_t address __asm__("a3") = address_in;

__asm__ volatile (
/* th.dcache.ipa a3*/
".insn 0x2A6800B\n"
:
: "r"(address)
);
}

int arch_dcache_invd_range(void *addr_in, size_t size)
{
uintptr_t addr = (uintptr_t)addr_in;

__asm__ volatile (
"fence\n"
);
for (uintptr_t i = addr; i < addr + size; i += CONFIG_DCACHE_LINE_SIZE) {
arch_cache_invalidate_dcache_line(i);
}
__asm__ volatile (
"fence\n"
);

return 0;
}

int arch_icache_invd_all(void)
{
__asm__ volatile (
"fence\n"
"fence.i\n"
/* th.icache.iall */
".insn 0x100000B\n"
"fence\n"
"fence.i\n"
);

return 0;
}

static void arch_cache_invalidate_icache_line(uintptr_t address_in)
{
register uintptr_t address __asm__("a3") = address_in;

__asm__ volatile (
/* th.icache.ipa a3*/
".insn 0x386800B\n"
:
: "r"(address)
);
}

int arch_icache_invd_range(void *addr_in, size_t size)
{
uintptr_t addr = (uintptr_t)addr_in;

__asm__ volatile (
"fence\n"
"fence.i\n"
);
for (uintptr_t i = addr; i < addr + size; i += CONFIG_ICACHE_LINE_SIZE) {
arch_cache_invalidate_icache_line(i);
}
__asm__ volatile (
"fence\n"
"fence.i\n"
);

return 0;
}

int arch_dcache_flush_all(void)
{
__asm__ volatile (
"fence\n"
/* th.dcache.call */
".insn 0x10000B\n"
"fence\n"
);

return 0;
}

static void arch_cache_clean_dcache_line(uintptr_t address_in)
{
register uintptr_t address __asm__("a3") = address_in;

__asm__ volatile (
/* th.dcache.cpa a3*/
".insn 0x296800B\n"
:
: "r"(address)
);
}

int arch_dcache_flush_range(void *addr_in, size_t size)
{
uintptr_t addr = (uintptr_t)addr_in;

__asm__ volatile (
"fence\n"
);
for (uintptr_t i = addr; i < addr + size; i += CONFIG_DCACHE_LINE_SIZE) {
arch_cache_clean_dcache_line(i);
}
__asm__ volatile (
"fence\n"
);

return 0;
}

int arch_dcache_flush_and_invd_all(void)
{
__asm__ volatile (
"fence\n"
/* th.dcache.ciall */
".insn 0x30000B\n"
"fence\n"
);

return 0;
}

static void arch_cache_clean_invalidate_dcache_line(uintptr_t address_in)
{
register uintptr_t address __asm__("a3") = address_in;

__asm__ volatile (
/* th.dcache.cipa a3*/
".insn 0x2B6800B\n"
:
: "r"(address)
);
}

int arch_dcache_flush_and_invd_range(void *addr_in, size_t size)
{
uintptr_t addr = (uintptr_t)addr_in;

__asm__ volatile (
"fence\n"
);
for (uintptr_t i = addr; i < addr + size; i += CONFIG_DCACHE_LINE_SIZE) {
arch_cache_clean_invalidate_dcache_line(i);
}
__asm__ volatile (
"fence\n"
);

return 0;
}

int arch_icache_flush_all(void)
{
return -ENOTSUP;
}

int arch_icache_flush_and_invd_all(void)
{
return -ENOTSUP;
}

int arch_icache_flush_range(void *addr, size_t size)
{
ARG_UNUSED(addr);
ARG_UNUSED(size);

return -ENOTSUP;
}

int arch_icache_flush_and_invd_range(void *addr, size_t size)
{
ARG_UNUSED(addr);
ARG_UNUSED(size);

return -ENOTSUP;
}
108 changes: 108 additions & 0 deletions arch/riscv/core/xuantie/cache_xtheadcmo_e907.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/cache.h>

/* "a Hardware CSR" */
#define THEAD_MHCR "0x7C1"

void arch_icache_enable(void)
{
uint32_t tmp;

__asm__ volatile (
"fence\n"
"fence.i\n"
/* th.icache.iall */
".insn 0x100000B\n"
);
__asm__ volatile(
"csrr %0, " THEAD_MHCR
: "=r"(tmp));
tmp |= (1 << 0);
__asm__ volatile(
"csrw " THEAD_MHCR ", %0"
:
: "r"(tmp));
__asm__ volatile (
"fence\n"
"fence.i\n"
);
}

void arch_dcache_enable(void)
{
uint32_t tmp;

__asm__ volatile (
"fence\n"
"fence.i\n"
/* th.dcache.iall */
".insn 0x20000B\n"
);
__asm__ volatile(
"csrr %0, " THEAD_MHCR
: "=r"(tmp));
tmp |= (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
__asm__ volatile(
"csrw " THEAD_MHCR ", %0"
:
: "r"(tmp));
__asm__ volatile (
"fence\n"
"fence.i\n"
);
}

void arch_icache_disable(void)
{
uint32_t tmp;

__asm__ volatile (
"fence\n"
"fence.i\n"
/* th.icache.iall */
".insn 0x100000B\n"
);
__asm__ volatile(
"csrr %0, " THEAD_MHCR
: "=r"(tmp));
tmp &= ~(1 << 0);
__asm__ volatile(
"csrw " THEAD_MHCR ", %0"
:
: "r"(tmp));
__asm__ volatile (
"fence\n"
"fence.i\n"
);
}

void arch_dcache_disable(void)
{
uint32_t tmp;

__asm__ volatile (
"fence\n"
"fence.i\n"
/* th.dcache.iall */
".insn 0x20000B\n"
);
__asm__ volatile(
"csrr %0, " THEAD_MHCR
: "=r"(tmp));
tmp &= ~((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4));
__asm__ volatile(
"csrw " THEAD_MHCR ", %0"
:
: "r"(tmp));
__asm__ volatile (
"fence\n"
"fence.i\n"
);
}
Loading