Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libcpu]rv添加c908 cpu #9458

Merged
merged 2 commits into from
Sep 23, 2024
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
2 changes: 1 addition & 1 deletion libcpu/risc-v/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ from building import *

Import('rtconfig')

common64_arch = ['virt64', 'c906']
common64_arch = ['virt64', 'c906', 'c908']
cwd = GetCurrentDir()
group = []
list = os.listdir(cwd)
Expand Down
13 changes: 13 additions & 0 deletions libcpu/risc-v/t-head/c908/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# RT-Thread building script for component

from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]

if not GetDepend('ARCH_USING_ASID'):
SrcRemove(src, ['asid.c'])

group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)

Return('group')
10 changes: 10 additions & 0 deletions libcpu/risc-v/t-head/c908/asm/sbiasm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _SBI_ASM_H
#define _SBI_ASM_H

.macro SBI_CALL which
li a7, \which
ecall
nop
.endm

#endif /* _SBI_ASM_H */
27 changes: 27 additions & 0 deletions libcpu/risc-v/t-head/c908/asm/sbidef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2019-2020, Xim
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#ifndef _ASM_SBI_DEF_H
#define _ASM_SBI_DEF_H

#define SBI_SET_TIMER 0
#define SBI_CONSOLE_PUTCHAR 1
#define SBI_CONSOLE_GETCHAR 2
#define SBI_CLEAR_IPI 3
#define SBI_SEND_IPI 4
#define SBI_REMOTE_FENCE_I 5
#define SBI_REMOTE_SFENCE_VMA 6
#define SBI_REMOTE_SFENCE_VMA_ASID 7
#define SBI_SHUTDOWN 8

#define SBI_CONSOLE_PUTSTR 9

#define SBI_SD_WRITE 10
#define SBI_SD_READ 11
#define SBI_NET_WRITE 12
#define SBI_NET_READ 13

#endif /* _ASM_SBI_DEF_H */
140 changes: 140 additions & 0 deletions libcpu/risc-v/t-head/c908/cache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-29 lizhirui first version
* 2021-11-05 JasonHu add C908 cache inst
* 2022-11-09 WangXiaoyao Support cache coherence operations;
* improve portability and make
* no assumption on undefined behavior
*/

#include <rthw.h>
#include <rtdef.h>
#include <board.h>
#include <riscv.h>

#include "opcode.h"
#include "cache.h"

#define L1_CACHE_BYTES (64)

/**
* GCC version not support t-head cache flush, so we use fixed code to achieve.
* The following function cannot be optimized.
*/
static void dcache_wb_range(unsigned long start, unsigned long end) __attribute__((optimize("O0")));
static void dcache_inv_range(unsigned long start, unsigned long end) __attribute__((optimize("O0")));
static void dcache_wbinv_range(unsigned long start, unsigned long end) __attribute__((optimize("O0")));
static void icache_inv_range(unsigned long start, unsigned long end) __attribute__((optimize("O0")));

#define CACHE_OP_RS1 %0
#define CACHE_OP_RANGE(instr) \
{ \
rt_ubase_t i = start & ~(L1_CACHE_BYTES - 1); \
for (; i < end; i += L1_CACHE_BYTES) \
{ \
__asm__ volatile(instr ::"r"(i) \
: "memory"); \
} \
}

static void dcache_wb_range(unsigned long start, unsigned long end)
{
CACHE_OP_RANGE(OPC_DCACHE_CVA(CACHE_OP_RS1));
}

static void dcachel1_wb_range(unsigned long start, unsigned long end)
{
CACHE_OP_RANGE(OPC_DCACHE_CVAL1(CACHE_OP_RS1));
}

static void dcache_inv_range(unsigned long start, unsigned long end)
{
CACHE_OP_RANGE(OPC_DCACHE_IVA(CACHE_OP_RS1));
}

static void dcache_wbinv_range(unsigned long start, unsigned long end)
{
CACHE_OP_RANGE(OPC_DCACHE_CIVA(CACHE_OP_RS1));
}

static void icache_inv_range(unsigned long start, unsigned long end)
{
CACHE_OP_RANGE(OPC_ICACHE_IVA(CACHE_OP_RS1));
}

rt_inline rt_uint32_t rt_cpu_icache_line_size(void)
{
return L1_CACHE_BYTES;
}

rt_inline rt_uint32_t rt_cpu_dcache_line_size(void)
{
return L1_CACHE_BYTES;
}

void rt_hw_cpu_icache_invalidate_local(void *addr, int size)
{
icache_inv_range((unsigned long)addr, (unsigned long)((unsigned char *)addr + size));
rt_hw_cpu_sync_i();
}

void rt_hw_cpu_dcache_invalidate_local(void *addr, int size)
{
dcache_inv_range((unsigned long)addr, (unsigned long)((unsigned char *)addr + size));
rt_hw_cpu_sync();
}

void rt_hw_cpu_dcache_clean_local(void *addr, int size)
{
dcache_wb_range((unsigned long)addr, (unsigned long)((unsigned char *)addr + size));
rt_hw_cpu_sync();
}

