Skip to content
Open
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
4 changes: 3 additions & 1 deletion firmware/fw_base.S
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ _start_warm:
add a4, a4, 1
blt a4, s7, 1b
2: add s6, a4, zero
3: bge s6, s7, _start_hang
3: bgeu s6, s7, _start_hang

/* Find the scratch space based on HART index */
lla tp, _fw_end
Expand Down Expand Up @@ -647,6 +647,8 @@ memcmp:
.align 3
.globl _trap_handler
_trap_handler:
sfence.vma zero, t0

TRAP_SAVE_AND_SETUP_SP_T0

TRAP_SAVE_MEPC_MSTATUS 0
Expand Down
17 changes: 13 additions & 4 deletions include/sbi/riscv_barrier.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@
#define mb() RISCV_FENCE(iorw,iorw)

/* Read Memory barrier */
#define rmb() RISCV_FENCE(ir,ir)
#define rmb() RISCV_FENCE(ir,iorw)

/* Write Memory barrier */
#define wmb() RISCV_FENCE(ow,ow)
#define wmb() RISCV_FENCE(iorw,ow)

/* SMP Read & Write Memory barrier */
#define smp_mb() RISCV_FENCE(rw,rw)

/* SMP Read Memory barrier */
#define smp_rmb() RISCV_FENCE(r,r)
#define smp_rmb() RISCV_FENCE(r,rw)

/* SMP Write Memory barrier */
#define smp_wmb() RISCV_FENCE(w,w)
#define smp_wmb() RISCV_FENCE(rw,w)

