Skip to content

Commit 5288585

Browse files
authored
add multicore_lockout_victim_deinit. clear lockedout_flag for core1 during core1 reset (earlephilhower#2223)
1 parent ccbd07c commit 5288585

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

src/rp2_common/pico_multicore/include/pico/multicore.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,13 @@ static inline uint multicore_doorbell_irq_num(uint doorbell_num) {
449449
*/
450450
void multicore_lockout_victim_init(void);
451451

452+
/*! \brief Stop the current core being able to be a "victim" of lockout (i.e. forced to pause in a known state by the other core)
453+
* \ingroup multicore_lockout
454+
*
455+
* This code unhooks the intercore FIFO IRQ, and the FIFO may be used for any other purpose after this.
456+
*/
457+
void multicore_lockout_victim_deinit(void);
458+
452459
/*! \brief Determine if \ref multicore_lockout_victim_init() has been called on the specified core.
453460
* \ingroup multicore_lockout
454461
*

src/rp2_common/pico_multicore/multicore.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@
2323
#endif
2424
#endif
2525

26-
// note that these are not reset by core reset, however for now, I think people resetting cores
27-
// and then relying on multicore_lockout for that core without re-initializing, is probably
28-
// something we can live with breaking.
29-
//
30-
// whilst we could clear this in core 1 reset path, that doesn't necessarily catch all,
31-
// and means pulling in this array even if multicore_lockout is not used.
26+
// Note that there is no automatic way for us to clear these flags when a particular core is reset, and yet
27+
// we DO ideally want to clear them, as the `multicore_lockout_victim_init()` checks the flag for the current core
28+
// and is a no-op if set. We DO have a new `multicore_lockout_victim_deinit()` method, which can be called in a pinch after
29+
// the reset before calling `multicore_lockout_victim_init()` again, so that is good. We will reset the flag
30+
// for core1 in `multicore_reset_core1()` though as a convenience since most people will use that to reset core 1.
3231
static bool lockout_victim_initialized[NUM_CORES];
3332

3433
void multicore_fifo_push_blocking(uint32_t data) {
@@ -118,6 +117,9 @@ void multicore_reset_core1(void) {
118117
bool enabled = irq_is_enabled(irq_num);
119118
irq_set_enabled(irq_num, false);
120119

120+
// Core 1 will be in un-initialized state
121+
lockout_victim_initialized[1] = false;
122+
121123
// Bring core 1 back out of reset. It will drain its own mailbox FIFO, then push
122124
// a 0 to our mailbox to tell us it has done this.
123125
*power_off_clr = PSM_FRCE_OFF_PROC1_BITS;
@@ -243,6 +245,18 @@ void multicore_lockout_victim_init(void) {
243245
lockout_victim_initialized[core_num] = true;
244246
}
245247

248+
void multicore_lockout_victim_deinit(void) {
249+
uint core_num = get_core_num();
250+
if (lockout_victim_initialized[core_num]) {
251+
// On platforms other than RP2040, these are actually the same IRQ number
252+
// (each core only sees its own IRQ, always at the same IRQ number).
253+
uint fifo_irq_this_core = SIO_FIFO_IRQ_NUM(core_num);
254+
irq_remove_handler(fifo_irq_this_core, multicore_lockout_handler);
255+
irq_set_enabled(fifo_irq_this_core, false);
256+
lockout_victim_initialized[core_num] = false;
257+
}
258+
}
259+
246260
static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) {
247261
uint irq_num = SIO_FIFO_IRQ_NUM(get_core_num());
248262
bool enabled = irq_is_enabled(irq_num);

0 commit comments

Comments
 (0)