Message ID | 20210724122503.2486624-2-anup.patel@wdc.com |
---|---|
State | Superseded |
Headers | show |
Series | ACLINT MTIMER improvements | expand |
On Sat, Jul 24, 2021 at 5:25 AM Anup Patel <anup.patel@wdc.com> wrote: > > We extend the ACLINT library to support separate base addresses > for MTIME and MTIMECMP registers. > > Signed-off-by: Anup Patel <anup.patel@wdc.com> > --- > include/sbi_utils/timer/aclint_mtimer.h | 19 ++++-- > lib/utils/timer/aclint_mtimer.c | 77 +++++++++++++++++++------ > lib/utils/timer/fdt_timer_mtimer.c | 16 +++-- > platform/fpga/ariane/platform.c | 8 ++- > platform/fpga/openpiton/platform.c | 13 ++++- > platform/kendryte/k210/platform.c | 8 ++- > platform/nuclei/ux600/platform.c | 8 ++- > platform/template/platform.c | 8 ++- > 8 files changed, 116 insertions(+), 41 deletions(-) > > diff --git a/include/sbi_utils/timer/aclint_mtimer.h b/include/sbi_utils/timer/aclint_mtimer.h > index 62aa086..54eb238 100644 > --- a/include/sbi_utils/timer/aclint_mtimer.h > +++ b/include/sbi_utils/timer/aclint_mtimer.h > @@ -12,16 +12,25 @@ > > #include <sbi/sbi_types.h> > > -#define ACLINT_MTIMER_ALIGN 0x1000 > -#define ACLINT_MTIMER_SIZE 0x8000 > -#define ACLINT_MTIMER_MAX_HARTS 4095 > +#define ACLINT_MTIME_ALIGN 0x8 > +#define ACLINT_MTIMECMP_ALIGN 0x8 > +#define ACLINT_MTIMER_MAX_HARTS 4095 duplicate definition > + > +#define ACLINT_DEFAULT_MTIME_OFFSET 0x7ff8 > +#define ACLINT_DEFAULT_MTIME_SIZE 0x8 > +#define ACLINT_DEFAULT_MTIMECMP_OFFSET 0x0000 > +#define ACLINT_DEFAULT_MTIMECMP_SIZE 0x7ff8 > +#define ACLINT_DEFAULT_MTIMER_SIZE 0x8000 > +#define ACLINT_DEFAULT_MTIMER_ALIGN 0x1000 > > #define CLINT_MTIMER_OFFSET 0x4000 > > struct aclint_mtimer_data { > /* Public details */ > - unsigned long addr; > - unsigned long size; > + unsigned long mtime_addr; > + unsigned long mtime_size; > + unsigned long mtimecmp_addr; > + unsigned long mtimecmp_size; > u32 first_hartid; > u32 hart_count; > bool has_64bit_mmio; > diff --git a/lib/utils/timer/aclint_mtimer.c b/lib/utils/timer/aclint_mtimer.c > index 41b0290..ebc9300 100644 > --- a/lib/utils/timer/aclint_mtimer.c > +++ b/lib/utils/timer/aclint_mtimer.c > @@ -10,6 +10,7 @@ > #include <sbi/riscv_asm.h> > #include <sbi/riscv_atomic.h> > #include <sbi/riscv_io.h> > +#include <sbi/sbi_bitops.h> > #include <sbi/sbi_domain.h> > #include <sbi/sbi_error.h> > #include <sbi/sbi_hartmask.h> > @@ -17,9 +18,6 @@ > #include <sbi/sbi_timer.h> > #include <sbi_utils/timer/aclint_mtimer.h> > > -#define MTIMER_CMP_OFF 0x0000 > -#define MTIMER_VAL_OFF 0x7ff8 > - > static struct aclint_mtimer_data *mtimer_hartid2data[SBI_HARTMASK_MAX_BITS]; > > #if __riscv_xlen != 32 > @@ -56,7 +54,7 @@ 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->addr) + MTIMER_VAL_OFF; > + u64 *time_val = (void *)mt->mtime_addr; > > /* Read MTIMER Time Value */ > return mt->time_rd(time_val) + mt->time_delta; > @@ -66,7 +64,7 @@ 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->addr + MTIMER_CMP_OFF; > + u64 *time_cmp = (void *)mt->mtimecmp_addr; > > /* Clear MTIMER Time Compare */ > mt->time_wr(true, -1ULL, &time_cmp[target_hart - mt->first_hartid]); > @@ -76,7 +74,7 @@ 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->addr + MTIMER_CMP_OFF; > + u64 *time_cmp = (void *)mt->mtimecmp_addr; > > /* Program MTIMER Time Compare */ > mt->time_wr(true, next_event - mt->time_delta, > @@ -111,8 +109,8 @@ int aclint_mtimer_warm_init(void) > */ > if (mt->time_delta_reference) { > reference = mt->time_delta_reference; > - mt_time_val = (void *)mt->addr + MTIMER_VAL_OFF; > - ref_time_val = (void *)reference->addr + MTIMER_VAL_OFF; > + mt_time_val = (void *)mt->mtime_addr; > + ref_time_val = (void *)reference->mtime_addr; > if (!atomic_raw_xchg_ulong(&mt->time_delta_computed, 1)) { > v1 = mt->time_rd(mt_time_val); > mv = reference->time_rd(ref_time_val); > @@ -122,24 +120,53 @@ int aclint_mtimer_warm_init(void) > } > > /* Clear Time Compare */ > - mt_time_cmp = (void *)mt->addr + MTIMER_CMP_OFF; > + mt_time_cmp = (void *)mt->mtimecmp_addr; > mt->time_wr(true, -1ULL, > &mt_time_cmp[target_hart - mt->first_hartid]); > > return 0; > } > > +static int aclint_mtimer_add_regions(unsigned long addr, unsigned long size) > +{ > + int rc; > + unsigned long pos, end, rsize; > + struct sbi_domain_memregion reg; > + > + pos = addr; > + end = addr + size; > + while (pos < end) { > + rsize = pos & (ACLINT_DEFAULT_MTIMER_ALIGN - 1); > + if (rsize) > + rsize = 1UL << __ffs(pos); > + else > + rsize = ((end - pos) < ACLINT_DEFAULT_MTIMER_ALIGN) ? > + (end - pos) : ACLINT_DEFAULT_MTIMER_ALIGN; > + > + sbi_domain_memregion_init(pos, rsize, > + SBI_DOMAIN_MEMREGION_MMIO, ®); > + rc = sbi_domain_root_add_memregion(®); > + if (rc) > + return rc; > + pos += rsize; > + } > + > + return 0; > +} > + > int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, > struct aclint_mtimer_data *reference) > { > u32 i; > int rc; > - unsigned long pos, region_size; > - struct sbi_domain_memregion reg; > > /* Sanity checks */ > - if (!mt || (mt->addr & (ACLINT_MTIMER_ALIGN - 1)) || > - (mt->size < ACLINT_MTIMER_SIZE) || > + if (!mt || !mt->mtime_size || > + (mt->hart_count && !mt->mtimecmp_size) || > + (mt->mtime_addr & (ACLINT_MTIME_ALIGN - 1)) || > + (mt->mtime_size & (ACLINT_MTIME_ALIGN - 1)) || > + (mt->mtimecmp_addr & (ACLINT_MTIMECMP_ALIGN - 1)) || > + (mt->mtimecmp_size & (ACLINT_MTIMECMP_ALIGN - 1)) || > (mt->first_hartid >= SBI_HARTMASK_MAX_BITS) || > (mt->hart_count > ACLINT_MTIMER_MAX_HARTS)) > return SBI_EINVAL; > @@ -164,12 +191,24 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, > mtimer_hartid2data[mt->first_hartid + i] = mt; > > /* Add MTIMER regions to the root domain */ > - for (pos = 0; pos < mt->size; pos += ACLINT_MTIMER_ALIGN) { > - region_size = ((mt->size - pos) < ACLINT_MTIMER_ALIGN) ? > - (mt->size - pos) : ACLINT_MTIMER_ALIGN; > - sbi_domain_memregion_init(mt->addr + pos, region_size, > - SBI_DOMAIN_MEMREGION_MMIO, ®); > - rc = sbi_domain_root_add_memregion(®); > + if (mt->mtime_addr == (mt->mtimecmp_addr + mt->mtimecmp_size)) { > + rc = aclint_mtimer_add_regions(mt->mtimecmp_addr, > + mt->mtime_size + mt->mtimecmp_size); > + if (rc) > + return rc; > + } else if (mt->mtimecmp_addr == (mt->mtime_addr + mt->mtime_size)) { > + rc = aclint_mtimer_add_regions(mt->mtime_addr, > + mt->mtime_size + mt->mtimecmp_size); > + if (rc) > + return rc; > + } else { > + rc = aclint_mtimer_add_regions(mt->mtime_addr, > + mt->mtime_size); > + if (rc) > + return rc; > + > + rc = aclint_mtimer_add_regions(mt->mtimecmp_addr, > + mt->mtimecmp_size); > if (rc) > return rc; > } > diff --git a/lib/utils/timer/fdt_timer_mtimer.c b/lib/utils/timer/fdt_timer_mtimer.c > index 4907428..3f830ad 100644 > --- a/lib/utils/timer/fdt_timer_mtimer.c > +++ b/lib/utils/timer/fdt_timer_mtimer.c > @@ -22,7 +22,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, > const struct fdt_match *match) > { > int rc; > - unsigned long offset; > + unsigned long offset, addr, size; > struct aclint_mtimer_data *mt, *mtmaster = NULL; > > if (MTIMER_MAX_NR <= mtimer_count) > @@ -31,19 +31,23 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, > if (0 < mtimer_count) > mtmaster = &mtimer[0]; > > - rc = fdt_parse_aclint_node(fdt, nodeoff, true, &mt->addr, &mt->size, > + rc = fdt_parse_aclint_node(fdt, nodeoff, true, &addr, &size, > &mt->first_hartid, &mt->hart_count); > if (rc) > return rc; > mt->has_64bit_mmio = true; > > + mt->mtimecmp_addr = addr + ACLINT_DEFAULT_MTIMECMP_OFFSET; > + mt->mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE; > + mt->mtime_addr = addr + ACLINT_DEFAULT_MTIME_OFFSET; > + mt->mtime_size = size - mt->mtimecmp_size; > + > if (match->data) { > /* Adjust MTIMER address and size for CLINT device */ > offset = *((unsigned long *)match->data); > - mt->addr += offset; > - if ((mt->size - offset) < ACLINT_MTIMER_SIZE) > - return SBI_EINVAL; > - mt->size -= offset; > + mt->mtime_addr += offset; > + mt->mtimecmp_addr += offset; > + mt->mtime_size -= offset; > /* Parse additional CLINT properties */ > if (fdt_getprop(fdt, nodeoff, "clint,has-no-64bit-mmio", &rc)) > mt->has_64bit_mmio = false; > diff --git a/platform/fpga/ariane/platform.c b/platform/fpga/ariane/platform.c > index 0b47aa0..58a46c0 100644 > --- a/platform/fpga/ariane/platform.c > +++ b/platform/fpga/ariane/platform.c > @@ -44,8 +44,12 @@ static struct aclint_mswi_data mswi = { > }; > > static struct aclint_mtimer_data mtimer = { > - .addr = ARIANE_ACLINT_MTIMER_ADDR, > - .size = ACLINT_MTIMER_SIZE, > + .mtime_addr = ARIANE_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIME_OFFSET, > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > + .mtimecmp_addr = ARIANE_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > .first_hartid = 0, > .hart_count = ARIANE_HART_COUNT, > .has_64bit_mmio = TRUE, > diff --git a/platform/fpga/openpiton/platform.c b/platform/fpga/openpiton/platform.c > index 57ec21b..bcfe7eb 100644 > --- a/platform/fpga/openpiton/platform.c > +++ b/platform/fpga/openpiton/platform.c > @@ -49,8 +49,12 @@ static struct aclint_mswi_data mswi = { > }; > > static struct aclint_mtimer_data mtimer = { > - .addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR, > - .size = ACLINT_MTIMER_SIZE, > + .mtime_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIME_OFFSET, > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > + .mtimecmp_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > .first_hartid = 0, > .hart_count = OPENPITON_DEFAULT_HART_COUNT, > .has_64bit_mmio = TRUE, > @@ -82,7 +86,10 @@ static int openpiton_early_init(bool cold_boot) > rc = fdt_parse_compat_addr(fdt, &clint_addr, "riscv,clint0"); > if (!rc) { > mswi.addr = clint_addr; > - mtimer.addr = clint_addr + CLINT_MTIMER_OFFSET; > + mtimer.mtime_addr = clint_addr + CLINT_MTIMER_OFFSET + > + ACLINT_DEFAULT_MTIME_OFFSET; > + mtimer.mtimecmp_addr = clint_addr + CLINT_MTIMER_OFFSET + > + ACLINT_DEFAULT_MTIMECMP_OFFSET; > } > > return 0; > diff --git a/platform/kendryte/k210/platform.c b/platform/kendryte/k210/platform.c > index 55c4b1e..ee4c223 100644 > --- a/platform/kendryte/k210/platform.c > +++ b/platform/kendryte/k210/platform.c > @@ -42,8 +42,12 @@ static struct aclint_mswi_data mswi = { > }; > > static struct aclint_mtimer_data mtimer = { > - .addr = K210_ACLINT_MTIMER_ADDR, > - .size = ACLINT_MTIMER_SIZE, > + .mtime_addr = K210_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIME_OFFSET, > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > + .mtimecmp_addr = K210_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > .first_hartid = 0, > .hart_count = K210_HART_COUNT, > .has_64bit_mmio = TRUE, > diff --git a/platform/nuclei/ux600/platform.c b/platform/nuclei/ux600/platform.c > index 22ca4c9..ab0becc 100644 > --- a/platform/nuclei/ux600/platform.c > +++ b/platform/nuclei/ux600/platform.c > @@ -74,8 +74,12 @@ static struct aclint_mswi_data mswi = { > }; > > static struct aclint_mtimer_data mtimer = { > - .addr = UX600_ACLINT_MTIMER_ADDR, > - .size = ACLINT_MTIMER_SIZE, > + .mtime_addr = UX600_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIME_OFFSET, > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > + .mtimecmp_addr = UX600_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > .first_hartid = 0, > .hart_count = UX600_HART_COUNT, > .has_64bit_mmio = TRUE, > diff --git a/platform/template/platform.c b/platform/template/platform.c > index 3f09d98..4528822 100644 > --- a/platform/template/platform.c > +++ b/platform/template/platform.c > @@ -43,8 +43,12 @@ static struct aclint_mswi_data mswi = { > }; > > static struct aclint_mtimer_data mtimer = { > - .addr = PLATFORM_ACLINT_MTIMER_ADDR, > - .size = ACLINT_MTIMER_SIZE, > + .mtime_addr = PLATFORM_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIME_OFFSET, > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > + .mtimecmp_addr = PLATFORM_ACLINT_MTIMER_ADDR + > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > .first_hartid = 0, > .hart_count = PLATFORM_HART_COUNT, > .has_64bit_mmio = TRUE, > -- > 2.25.1 > > > -- > opensbi mailing list > opensbi@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/opensbi Reviewed-by: Atish Patra <atish.patra@wdc.com>
On Sat, Jul 24, 2021 at 8:26 PM Anup Patel <anup.patel@wdc.com> wrote: > > We extend the ACLINT library to support separate base addresses > for MTIME and MTIMECMP registers. > > Signed-off-by: Anup Patel <anup.patel@wdc.com> > --- > include/sbi_utils/timer/aclint_mtimer.h | 19 ++++-- > lib/utils/timer/aclint_mtimer.c | 77 +++++++++++++++++++------ > lib/utils/timer/fdt_timer_mtimer.c | 16 +++-- > platform/fpga/ariane/platform.c | 8 ++- > platform/fpga/openpiton/platform.c | 13 ++++- > platform/kendryte/k210/platform.c | 8 ++- > platform/nuclei/ux600/platform.c | 8 ++- > platform/template/platform.c | 8 ++- > 8 files changed, 116 insertions(+), 41 deletions(-) > > diff --git a/include/sbi_utils/timer/aclint_mtimer.h b/include/sbi_utils/timer/aclint_mtimer.h > index 62aa086..54eb238 100644 > --- a/include/sbi_utils/timer/aclint_mtimer.h > +++ b/include/sbi_utils/timer/aclint_mtimer.h > @@ -12,16 +12,25 @@ > > #include <sbi/sbi_types.h> > > -#define ACLINT_MTIMER_ALIGN 0x1000 > -#define ACLINT_MTIMER_SIZE 0x8000 > -#define ACLINT_MTIMER_MAX_HARTS 4095 > +#define ACLINT_MTIME_ALIGN 0x8 > +#define ACLINT_MTIMECMP_ALIGN 0x8 > +#define ACLINT_MTIMER_MAX_HARTS 4095 > + > +#define ACLINT_DEFAULT_MTIME_OFFSET 0x7ff8 > +#define ACLINT_DEFAULT_MTIME_SIZE 0x8 > +#define ACLINT_DEFAULT_MTIMECMP_OFFSET 0x0000 > +#define ACLINT_DEFAULT_MTIMECMP_SIZE 0x7ff8 > +#define ACLINT_DEFAULT_MTIMER_SIZE 0x8000 > +#define ACLINT_DEFAULT_MTIMER_ALIGN 0x1000 It is confusing to have some macros be defined as MTIME while some others with MTIMER. Can we keep them consistent? > > #define CLINT_MTIMER_OFFSET 0x4000 > > struct aclint_mtimer_data { > /* Public details */ > - unsigned long addr; > - unsigned long size; > + unsigned long mtime_addr; > + unsigned long mtime_size; > + unsigned long mtimecmp_addr; > + unsigned long mtimecmp_size; > u32 first_hartid; > u32 hart_count; > bool has_64bit_mmio; [snip] Regards, Bin
On Tue, Aug 3, 2021 at 1:08 AM Atish Patra <atishp@atishpatra.org> wrote: > > On Sat, Jul 24, 2021 at 5:25 AM Anup Patel <anup.patel@wdc.com> wrote: > > > > We extend the ACLINT library to support separate base addresses > > for MTIME and MTIMECMP registers. > > > > Signed-off-by: Anup Patel <anup.patel@wdc.com> > > --- > > include/sbi_utils/timer/aclint_mtimer.h | 19 ++++-- > > lib/utils/timer/aclint_mtimer.c | 77 +++++++++++++++++++------ > > lib/utils/timer/fdt_timer_mtimer.c | 16 +++-- > > platform/fpga/ariane/platform.c | 8 ++- > > platform/fpga/openpiton/platform.c | 13 ++++- > > platform/kendryte/k210/platform.c | 8 ++- > > platform/nuclei/ux600/platform.c | 8 ++- > > platform/template/platform.c | 8 ++- > > 8 files changed, 116 insertions(+), 41 deletions(-) > > > > diff --git a/include/sbi_utils/timer/aclint_mtimer.h b/include/sbi_utils/timer/aclint_mtimer.h > > index 62aa086..54eb238 100644 > > --- a/include/sbi_utils/timer/aclint_mtimer.h > > +++ b/include/sbi_utils/timer/aclint_mtimer.h > > @@ -12,16 +12,25 @@ > > > > #include <sbi/sbi_types.h> > > > > -#define ACLINT_MTIMER_ALIGN 0x1000 > > -#define ACLINT_MTIMER_SIZE 0x8000 > > -#define ACLINT_MTIMER_MAX_HARTS 4095 > > +#define ACLINT_MTIME_ALIGN 0x8 > > +#define ACLINT_MTIMECMP_ALIGN 0x8 > > +#define ACLINT_MTIMER_MAX_HARTS 4095 > > duplicate definition Okay, will drop duplicate defines. > > > + > > +#define ACLINT_DEFAULT_MTIME_OFFSET 0x7ff8 > > +#define ACLINT_DEFAULT_MTIME_SIZE 0x8 > > +#define ACLINT_DEFAULT_MTIMECMP_OFFSET 0x0000 > > +#define ACLINT_DEFAULT_MTIMECMP_SIZE 0x7ff8 > > +#define ACLINT_DEFAULT_MTIMER_SIZE 0x8000 > > +#define ACLINT_DEFAULT_MTIMER_ALIGN 0x1000 > > > > #define CLINT_MTIMER_OFFSET 0x4000 > > > > struct aclint_mtimer_data { > > /* Public details */ > > - unsigned long addr; > > - unsigned long size; > > + unsigned long mtime_addr; > > + unsigned long mtime_size; > > + unsigned long mtimecmp_addr; > > + unsigned long mtimecmp_size; > > u32 first_hartid; > > u32 hart_count; > > bool has_64bit_mmio; > > diff --git a/lib/utils/timer/aclint_mtimer.c b/lib/utils/timer/aclint_mtimer.c > > index 41b0290..ebc9300 100644 > > --- a/lib/utils/timer/aclint_mtimer.c > > +++ b/lib/utils/timer/aclint_mtimer.c > > @@ -10,6 +10,7 @@ > > #include <sbi/riscv_asm.h> > > #include <sbi/riscv_atomic.h> > > #include <sbi/riscv_io.h> > > +#include <sbi/sbi_bitops.h> > > #include <sbi/sbi_domain.h> > > #include <sbi/sbi_error.h> > > #include <sbi/sbi_hartmask.h> > > @@ -17,9 +18,6 @@ > > #include <sbi/sbi_timer.h> > > #include <sbi_utils/timer/aclint_mtimer.h> > > > > -#define MTIMER_CMP_OFF 0x0000 > > -#define MTIMER_VAL_OFF 0x7ff8 > > - > > static struct aclint_mtimer_data *mtimer_hartid2data[SBI_HARTMASK_MAX_BITS]; > > > > #if __riscv_xlen != 32 > > @@ -56,7 +54,7 @@ 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->addr) + MTIMER_VAL_OFF; > > + u64 *time_val = (void *)mt->mtime_addr; > > > > /* Read MTIMER Time Value */ > > return mt->time_rd(time_val) + mt->time_delta; > > @@ -66,7 +64,7 @@ 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->addr + MTIMER_CMP_OFF; > > + u64 *time_cmp = (void *)mt->mtimecmp_addr; > > > > /* Clear MTIMER Time Compare */ > > mt->time_wr(true, -1ULL, &time_cmp[target_hart - mt->first_hartid]); > > @@ -76,7 +74,7 @@ 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->addr + MTIMER_CMP_OFF; > > + u64 *time_cmp = (void *)mt->mtimecmp_addr; > > > > /* Program MTIMER Time Compare */ > > mt->time_wr(true, next_event - mt->time_delta, > > @@ -111,8 +109,8 @@ int aclint_mtimer_warm_init(void) > > */ > > if (mt->time_delta_reference) { > > reference = mt->time_delta_reference; > > - mt_time_val = (void *)mt->addr + MTIMER_VAL_OFF; > > - ref_time_val = (void *)reference->addr + MTIMER_VAL_OFF; > > + mt_time_val = (void *)mt->mtime_addr; > > + ref_time_val = (void *)reference->mtime_addr; > > if (!atomic_raw_xchg_ulong(&mt->time_delta_computed, 1)) { > > v1 = mt->time_rd(mt_time_val); > > mv = reference->time_rd(ref_time_val); > > @@ -122,24 +120,53 @@ int aclint_mtimer_warm_init(void) > > } > > > > /* Clear Time Compare */ > > - mt_time_cmp = (void *)mt->addr + MTIMER_CMP_OFF; > > + mt_time_cmp = (void *)mt->mtimecmp_addr; > > mt->time_wr(true, -1ULL, > > &mt_time_cmp[target_hart - mt->first_hartid]); > > > > return 0; > > } > > > > +static int aclint_mtimer_add_regions(unsigned long addr, unsigned long size) > > +{ > > + int rc; > > + unsigned long pos, end, rsize; > > + struct sbi_domain_memregion reg; > > + > > + pos = addr; > > + end = addr + size; > > + while (pos < end) { > > + rsize = pos & (ACLINT_DEFAULT_MTIMER_ALIGN - 1); > > + if (rsize) > > + rsize = 1UL << __ffs(pos); > > + else > > + rsize = ((end - pos) < ACLINT_DEFAULT_MTIMER_ALIGN) ? > > + (end - pos) : ACLINT_DEFAULT_MTIMER_ALIGN; > > + > > + sbi_domain_memregion_init(pos, rsize, > > + SBI_DOMAIN_MEMREGION_MMIO, ®); > > + rc = sbi_domain_root_add_memregion(®); > > + if (rc) > > + return rc; > > + pos += rsize; > > + } > > + > > + return 0; > > +} > > + > > int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, > > struct aclint_mtimer_data *reference) > > { > > u32 i; > > int rc; > > - unsigned long pos, region_size; > > - struct sbi_domain_memregion reg; > > > > /* Sanity checks */ > > - if (!mt || (mt->addr & (ACLINT_MTIMER_ALIGN - 1)) || > > - (mt->size < ACLINT_MTIMER_SIZE) || > > + if (!mt || !mt->mtime_size || > > + (mt->hart_count && !mt->mtimecmp_size) || > > + (mt->mtime_addr & (ACLINT_MTIME_ALIGN - 1)) || > > + (mt->mtime_size & (ACLINT_MTIME_ALIGN - 1)) || > > + (mt->mtimecmp_addr & (ACLINT_MTIMECMP_ALIGN - 1)) || > > + (mt->mtimecmp_size & (ACLINT_MTIMECMP_ALIGN - 1)) || > > (mt->first_hartid >= SBI_HARTMASK_MAX_BITS) || > > (mt->hart_count > ACLINT_MTIMER_MAX_HARTS)) > > return SBI_EINVAL; > > @@ -164,12 +191,24 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, > > mtimer_hartid2data[mt->first_hartid + i] = mt; > > > > /* Add MTIMER regions to the root domain */ > > - for (pos = 0; pos < mt->size; pos += ACLINT_MTIMER_ALIGN) { > > - region_size = ((mt->size - pos) < ACLINT_MTIMER_ALIGN) ? > > - (mt->size - pos) : ACLINT_MTIMER_ALIGN; > > - sbi_domain_memregion_init(mt->addr + pos, region_size, > > - SBI_DOMAIN_MEMREGION_MMIO, ®); > > - rc = sbi_domain_root_add_memregion(®); > > + if (mt->mtime_addr == (mt->mtimecmp_addr + mt->mtimecmp_size)) { > > + rc = aclint_mtimer_add_regions(mt->mtimecmp_addr, > > + mt->mtime_size + mt->mtimecmp_size); > > + if (rc) > > + return rc; > > + } else if (mt->mtimecmp_addr == (mt->mtime_addr + mt->mtime_size)) { > > + rc = aclint_mtimer_add_regions(mt->mtime_addr, > > + mt->mtime_size + mt->mtimecmp_size); > > + if (rc) > > + return rc; > > + } else { > > + rc = aclint_mtimer_add_regions(mt->mtime_addr, > > + mt->mtime_size); > > + if (rc) > > + return rc; > > + > > + rc = aclint_mtimer_add_regions(mt->mtimecmp_addr, > > + mt->mtimecmp_size); > > if (rc) > > return rc; > > } > > diff --git a/lib/utils/timer/fdt_timer_mtimer.c b/lib/utils/timer/fdt_timer_mtimer.c > > index 4907428..3f830ad 100644 > > --- a/lib/utils/timer/fdt_timer_mtimer.c > > +++ b/lib/utils/timer/fdt_timer_mtimer.c > > @@ -22,7 +22,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, > > const struct fdt_match *match) > > { > > int rc; > > - unsigned long offset; > > + unsigned long offset, addr, size; > > struct aclint_mtimer_data *mt, *mtmaster = NULL; > > > > if (MTIMER_MAX_NR <= mtimer_count) > > @@ -31,19 +31,23 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, > > if (0 < mtimer_count) > > mtmaster = &mtimer[0]; > > > > - rc = fdt_parse_aclint_node(fdt, nodeoff, true, &mt->addr, &mt->size, > > + rc = fdt_parse_aclint_node(fdt, nodeoff, true, &addr, &size, > > &mt->first_hartid, &mt->hart_count); > > if (rc) > > return rc; > > mt->has_64bit_mmio = true; > > > > + mt->mtimecmp_addr = addr + ACLINT_DEFAULT_MTIMECMP_OFFSET; > > + mt->mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE; > > + mt->mtime_addr = addr + ACLINT_DEFAULT_MTIME_OFFSET; > > + mt->mtime_size = size - mt->mtimecmp_size; > > + > > if (match->data) { > > /* Adjust MTIMER address and size for CLINT device */ > > offset = *((unsigned long *)match->data); > > - mt->addr += offset; > > - if ((mt->size - offset) < ACLINT_MTIMER_SIZE) > > - return SBI_EINVAL; > > - mt->size -= offset; > > + mt->mtime_addr += offset; > > + mt->mtimecmp_addr += offset; > > + mt->mtime_size -= offset; > > /* Parse additional CLINT properties */ > > if (fdt_getprop(fdt, nodeoff, "clint,has-no-64bit-mmio", &rc)) > > mt->has_64bit_mmio = false; > > diff --git a/platform/fpga/ariane/platform.c b/platform/fpga/ariane/platform.c > > index 0b47aa0..58a46c0 100644 > > --- a/platform/fpga/ariane/platform.c > > +++ b/platform/fpga/ariane/platform.c > > @@ -44,8 +44,12 @@ static struct aclint_mswi_data mswi = { > > }; > > > > static struct aclint_mtimer_data mtimer = { > > - .addr = ARIANE_ACLINT_MTIMER_ADDR, > > - .size = ACLINT_MTIMER_SIZE, > > + .mtime_addr = ARIANE_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIME_OFFSET, > > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > > + .mtimecmp_addr = ARIANE_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > > .first_hartid = 0, > > .hart_count = ARIANE_HART_COUNT, > > .has_64bit_mmio = TRUE, > > diff --git a/platform/fpga/openpiton/platform.c b/platform/fpga/openpiton/platform.c > > index 57ec21b..bcfe7eb 100644 > > --- a/platform/fpga/openpiton/platform.c > > +++ b/platform/fpga/openpiton/platform.c > > @@ -49,8 +49,12 @@ static struct aclint_mswi_data mswi = { > > }; > > > > static struct aclint_mtimer_data mtimer = { > > - .addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR, > > - .size = ACLINT_MTIMER_SIZE, > > + .mtime_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIME_OFFSET, > > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > > + .mtimecmp_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > > .first_hartid = 0, > > .hart_count = OPENPITON_DEFAULT_HART_COUNT, > > .has_64bit_mmio = TRUE, > > @@ -82,7 +86,10 @@ static int openpiton_early_init(bool cold_boot) > > rc = fdt_parse_compat_addr(fdt, &clint_addr, "riscv,clint0"); > > if (!rc) { > > mswi.addr = clint_addr; > > - mtimer.addr = clint_addr + CLINT_MTIMER_OFFSET; > > + mtimer.mtime_addr = clint_addr + CLINT_MTIMER_OFFSET + > > + ACLINT_DEFAULT_MTIME_OFFSET; > > + mtimer.mtimecmp_addr = clint_addr + CLINT_MTIMER_OFFSET + > > + ACLINT_DEFAULT_MTIMECMP_OFFSET; > > } > > > > return 0; > > diff --git a/platform/kendryte/k210/platform.c b/platform/kendryte/k210/platform.c > > index 55c4b1e..ee4c223 100644 > > --- a/platform/kendryte/k210/platform.c > > +++ b/platform/kendryte/k210/platform.c > > @@ -42,8 +42,12 @@ static struct aclint_mswi_data mswi = { > > }; > > > > static struct aclint_mtimer_data mtimer = { > > - .addr = K210_ACLINT_MTIMER_ADDR, > > - .size = ACLINT_MTIMER_SIZE, > > + .mtime_addr = K210_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIME_OFFSET, > > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > > + .mtimecmp_addr = K210_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > > .first_hartid = 0, > > .hart_count = K210_HART_COUNT, > > .has_64bit_mmio = TRUE, > > diff --git a/platform/nuclei/ux600/platform.c b/platform/nuclei/ux600/platform.c > > index 22ca4c9..ab0becc 100644 > > --- a/platform/nuclei/ux600/platform.c > > +++ b/platform/nuclei/ux600/platform.c > > @@ -74,8 +74,12 @@ static struct aclint_mswi_data mswi = { > > }; > > > > static struct aclint_mtimer_data mtimer = { > > - .addr = UX600_ACLINT_MTIMER_ADDR, > > - .size = ACLINT_MTIMER_SIZE, > > + .mtime_addr = UX600_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIME_OFFSET, > > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > > + .mtimecmp_addr = UX600_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > > .first_hartid = 0, > > .hart_count = UX600_HART_COUNT, > > .has_64bit_mmio = TRUE, > > diff --git a/platform/template/platform.c b/platform/template/platform.c > > index 3f09d98..4528822 100644 > > --- a/platform/template/platform.c > > +++ b/platform/template/platform.c > > @@ -43,8 +43,12 @@ static struct aclint_mswi_data mswi = { > > }; > > > > static struct aclint_mtimer_data mtimer = { > > - .addr = PLATFORM_ACLINT_MTIMER_ADDR, > > - .size = ACLINT_MTIMER_SIZE, > > + .mtime_addr = PLATFORM_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIME_OFFSET, > > + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, > > + .mtimecmp_addr = PLATFORM_ACLINT_MTIMER_ADDR + > > + ACLINT_DEFAULT_MTIMECMP_OFFSET, > > + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, > > .first_hartid = 0, > > .hart_count = PLATFORM_HART_COUNT, > > .has_64bit_mmio = TRUE, > > -- > > 2.25.1 > > > > > > -- > > opensbi mailing list > > opensbi@lists.infradead.org > > http://lists.infradead.org/mailman/listinfo/opensbi > > > Reviewed-by: Atish Patra <atish.patra@wdc.com> > > -- > Regards, > Atish
On Thu, Aug 5, 2021 at 11:59 AM Bin Meng <bmeng.cn@gmail.com> wrote: > > On Sat, Jul 24, 2021 at 8:26 PM Anup Patel <anup.patel@wdc.com> wrote: > > > > We extend the ACLINT library to support separate base addresses > > for MTIME and MTIMECMP registers. > > > > Signed-off-by: Anup Patel <anup.patel@wdc.com> > > --- > > include/sbi_utils/timer/aclint_mtimer.h | 19 ++++-- > > lib/utils/timer/aclint_mtimer.c | 77 +++++++++++++++++++------ > > lib/utils/timer/fdt_timer_mtimer.c | 16 +++-- > > platform/fpga/ariane/platform.c | 8 ++- > > platform/fpga/openpiton/platform.c | 13 ++++- > > platform/kendryte/k210/platform.c | 8 ++- > > platform/nuclei/ux600/platform.c | 8 ++- > > platform/template/platform.c | 8 ++- > > 8 files changed, 116 insertions(+), 41 deletions(-) > > > > diff --git a/include/sbi_utils/timer/aclint_mtimer.h b/include/sbi_utils/timer/aclint_mtimer.h > > index 62aa086..54eb238 100644 > > --- a/include/sbi_utils/timer/aclint_mtimer.h > > +++ b/include/sbi_utils/timer/aclint_mtimer.h > > @@ -12,16 +12,25 @@ > > > > #include <sbi/sbi_types.h> > > > > -#define ACLINT_MTIMER_ALIGN 0x1000 > > -#define ACLINT_MTIMER_SIZE 0x8000 > > -#define ACLINT_MTIMER_MAX_HARTS 4095 > > +#define ACLINT_MTIME_ALIGN 0x8 > > +#define ACLINT_MTIMECMP_ALIGN 0x8 > > +#define ACLINT_MTIMER_MAX_HARTS 4095 > > + > > +#define ACLINT_DEFAULT_MTIME_OFFSET 0x7ff8 > > +#define ACLINT_DEFAULT_MTIME_SIZE 0x8 > > +#define ACLINT_DEFAULT_MTIMECMP_OFFSET 0x0000 > > +#define ACLINT_DEFAULT_MTIMECMP_SIZE 0x7ff8 > > +#define ACLINT_DEFAULT_MTIMER_SIZE 0x8000 > > +#define ACLINT_DEFAULT_MTIMER_ALIGN 0x1000 > > It is confusing to have some macros be defined as MTIME while some > others with MTIMER. Can we keep them consistent? Okay, let me try to simplify this. Regards, Anup > > > > > #define CLINT_MTIMER_OFFSET 0x4000 > > > > struct aclint_mtimer_data { > > /* Public details */ > > - unsigned long addr; > > - unsigned long size; > > + unsigned long mtime_addr; > > + unsigned long mtime_size; > > + unsigned long mtimecmp_addr; > > + unsigned long mtimecmp_size; > > u32 first_hartid; > > u32 hart_count; > > bool has_64bit_mmio; > > [snip] > > Regards, > Bin
diff --git a/include/sbi_utils/timer/aclint_mtimer.h b/include/sbi_utils/timer/aclint_mtimer.h index 62aa086..54eb238 100644 --- a/include/sbi_utils/timer/aclint_mtimer.h +++ b/include/sbi_utils/timer/aclint_mtimer.h @@ -12,16 +12,25 @@ #include <sbi/sbi_types.h> -#define ACLINT_MTIMER_ALIGN 0x1000 -#define ACLINT_MTIMER_SIZE 0x8000 -#define ACLINT_MTIMER_MAX_HARTS 4095 +#define ACLINT_MTIME_ALIGN 0x8 +#define ACLINT_MTIMECMP_ALIGN 0x8 +#define ACLINT_MTIMER_MAX_HARTS 4095 + +#define ACLINT_DEFAULT_MTIME_OFFSET 0x7ff8 +#define ACLINT_DEFAULT_MTIME_SIZE 0x8 +#define ACLINT_DEFAULT_MTIMECMP_OFFSET 0x0000 +#define ACLINT_DEFAULT_MTIMECMP_SIZE 0x7ff8 +#define ACLINT_DEFAULT_MTIMER_SIZE 0x8000 +#define ACLINT_DEFAULT_MTIMER_ALIGN 0x1000 #define CLINT_MTIMER_OFFSET 0x4000 struct aclint_mtimer_data { /* Public details */ - unsigned long addr; - unsigned long size; + unsigned long mtime_addr; + unsigned long mtime_size; + unsigned long mtimecmp_addr; + unsigned long mtimecmp_size; u32 first_hartid; u32 hart_count; bool has_64bit_mmio; diff --git a/lib/utils/timer/aclint_mtimer.c b/lib/utils/timer/aclint_mtimer.c index 41b0290..ebc9300 100644 --- a/lib/utils/timer/aclint_mtimer.c +++ b/lib/utils/timer/aclint_mtimer.c @@ -10,6 +10,7 @@ #include <sbi/riscv_asm.h> #include <sbi/riscv_atomic.h> #include <sbi/riscv_io.h> +#include <sbi/sbi_bitops.h> #include <sbi/sbi_domain.h> #include <sbi/sbi_error.h> #include <sbi/sbi_hartmask.h> @@ -17,9 +18,6 @@ #include <sbi/sbi_timer.h> #include <sbi_utils/timer/aclint_mtimer.h> -#define MTIMER_CMP_OFF 0x0000 -#define MTIMER_VAL_OFF 0x7ff8 - static struct aclint_mtimer_data *mtimer_hartid2data[SBI_HARTMASK_MAX_BITS]; #if __riscv_xlen != 32 @@ -56,7 +54,7 @@ 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->addr) + MTIMER_VAL_OFF; + u64 *time_val = (void *)mt->mtime_addr; /* Read MTIMER Time Value */ return mt->time_rd(time_val) + mt->time_delta; @@ -66,7 +64,7 @@ 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->addr + MTIMER_CMP_OFF; + u64 *time_cmp = (void *)mt->mtimecmp_addr; /* Clear MTIMER Time Compare */ mt->time_wr(true, -1ULL, &time_cmp[target_hart - mt->first_hartid]); @@ -76,7 +74,7 @@ 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->addr + MTIMER_CMP_OFF; + u64 *time_cmp = (void *)mt->mtimecmp_addr; /* Program MTIMER Time Compare */ mt->time_wr(true, next_event - mt->time_delta, @@ -111,8 +109,8 @@ int aclint_mtimer_warm_init(void) */ if (mt->time_delta_reference) { reference = mt->time_delta_reference; - mt_time_val = (void *)mt->addr + MTIMER_VAL_OFF; - ref_time_val = (void *)reference->addr + MTIMER_VAL_OFF; + mt_time_val = (void *)mt->mtime_addr; + ref_time_val = (void *)reference->mtime_addr; if (!atomic_raw_xchg_ulong(&mt->time_delta_computed, 1)) { v1 = mt->time_rd(mt_time_val); mv = reference->time_rd(ref_time_val); @@ -122,24 +120,53 @@ int aclint_mtimer_warm_init(void) } /* Clear Time Compare */ - mt_time_cmp = (void *)mt->addr + MTIMER_CMP_OFF; + mt_time_cmp = (void *)mt->mtimecmp_addr; mt->time_wr(true, -1ULL, &mt_time_cmp[target_hart - mt->first_hartid]); return 0; } +static int aclint_mtimer_add_regions(unsigned long addr, unsigned long size) +{ + int rc; + unsigned long pos, end, rsize; + struct sbi_domain_memregion reg; + + pos = addr; + end = addr + size; + while (pos < end) { + rsize = pos & (ACLINT_DEFAULT_MTIMER_ALIGN - 1); + if (rsize) + rsize = 1UL << __ffs(pos); + else + rsize = ((end - pos) < ACLINT_DEFAULT_MTIMER_ALIGN) ? + (end - pos) : ACLINT_DEFAULT_MTIMER_ALIGN; + + sbi_domain_memregion_init(pos, rsize, + SBI_DOMAIN_MEMREGION_MMIO, ®); + rc = sbi_domain_root_add_memregion(®); + if (rc) + return rc; + pos += rsize; + } + + return 0; +} + int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, struct aclint_mtimer_data *reference) { u32 i; int rc; - unsigned long pos, region_size; - struct sbi_domain_memregion reg; /* Sanity checks */ - if (!mt || (mt->addr & (ACLINT_MTIMER_ALIGN - 1)) || - (mt->size < ACLINT_MTIMER_SIZE) || + if (!mt || !mt->mtime_size || + (mt->hart_count && !mt->mtimecmp_size) || + (mt->mtime_addr & (ACLINT_MTIME_ALIGN - 1)) || + (mt->mtime_size & (ACLINT_MTIME_ALIGN - 1)) || + (mt->mtimecmp_addr & (ACLINT_MTIMECMP_ALIGN - 1)) || + (mt->mtimecmp_size & (ACLINT_MTIMECMP_ALIGN - 1)) || (mt->first_hartid >= SBI_HARTMASK_MAX_BITS) || (mt->hart_count > ACLINT_MTIMER_MAX_HARTS)) return SBI_EINVAL; @@ -164,12 +191,24 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt, mtimer_hartid2data[mt->first_hartid + i] = mt; /* Add MTIMER regions to the root domain */ - for (pos = 0; pos < mt->size; pos += ACLINT_MTIMER_ALIGN) { - region_size = ((mt->size - pos) < ACLINT_MTIMER_ALIGN) ? - (mt->size - pos) : ACLINT_MTIMER_ALIGN; - sbi_domain_memregion_init(mt->addr + pos, region_size, - SBI_DOMAIN_MEMREGION_MMIO, ®); - rc = sbi_domain_root_add_memregion(®); + if (mt->mtime_addr == (mt->mtimecmp_addr + mt->mtimecmp_size)) { + rc = aclint_mtimer_add_regions(mt->mtimecmp_addr, + mt->mtime_size + mt->mtimecmp_size); + if (rc) + return rc; + } else if (mt->mtimecmp_addr == (mt->mtime_addr + mt->mtime_size)) { + rc = aclint_mtimer_add_regions(mt->mtime_addr, + mt->mtime_size + mt->mtimecmp_size); + if (rc) + return rc; + } else { + rc = aclint_mtimer_add_regions(mt->mtime_addr, + mt->mtime_size); + if (rc) + return rc; + + rc = aclint_mtimer_add_regions(mt->mtimecmp_addr, + mt->mtimecmp_size); if (rc) return rc; } diff --git a/lib/utils/timer/fdt_timer_mtimer.c b/lib/utils/timer/fdt_timer_mtimer.c index 4907428..3f830ad 100644 --- a/lib/utils/timer/fdt_timer_mtimer.c +++ b/lib/utils/timer/fdt_timer_mtimer.c @@ -22,7 +22,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, const struct fdt_match *match) { int rc; - unsigned long offset; + unsigned long offset, addr, size; struct aclint_mtimer_data *mt, *mtmaster = NULL; if (MTIMER_MAX_NR <= mtimer_count) @@ -31,19 +31,23 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, if (0 < mtimer_count) mtmaster = &mtimer[0]; - rc = fdt_parse_aclint_node(fdt, nodeoff, true, &mt->addr, &mt->size, + rc = fdt_parse_aclint_node(fdt, nodeoff, true, &addr, &size, &mt->first_hartid, &mt->hart_count); if (rc) return rc; mt->has_64bit_mmio = true; + mt->mtimecmp_addr = addr + ACLINT_DEFAULT_MTIMECMP_OFFSET; + mt->mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE; + mt->mtime_addr = addr + ACLINT_DEFAULT_MTIME_OFFSET; + mt->mtime_size = size - mt->mtimecmp_size; + if (match->data) { /* Adjust MTIMER address and size for CLINT device */ offset = *((unsigned long *)match->data); - mt->addr += offset; - if ((mt->size - offset) < ACLINT_MTIMER_SIZE) - return SBI_EINVAL; - mt->size -= offset; + mt->mtime_addr += offset; + mt->mtimecmp_addr += offset; + mt->mtime_size -= offset; /* Parse additional CLINT properties */ if (fdt_getprop(fdt, nodeoff, "clint,has-no-64bit-mmio", &rc)) mt->has_64bit_mmio = false; diff --git a/platform/fpga/ariane/platform.c b/platform/fpga/ariane/platform.c index 0b47aa0..58a46c0 100644 --- a/platform/fpga/ariane/platform.c +++ b/platform/fpga/ariane/platform.c @@ -44,8 +44,12 @@ static struct aclint_mswi_data mswi = { }; static struct aclint_mtimer_data mtimer = { - .addr = ARIANE_ACLINT_MTIMER_ADDR, - .size = ACLINT_MTIMER_SIZE, + .mtime_addr = ARIANE_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIME_OFFSET, + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, + .mtimecmp_addr = ARIANE_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIMECMP_OFFSET, + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, .first_hartid = 0, .hart_count = ARIANE_HART_COUNT, .has_64bit_mmio = TRUE, diff --git a/platform/fpga/openpiton/platform.c b/platform/fpga/openpiton/platform.c index 57ec21b..bcfe7eb 100644 --- a/platform/fpga/openpiton/platform.c +++ b/platform/fpga/openpiton/platform.c @@ -49,8 +49,12 @@ static struct aclint_mswi_data mswi = { }; static struct aclint_mtimer_data mtimer = { - .addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR, - .size = ACLINT_MTIMER_SIZE, + .mtime_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIME_OFFSET, + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, + .mtimecmp_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIMECMP_OFFSET, + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, .first_hartid = 0, .hart_count = OPENPITON_DEFAULT_HART_COUNT, .has_64bit_mmio = TRUE, @@ -82,7 +86,10 @@ static int openpiton_early_init(bool cold_boot) rc = fdt_parse_compat_addr(fdt, &clint_addr, "riscv,clint0"); if (!rc) { mswi.addr = clint_addr; - mtimer.addr = clint_addr + CLINT_MTIMER_OFFSET; + mtimer.mtime_addr = clint_addr + CLINT_MTIMER_OFFSET + + ACLINT_DEFAULT_MTIME_OFFSET; + mtimer.mtimecmp_addr = clint_addr + CLINT_MTIMER_OFFSET + + ACLINT_DEFAULT_MTIMECMP_OFFSET; } return 0; diff --git a/platform/kendryte/k210/platform.c b/platform/kendryte/k210/platform.c index 55c4b1e..ee4c223 100644 --- a/platform/kendryte/k210/platform.c +++ b/platform/kendryte/k210/platform.c @@ -42,8 +42,12 @@ static struct aclint_mswi_data mswi = { }; static struct aclint_mtimer_data mtimer = { - .addr = K210_ACLINT_MTIMER_ADDR, - .size = ACLINT_MTIMER_SIZE, + .mtime_addr = K210_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIME_OFFSET, + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, + .mtimecmp_addr = K210_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIMECMP_OFFSET, + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, .first_hartid = 0, .hart_count = K210_HART_COUNT, .has_64bit_mmio = TRUE, diff --git a/platform/nuclei/ux600/platform.c b/platform/nuclei/ux600/platform.c index 22ca4c9..ab0becc 100644 --- a/platform/nuclei/ux600/platform.c +++ b/platform/nuclei/ux600/platform.c @@ -74,8 +74,12 @@ static struct aclint_mswi_data mswi = { }; static struct aclint_mtimer_data mtimer = { - .addr = UX600_ACLINT_MTIMER_ADDR, - .size = ACLINT_MTIMER_SIZE, + .mtime_addr = UX600_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIME_OFFSET, + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, + .mtimecmp_addr = UX600_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIMECMP_OFFSET, + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, .first_hartid = 0, .hart_count = UX600_HART_COUNT, .has_64bit_mmio = TRUE, diff --git a/platform/template/platform.c b/platform/template/platform.c index 3f09d98..4528822 100644 --- a/platform/template/platform.c +++ b/platform/template/platform.c @@ -43,8 +43,12 @@ static struct aclint_mswi_data mswi = { }; static struct aclint_mtimer_data mtimer = { - .addr = PLATFORM_ACLINT_MTIMER_ADDR, - .size = ACLINT_MTIMER_SIZE, + .mtime_addr = PLATFORM_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIME_OFFSET, + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, + .mtimecmp_addr = PLATFORM_ACLINT_MTIMER_ADDR + + ACLINT_DEFAULT_MTIMECMP_OFFSET, + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, .first_hartid = 0, .hart_count = PLATFORM_HART_COUNT, .has_64bit_mmio = TRUE,
We extend the ACLINT library to support separate base addresses for MTIME and MTIMECMP registers. Signed-off-by: Anup Patel <anup.patel@wdc.com> --- include/sbi_utils/timer/aclint_mtimer.h | 19 ++++-- lib/utils/timer/aclint_mtimer.c | 77 +++++++++++++++++++------ lib/utils/timer/fdt_timer_mtimer.c | 16 +++-- platform/fpga/ariane/platform.c | 8 ++- platform/fpga/openpiton/platform.c | 13 ++++- platform/kendryte/k210/platform.c | 8 ++- platform/nuclei/ux600/platform.c | 8 ++- platform/template/platform.c | 8 ++- 8 files changed, 116 insertions(+), 41 deletions(-)