sched: rework irq pend requests

pull/1/head
Felix Kopp 4 years ago
parent 523f6f4bb2
commit 55ee84b99b
No known key found for this signature in database
GPG Key ID: C478BA0A85F75728

@ -6,12 +6,33 @@
void arch_irq_enable(enum irqno irqno)
{
REG_NVIC_ISER((uint32_t)irqno >> 5) = 1 << ( ((uint32_t)irqno) & 0x1F );
if (irqno >= 0)
REG_NVIC_ISER((uint32_t)irqno >> 5) = 1 << ( ((uint32_t)irqno) & 0x1F );
}
void arch_irq_disable(enum irqno irqno)
{
REG_NVIC_ICER((uint32_t)irqno >> 5) = 1 << ( ((uint32_t)irqno) & 0x1F );
if (irqno >= 0)
REG_NVIC_ICER((uint32_t)irqno >> 5) = 1 << ( ((uint32_t)irqno) & 0x1F );
}
void arch_irq_invoke(enum irqno irqno)
{
if (irqno < 0) {
switch (irqno) {
case IRQNO_PEND_SV:
REG_SCB_ICSR = REG_SCB_ICSR_PENDSVSET_BIT;
break;
case IRQNO_SYS_TICK:
REG_SCB_ICSR = REG_SCB_ICSR_PENDSTSET_BIT;
break;
/* TODO: Implement the rest of interrupts < 0 */
}
} else {
REG_NVIC_ISPR((uint32_t)irqno >> 5) = 1 << ( ((uint32_t)irqno) & 0x1F );
}
}
/*

@ -11,30 +11,13 @@
#include <stdbool.h>
#include <toolchain.h>
/**
* Set the PENDSV bit in the system control block.
*/
static __always_inline void sched_pendsv_req(void)
{
REG_SCB_ICSR |= REG_SCB_ICSR_PENDSVSET_BIT;
}
void irq_sys_tick(void)
{
/*
* fire a PendSV interrupt and do the actual context switching there
* because it is faster that way (according to the docs, at least)
*/
sched_pendsv_req();
}
void sched_init_process_regs(struct reg_snapshot *reg_snap, int (*entry)(void))
{
memset(reg_snap, 0, sizeof(*reg_snap));
reg_snap->hw.lr = (void *)0xFFFFFFF9U;
reg_snap->hw.pc = entry;
reg_snap->hw.psr = 0x01000000U;
arch_irq_invoke(IRQNO_PEND_SV);
}
/**
@ -79,13 +62,14 @@ void arch_sched_process_init(struct process *process, void (*entry)(void))
process->sp = regs;
memset(regs, 0, sizeof(*regs));
regs->hw.pc = (void *)((uint32_t)entry | 1U); /* thumb instruction set flag */
regs->hw.pc = entry;
}
void sched_exec_early(void)
void sched_switch_early(enum proc_state state)
{
REG_SYSTICK_VAL = 0U; /* Reset timer */
sched_pendsv_req();
_current_process->state = state;
arch_irq_invoke(IRQNO_PEND_SV);
}
/*

@ -167,6 +167,8 @@ void arch_irq_enable(enum irqno irqno);
void arch_irq_disable(enum irqno irqno);
void arch_irq_invoke(enum irqno irqno);
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>
*

Loading…
Cancel
Save