@@ -207,25 +207,27 @@ void multicore_launch_core1_raw(void (*entry)(void), uint32_t *sp, uint32_t vect
207207 irq_set_enabled (irq_num , enabled );
208208}
209209
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 ;
213213static mutex_t lockout_mutex ;
214- static bool lockout_in_progress ;
215214
216215// note this method is in RAM because lockout is used when writing to flash
217216// it only makes inline calls
218217static void __isr __not_in_flash_func (multicore_lockout_handler )(void ) {
219218 multicore_fifo_clear_irq ();
220219 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
222223 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 ();
226229 }
227230 restore_interrupts_from_disabled (save );
228- multicore_fifo_push_blocking_inline (LOCKOUT_MAGIC_END );
229231 }
230232 }
231233}
@@ -262,7 +264,7 @@ void multicore_lockout_victim_deinit(void) {
262264 }
263265}
264266
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 ) {
266268 uint irq_num = SIO_FIFO_IRQ_NUM (get_core_num ());
267269 bool enabled = irq_is_enabled (irq_num );
268270 if (enabled ) irq_set_enabled (irq_num , false);
@@ -272,7 +274,7 @@ static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) {
272274 if (next_timeout_us < 0 ) {
273275 break ;
274276 }
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 );
276278 next_timeout_us = absolute_time_diff_us (get_absolute_time (), until );
277279 if (next_timeout_us < 0 ) {
278280 break ;
@@ -281,22 +283,36 @@ static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) {
281283 if (!multicore_fifo_pop_timeout_us ((uint64_t )next_timeout_us , & word )) {
282284 break ;
283285 }
284- if (word == magic ) {
286+ if (word == request_id ) {
285287 rc = true;
286288 }
287289 } while (!rc );
288290 if (enabled ) irq_set_enabled (irq_num , true);
289291 return rc ;
290292}
291293
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+
292303static bool multicore_lockout_start_block_until (absolute_time_t until ) {
293304 check_lockout_mutex_init ();
294305 if (!mutex_enter_block_until (& lockout_mutex , until )) {
295306 return false;
296307 }
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+ }
300316 mutex_exit (& lockout_mutex );
301317 return rc ;
302318}
@@ -314,13 +330,10 @@ static bool multicore_lockout_end_block_until(absolute_time_t until) {
314330 if (!mutex_enter_block_until (& lockout_mutex , until )) {
315331 return false;
316332 }
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 ();
322335 mutex_exit (& lockout_mutex );
323- return rc ;
336+ return true ;
324337}
325338
326339bool multicore_lockout_end_timeout_us (uint64_t timeout_us ) {
@@ -407,4 +420,4 @@ void multicore_doorbell_unclaim(uint doorbell_num, uint core_mask) {
407420}
408421
409422
410- #endif
423+ #endif
0 commit comments