The branch main has been updated by seuros:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ba28690cc6e0ce6f418122d3db0b1eddec3d93a9

commit ba28690cc6e0ce6f418122d3db0b1eddec3d93a9
Author:     Abdelkader Boudih <[email protected]>
AuthorDate: 2026-09-06 17:55:02 +0000
Commit:     Abdelkader Boudih <[email protected]>
CommitDate: 2026-09-06 19:47:44 +0000

    apple_bce: fix cold boot panic in mailbox send
    
    Poll mailbox reply registers with DELAY() when the system is still
    cold, falling back to the interrupt-driven
    sema_timedwait path once timers are available.
    
    Reviewed by:    adrian
    Differential Revision:  https://reviews.freebsd.org/D58871
---
 sys/dev/apple_bce/apple_bce_mailbox.c | 50 ++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/sys/dev/apple_bce/apple_bce_mailbox.c 
b/sys/dev/apple_bce/apple_bce_mailbox.c
index c19a01b7269c..deacb7ed5317 100644
--- a/sys/dev/apple_bce/apple_bce_mailbox.c
+++ b/sys/dev/apple_bce/apple_bce_mailbox.c
@@ -7,6 +7,7 @@
  */
 
 #include <sys/param.h>
+#include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/sema.h>
@@ -62,20 +63,41 @@ bce_mailbox_send(struct bce_mailbox *mb, uint64_t msg, 
uint64_t *recv,
                return (0);
        }
 
-       /* Wait for interrupt-driven reply */
-       if (sema_timedwait(&mb->mb_cmpl, hz * timeout_ms / 1000) != 0) {
-               /* Timeout -- reset to idle */
-               atomic_store_int(&mb->status, 0);
-               return (ETIMEDOUT);
-       }
-
-       if (atomic_load_int(&mb->status) != 2) {
-               atomic_store_int(&mb->status, 0);
-               return (ETIMEDOUT);
+       if (cold) {
+               /*
+                * During early boot, timer-backed sleeps are not available.
+                * Poll the hardware directly, but account for an installed
+                * interrupt handler consuming the reply first.
+                */
+               unsigned int waited = 0;
+
+               while (waited < timeout_ms * 1000) {
+                       if (atomic_load_int(&mb->status) == 2)
+                               break;
+                       (void)bce_mailbox_handle_interrupt(mb);
+                       if (atomic_load_int(&mb->status) == 2)
+                               break;
+                       DELAY(100);
+                       waited += 100;
+               }
+               if (atomic_load_int(&mb->status) != 2) {
+                       atomic_store_int(&mb->status, 0);
+                       return (ETIMEDOUT);
+               }
+       } else {
+               /* Wait for interrupt-driven reply */
+               if (sema_timedwait(&mb->mb_cmpl,
+                   hz * timeout_ms / 1000) != 0) {
+                       atomic_store_int(&mb->status, 0);
+                       return (ETIMEDOUT);
+               }
+               if (atomic_load_int(&mb->status) != 2) {
+                       atomic_store_int(&mb->status, 0);
+                       return (ETIMEDOUT);
+               }
        }
 
-       if (recv != NULL)
-               *recv = mb->mb_result;
+       *recv = mb->mb_result;
 
        atomic_store_int(&mb->status, 0);
        return (0);
@@ -106,7 +128,9 @@ bce_mailbox_handle_interrupt(struct bce_mailbox *mb)
 
        if (atomic_load_int(&mb->status) == 1) {
                atomic_store_int(&mb->status, 2);
-               sema_post(&mb->mb_cmpl);
+               /* A cold sender polls status and must not leave a token. */
+               if (!cold)
+                       sema_post(&mb->mb_cmpl);
        }
 
        return (0);

Reply via email to