mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-08-06 07:00:05 +08:00
feat(gdbstub): bring GDB stub from esp-idf
Commit ID: 758db1e0
This commit is contained in:
91
components/esp_gdbstub/xtensa/esp_gdbstub_arch.h
Normal file
91
components/esp_gdbstub/xtensa/esp_gdbstub_arch.h
Normal file
@ -0,0 +1,91 @@
|
||||
// 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 <stdint.h>
|
||||
#include "freertos/xtensa_context.h"
|
||||
#include "gdbstub_target_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef XtExcFrame esp_gdbstub_frame_t;
|
||||
|
||||
/* GDB regfile structure, configuration dependent */
|
||||
typedef struct {
|
||||
uint32_t pc;
|
||||
uint32_t a[XCHAL_NUM_AREGS];
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
uint32_t lbeg;
|
||||
uint32_t lend;
|
||||
uint32_t lcount;
|
||||
#endif
|
||||
|
||||
uint32_t sar;
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
uint32_t windowbase;
|
||||
uint32_t windowstart;
|
||||
#endif
|
||||
|
||||
uint32_t configid0;
|
||||
uint32_t configid1;
|
||||
uint32_t ps;
|
||||
|
||||
#if XCHAL_HAVE_THREADPTR
|
||||
uint32_t threadptr;
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_BOOLEANS
|
||||
uint32_t br;
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
uint32_t scompare1;
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_MAC16
|
||||
uint32_t acclo;
|
||||
uint32_t acchi;
|
||||
uint32_t m0;
|
||||
uint32_t m1;
|
||||
uint32_t m2;
|
||||
uint32_t m3;
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_DFP_ACCEL
|
||||
uint32_t expstate;
|
||||
uint32_t f64r_lo;
|
||||
uint32_t f64r_hi;
|
||||
uint32_t f64s;
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_FP
|
||||
uint32_t f[16];
|
||||
uint32_t fcr;
|
||||
uint32_t fsr;
|
||||
#endif
|
||||
|
||||
#if GDBSTUB_EXTRA_TIE_SIZE > 0
|
||||
uint32_t tie[GDBSTUB_EXTRA_TIE_SIZE];
|
||||
#endif
|
||||
|
||||
} esp_gdbstub_gdb_regfile_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
118
components/esp_gdbstub/xtensa/gdbstub_xtensa.c
Normal file
118
components/esp_gdbstub/xtensa/gdbstub_xtensa.c
Normal file
@ -0,0 +1,118 @@
|
||||
// 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 <string.h>
|
||||
#include "esp_gdbstub.h"
|
||||
#include "esp_gdbstub_common.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if !XCHAL_HAVE_WINDOWED
|
||||
#warning "gdbstub_xtensa: revisit the implementation for Call0 ABI"
|
||||
#endif
|
||||
|
||||
static void init_regfile(esp_gdbstub_gdb_regfile_t *dst)
|
||||
{
|
||||
memset(dst, 0, sizeof(*dst));
|
||||
}
|
||||
|
||||
static void update_regfile_common(esp_gdbstub_gdb_regfile_t *dst)
|
||||
{
|
||||
if (dst->a[0] & 0x8000000U) {
|
||||
dst->a[0] = (dst->a[0] & 0x3fffffffU) | 0x40000000U;
|
||||
}
|
||||
if (!esp_stack_ptr_is_sane(dst->a[1])) {
|
||||
dst->a[1] = 0xDEADBEEF;
|
||||
}
|
||||
dst->windowbase = 0;
|
||||
dst->windowstart = 0x1;
|
||||
RSR(CONFIGID0, dst->configid0);
|
||||
RSR(CONFIGID1, dst->configid1);
|
||||
}
|
||||
|
||||
void esp_gdbstub_frame_to_regfile(const esp_gdbstub_frame_t *frame, esp_gdbstub_gdb_regfile_t *dst)
|
||||
{
|
||||
init_regfile(dst);
|
||||
const uint32_t *a_regs = (const uint32_t *) &frame->a0;
|
||||
dst->pc = (frame->pc & 0x3fffffffU) | 0x40000000U;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
dst->a[i] = a_regs[i];
|
||||
}
|
||||
for (int i = 16; i < 64; i++) {
|
||||
dst->a[i] = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
dst->lbeg = frame->lbeg;
|
||||
dst->lend = frame->lend;
|
||||
dst->lcount = frame->lcount;
|
||||
#endif
|
||||
|
||||
dst->ps = (frame->ps & PS_UM) ? (frame->ps & ~PS_EXCM) : frame->ps;
|
||||
dst->sar = frame->sar;
|
||||
update_regfile_common(dst);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_GDBSTUB_SUPPORT_TASKS
|
||||
|
||||
static void solicited_frame_to_regfile(const XtSolFrame *frame, esp_gdbstub_gdb_regfile_t *dst)
|
||||
{
|
||||
init_regfile(dst);
|
||||
const uint32_t *a_regs = (const uint32_t *) &frame->a0;
|
||||
dst->pc = (frame->pc & 0x3fffffffU) | 0x40000000U;
|
||||
|
||||
/* only 4 registers saved in the solicited frame */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
dst->a[i] = a_regs[i];
|
||||
}
|
||||
for (int i = 4; i < 64; i++) {
|
||||
dst->a[i] = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
dst->ps = (frame->ps & PS_UM) ? (frame->ps & ~PS_EXCM) : frame->ps;
|
||||
update_regfile_common(dst);
|
||||
}
|
||||
|
||||
/* 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 XtExcFrame *frame = (XtExcFrame *) dummy_tcb->top_of_stack;
|
||||
if (frame->exit != 0) {
|
||||
esp_gdbstub_frame_to_regfile(frame, dst);
|
||||
} else {
|
||||
const XtSolFrame *taskFrame = (const XtSolFrame *) dummy_tcb->top_of_stack;
|
||||
solicited_frame_to_regfile(taskFrame, dst);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_ESP_GDBSTUB_SUPPORT_TASKS
|
||||
|
||||
int esp_gdbstub_get_signal(const esp_gdbstub_frame_t *frame)
|
||||
{
|
||||
const char exccause_to_signal[] = {4, 31, 11, 11, 2, 6, 8, 0, 6, 7, 0, 0, 7, 7, 7, 7};
|
||||
if (frame->exccause > sizeof(exccause_to_signal)) {
|
||||
return 11;
|
||||
}
|
||||
return (int) exccause_to_signal[frame->exccause];
|
||||
}
|
Reference in New Issue
Block a user