feat(nemu): gdb remote debug
This commit is contained in:
parent
a54c0d6480
commit
7f0d1ba75a
22 changed files with 613 additions and 846 deletions
|
@ -17,8 +17,18 @@
|
|||
#define __CPU_CPU_H__
|
||||
|
||||
#include <common.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <gdbstub.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
size_t addr;
|
||||
bp_type_t type;
|
||||
} breakpoint_t;
|
||||
|
||||
void cpu_exec(uint64_t n);
|
||||
breakpoint_t *cpu_exec_with_bp(uint64_t n, breakpoint_t *bp, size_t len);
|
||||
|
||||
void set_nemu_state(int state, vaddr_t pc, int halt_ret);
|
||||
void invalid_inst(vaddr_t thispc);
|
||||
|
|
|
@ -16,39 +16,62 @@
|
|||
#ifndef __CPU_DECODE_H__
|
||||
#define __CPU_DECODE_H__
|
||||
|
||||
#include "types.h"
|
||||
#include <isa.h>
|
||||
|
||||
typedef enum { INST_NORMAL, INST_MEM_WRITE, INST_MEM_READ } inst_type_t;
|
||||
|
||||
typedef union {
|
||||
paddr_t rmem;
|
||||
paddr_t wmem;
|
||||
} inst_type_op;
|
||||
|
||||
typedef struct Decode {
|
||||
vaddr_t pc;
|
||||
vaddr_t snpc; // static next pc
|
||||
vaddr_t dnpc; // dynamic next pc
|
||||
inst_type_t inst_type;
|
||||
inst_type_op inst_value;
|
||||
ISADecodeInfo isa;
|
||||
} Decode;
|
||||
|
||||
// --- pattern matching mechanism ---
|
||||
__attribute__((always_inline))
|
||||
static inline void pattern_decode(const char *str, int len,
|
||||
uint64_t *key, uint64_t *mask, uint64_t *shift) {
|
||||
__attribute__((always_inline)) static inline void
|
||||
pattern_decode(const char *str, int len, uint64_t *key, uint64_t *mask,
|
||||
uint64_t *shift) {
|
||||
uint64_t __key = 0, __mask = 0, __shift = 0;
|
||||
#define macro(i) \
|
||||
if ((i) >= len) goto finish; \
|
||||
else { \
|
||||
char c = str[i]; \
|
||||
if (c != ' ') { \
|
||||
Assert(c == '0' || c == '1' || c == '?', \
|
||||
"invalid character '%c' in pattern string", c); \
|
||||
__key = (__key << 1) | (c == '1' ? 1 : 0); \
|
||||
__mask = (__mask << 1) | (c == '?' ? 0 : 1); \
|
||||
__shift = (c == '?' ? __shift + 1 : 0); \
|
||||
} \
|
||||
#define macro(i) \
|
||||
if ((i) >= len) \
|
||||
goto finish; \
|
||||
else { \
|
||||
char c = str[i]; \
|
||||
if (c != ' ') { \
|
||||
Assert(c == '0' || c == '1' || c == '?', \
|
||||
"invalid character '%c' in pattern string", c); \
|
||||
__key = (__key << 1) | (c == '1' ? 1 : 0); \
|
||||
__mask = (__mask << 1) | (c == '?' ? 0 : 1); \
|
||||
__shift = (c == '?' ? __shift + 1 : 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define macro2(i) macro(i); macro((i) + 1)
|
||||
#define macro4(i) macro2(i); macro2((i) + 2)
|
||||
#define macro8(i) macro4(i); macro4((i) + 4)
|
||||
#define macro16(i) macro8(i); macro8((i) + 8)
|
||||
#define macro32(i) macro16(i); macro16((i) + 16)
|
||||
#define macro64(i) macro32(i); macro32((i) + 32)
|
||||
#define macro2(i) \
|
||||
macro(i); \
|
||||
macro((i) + 1)
|
||||
#define macro4(i) \
|
||||
macro2(i); \
|
||||
macro2((i) + 2)
|
||||
#define macro8(i) \
|
||||
macro4(i); \
|
||||
macro4((i) + 4)
|
||||
#define macro16(i) \
|
||||
macro8(i); \
|
||||
macro8((i) + 8)
|
||||
#define macro32(i) \
|
||||
macro16(i); \
|
||||
macro16((i) + 16)
|
||||
#define macro64(i) \
|
||||
macro32(i); \
|
||||
macro32((i) + 32)
|
||||
macro64(0);
|
||||
panic("pattern too long");
|
||||
#undef macro
|
||||
|
@ -58,21 +81,24 @@ finish:
|
|||
*shift = __shift;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void pattern_decode_hex(const char *str, int len,
|
||||
uint64_t *key, uint64_t *mask, uint64_t *shift) {
|
||||
__attribute__((always_inline)) static inline void
|
||||
pattern_decode_hex(const char *str, int len, uint64_t *key, uint64_t *mask,
|
||||
uint64_t *shift) {
|
||||
uint64_t __key = 0, __mask = 0, __shift = 0;
|
||||
#define macro(i) \
|
||||
if ((i) >= len) goto finish; \
|
||||
else { \
|
||||
char c = str[i]; \
|
||||
if (c != ' ') { \
|
||||
Assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == '?', \
|
||||
"invalid character '%c' in pattern string", c); \
|
||||
__key = (__key << 4) | (c == '?' ? 0 : (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10); \
|
||||
__mask = (__mask << 4) | (c == '?' ? 0 : 0xf); \
|
||||
__shift = (c == '?' ? __shift + 4 : 0); \
|
||||
} \
|
||||
#define macro(i) \
|
||||
if ((i) >= len) \
|
||||
goto finish; \
|
||||
else { \
|
||||
char c = str[i]; \
|
||||
if (c != ' ') { \
|
||||
Assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == '?', \
|
||||
"invalid character '%c' in pattern string", c); \
|
||||
__key = (__key << 4) | (c == '?' ? 0 \
|
||||
: (c >= '0' && c <= '9') ? c - '0' \
|
||||
: c - 'a' + 10); \
|
||||
__mask = (__mask << 4) | (c == '?' ? 0 : 0xf); \
|
||||
__shift = (c == '?' ? __shift + 4 : 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
macro16(0);
|
||||
|
@ -84,18 +110,22 @@ finish:
|
|||
*shift = __shift;
|
||||
}
|
||||
|
||||
|
||||
// --- pattern matching wrappers for decode ---
|
||||
#define INSTPAT(pattern, ...) do { \
|
||||
uint64_t key, mask, shift; \
|
||||
pattern_decode(pattern, STRLEN(pattern), &key, &mask, &shift); \
|
||||
if ((((uint64_t)INSTPAT_INST(s) >> shift) & mask) == key) { \
|
||||
INSTPAT_MATCH(s, ##__VA_ARGS__); \
|
||||
goto *(__instpat_end); \
|
||||
} \
|
||||
} while (0)
|
||||
#define INSTPAT(pattern, ...) \
|
||||
do { \
|
||||
uint64_t key, mask, shift; \
|
||||
pattern_decode(pattern, STRLEN(pattern), &key, &mask, &shift); \
|
||||
if ((((uint64_t)INSTPAT_INST(s) >> shift) & mask) == key) { \
|
||||
INSTPAT_MATCH(s, ##__VA_ARGS__); \
|
||||
goto *(__instpat_end); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define INSTPAT_START(name) { const void ** __instpat_end = &&concat(__instpat_end_, name);
|
||||
#define INSTPAT_END(name) concat(__instpat_end_, name): ; }
|
||||
#define INSTPAT_START(name) \
|
||||
{ \
|
||||
const void **__instpat_end = &&concat(__instpat_end_, name);
|
||||
#define INSTPAT_END(name) \
|
||||
concat(__instpat_end_, name) :; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define __ISA_H__
|
||||
|
||||
// Located at src/isa/$(GUEST_ISA)/include/isa-def.h
|
||||
#include <gdbstub.h>
|
||||
#include <isa-def.h>
|
||||
|
||||
// The macro `__GUEST_ISA__` is defined in $(CFLAGS).
|
||||
|
@ -30,8 +31,11 @@ void init_isa();
|
|||
|
||||
// reg
|
||||
extern CPU_state cpu;
|
||||
extern arch_info_t isa_arch_info;
|
||||
void isa_reg_display();
|
||||
word_t isa_reg_str2val(const char *name, bool *success);
|
||||
int isa_read_reg(void *args, int regno, size_t *reg_value);
|
||||
int isa_write_reg(void *args, int regno, size_t data);
|
||||
|
||||
// exec
|
||||
struct Decode;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue