summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngus Gratton <angus@redyak.com.au>2024-07-03 15:52:31 +1000
committerDamien George <damien@micropython.org>2024-07-23 16:02:59 +1000
commit9db16cfe31c70a75bfd8a8d93401ff7f6010b1ae (patch)
tree154b10037cc97296576750217fb6f79254cb0c87
parenteced9d86a709f3f267edc7bc08e52115d0c0c9df (diff)
rp2: Fix wakeup from WFE on core1.
If core1 executes `mp_wfe_or_timeout()` then it needs to receive an interrupt or a SEV to resume execution, but the soft timer interrupt only fires on core 0. This fix adds a SEV to the soft timer interrupt handler. This issue was masked by the issue fixed in the previous commit, as WFE previously wasn't suspending properly. Verified via the existing thread_sleep2 test. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
-rw-r--r--ports/rp2/mphalport.c7
-rw-r--r--ports/rp2/mpthreadport.c2
-rw-r--r--ports/rp2/mpthreadport.h4
3 files changed, 12 insertions, 1 deletions
diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c
index 3fe5357c8..ad51cf8e2 100644
--- a/ports/rp2/mphalport.c
+++ b/ports/rp2/mphalport.c
@@ -228,6 +228,13 @@ static void soft_timer_hardware_callback(unsigned int alarm_num) {
// The timer alarm ISR needs to call here and trigger PendSV dispatch via
// a second ISR, as PendSV may be currently suspended by the other CPU.
pendsv_schedule_dispatch(PENDSV_DISPATCH_SOFT_TIMER, soft_timer_handler);
+
+ // This ISR only runs on core0, but if core1 is running Python code then it
+ // may be blocked in WFE so wake it up as well. Unfortunately this also sets
+ // the event flag on core0, so a subsequent WFE on this core will not suspend
+ if (core1_entry != NULL) {
+ __sev();
+ }
}
void soft_timer_init(void) {
diff --git a/ports/rp2/mpthreadport.c b/ports/rp2/mpthreadport.c
index 5b8e804f9..0d3b343ca 100644
--- a/ports/rp2/mpthreadport.c
+++ b/ports/rp2/mpthreadport.c
@@ -39,7 +39,7 @@ extern uint8_t __StackTop, __StackBottom;
void *core_state[2];
// This will be non-NULL while Python code is executing.
-static void *(*core1_entry)(void *) = NULL;
+core_entry_func_t core1_entry = NULL;
static void *core1_arg = NULL;
static uint32_t *core1_stack = NULL;
diff --git a/ports/rp2/mpthreadport.h b/ports/rp2/mpthreadport.h
index 7982de96a..67a0da0e9 100644
--- a/ports/rp2/mpthreadport.h
+++ b/ports/rp2/mpthreadport.h
@@ -32,6 +32,10 @@ typedef struct mutex mp_thread_mutex_t;
extern void *core_state[2];
+typedef void *(*core_entry_func_t)(void *);
+
+extern core_entry_func_t core1_entry;
+
void mp_thread_init(void);
void mp_thread_deinit(void);
void mp_thread_gc_others(void);