void rt_hw_cpu_dcache_clean_invalidate_local(void *addr, int size)
{
dcache_wbinv_range((unsigned long)addr, (unsigned long)((unsigned char *)addr + size));
rt_hw_cpu_sync();
}

void rt_hw_cpu_dcachel1_clean_local(void *addr, int size)
{
__asm__ volatile(OPC_DCACHE_CVAL1(a0)::
: "memory");
}

/**
* =====================================================
* Architecture Independent API
* =====================================================
*/

void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
{
if (ops == RT_HW_CACHE_INVALIDATE)
{
rt_hw_cpu_icache_invalidate(addr, size);
}
}

void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
{
if (ops == RT_HW_CACHE_FLUSH)
{
rt_hw_cpu_dcache_clean(addr, size);
}
else
{
rt_hw_cpu_dcache_invalidate(addr, size);
}
}

void rt_hw_sync_cache_local(void *addr, int size)
{
rt_hw_cpu_dcachel1_clean_local(addr, size);
rt_hw_cpu_icache_invalidate_local(addr, size);
}
127 changes: 127 additions & 0 deletions libcpu/risc-v/t-head/c908/cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-05 JasonHu The first version
* 2022-11-09 WangXiaoyao Distinguish local and broadcast operations
*/

#ifndef CACHE_H__
#define CACHE_H__

#include "opcode.h"

#ifndef ALWAYS_INLINE
#define ALWAYS_INLINE inline __attribute__((always_inline))
#endif

ALWAYS_INLINE void rt_hw_cpu_sync(void)
{
asm volatile(OPC_SYNC::
: "memory");
}

ALWAYS_INLINE void rt_hw_cpu_sync_i(void)
{
asm volatile(OPC_SYNC_I::
: "memory");
}

ALWAYS_INLINE void rt_hw_cpu_sync_s(void)
{
asm volatile(OPC_SYNC_S::
: "memory");
}

ALWAYS_INLINE void rt_hw_cpu_sync_is(void)
{
asm volatile(OPC_SYNC_IS::
: "memory");
}

/**
* ========================================
* Local cpu cache maintainence operations
* ========================================
*/

void rt_hw_cpu_dcache_clean_local(void *addr, int size);
void rt_hw_cpu_dcache_invalidate_local(void *addr, int size);
void rt_hw_cpu_dcache_clean_invalidate_local(void *addr, int size);

void rt_hw_cpu_icache_invalidate_local(void *addr, int size);

ALWAYS_INLINE void rt_hw_cpu_dcache_clean_all_local(void)
{
__asm__ volatile(OPC_DCACHE_CALL ::
: "memory");
rt_hw_cpu_sync();
}

ALWAYS_INLINE void rt_hw_cpu_dcache_invalidate_all_local(void)
{
__asm__ volatile(OPC_DCACHE_IALL ::
: "memory");
rt_hw_cpu_sync();
}

ALWAYS_INLINE void rt_hw_cpu_dcache_clean_invalidate_all_local(void)
{
__asm__ volatile(OPC_DCACHE_CIALL ::
: "memory");
rt_hw_cpu_sync();
}

ALWAYS_INLINE void rt_hw_cpu_icache_invalidate_all_local(void)
{
__asm__ volatile(OPC_ICACHE_IALL ::
: "memory");
rt_hw_cpu_sync_i();
}

#define rt_hw_icache_invalidate_all rt_hw_cpu_icache_invalidate_all

/**
* ========================================
* Multi-core cache maintainence operations
* ========================================
*/

#ifdef RT_USING_SMP
#error "TODO: cache maintainence have not ported to RISC-V SMP yet"

void rt_hw_cpu_dcache_clean(void *addr, int size);
void rt_hw_cpu_dcache_invalidate(void *addr, int size);
void rt_hw_cpu_dcache_clean_invalidate(void *addr, int size);

void rt_hw_cpu_dcache_clean_all(void);
void rt_hw_cpu_dcache_invalidate_all(void);
void rt_hw_cpu_dcache_clean_invalidate_all(void);

void rt_hw_cpu_icache_invalidate(void *addr, int size);
void rt_hw_cpu_icache_invalidate_all(void);

#else /* !RT_USING_SMP */

#define rt_hw_cpu_dcache_clean rt_hw_cpu_dcache_clean_local
#define rt_hw_cpu_dcache_invalidate rt_hw_cpu_dcache_invalidate_local
#define rt_hw_cpu_dcache_clean_and_invalidate rt_hw_cpu_dcache_clean_invalidate_local

#define rt_hw_cpu_dcache_clean_all rt_hw_cpu_dcache_clean_all_local
#define rt_hw_cpu_dcache_invalidate_all rt_hw_cpu_dcache_invalidate_all_local
#define rt_hw_cpu_dcache_clean_invalidate_all rt_hw_cpu_dcache_clean_invalidate_all_local

#define rt_hw_cpu_icache_invalidate rt_hw_cpu_icache_invalidate_local
#define rt_hw_cpu_icache_invalidate_all rt_hw_cpu_icache_invalidate_all_local

#endif /* RT_USING_SMP */

/**
* @brief Synchronize cache to Point of Unification
*/
void rt_hw_sync_cache_local(void *addr, int size);

#endif /* CACHE_H__ */
Loading
Loading