diff options
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | gdb-xml/avr-cpu.xml | 49 | ||||
-rw-r--r-- | target/avr/cpu.c | 4 | ||||
-rw-r--r-- | target/avr/cpu.h | 2 | ||||
-rw-r--r-- | target/avr/gdbstub.c | 84 |
5 files changed, 140 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index dda872ef2a..7833db3abe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -171,6 +171,7 @@ AVR TCG CPUs M: Michael Rolnik <mrolnik@gmail.com> R: Sarah Harris <S.E.Harris@kent.ac.uk> S: Maintained +F: gdb-xml/avr-cpu.xml F: target/avr/ CRIS TCG CPUs diff --git a/gdb-xml/avr-cpu.xml b/gdb-xml/avr-cpu.xml new file mode 100644 index 0000000000..c4747f5b40 --- /dev/null +++ b/gdb-xml/avr-cpu.xml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!-- Register numbers are hard-coded in order to maintain backward + compatibility with older versions of tools that didn't use xml + register descriptions. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.riscv.cpu"> + <reg name="r0" bitsize="8" type="int" regnum="0"/> + <reg name="r1" bitsize="8" type="int"/> + <reg name="r2" bitsize="8" type="int"/> + <reg name="r3" bitsize="8" type="int"/> + <reg name="r4" bitsize="8" type="int"/> + <reg name="r5" bitsize="8" type="int"/> + <reg name="r6" bitsize="8" type="int"/> + <reg name="r7" bitsize="8" type="int"/> + <reg name="r8" bitsize="8" type="int"/> + <reg name="r9" bitsize="8" type="int"/> + <reg name="r10" bitsize="8" type="int"/> + <reg name="r11" bitsize="8" type="int"/> + <reg name="r12" bitsize="8" type="int"/> + <reg name="r13" bitsize="8" type="int"/> + <reg name="r14" bitsize="8" type="int"/> + <reg name="r15" bitsize="8" type="int"/> + <reg name="r16" bitsize="8" type="int"/> + <reg name="r17" bitsize="8" type="int"/> + <reg name="r18" bitsize="8" type="int"/> + <reg name="r19" bitsize="8" type="int"/> + <reg name="r20" bitsize="8" type="int"/> + <reg name="r21" bitsize="8" type="int"/> + <reg name="r22" bitsize="8" type="int"/> + <reg name="r23" bitsize="8" type="int"/> + <reg name="r24" bitsize="8" type="int"/> + <reg name="r25" bitsize="8" type="int"/> + <reg name="r26" bitsize="8" type="int"/> + <reg name="r27" bitsize="8" type="int"/> + <reg name="r28" bitsize="8" type="int"/> + <reg name="r29" bitsize="8" type="int"/> + <reg name="r30" bitsize="8" type="int"/> + <reg name="r31" bitsize="8" type="int"/> + <reg name="sreg" bitsize="8" type="int"/> + <reg name="sp" bitsize="8" type="int"/> + <reg name="pc" bitsize="8" type="int"/> +</feature> diff --git a/target/avr/cpu.c b/target/avr/cpu.c index be06875225..05dd5551c7 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c @@ -210,4 +210,8 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data) cc->disas_set_info = avr_cpu_disas_set_info; cc->tcg_initialize = avr_cpu_tcg_init; cc->synchronize_from_tb = avr_cpu_synchronize_from_tb; + cc->gdb_read_register = avr_cpu_gdb_read_register; + cc->gdb_write_register = avr_cpu_gdb_write_register; + cc->gdb_num_core_regs = 35; + cc->gdb_core_xml_file = "avr-cpu.xml"; } diff --git a/target/avr/cpu.h b/target/avr/cpu.h index 99875e50b1..8d99122804 100644 --- a/target/avr/cpu.h +++ b/target/avr/cpu.h @@ -123,6 +123,8 @@ extern const struct VMStateDescription vms_avr_cpu; void avr_cpu_do_interrupt(CPUState *cpu); bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req); hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); +int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #define cpu_list avr_cpu_list #define cpu_signal_handler cpu_avr_signal_handler diff --git a/target/avr/gdbstub.c b/target/avr/gdbstub.c new file mode 100644 index 0000000000..c28ed67efe --- /dev/null +++ b/target/avr/gdbstub.c @@ -0,0 +1,84 @@ +/* + * QEMU AVR gdbstub + * + * Copyright (c) 2016-2020 Michael Rolnik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ + +#include "qemu/osdep.h" +#include "exec/gdbstub.h" + +int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) +{ + AVRCPU *cpu = AVR_CPU(cs); + CPUAVRState *env = &cpu->env; + + /* R */ + if (n < 32) { + return gdb_get_reg8(mem_buf, env->r[n]); + } + + /* SREG */ + if (n == 32) { + uint8_t sreg = cpu_get_sreg(env); + + return gdb_get_reg8(mem_buf, sreg); + } + + /* SP */ + if (n == 33) { + return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff); + } + + /* PC */ + if (n == 34) { + return gdb_get_reg32(mem_buf, env->pc_w * 2); + } + + return 0; +} + +int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) +{ + AVRCPU *cpu = AVR_CPU(cs); + CPUAVRState *env = &cpu->env; + + /* R */ + if (n < 32) { + env->r[n] = *mem_buf; + return 1; + } + + /* SREG */ + if (n == 32) { + cpu_set_sreg(env, *mem_buf); + return 1; + } + + /* SP */ + if (n == 33) { + env->sp = lduw_p(mem_buf); + return 2; + } + + /* PC */ + if (n == 34) { + env->pc_w = ldl_p(mem_buf) / 2; + return 4; + } + + return 0; +} |