dbg_stubs.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2017 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. // This module implements debug/trace stubs. The stub is a piece of special code which can invoked by OpenOCD
  14. // Currently one stub is used for GCOV functionality
  15. //
  16. #include "eri.h"
  17. #include "xtensa-debug-module.h"
  18. #include "esp_private/dbg_stubs.h"
  19. #include "esp_attr.h"
  20. #if CONFIG_ESP_DEBUG_STUBS_ENABLE
  21. /*
  22. Debug stubs is actually a table of 4-byte entries. Every entry is equal to zero or must contain meaningfull data.
  23. The first entry is a service one and has the followinf format:
  24. - tramp_addr, 4 bytes; Address of buffer for trampoline/code. Max size is ESP_DBG_STUBS_CODE_BUF_SIZE.
  25. - min_stack_addr, 4 bytes; Start of the buffer for minimal onboard stack or data. Max size is ESP_DBG_STUBS_STACK_MIN_SIZE.
  26. - data_alloc, 4 bytes; Address of function to allocate memory on target.
  27. - data_free, 4 bytes; Address of function to free target memory.
  28. This entry is used by OpenOCD code to invoke other stub entries and allocate memory for them.
  29. */
  30. #include "esp_log.h"
  31. const static char *TAG = "esp_dbg_stubs";
  32. #define ESP_DBG_STUBS_TRAX_REG ERI_TRAX_TRIGGERPC
  33. #define ESP_DBG_STUBS_CODE_BUF_SIZE 32
  34. #define ESP_DBG_STUBS_STACK_MIN_SIZE 2048
  35. #define DBG_STUB_TRAMP_ATTR IRAM_ATTR
  36. static struct {
  37. uint32_t tramp_addr;
  38. uint32_t min_stack_addr; // minimal stack addr
  39. uint32_t data_alloc;
  40. uint32_t data_free;
  41. } s_dbg_stubs_ctl_data;
  42. static uint32_t s_stub_entry[ESP_DBG_STUB_ENTRY_MAX];
  43. static uint8_t s_stub_min_stack[ESP_DBG_STUBS_STACK_MIN_SIZE];
  44. static DBG_STUB_TRAMP_ATTR uint8_t s_stub_code_buf[ESP_DBG_STUBS_CODE_BUF_SIZE];
  45. // TODO: all called funcs should be in IRAM to work with disabled flash cache
  46. static void * esp_dbg_stubs_data_alloc(uint32_t size)
  47. {
  48. ESP_LOGV(TAG, "%s %d", __func__, size);
  49. void *p = malloc(size);
  50. ESP_LOGV(TAG, "%s EXIT %p", __func__, p);
  51. return p;
  52. }
  53. static void esp_dbg_stubs_data_free(void *addr)
  54. {
  55. ESP_LOGV(TAG, "%s %p", __func__, addr);
  56. free(addr);
  57. ESP_LOGV(TAG, "%s EXIT %p", __func__, addr);
  58. }
  59. void esp_dbg_stubs_init(void)
  60. {
  61. s_dbg_stubs_ctl_data.tramp_addr = (uint32_t)s_stub_code_buf;
  62. s_dbg_stubs_ctl_data.min_stack_addr = (uint32_t)s_stub_min_stack;
  63. s_dbg_stubs_ctl_data.data_alloc = (uint32_t)esp_dbg_stubs_data_alloc;
  64. s_dbg_stubs_ctl_data.data_free = (uint32_t)esp_dbg_stubs_data_free;
  65. s_stub_entry[ESP_DBG_STUB_MAGIC_NUM] = ESP_DBG_STUB_MAGIC_NUM_VAL;
  66. s_stub_entry[ESP_DBG_STUB_TABLE_SIZE] = ESP_DBG_STUB_ENTRY_MAX;
  67. s_stub_entry[ESP_DBG_STUB_CONTROL_DATA] = (uint32_t)&s_dbg_stubs_ctl_data;
  68. eri_write(ESP_DBG_STUBS_TRAX_REG, (uint32_t)s_stub_entry);
  69. ESP_LOGV(TAG, "%s stubs %x", __func__, eri_read(ESP_DBG_STUBS_TRAX_REG));
  70. }
  71. // TODO: add lock mechanism. Not now but in the future ESP_DBG_STUB_ENTRY_CAPABILITIES can be set from different places.
  72. esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry)
  73. {
  74. if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) {
  75. ESP_LOGE(TAG, "Invalid stub id %d!", id);
  76. return ESP_ERR_INVALID_ARG;
  77. }
  78. s_stub_entry[id] = entry;
  79. return ESP_OK;
  80. }
  81. esp_err_t esp_dbg_stub_entry_get(esp_dbg_stub_id_t id, uint32_t *entry)
  82. {
  83. if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) {
  84. ESP_LOGE(TAG, "Invalid stub id %d!", id);
  85. return ESP_ERR_INVALID_ARG;
  86. }
  87. *entry = s_stub_entry[id];
  88. return ESP_OK;
  89. }
  90. #endif