forked from Imagelibrary/rtems
bsps/riscv: Add per cpu clock interrupt
- Fixes failure of test smpclock01
This commit is contained in:
@@ -155,6 +155,7 @@ typedef enum {
|
|||||||
RISCV_FATAL_INVALID_INTERRUPT_AFFINITY,
|
RISCV_FATAL_INVALID_INTERRUPT_AFFINITY,
|
||||||
RISCV_FATAL_NO_NS16550_INTERRUPTS_IN_DEVICE_TREE,
|
RISCV_FATAL_NO_NS16550_INTERRUPTS_IN_DEVICE_TREE,
|
||||||
RISCV_FATAL_NO_TLCLOCK_FREQUENCY_IN_DEVICE_TREE,
|
RISCV_FATAL_NO_TLCLOCK_FREQUENCY_IN_DEVICE_TREE,
|
||||||
|
RISCV_FATAL_CLOCK_SMP_INIT,
|
||||||
|
|
||||||
/* GRLIB fatal codes */
|
/* GRLIB fatal codes */
|
||||||
GRLIB_FATAL_CLOCK_NO_IRQMP_TIMESTAMP_SUPPORT = BSP_FATAL_CODE_BLOCK(14),
|
GRLIB_FATAL_CLOCK_NO_IRQMP_TIMESTAMP_SUPPORT = BSP_FATAL_CODE_BLOCK(14),
|
||||||
|
|||||||
@@ -92,13 +92,14 @@ static void riscv_clock_at_tick(riscv_timecounter *tc)
|
|||||||
{
|
{
|
||||||
volatile RISCV_CLINT_regs *clint;
|
volatile RISCV_CLINT_regs *clint;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
uint32_t cpu = rtems_scheduler_get_processor();
|
||||||
|
|
||||||
clint = tc->clint;
|
clint = tc->clint;
|
||||||
|
|
||||||
value = clint->mtimecmp[0].val_64;
|
value = clint->mtimecmp[cpu].val_64;
|
||||||
value += tc->interval;
|
value += tc->interval;
|
||||||
|
|
||||||
riscv_clock_write_mtimecmp(&clint->mtimecmp[0], value);
|
riscv_clock_write_mtimecmp(&clint->mtimecmp[cpu], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void riscv_clock_handler_install(void)
|
static void riscv_clock_handler_install(void)
|
||||||
@@ -148,6 +149,47 @@ static uint32_t riscv_clock_get_timebase_frequency(const void *fdt)
|
|||||||
return fdt32_to_cpu(*val);
|
return fdt32_to_cpu(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void riscv_clock_clint_init(
|
||||||
|
volatile RISCV_CLINT_regs *clint,
|
||||||
|
uint64_t cmpval,
|
||||||
|
uint32_t cpu
|
||||||
|
)
|
||||||
|
{
|
||||||
|
riscv_clock_write_mtimecmp(
|
||||||
|
&clint->mtimecmp[cpu],
|
||||||
|
cmpval
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Enable mtimer interrupts */
|
||||||
|
set_csr(mie, MIP_MTIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RTEMS_SMP) && !defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
|
||||||
|
static void riscv_clock_secondary_action(void *arg)
|
||||||
|
{
|
||||||
|
volatile RISCV_CLINT_regs *clint = riscv_clint;
|
||||||
|
uint64_t *cmpval = arg;
|
||||||
|
uint32_t cpu = _CPU_SMP_Get_current_processor();
|
||||||
|
|
||||||
|
riscv_clock_clint_init(clint, *cmpval, cpu);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void riscv_clock_secondary_initialization(
|
||||||
|
volatile RISCV_CLINT_regs *clint,
|
||||||
|
uint64_t cmpval,
|
||||||
|
uint32_t interval
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if defined(RTEMS_SMP) && !defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
|
||||||
|
_SMP_Othercast_action(riscv_clock_secondary_action, &cmpval);
|
||||||
|
|
||||||
|
if (cmpval - riscv_clock_read_mtime(&clint->mtime) >= interval) {
|
||||||
|
bsp_fatal(RISCV_FATAL_CLOCK_SMP_INIT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void riscv_clock_initialize(void)
|
static void riscv_clock_initialize(void)
|
||||||
{
|
{
|
||||||
const char *fdt;
|
const char *fdt;
|
||||||
@@ -156,6 +198,7 @@ static void riscv_clock_initialize(void)
|
|||||||
uint32_t tb_freq;
|
uint32_t tb_freq;
|
||||||
uint64_t us_per_tick;
|
uint64_t us_per_tick;
|
||||||
uint32_t interval;
|
uint32_t interval;
|
||||||
|
uint64_t cmpval;
|
||||||
|
|
||||||
fdt = bsp_fdt_get();
|
fdt = bsp_fdt_get();
|
||||||
tb_freq = riscv_clock_get_timebase_frequency(fdt);
|
tb_freq = riscv_clock_get_timebase_frequency(fdt);
|
||||||
@@ -167,13 +210,11 @@ static void riscv_clock_initialize(void)
|
|||||||
tc->clint = clint;
|
tc->clint = clint;
|
||||||
tc->interval = interval;
|
tc->interval = interval;
|
||||||
|
|
||||||
riscv_clock_write_mtimecmp(
|
cmpval = riscv_clock_read_mtime(&clint->mtime);
|
||||||
&clint->mtimecmp[0],
|
cmpval += interval;
|
||||||
riscv_clock_read_mtime(&clint->mtime) + interval
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Enable mtimer interrupts */
|
riscv_clock_clint_init(clint, cmpval, 0);
|
||||||
set_csr(mie, MIP_MTIP);
|
riscv_clock_secondary_initialization(clint, cmpval, interval);
|
||||||
|
|
||||||
/* Initialize timecounter */
|
/* Initialize timecounter */
|
||||||
tc->base.tc_get_timecount = riscv_clock_get_timecount;
|
tc->base.tc_get_timecount = riscv_clock_get_timecount;
|
||||||
@@ -213,6 +254,4 @@ RTEMS_SYSINIT_ITEM(
|
|||||||
#define Clock_driver_support_install_isr(isr) \
|
#define Clock_driver_support_install_isr(isr) \
|
||||||
riscv_clock_handler_install()
|
riscv_clock_handler_install()
|
||||||
|
|
||||||
#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR
|
|
||||||
|
|
||||||
#include "../../../shared/dev/clock/clockimpl.h"
|
#include "../../../shared/dev/clock/clockimpl.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user