From d600496800238be3b77ba280f46ed76516eba979 Mon Sep 17 00:00:00 2001 From: zwj Date: Thu, 20 Oct 2022 21:35:30 +0800 Subject: [PATCH] support BLE memory release on ESP32C3 and ESP32S3 --- components/bt/controller/esp32c3/bt.c | 149 +++++++++++++++++++++-- components/bt/controller/esp32s3/bt.c | 165 ++++++++++++++++++++++++-- 2 files changed, 291 insertions(+), 23 deletions(-) diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index e3a5b761b5..57d1f6fb67 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -250,24 +250,19 @@ extern void esp_mac_bb_power_up(void); extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); #endif -extern char _bss_start_btdm; -extern char _bss_end_btdm; -extern char _data_start_btdm; -extern char _data_end_btdm; -extern uint32_t _data_start_btdm_rom; -extern uint32_t _data_end_btdm_rom; - extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _btdm_bss_start; extern uint32_t _btdm_bss_end; +extern uint32_t _nimble_bss_start; +extern uint32_t _nimble_bss_end; extern uint32_t _bt_data_start; extern uint32_t _bt_data_end; extern uint32_t _btdm_data_start; extern uint32_t _btdm_data_end; +extern uint32_t _nimble_data_start; +extern uint32_t _nimble_data_end; -extern char _bt_tmp_bss_start; -extern char _bt_tmp_bss_end; /* Local Function Declare ********************************************************************* @@ -317,6 +312,9 @@ static void btdm_hw_mac_power_down_wrapper(void); static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); static void btdm_slp_tmr_callback(void *arg); + +static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end); + /* Local variable definition *************************************************************************** */ @@ -877,13 +875,142 @@ static void btdm_controller_mem_init(void) esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) { - ESP_LOGW(BTDM_LOG_TAG, "%s not implemented, return OK", __func__); + intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } + + if (mode & ESP_BT_MODE_BLE) { + /* if the addresses of rom btdm .data and .bss are consecutive, + they are registered in the system heap as a piece of memory + */ + if(ets_rom_layout_p->data_end_btdm == ets_rom_layout_p->bss_start_btdm) { + mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release rom btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)ets_rom_layout_p->bss_start_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release rom btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; + mem_end = (intptr_t)ets_rom_layout_p->data_end_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release rom btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + /* if the addresses of rom interface btdm .data and .bss are consecutive, + they are registered in the system heap as a piece of memory + */ + if(ets_rom_layout_p->data_end_interface_btdm == ets_rom_layout_p->bss_start_interface_btdm) { + mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release rom interface btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; + mem_end = (intptr_t)ets_rom_layout_p->data_end_interface_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release rom interface btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release rom interface btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + + } return ESP_OK; } esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - ESP_LOGW(BTDM_LOG_TAG, "%s not implemented, return OK", __func__); + int ret; + intptr_t mem_start, mem_end; + + ret = esp_bt_controller_mem_release(mode); + if (ret != ESP_OK) { + return ret; + } + + if (mode & ESP_BT_MODE_BLE) { + /* if the addresses of btdm .bss and bt .bss are consecutive, + they are registered in the system heap as a piece of memory + */ + if(_bt_bss_end == _btdm_bss_start) { + mem_start = (intptr_t)&_bt_bss_start; + mem_end = (intptr_t)&_btdm_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)&_bt_bss_start; + mem_end = (intptr_t)&_bt_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)&_btdm_bss_start; + mem_end = (intptr_t)&_btdm_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + /* if the addresses of btdm .data and bt .data are consecutive, + they are registered in the system heap as a piece of memory + */ + if(_bt_data_end == _btdm_data_start) { + mem_start = (intptr_t)&_bt_data_start; + mem_end = (intptr_t)&_btdm_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)&_bt_data_start; + mem_end = (intptr_t)&_bt_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)&_btdm_data_start; + mem_end = (intptr_t)&_btdm_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + + mem_start = (intptr_t)&_nimble_bss_start; + mem_end = (intptr_t)&_nimble_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + mem_start = (intptr_t)&_nimble_data_start; + mem_end = (intptr_t)&_nimble_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } return ESP_OK; } diff --git a/components/bt/controller/esp32s3/bt.c b/components/bt/controller/esp32s3/bt.c index b38e9ec9e5..5aa1d03cdd 100644 --- a/components/bt/controller/esp32s3/bt.c +++ b/components/bt/controller/esp32s3/bt.c @@ -39,6 +39,7 @@ #include "esp_timer.h" #include "esp_sleep.h" #include "esp_rom_sys.h" +#include "esp32s3/rom/rom_layout.h" #if CONFIG_BT_ENABLED @@ -254,24 +255,18 @@ extern void esp_mac_bb_power_up(void); extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); #endif -extern char _bss_start_btdm; -extern char _bss_end_btdm; -extern char _data_start_btdm; -extern char _data_end_btdm; -extern uint32_t _data_start_btdm_rom; -extern uint32_t _data_end_btdm_rom; - extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _btdm_bss_start; extern uint32_t _btdm_bss_end; +extern uint32_t _nimble_bss_start; +extern uint32_t _nimble_bss_end; extern uint32_t _bt_data_start; extern uint32_t _bt_data_end; extern uint32_t _btdm_data_start; extern uint32_t _btdm_data_end; - -extern char _bt_tmp_bss_start; -extern char _bt_tmp_bss_end; +extern uint32_t _nimble_data_start; +extern uint32_t _nimble_data_end; /* Local Function Declare ********************************************************************* @@ -321,6 +316,9 @@ static void btdm_hw_mac_power_down_wrapper(void); static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); static void btdm_slp_tmr_callback(void *arg); + +static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end); + /* Local variable definition *************************************************************************** */ @@ -929,16 +927,159 @@ static void btdm_controller_mem_init(void) esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) { - ESP_LOGW(BT_LOG_TAG, "%s not implemented, return OK", __func__); + intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } + + if (mode & ESP_BT_MODE_BLE) { + /* if the addresses of rom btdm .data and .bss are consecutive, + they are registered in the system heap as a piece of memory + */ + if(ets_rom_layout_p->data_end_btdm == ets_rom_layout_p->bss_start_btdm) { + mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release rom btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)ets_rom_layout_p->bss_start_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release rom btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; + mem_end = (intptr_t)ets_rom_layout_p->data_end_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release rom btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + /* if the addresses of rom interface btdm .data and .bss are consecutive, + they are registered in the system heap as a piece of memory + */ + if(ets_rom_layout_p->data_end_interface_btdm == ets_rom_layout_p->bss_start_interface_btdm) { + mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; + mem_end = (intptr_t)ets_rom_layout_p->data_end_interface_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm; + mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + + } return ESP_OK; } esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - ESP_LOGW(BT_LOG_TAG, "%s not implemented, return OK", __func__); + int ret; + intptr_t mem_start, mem_end; + + ret = esp_bt_controller_mem_release(mode); + if (ret != ESP_OK) { + return ret; + } + + if (mode & ESP_BT_MODE_BLE) { + /* if the addresses of btdm .bss and bt .bss are consecutive, + they are registered in the system heap as a piece of memory + */ + if(_bt_bss_end == _btdm_bss_start) { + mem_start = (intptr_t)&_bt_bss_start; + mem_end = (intptr_t)&_btdm_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)&_bt_bss_start; + mem_end = (intptr_t)&_bt_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)&_btdm_bss_start; + mem_end = (intptr_t)&_btdm_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + /* if the addresses of btdm .data and bt .data are consecutive, + they are registered in the system heap as a piece of memory + */ + if(_bt_data_end == _btdm_data_start) { + mem_start = (intptr_t)&_bt_data_start; + mem_end = (intptr_t)&_btdm_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } else { + mem_start = (intptr_t)&_bt_data_start; + mem_end = (intptr_t)&_bt_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + + mem_start = (intptr_t)&_btdm_data_start; + mem_end = (intptr_t)&_btdm_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } + + mem_start = (intptr_t)&_nimble_bss_start; + mem_end = (intptr_t)&_nimble_bss_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + mem_start = (intptr_t)&_nimble_data_start; + mem_end = (intptr_t)&_nimble_data_end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); + ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + } + } return ESP_OK; } +static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) +{ + int ret = heap_caps_add_region(start, end); + /* heap_caps_add_region() returns ESP_ERR_INVALID_SIZE if the memory region is + * is too small to fit a heap. This cannot be termed as a fatal error and hence + * we replace it by ESP_OK + */ + + if (ret == ESP_ERR_INVALID_SIZE) { + return ESP_OK; + } + return ret; +} + #if CONFIG_MAC_BB_PD static void IRAM_ATTR btdm_mac_bb_power_down_cb(void) {