From a7683fc2563155bedb0df6e872bc5ed537d0748b Mon Sep 17 00:00:00 2001 From: Jakob Hasse Date: Thu, 26 Nov 2020 13:38:09 +0800 Subject: [PATCH] [system/tools]: gdbstub support C3 Closes IDF-1757 Closes IDF-2489 --- components/esp_gdbstub/CMakeLists.txt | 19 +++-- .../esp_gdbstub/esp32c3/gdbstub_esp32c3.c | 83 +++++++++++++++++++ .../esp_gdbstub/riscv/esp_gdbstub_arch.h | 34 ++++++++ components/esp_gdbstub/riscv/gdbstub_riscv.c | 60 ++++++++++++++ 4 files changed, 188 insertions(+), 8 deletions(-) create mode 100644 components/esp_gdbstub/esp32c3/gdbstub_esp32c3.c create mode 100644 components/esp_gdbstub/riscv/esp_gdbstub_arch.h create mode 100644 components/esp_gdbstub/riscv/gdbstub_riscv.c diff --git a/components/esp_gdbstub/CMakeLists.txt b/components/esp_gdbstub/CMakeLists.txt index 74213d20a0..0d64fc4465 100644 --- a/components/esp_gdbstub/CMakeLists.txt +++ b/components/esp_gdbstub/CMakeLists.txt @@ -1,13 +1,16 @@ idf_build_get_property(target IDF_TARGET) -set(esp_gdbstub_srcs "src/gdbstub.c" - "src/packet.c" - "${target}/gdbstub_${target}.c" - "xtensa/gdbstub_xtensa.c") - -idf_component_register(SRCS "${esp_gdbstub_srcs}" - INCLUDE_DIRS "include" "xtensa" "${target}" +idf_component_register(SRCS "src/gdbstub.c" "src/packet.c" + INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "private_include" LDFRAGMENTS "linker.lf" REQUIRES "freertos" - PRIV_REQUIRES "soc" "xtensa" "esp_rom") + PRIV_REQUIRES "soc" "esp_rom") + +if(CONFIG_IDF_TARGET_ARCH_XTENSA) + target_include_directories(${COMPONENT_LIB} PUBLIC "xtensa" "${target}") + target_sources(${COMPONENT_LIB} PRIVATE "xtensa/gdbstub_xtensa.c" "${target}/gdbstub_${target}.c") +elseif(CONFIG_IDF_TARGET_ARCH_RISCV) + target_include_directories(${COMPONENT_LIB} PUBLIC "riscv" "${target}") + target_sources(${COMPONENT_LIB} PRIVATE "riscv/gdbstub_riscv.c" "${target}/gdbstub_${target}.c") +endif() diff --git a/components/esp_gdbstub/esp32c3/gdbstub_esp32c3.c b/components/esp_gdbstub/esp32c3/gdbstub_esp32c3.c new file mode 100644 index 0000000000..93d3a6016d --- /dev/null +++ b/components/esp_gdbstub/esp32c3/gdbstub_esp32c3.c @@ -0,0 +1,83 @@ +// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "soc/uart_periph.h" +#include "soc/gpio_periph.h" +#include "soc/soc.h" +#include "esp_gdbstub_common.h" +#include "sdkconfig.h" + +#define UART_NUM CONFIG_ESP_CONSOLE_UART_NUM + +#define GDBSTUB_MEM_REGION_COUNT 9 + +typedef struct { + intptr_t lower; + intptr_t upper; +} mem_bound_t; + +static const mem_bound_t mem_region_table [GDBSTUB_MEM_REGION_COUNT] = +{ + {SOC_DROM_LOW, SOC_DROM_HIGH}, + {SOC_IROM_LOW, SOC_IROM_HIGH}, + {SOC_IRAM_LOW, SOC_IRAM_HIGH}, + {SOC_DRAM_LOW, SOC_DRAM_HIGH}, + {SOC_IROM_MASK_LOW, SOC_IROM_MASK_HIGH}, + {SOC_DROM_MASK_LOW, SOC_DROM_MASK_HIGH}, + {SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH}, + // RTC DRAM and RTC DATA are identical with RTC IRAM + {SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH}, + {SOC_DEBUG_LOW, SOC_DEBUG_HIGH}, +}; + +static inline bool check_inside_valid_region(intptr_t addr) +{ + for (size_t i = 0; i < GDBSTUB_MEM_REGION_COUNT; i++) { + if (addr >= mem_region_table[i].lower && addr < mem_region_table[i].upper) { + return true; + } + } + return false; +} + +void esp_gdbstub_target_init() +{ +} + +int esp_gdbstub_getchar() +{ + while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_RXFIFO_CNT) == 0) { + ; + } + return REG_READ(UART_FIFO_AHB_REG(UART_NUM)); +} + +void esp_gdbstub_putchar(int c) +{ + while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_TXFIFO_CNT) >= 126) { + ; + } + REG_WRITE(UART_FIFO_AHB_REG(UART_NUM), c); +} + +int esp_gdbstub_readmem(intptr_t addr) +{ + if (!check_inside_valid_region(addr)) { + /* see esp_cpu_configure_region_protection */ + return -1; + } + uint32_t val_aligned = *(uint32_t *)(addr & (~3)); + uint32_t shift = (addr & 3) * 8; + return (val_aligned >> shift) & 0xff; +} diff --git a/components/esp_gdbstub/riscv/esp_gdbstub_arch.h b/components/esp_gdbstub/riscv/esp_gdbstub_arch.h new file mode 100644 index 0000000000..d7c3aca0e7 --- /dev/null +++ b/components/esp_gdbstub/riscv/esp_gdbstub_arch.h @@ -0,0 +1,34 @@ +// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include +#include "riscv/rvruntime-frames.h" +#include "gdbstub_target_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef RvExcFrame esp_gdbstub_frame_t; + +/* GDB regfile structure, configuration dependent */ +typedef struct { + uint32_t x[32]; + uint32_t pc; +} esp_gdbstub_gdb_regfile_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_gdbstub/riscv/gdbstub_riscv.c b/components/esp_gdbstub/riscv/gdbstub_riscv.c new file mode 100644 index 0000000000..7cded48a34 --- /dev/null +++ b/components/esp_gdbstub/riscv/gdbstub_riscv.c @@ -0,0 +1,60 @@ +// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "esp_gdbstub.h" +#include "esp_gdbstub_common.h" +#include "soc/cpu.h" +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +static void init_regfile(esp_gdbstub_gdb_regfile_t *dst) +{ + memset(dst, 0, sizeof(*dst)); +} + +void esp_gdbstub_frame_to_regfile(const esp_gdbstub_frame_t *frame, esp_gdbstub_gdb_regfile_t *dst) +{ + init_regfile(dst); + dst->pc = frame->mepc; + + // We omit register x0 here since it's the zero register and always hard-wired to 0. + // See The RISC-V Instruction Set Manual Volume I: Unprivileged ISA Document Version 20191213 for more details. + memcpy(&(dst->x[1]), &frame->ra, sizeof(uint32_t) * 31); +} + +#ifdef CONFIG_ESP_GDBSTUB_SUPPORT_TASKS + +/* Represents FreeRTOS TCB structure */ +typedef struct { + uint8_t *top_of_stack; + /* Other members aren't needed */ +} dummy_tcb_t; + + +void esp_gdbstub_tcb_to_regfile(TaskHandle_t tcb, esp_gdbstub_gdb_regfile_t *dst) +{ + const dummy_tcb_t *dummy_tcb = (const dummy_tcb_t *) tcb; + + const RvExcFrame *frame = (RvExcFrame *) dummy_tcb->top_of_stack; + esp_gdbstub_frame_to_regfile(frame, dst); +} + +#endif // CONFIG_ESP_GDBSTUB_SUPPORT_TASKS + +int esp_gdbstub_get_signal(const esp_gdbstub_frame_t *frame) +{ + return 5; // SIGTRAP, see IDF-2490 +}