/* CPU relax for busy loop */
#define cpu_relax() \
Expand All @@ -48,11 +48,20 @@ do { \

/* clang-format on */

#ifdef CONFIG_PLATFORM_SOPHGO_MANGO
#define __smp_store_release(p, v) \
do { \
RISCV_FENCE(rw, w); \
*(p) = (v); \
RISCV_FENCE(w, rw); \
} while (0)
#else
#define __smp_store_release(p, v) \
do { \
RISCV_FENCE(rw, w); \
*(p) = (v); \
} while (0)
#endif

#define __smp_load_acquire(p) \
({ \
Expand Down
2 changes: 2 additions & 0 deletions include/sbi/riscv_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,8 @@
/* Counter Overflow CSR */
#define CSR_SCOUNTOVF 0xda0

#define MCOUNTEREN_TM (_UL(1) << 1)

/* Debug/Trace Registers */
#define CSR_TSELECT 0x7a0
#define CSR_TDATA1 0x7a1
Expand Down
107 changes: 107 additions & 0 deletions include/sbi/sbi_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct sbi_domain_memregion;
struct sbi_ecall_return;
struct sbi_trap_regs;
struct sbi_hart_features;
struct sbi_tlb_info;
union sbi_ldst_data;

/** Possible feature flags of a platform */
Expand All @@ -76,6 +77,9 @@ struct sbi_platform_operations {
/* Check if specified HART is allowed to do cold boot */
bool (*cold_boot_allowed)(u32 hartid);

/* Check if platform force emulate time csr, instead of using csr directly */
bool (*force_emulate_time_csr)(void);

/* Check if platform requires single firmware region */
bool (*single_fw_region)(void);

Expand Down Expand Up @@ -125,6 +129,20 @@ struct sbi_platform_operations {
/** Get tlb fifo num entries*/
u32 (*get_tlb_num_entries)(void);

void (*local_fence_i)(struct sbi_tlb_info *tinfo);

void (*local_sfence_vma)(struct sbi_tlb_info *tinfo);

void (*local_sfence_vma_asid)(struct sbi_tlb_info *tinfo);

void (*local_hfence_gvma_vmid)(struct sbi_tlb_info *tinfo);

void (*local_hfence_gvma)(struct sbi_tlb_info *tinfo);

void (*local_hfence_vvma_asid)(struct sbi_tlb_info *tinfo);

void (*local_hfence_vvma)(struct sbi_tlb_info *tinfo);

/** Initialize platform timer during cold boot */
int (*timer_init)(void);

Expand Down Expand Up @@ -305,6 +323,81 @@ static inline u32 sbi_platform_tlb_fifo_num_entries(const struct sbi_platform *p
return sbi_hart_count();
}

static inline u32 sbi_platform_local_fence_i(
const struct sbi_platform *plat,
struct sbi_tlb_info *tinfo)
{
if (plat && sbi_platform_ops(plat)->local_fence_i) {
sbi_platform_ops(plat)->local_fence_i(tinfo);
return 0;
}
return SBI_ENOTSUPP;
}

static inline u32 sbi_platform_local_sfence_vma(
const struct sbi_platform *plat,
struct sbi_tlb_info *tinfo)
{
if (plat && sbi_platform_ops(plat)->local_sfence_vma) {
sbi_platform_ops(plat)->local_sfence_vma(tinfo);
return 0;
}
return SBI_ENOTSUPP;
}

static inline u32 sbi_platform_local_sfence_vma_asid(
const struct sbi_platform *plat,
struct sbi_tlb_info *tinfo)
{
if (plat && sbi_platform_ops(plat)->local_sfence_vma_asid) {
sbi_platform_ops(plat)->local_sfence_vma_asid(tinfo);
return 0;
}
return SBI_ENOTSUPP;
}

static inline u32 sbi_platform_local_hfence_gvma_vmid(
const struct sbi_platform *plat,
struct sbi_tlb_info *tinfo)
{
if (plat && sbi_platform_ops(plat)->local_hfence_gvma_vmid) {
sbi_platform_ops(plat)->local_hfence_gvma_vmid(tinfo);
return 0;
}
return SBI_ENOTSUPP;
}

static inline u32 sbi_platform_local_hfence_gvma(
const struct sbi_platform *plat,
struct sbi_tlb_info *tinfo)
{
if (plat && sbi_platform_ops(plat)->local_hfence_gvma) {
sbi_platform_ops(plat)->local_hfence_gvma(tinfo);
return 0;
}
return SBI_ENOTSUPP;
}
static inline u32 sbi_platform_local_hfence_vvma_asid(
const struct sbi_platform *plat,
struct sbi_tlb_info *tinfo)
{
if (plat && sbi_platform_ops(plat)->local_hfence_vvma_asid) {
sbi_platform_ops(plat)->local_hfence_vvma_asid(tinfo);
return 0;
}
return SBI_ENOTSUPP;
}
static inline u32 sbi_platform_local_hfence_vvma(
const struct sbi_platform *plat,
struct sbi_tlb_info *tinfo)
{
if (plat && sbi_platform_ops(plat)->local_hfence_vvma) {
sbi_platform_ops(plat)->local_hfence_vvma(tinfo);
return 0;
}
return SBI_ENOTSUPP;
}

/**
* Get total number of HARTs supported by the platform
*
Expand Down Expand Up @@ -350,6 +443,20 @@ static inline bool sbi_platform_cold_boot_allowed(
return true;
}

/**
* Check whether given platform should force emulate time CSR
*
* @param plat pointer to struct sbi_platform
*
* @return true such platform force emulate time CSR, false otherwise
*/
static inline bool sbi_platform_force_emulate_time_csr(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->force_emulate_time_csr)
return sbi_platform_ops(plat)->force_emulate_time_csr();
return false;
}

/**
* Check whether platform requires single firmware region
*
Expand Down
1 change: 1 addition & 0 deletions include/sbi_utils/timer/aclint_mtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct aclint_mtimer_data {
u32 hart_count;
bool has_64bit_mmio;
bool has_shared_mtime;
bool use_extern_domain;
/* Private details (initialized and used by ACLINT MTIMER library) */
struct aclint_mtimer_data *time_delta_reference;
unsigned long time_delta_computed;
Expand Down
21 changes: 21 additions & 0 deletions include/sbi_utils/timer/sg2042_gmt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 SOPHGO Corporation
*
* Authors:
* Chao Wei <chao.wei@sophgo.com>
*/

#ifndef __SG2042_GMT_H__
#define __SG2042_GMT_H__

int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
unsigned long mtimecmp_base,
unsigned long mtimecmp_size,
unsigned long delcared_freq,
unsigned long actual_freq,
unsigned long timecmp_freq);
Comment on lines +13 to +18
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (typo): Typo in parameter name delcared_freq in SG2042 GMT timer header

The prototype uses delcared_freq but the implementation uses declared_freq. Please align the spelling here to avoid confusion when searching or reading the header.

Suggested change
int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
unsigned long mtimecmp_base,
unsigned long mtimecmp_size,
unsigned long delcared_freq,
unsigned long actual_freq,
unsigned long timecmp_freq);
int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
unsigned long mtimecmp_base,
unsigned long mtimecmp_size,
unsigned long declared_freq,
unsigned long actual_freq,
unsigned long timecmp_freq);

int sg2042gmt_warm_timer_init(void);

#endif /* __SG2042_GMT_H__ */
3 changes: 3 additions & 0 deletions lib/sbi/riscv_locks.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ void spin_lock(spinlock_t *lock)
#error "need A or Zaamo or Zalrsc"
#endif

"fence w, o\n"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Additional fence in spin_lock hot path may hurt performance without clear benefit

The fence w, o inside the spin_lock loop adds a barrier on every failed CAS in the contended path and may degrade scalability, given that __smp_store_release and other barriers already provide ordering for lock acquire/release. Please confirm that this specific fence is needed for a particular device-ordering requirement; if not, consider removing it or relocating it outside the hot retry loop.


/* Did we get the lock? */
" srli %1, %0, %6\n"
" and %1, %1, %5\n"
Expand All @@ -83,4 +85,5 @@ void spin_lock(spinlock_t *lock)
void spin_unlock(spinlock_t *lock)
{
__smp_store_release(&lock->owner, lock->owner + 1);
RISCV_FENCE(w, o);
}
8 changes: 7 additions & 1 deletion lib/sbi/sbi_hart.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ static void mstatus_init(struct sbi_scratch *scratch)
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10)
csr_write(CSR_MCOUNTEREN, -1);

