@@ -207,25 +207,27 @@ void multicore_launch_core1_raw(void (*entry)(void), uint32_t *sp, uint32_t vect
207
207
irq_set_enabled (irq_num , enabled );
208
208
}
209
209
210
- #define LOCKOUT_MAGIC_START 0x73a8831eu
211
- #define LOCKOUT_MAGIC_END (~LOCKOUT_MAGIC_START)
212
-
210
+ // A non-zero initialisation value is used in order to reduce the chance of
211
+ // entering the lock handler on bootup due to a 0-word being present in the FIFO
212
+ static volatile uint32_t lockout_request_id = 0x73a8831eu ;
213
213
static mutex_t lockout_mutex ;
214
- static bool lockout_in_progress ;
215
214
216
215
// note this method is in RAM because lockout is used when writing to flash
217
216
// it only makes inline calls
218
217
static void __isr __not_in_flash_func (multicore_lockout_handler )(void ) {
219
218
multicore_fifo_clear_irq ();
220
219
while (multicore_fifo_rvalid ()) {
221
- if (sio_hw -> fifo_rd == LOCKOUT_MAGIC_START ) {
220
+ uint32_t request_id = sio_hw -> fifo_rd ;
221
+ if (request_id == lockout_request_id ) {
222
+ // valid lockout request received
222
223
uint32_t save = save_and_disable_interrupts ();
223
- multicore_fifo_push_blocking_inline (LOCKOUT_MAGIC_START );
224
- while (multicore_fifo_pop_blocking_inline () != LOCKOUT_MAGIC_END ) {
225
- tight_loop_contents (); // not tight but endless potentially
224
+ multicore_fifo_push_blocking_inline (request_id );
225
+ // wait for the lockout to expire
226
+ while (request_id == lockout_request_id ) {
227
+ // when lockout_request_id is updated, the other CPU core calls __sev
228
+ __wfe ();
226
229
}
227
230
restore_interrupts_from_disabled (save );
228
- multicore_fifo_push_blocking_inline (LOCKOUT_MAGIC_END );
229
231
}
230
232
}
231
233
}
@@ -262,7 +264,7 @@ void multicore_lockout_victim_deinit(void) {
262
264
}
263
265
}
264
266
265
- static bool multicore_lockout_handshake (uint32_t magic , absolute_time_t until ) {
267
+ static bool multicore_lockout_handshake (uint32_t request_id , absolute_time_t until ) {
266
268
uint irq_num = SIO_FIFO_IRQ_NUM (get_core_num ());
267
269
bool enabled = irq_is_enabled (irq_num );
268
270
if (enabled ) irq_set_enabled (irq_num , false);
@@ -272,7 +274,7 @@ static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) {
272
274
if (next_timeout_us < 0 ) {
273
275
break ;
274
276
}
275
- multicore_fifo_push_timeout_us (magic , (uint64_t )next_timeout_us );
277
+ multicore_fifo_push_timeout_us (request_id , (uint64_t )next_timeout_us );
276
278
next_timeout_us = absolute_time_diff_us (get_absolute_time (), until );
277
279
if (next_timeout_us < 0 ) {
278
280
break ;
@@ -281,22 +283,36 @@ static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) {
281
283
if (!multicore_fifo_pop_timeout_us ((uint64_t )next_timeout_us , & word )) {
282
284
break ;
283
285
}
284
- if (word == magic ) {
286
+ if (word == request_id ) {
285
287
rc = true;
286
288
}
287
289
} while (!rc );
288
290
if (enabled ) irq_set_enabled (irq_num , true);
289
291
return rc ;
290
292
}
291
293
294
+ static uint32_t update_lockout_request_id (void ) {
295
+ // generate new number and then update shared variable
296
+ uint32_t new_request_id = lockout_request_id + 1 ;
297
+ lockout_request_id = new_request_id ;
298
+ // notify other core
299
+ __sev ();
300
+ return new_request_id ;
301
+ }
302
+
292
303
static bool multicore_lockout_start_block_until (absolute_time_t until ) {
293
304
check_lockout_mutex_init ();
294
305
if (!mutex_enter_block_until (& lockout_mutex , until )) {
295
306
return false;
296
307
}
297
- hard_assert (!lockout_in_progress );
298
- bool rc = multicore_lockout_handshake (LOCKOUT_MAGIC_START , until );
299
- lockout_in_progress = rc ;
308
+ // generate a new request_id number
309
+ uint32_t request_id = update_lockout_request_id ();
310
+ // attempt to lock out
311
+ bool rc = multicore_lockout_handshake (request_id , until );
312
+ if (!rc ) {
313
+ // lockout failed - cancel it
314
+ update_lockout_request_id ();
315
+ }
300
316
mutex_exit (& lockout_mutex );
301
317
return rc ;
302
318
}
@@ -314,13 +330,10 @@ static bool multicore_lockout_end_block_until(absolute_time_t until) {
314
330
if (!mutex_enter_block_until (& lockout_mutex , until )) {
315
331
return false;
316
332
}
317
- assert (lockout_in_progress );
318
- bool rc = multicore_lockout_handshake (LOCKOUT_MAGIC_END , until );
319
- if (rc ) {
320
- lockout_in_progress = false;
321
- }
333
+ // lockout finished - cancel it
334
+ update_lockout_request_id ();
322
335
mutex_exit (& lockout_mutex );
323
- return rc ;
336
+ return true ;
324
337
}
325
338
326
339
bool multicore_lockout_end_timeout_us (uint64_t timeout_us ) {
@@ -407,4 +420,4 @@ void multicore_doorbell_unclaim(uint doorbell_num, uint core_mask) {
407
420
}
408
421
409
422
410
- #endif
423
+ #endif
0 commit comments