Skip to content

Commit 8c9f017

Browse files
gmarullclaude
andcommitted
fw/coredump: wake LCPU during dump so BLE crashes capture its RAM
The LCPU (BLE controller) RAM lives in the LPSYS domain and is only reachable while that domain is powered. NimBLE host asserts (e.g. ble_hs.c start_stage2) crash through the generic assert path, which leaves the LCPU asleep, so their coredumps dropped the 24 KB LCPU region entirely. Wake the LCPU from prv_dump_lcpu_ram() so the controller RAM is captured for every crash type. If the LCPU is fully powered down the wake blocks until the watchdog reboots us, costing only this dump. The two special-case wake calls in the NimBLE init path are now redundant and removed, along with the wrapper. Fixes FIRM-2292 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
1 parent 916fdbf commit 8c9f017

3 files changed

Lines changed: 10 additions & 23 deletions

File tree

src/bluetooth-fw/nimble/init.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ static const uint32_t s_bt_stack_start_stop_timeout_ms = 10000;
2727

2828
extern void pebble_pairing_service_init(void);
2929
extern void nimble_discover_init(void);
30-
#ifdef CONFIG_SOC_SF32LB52
31-
extern void ble_transport_ll_wake_lcpu(void);
32-
#endif
3330

3431
#if NIMBLE_CFG_CONTROLLER
3532
static TaskHandle_t s_ll_task_handle;
@@ -60,9 +57,8 @@ static void prv_sync_cb(void) {
6057
static void prv_reset_cb(int reason) {
6158
PBL_LOG_D_WRN(LOG_DOMAIN_BT, "NimBLE host reset (reason: 0x%04x)", (uint16_t)reason);
6259
#ifdef CONFIG_SOC_SF32LB52
63-
// Controller stopped answering HCI. Keep the LCPU reachable and crash so the
64-
// coredump captures LCPU RAM; the reboot cold-recovers the controller.
65-
ble_transport_ll_wake_lcpu();
60+
// Controller stopped answering HCI. Crash so the coredump captures LCPU RAM
61+
// (core_dump wakes the LCPU itself); the reboot cold-recovers the controller.
6662
PBL_CROAK("NimBLE host reset 0x%04x; captured LCPU RAM", (uint16_t)reason);
6763
#endif
6864
}
@@ -155,10 +151,7 @@ bool bt_driver_start(BTDriverConfig *config) {
155151
ble_hs_sched_start();
156152
f_rc = xSemaphoreTake(s_host_started, milliseconds_to_ticks(s_bt_stack_start_stop_timeout_ms));
157153
if (f_rc != pdTRUE) {
158-
#ifdef CONFIG_SOC_SF32LB52
159-
// Keep the LCPU reachable so the coredump captures its RAM.
160-
ble_transport_ll_wake_lcpu();
161-
#endif
154+
// core_dump wakes the LCPU itself, so its RAM is captured here too.
162155
PBL_CROAK("NimBLE host start timed out");
163156
}
164157

src/fw/kernel/core_dump.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -447,14 +447,14 @@ static void prv_write_memory_regions(const MemoryRegion *regions, unsigned int c
447447
}
448448

449449
#if defined(CONFIG_SOC_SF32LB52)
450-
// LCPU RAM lives in the LPSYS domain; reading it while that domain is powered
451-
// down hangs/faults. LP_ACTIVE reports whether it is reachable.
450+
// Wake the LCPU so its LPSYS RAM is reachable, letting BLE crashes (e.g. NimBLE
451+
// host asserts) capture the controller RAM. HAL_HPAON_WakeCore busy-waits for
452+
// the LCPU to ack; if it is fully powered down this blocks until the watchdog
453+
// reboots us, costing only this dump. We reset right after, so the wake request
454+
// is never balanced.
452455
static void prv_dump_lcpu_ram(uint32_t flash_base) {
453-
if (hwp_hpsys_aon->ISSR & HPSYS_AON_ISSR_LP_ACTIVE) {
454-
prv_write_memory_regions(&LCPU_MEMORY_REGION, 1, flash_base);
455-
} else {
456-
prv_debug_str("CD: LCPU domain off, skipping LCPU RAM");
457-
}
456+
HAL_HPAON_WakeCore(CORE_ID_LCPU);
457+
prv_write_memory_regions(&LCPU_MEMORY_REGION, 1, flash_base);
458458
}
459459
#endif
460460

third_party/nimble/transport/hci_sf32lb52.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,6 @@ void ble_transport_ll_init(void) {
336336
PBL_ASSERTN(s_hci_task_handle);
337337
}
338338

339-
// Hold the LP active request (no cancel) so LPSYS RAM stays reachable from the
340-
// HCPU while the coredump runs after a crash on host reset.
341-
void ble_transport_ll_wake_lcpu(void) {
342-
HAL_HPAON_WakeCore(CORE_ID_LCPU);
343-
}
344-
345339
void ble_transport_ll_deinit(void) {
346340
NVIC_DisableIRQ(LCPU2HCPU_IRQn);
347341
ipc_queue_close(s_ipc_port);

0 commit comments

Comments
 (0)