if (sbi_platform_force_emulate_time_csr(sbi_platform_thishart_ptr())) {
csr_clear(CSR_MCOUNTEREN, MCOUNTEREN_TM);
csr_clear(CSR_SCOUNTEREN, MCOUNTEREN_TM);
}

/* All programmable counters will start running at runtime after S-mode request */
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11)
csr_write(CSR_MCOUNTINHIBIT, 0xFFFFFFF8);
Expand Down Expand Up @@ -670,7 +675,8 @@ static int hart_detect_features(struct sbi_scratch *scratch)
__set_bit(__csr_id, hfeatures->csrs);

__check_csr_existence(CSR_CYCLE, SBI_HART_CSR_CYCLE);
__check_csr_existence(CSR_TIME, SBI_HART_CSR_TIME);
if (!sbi_platform_force_emulate_time_csr(sbi_platform_thishart_ptr()))
__check_csr_existence(CSR_TIME, SBI_HART_CSR_TIME);
__check_csr_existence(CSR_INSTRET, SBI_HART_CSR_INSTRET);

#undef __check_csr_existence
Expand Down
1 change: 1 addition & 0 deletions lib/sbi/sbi_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ static void wake_coldboot_harts(struct sbi_scratch *scratch)
{
/* Mark coldboot done */
__smp_store_release(&coldboot_done, 1);
RISCV_FENCE(w, o);
}

static unsigned long entry_count_offset;
Expand Down
5 changes: 5 additions & 0 deletions lib/sbi/sbi_pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,8 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
ret = pmu_ctr_stop_hw(cidx);

