16#pragma GCC diagnostic push
17#pragma GCC diagnostic ignored "-Wpmf-conversions"
20#include "task_rp2350.h"
21#include "multicore_rp2350.h"
23#include "system_rp2350.h"
24#include "yahal_config.h"
29using namespace _TIMER0_;
33bool multitasking_on_core[NUMBER_OF_CORES] {
false};
36void task::_setup_stack(
bool priv) {
39 _stack_ptr = _stack_base +
43 frame->crsr.psr = 0x01000000;
44 frame->crsr.pc = (void (*)(void))(&task::_run);
45 frame->crsr.r0 =
this;
46 frame->cesr.exc_return = EXC_RETURN_THREAD_PSP_NOFP;
47 frame->cesr.ctrl = CONTROL_SPSEL_PSP |
48 (priv ? CONTROL_PRIV : CONTROL_NOT_PRIV);
51void task::_context_switch() {
53 PPB.ICSR.PENDSVSET = 1;
56uint64_t task::millis() {
57 uint32_t lo = TIMER0.TIMELR;
58 uint32_t hi = TIMER0.TIMEHR;
59 return (((uint64_t)hi << 32l) | lo) / timer_ticks_per_us / 1000;
62bool task::is_irq_context() {
66bool task::multitasking_running() {
67 return multitasking_on_core[SIO.CPUID];
70int8_t task::get_core() {
74void task::start_scheduler() {
75 assert(!multitasking_running());
76 sys_call(SYS_START_SCHEDULER);
80 if(multitasking_running()) {
85void task::cpu_sleep() {
89void task::enterCritical() {
90 NVIC_DisableIRQ(PendSV_IRQn);
96void task::leaveCritical() {
97 NVIC_EnableIRQ(PendSV_IRQn);
102bool task::isPrivileged()
const {
104 if (_run_ptr[_core] ==
this) {
112bool task::isUsingFloat()
const {
114 if (_run_ptr[_core] ==
this) {
129 task::_tick_handler();
132uint8_t * switch_context(uint8_t * last_sp) {
133 task::_setStackPtr(last_sp);
134#ifdef CHECK_STACK_OVERFLOW
135 assert((last_sp - task::_getStackBase()) > 10);
137 task::_switchToNext();
138 return task::_getStackPtr();
143 " mrs r0, psp @ get the current SP \n"
144 " tst lr, #0x10 @ EXC_RETURN_INT_ONLY_STACK_FRAME \n"
146 " vstmdbeq r0!, {s16-s31} @ push additional FP registers \n"
148 " mrs r3, control @ \n"
149 " stmdb r0!, {r2-r11} @ save lr, control, r4-r11 \n"
150 " bl switch_context @ \n"
151 " ldmia r0!, {r2-r11} @ get lr, control, r4-r11 \n"
153 " msr control, r3 @ \n"
154 " isb @ arch recommendation \n"
155 " tst lr, #0x10 @ EXC_RETURN_INT_ONLY_STACK_FRAME \n"
157 " vldmiaeq r0!, {s16-s31} @ pop additional FP registers \n"
159 " bx lr @ jump to new task \n");
164 " tst lr, #4 @ EXC_RETURN_PROCESS_STACK_POINTER \n"
166 " mrseq r0, msp @ R0 (SP) will be first parameter \n"
167 " mrsne r0, psp @ of SCV_Handler_C, \n"
168 " tst lr, 0x20 @ EXC_RETURN_NORMAL_CALLEE_STACKING \n"
170 " addeq r0, #40 @ skip additional context if existing \n"
171 " mov r1, lr @ R1 (LR) is second parameter \n"
172 " bl SVC_Handler_C @ Call C part of SVC handler \n"
173 " bx r0 @ Use return value as EXC_RETURN \n"
177uint32_t SVC_Handler_C(uint32_t * sp, uint32_t exc_return) {
180 auto * pc = (uint16_t *)sp[6];
182 uint16_t svc_arg = pc[-1] & 0xff;
189 case SYS_START_SCHEDULER:
193 multitasking_on_core[SIO.CPUID] =
true;
199 idle_tasks[SIO.CPUID].sign_up(core_t::CURRENT_CORE, 1);
202 task::_switchToHead();
206 NVIC_SetPriority(PendSV_IRQn, 15);
207 NVIC_SetPriority(SysTick_IRQn, 15);
211 PPB.SYST_RVR = (systick_ref_freq / TICK_FREQUENCY)-1;
213 PPB.SYST_CSR.CLKSOURCE = 0;
214 PPB.SYST_CSR.TICKINT = 1;
215 PPB.SYST_CSR.ENABLE = 1;
218 exc_return = EXC_RETURN_THREAD_PSP_NOFP;
222 __set_PSP((uint32_t)(task::_getStackPtr() +
249#pragma GCC diagnostic pop
#define CONTROL_nPRIV_Msk
#define __ISB()
Instruction Synchronization Barrier.
#define __DSB()
Data Synchronization Barrier.
#define __WFE
Wait For Event.
__STATIC_INLINE void __set_CONTROL(uint32_t control)
Set Control Register.
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
Set Process Stack Pointer.
__STATIC_INLINE uint32_t __get_CONTROL(void)
Enable IRQ Interrupts.
__STATIC_INLINE uint32_t __get_IPSR(void)
Get IPSR Register.
void __attribute__((noreturn))(*rom_reset_usb_boot_fn)(uint32_t
Reboot the device into BOOTSEL mode.