Skip to content

Commit

Permalink
zynq7000: adjust interrupts for SMP
Browse files Browse the repository at this point in the history
Allow interrupts to run on any core
Schedule timer interrupt in a round-robin fashion across both cores
Adjust timer to keep the current scheduling period on both cores

JIRA: RTOS-796
  • Loading branch information
jmaksymowicz committed May 10, 2024
1 parent 51bf93d commit cf271e4
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
8 changes: 5 additions & 3 deletions hal/armv7a/zynq7000/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#define SGI_FLT_OTHER_CPUS 1 /* Send SGI to all CPUs except the one that called this function */
#define SGI_FLT_THIS_CPU 2 /* Send SGI to the CPU that called this function */

#define DEFAULT_CPU_MASK 0x3


/* clang-format off */
enum {
Expand Down Expand Up @@ -132,7 +134,7 @@ static void interrupts_setConf(unsigned int irqn, u32 conf)
}


static void interrupts_setCPU(unsigned int irqn, u32 cpuID)
void _zynq_interrupts_setCPU(unsigned int irqn, u32 cpuID)
{
u32 mask;

Expand Down Expand Up @@ -166,7 +168,7 @@ int hal_interruptsSetHandler(intr_handler_t *h)
HAL_LIST_ADD(&interrupts_common.handlers[h->n], h);

interrupts_setPriority(h->n, 0xa);
interrupts_setCPU(h->n, 0x1);
_zynq_interrupts_setCPU(h->n, DEFAULT_CPU_MASK);
interrupts_enableIRQ(h->n);

hal_spinlockClear(&interrupts_common.spinlock[h->n], &sc);
Expand Down Expand Up @@ -227,7 +229,7 @@ void _hal_interruptsInit(void)
/* Set required configuration and CPU_0 as a default processor */
for (i = SPI_FIRST_IRQID; i < SIZE_INTERRUPTS; ++i) {
interrupts_setConf(i, spiConf[i - SPI_FIRST_IRQID]);
interrupts_setCPU(i, 0x1);
_zynq_interrupts_setCPU(i, DEFAULT_CPU_MASK);
}

/* SGI and PPI interrupts are fixed to always be on both CPUs */
Expand Down
17 changes: 12 additions & 5 deletions hal/armv7a/zynq7000/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "hal/spinlock.h"
#include "hal/string.h"

#include "zynq.h"

#define TIMER_SRC_CLK_CPU_1x 111111115 /* Hz */
#define TIMER_IRQ_ID 42

Expand Down Expand Up @@ -47,13 +49,18 @@ static int _timer_irqHandler(unsigned int n, cpu_context_t *ctx, void *arg)
(void)arg;
(void)ctx;

u32 st = *(timer_common.ttc + isr);

spinlock_ctx_t sc;
hal_spinlockSet(&timer_common.sp, &sc);
/* Interval IRQ */
if (st & 0x1) {
if ((*(timer_common.ttc + isr) & 1) != 0) {
timer_common.jiffies += timer_common.ticksPerFreq;
}

hal_spinlockClear(&timer_common.sp, &sc);

u32 nextID = hal_cpuGetID() + 1;
u32 nextTargetCPU = (nextID == hal_cpuGetCount()) ? 1 : (1 << nextID);
_zynq_interrupts_setCPU(n, nextTargetCPU);
hal_cpuDataSyncBarrier();

return 0;
Expand All @@ -62,7 +69,7 @@ static int _timer_irqHandler(unsigned int n, cpu_context_t *ctx, void *arg)

static time_t hal_timerCyc2Us(time_t cyc)
{
return (cyc * 1000LL) / (time_t)(timer_common.ticksPerFreq);
return (cyc * 1000LL) / (time_t)(timer_common.ticksPerFreq * hal_cpuGetCount());
}


Expand Down Expand Up @@ -167,7 +174,7 @@ void _hal_timerInit(u32 interval)
/* Reset counters and restart counting */
*(timer_common.ttc + cnt_ctrl) = 0x10;

hal_timerSetPrescaler(interval);
hal_timerSetPrescaler(interval * hal_cpuGetCount());

hal_spinlockCreate(&timer_common.sp, "timer");
timer_common.handler.f = _timer_irqHandler;
Expand Down
3 changes: 3 additions & 0 deletions hal/armv7a/zynq7000/zynq.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ extern int _zynq_setMIO(unsigned int pin, char disableRcvr, char pullup, char io
extern int _zynq_setAmbaClk(u32 dev, u32 state);


extern void _zynq_interrupts_setCPU(unsigned int irqn, u32 cpuID);


#endif

0 comments on commit cf271e4

Please sign in to comment.