From f0516beae068ffce0d5a79f09a96904a661a25ba Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 19 Apr 2023 21:27:27 +0530 Subject: [PATCH] lib: utils/timer: Use scratch space to save per-HART MTIMER pointer Instead of using a global array indexed by hartid, we should use scratch space to save per-HART MTIMER pointer. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones --- lib/utils/timer/aclint_mtimer.c | 76 ++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/lib/utils/timer/aclint_mtimer.c b/lib/utils/timer/aclint_mtimer.c index 84ded4e..13af5d8 100644 --- a/lib/utils/timer/aclint_mtimer.c +++ b/lib/utils/timer/aclint_mtimer.c @@ -13,12 +13,17 @@ #include #include #include -#include -#include +#include #include #include -static struct aclint_mtimer_data *mtimer_hartid2data[SBI_HARTMASK_MAX_BITS]; +static unsigned long mtimer_ptr_offset; + +#define mtimer_get_hart_data_ptr(__scratch) \ + sbi_scratch_read_type((__scratch), void *, mtimer_ptr_offset) + +#define mtimer_set_hart_data_ptr(__scratch, __mtimer) \ + sbi_scratch_write_type((__scratch), void *, mtimer_ptr_offset, (__mtimer)) #if __riscv_xlen != 32 static u64 mtimer_time_rd64(volatile u64 *addr) @@ -53,30 +58,54 @@ static void mtimer_time_wr32(bool timecmp, u64 value, volatile u64 *addr) static u64 mtimer_value(void) { - struct aclint_mtimer_data *mt = mtimer_hartid2data[current_hartid()]; - u64 *time_val = (void *)mt->mtime_addr; + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + struct aclint_mtimer_data *mt; + + mt = mtimer_get_hart_data_ptr(scratch); + if (!mt) + return 0; /* Read MTIMER Time Value */ - return mt->time_rd(time_val); + return mt->time_rd((void *)mt->mtime_addr); } static void mtimer_event_stop(void) { u32 target_hart = current_hartid(); - struct aclint_mtimer_data *mt = mtimer_hartid2data[target_hart]; - u64 *time_cmp = (void *)mt->mtimecmp_addr; + struct sbi_scratch *scratch; + struct aclint_mtimer_data *mt; + u64 *time_cmp; + + scratch = sbi_hartid_to_scratch(target_hart); + if (!scratch) + return; + + mt = mtimer_get_hart_data_ptr(scratch); + if (!mt) + return; /* Clear MTIMER Time Compare */ + time_cmp = (void *)mt->mtimecmp_addr; mt->time_wr(true, -1ULL, &time_cmp[target_hart - mt->first_hartid]); } static void mtimer_event_start(u64 next_event) { u32 target_hart = current_hartid(); - struct aclint_mtimer_data *mt = mtimer_hartid2data[target_hart]; - u64 *time_cmp = (void *)mt->mtimecmp_addr; + struct sbi_scratch *scratch; + struct aclint_mtimer_data *mt; + u64 *time_cmp; + + scratch = sbi_hartid_to_scratch(target_hart); + if (!scratch) + return; + + mt = mtimer_get_hart_data_ptr(scratch); + if (!mt) + return; /* Program MTIMER Time Compare */ + time_cmp = (void *)mt->mtimecmp_addr; mt->time_wr(true, next_event, &time_cmp[target_hart - mt->first_hartid]); } @@ -126,8 +155,14 @@ int aclint_mtimer_warm_init(void) { u64 *mt_time_cmp; u32 target_hart = current_hartid(); - struct aclint_mtimer_data *mt = mtimer_hartid2data[target_hart]; + struct sbi_scratch *scratch; + struct aclint_mtimer_data *mt; + scratch = sbi_hartid_to_scratch(target_hart); + if (!scratch) + return SBI_ENOENT; + + mt = mtimer_get_hart_data_ptr(scratch); if (!mt) return SBI_ENODEV; @@ -147,6 +182,7 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, { u32 i; int rc; + struct sbi_scratch *scratch; /* Sanity checks */ if (!mt || @@ -155,12 +191,18 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, (mt->mtime_size && (mt->mtime_size & (ACLINT_MTIMER_ALIGN - 1))) || (mt->mtimecmp_addr & (ACLINT_MTIMER_ALIGN - 1)) || (mt->mtimecmp_size & (ACLINT_MTIMER_ALIGN - 1)) || - (mt->first_hartid >= SBI_HARTMASK_MAX_BITS) || (mt->hart_count > ACLINT_MTIMER_MAX_HARTS)) return SBI_EINVAL; if (reference && mt->mtime_freq != reference->mtime_freq) return SBI_EINVAL; + /* Allocate scratch space pointer */ + if (!mtimer_ptr_offset) { + mtimer_ptr_offset = sbi_scratch_alloc_type_offset(void *); + if (!mtimer_ptr_offset) + return SBI_ENOMEM; + } + /* Initialize private data */ aclint_mtimer_set_reference(mt, reference); mt->time_rd = mtimer_time_rd32; @@ -174,9 +216,13 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, } #endif - /* Update MTIMER hartid table */ - for (i = 0; i < mt->hart_count; i++) - mtimer_hartid2data[mt->first_hartid + i] = mt; + /* Update MTIMER pointer in scratch space */ + for (i = 0; i < mt->hart_count; i++) { + scratch = sbi_hartid_to_scratch(mt->first_hartid + i); + if (!scratch) + return SBI_ENOENT; + mtimer_set_hart_data_ptr(scratch, mt); + } if (!mt->mtime_size) { /* Disable reading mtime when mtime is not available */