if (cidx > (CSR_INSTRET - CSR_CYCLE) && flag & SBI_PMU_STOP_FLAG_RESET) {
if (pmu_dev && pmu_dev->hw_counter_disable_irq)
pmu_dev->hw_counter_disable_irq(cidx);
phs->active_events[cidx] = SBI_PMU_EVENT_IDX_INVALID;
pmu_reset_hw_mhpmevent(cidx);
}
Expand Down Expand Up @@ -1135,6 +1137,9 @@ void sbi_pmu_exit(struct sbi_scratch *scratch)
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10)
csr_write(CSR_MCOUNTEREN, -1);

if (sbi_platform_force_emulate_time_csr(sbi_platform_thishart_ptr()))
csr_clear(CSR_MCOUNTEREN, MCOUNTEREN_TM);

if (unlikely(!phs))
return;

Expand Down
28 changes: 28 additions & 0 deletions lib/sbi/sbi_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ static void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo)

sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_VVMA_RCVD);

if (sbi_platform_local_hfence_vvma(
sbi_platform_thishart_ptr(), tinfo) == SBI_OK)
return;

hgatp = csr_swap(CSR_HGATP,
(vmid << HGATP_VMID_SHIFT) & HGATP_VMID_MASK);

Expand All @@ -67,6 +71,10 @@ static void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)

sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_GVMA_RCVD);

if (sbi_platform_local_hfence_gvma(
sbi_platform_thishart_ptr(), tinfo) == SBI_OK)
return;

if ((start == 0 && size == 0) || (size == SBI_TLB_FLUSH_ALL)) {
__sbi_hfence_gvma_all();
return;
Expand All @@ -85,6 +93,10 @@ static void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)

sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_RCVD);

if (sbi_platform_local_sfence_vma(
sbi_platform_thishart_ptr(), tinfo) == SBI_OK)
return;

if ((start == 0 && size == 0) || (size == SBI_TLB_FLUSH_ALL)) {
__sbi_sfence_vma_all();
return;
Expand All @@ -108,6 +120,10 @@ static void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo)

sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_VVMA_ASID_RCVD);

if (sbi_platform_local_hfence_vvma_asid(
sbi_platform_thishart_ptr(), tinfo) == SBI_OK)
return;

hgatp = csr_swap(CSR_HGATP,
(vmid << HGATP_VMID_SHIFT) & HGATP_VMID_MASK);

Expand All @@ -133,6 +149,10 @@ static void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)

sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_GVMA_VMID_RCVD);

if (sbi_platform_local_hfence_gvma_vmid(
sbi_platform_thishart_ptr(), tinfo) == SBI_OK)
return;

if ((start == 0 && size == 0) || (size == SBI_TLB_FLUSH_ALL)) {
__sbi_hfence_gvma_vmid(vmid);
return;
Expand All @@ -152,6 +172,10 @@ static void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)

sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_ASID_RCVD);

if (sbi_platform_local_sfence_vma_asid(
sbi_platform_thishart_ptr(), tinfo) == SBI_OK)
return;

/* Flush entire MM context for a given ASID */
if ((start == 0 && size == 0) || (size == SBI_TLB_FLUSH_ALL)) {
__asm__ __volatile__("sfence.vma x0, %0"
Expand All @@ -173,6 +197,10 @@ static void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo)
{
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_FENCE_I_RECVD);

if (sbi_platform_local_fence_i(
sbi_platform_thishart_ptr(), tinfo) == SBI_OK)
return;

__asm__ __volatile("fence.i");
}

Expand Down
4 changes: 4 additions & 0 deletions lib/utils/gpio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ config FDT_GPIO_SIFIVE
bool "SiFive GPIO FDT driver"
default n

config FDT_GPIO_SOPHGO
bool "Sophgo GPIO FDT driver"
default n

config FDT_GPIO_STARFIVE
bool "StarFive GPIO FDT driver"
default n
Expand Down
Loading