Skip to content

Commit

Permalink
[libcpu]rv添加c908 cpu
Browse files Browse the repository at this point in the history
  • Loading branch information
heyuanjie87 authored and Rbb666 committed Sep 23, 2024
1 parent cee64a4 commit af5ca55
Show file tree
Hide file tree
Showing 14 changed files with 1,387 additions and 1 deletion.
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

0 comments on commit af5ca55

Please sign in to comment.