gdbstub_common.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright 2015-2019 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. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "soc/uart_periph.h"
  15. #include "soc/gpio_periph.h"
  16. #include "esp_gdbstub_common.h"
  17. #include "sdkconfig.h"
  18. #include "hal/uart_ll.h"
  19. #define UART_NUM CONFIG_ESP_CONSOLE_UART_NUM
  20. static uart_dev_t *gdb_uart = NULL;
  21. void esp_gdbstub_target_init(void)
  22. {
  23. switch (UART_NUM) {
  24. case 0:
  25. gdb_uart = &UART0;
  26. break;
  27. #if SOC_UART_NUM > 1
  28. case 1:
  29. gdb_uart = &UART1;
  30. break;
  31. #endif
  32. #if SOC_UART_NUM > 2
  33. case 2:
  34. gdb_uart = &UART2;
  35. break;
  36. #endif
  37. default:
  38. gdb_uart = &UART0;
  39. break;
  40. }
  41. }
  42. int esp_gdbstub_getchar(void)
  43. {
  44. if (gdb_uart == NULL) {
  45. esp_gdbstub_target_init();
  46. }
  47. unsigned char data;
  48. while (uart_ll_get_rxfifo_len(gdb_uart) == 0) {
  49. }
  50. uart_ll_read_rxfifo(gdb_uart, &data, 1);
  51. return data;
  52. }
  53. void esp_gdbstub_putchar(int c)
  54. {
  55. if (gdb_uart == NULL) {
  56. esp_gdbstub_target_init();
  57. }
  58. while (uart_ll_get_txfifo_len(gdb_uart) <= 126) {
  59. }
  60. uart_ll_write_txfifo(gdb_uart, (uint8_t *)&c, 1);
  61. }
  62. void esp_gdbstub_flush()
  63. {
  64. //not needed for uart
  65. }
  66. int esp_gdbstub_getfifo()
  67. {
  68. if (gdb_uart == NULL) {
  69. esp_gdbstub_target_init();
  70. }
  71. int doDebug = 0;
  72. int fifolen = uart_ll_get_rxfifo_len(gdb_uart);
  73. while (fifolen != 0) {
  74. unsigned char data;
  75. uart_ll_read_rxfifo(gdb_uart, &data, 1);
  76. if (data == 0x3) {
  77. doDebug = 1; //Check if any of the chars is Ctrl+C. Throw away rest.
  78. }
  79. if (data == '+') {
  80. doDebug = 1; //Check if any of the chars is '+'. Throw away rest.
  81. }
  82. fifolen--;
  83. }
  84. uart_ll_clr_intsts_mask(gdb_uart, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT);
  85. return doDebug;
  86. }
  87. int esp_gdbstub_readmem(intptr_t addr)
  88. {
  89. if (addr < 0x20000000 || addr >= 0x80000000) {
  90. /* see cpu_configure_region_protection */
  91. return -1;
  92. }
  93. uint32_t val_aligned = *(uint32_t *)(addr & (~3));
  94. uint32_t shift = (addr & 3) * 8;
  95. return (val_aligned >> shift) & 0xff;
  96. }
  97. int esp_gdbstub_writemem(unsigned int addr, unsigned char data)
  98. {
  99. if (addr < 0x20000000 || addr >= 0x80000000) {
  100. /* see cpu_configure_region_protection */
  101. return -1;
  102. }
  103. int *i = (int *)(addr & (~3));
  104. if ((addr & 3) == 0) {
  105. *i = (*i & 0xffffff00) | (data << 0);
  106. }
  107. if ((addr & 3) == 1) {
  108. *i = (*i & 0xffff00ff) | (data << 8);
  109. }
  110. if ((addr & 3) == 2) {
  111. *i = (*i & 0xff00ffff) | (data << 16);
  112. }
  113. if ((addr & 3) == 3) {
  114. *i = (*i & 0x00ffffff) | (data << 24);
  115. }
  116. asm volatile("ISYNC\nISYNC\n");
  117. return 0;
  118. }