From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375326; cv=none; d=zohomail.com; s=zohoarc; b=GQmKFD6jOfGz1Fgw3QzvklRceNs4zH9XY2T3n+jhO1ZLfsYgvH1czwXJJZney48TT81YbVQbO6bK/e2qQvfllecumY2uI8zec5C0Y1ADBLfmbKZRsIRepolhI0SsFcwpD4rv/dEHLWl7+bkm71A7fUXd+6JCW6kW18TjHZuu2SA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375326; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=2PMQVyXFv2eii9jVDF9+QNazFj1KogeI6P2QrVCcPeo=; b=Il7oQQ5YSvLwOeAkX7mANMZLJsiUqbjvYDgm+7a3jVnTUs5pWLfnmUvzuMtnQfwg+H3y/VSHGu4Oa+RSMbUzyAiKonUq1DIGn8UE0rKYrYNhx8qMaIFo23vfCLQgHzFgmjbSOAX9BWvWTJddePBnB7HfMH+hjZdUuqFckvJ19n8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375326604823.4232190676313; Sat, 18 Jan 2020 11:22:06 -0800 (PST) Received: from localhost ([::1]:44034 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istfZ-0005qu-25 for importer@patchew.org; Sat, 18 Jan 2020 14:22:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49585) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istc0-0002KQ-Im for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istbv-0003Jb-Sd for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:24 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:43718) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istbv-0003It-GV for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:19 -0500 Received: by mail-wr1-x442.google.com with SMTP id d16so25734156wre.10 for ; Sat, 18 Jan 2020 11:18:19 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.17.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:18:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2PMQVyXFv2eii9jVDF9+QNazFj1KogeI6P2QrVCcPeo=; b=Nk13pImp2zJ+UVyZmZkVpeWRoyImIToxECvFlCrdrvCPPh2+FTvRXxPAGErsXC1Xr9 brknI8Dxwg3HvalsAZdL9YcOPf5M1QstvuA6V4VVCa+W9c0nUnv81ZcQrkqhevTqjw1a z2on4NRo1GdZwt2IFNL95aqSGwIihJXy6G9Ggf7Gy6u/kXFhfPv9jsO0mcFJrWSMCmci m5VQCuBbqyEOBS8w8PjVITHGeb6UhkGZAaSPRGn29B5Kw3ez09DT+vz9mWJMzdgeNYAe Yw8CBgURJnYHp+3ofFOZTl4c8AFCzIK6qiT+8g4pjXFxwHaWvtcBrjtUzVvgNXiooKYb GV5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2PMQVyXFv2eii9jVDF9+QNazFj1KogeI6P2QrVCcPeo=; b=BvewscMhSzVtaNdpqWVJmXy4swxk1l5VTzNrEfwqaBtth3gH0QDlknTmcnyR5ok+If ppQx2ucFi08JrVLEyP4sOz/JnZX+UsI1sQenBLDRriltNKccCK5LFU3I734YFgMleMV0 0mWpGcjE3WICm2YWOgrCoDq6q5qpzaDUNKpQF7+4N5kRohfen6MpTZ48xQyvbMllHP4q U1Wj6Ps1E3KVjgAVVzoZw+iJ2cCAThwHKoXYypw7oZT5drV3xFSDz/d3ZnFoj5JZI4fT PceMtHPWoiBYYbMETvrrhN1oQuDYVED00sq0MCI8KUOBgoQZOf4wwyYt+7jTkagYxR+2 CluQ== X-Gm-Message-State: APjAAAUvBvydhkedFm7KOiz38Lwm3107hox5+DLyQqkDH94gr9Uh+znQ zA+Bq3MLiVQn865UkCbhl3F0GXXUunjQSCVR X-Google-Smtp-Source: APXvYqy61YIuFJn0KmaBNfqwJDuCd3r5nPxC88i5Y+ApUMUAY3BZEU8BSqcW9n1tpfdabTcuIYrx3A== X-Received: by 2002:adf:978c:: with SMTP id s12mr9677155wrb.408.1579375097545; Sat, 18 Jan 2020 11:18:17 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 01/21] target/avr: Add outward facing interfaces and core CPU logic Date: Sat, 18 Jan 2020 21:13:56 +0200 Message-Id: <20200118191416.19934-2-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, Sarah Harris , dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) This includes: - CPU data structures - object model classes and functions - migration functions - GDB hooks Co-developed-by: Michael Rolnik Co-developed-by: Sarah Harris Signed-off-by: Michael Rolnik Signed-off-by: Sarah Harris Signed-off-by: Michael Rolnik Acked-by: Igor Mammedov Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/cpu-param.h | 37 ++ target/avr/cpu-qom.h | 54 +++ target/avr/cpu.h | 258 +++++++++++++ target/avr/cpu.c | 826 +++++++++++++++++++++++++++++++++++++++++ target/avr/gdbstub.c | 84 +++++ target/avr/machine.c | 121 ++++++ gdb-xml/avr-cpu.xml | 49 +++ 7 files changed, 1429 insertions(+) create mode 100644 target/avr/cpu-param.h create mode 100644 target/avr/cpu-qom.h create mode 100644 target/avr/cpu.h create mode 100644 target/avr/cpu.c create mode 100644 target/avr/gdbstub.c create mode 100644 target/avr/machine.c create mode 100644 gdb-xml/avr-cpu.xml diff --git a/target/avr/cpu-param.h b/target/avr/cpu-param.h new file mode 100644 index 0000000000..0c29ce4223 --- /dev/null +++ b/target/avr/cpu-param.h @@ -0,0 +1,37 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#ifndef AVR_CPU_PARAM_H +#define AVR_CPU_PARAM_H + +#define TARGET_LONG_BITS 32 +/* + * TARGET_PAGE_BITS cannot be more than 8 bits because + * 1. all IO registers occupy [0x0000 .. 0x00ff] address range, and they + * should be implemented as a device and not memory + * 2. SRAM starts at the address 0x0100 + */ +#define TARGET_PAGE_BITS 8 +#define TARGET_PHYS_ADDR_SPACE_BITS 24 +#define TARGET_VIRT_ADDR_SPACE_BITS 24 +#define NB_MMU_MODES 2 + + +#endif diff --git a/target/avr/cpu-qom.h b/target/avr/cpu-qom.h new file mode 100644 index 0000000000..e28b58c897 --- /dev/null +++ b/target/avr/cpu-qom.h @@ -0,0 +1,54 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#ifndef QEMU_AVR_QOM_H +#define QEMU_AVR_QOM_H + +#include "hw/core/cpu.h" + +#define TYPE_AVR_CPU "avr-cpu" + +#define AVR_CPU_CLASS(klass) \ + OBJECT_CLASS_CHECK(AVRCPUClass, (klass), TYPE_AVR_CPU) +#define AVR_CPU(obj) \ + OBJECT_CHECK(AVRCPU, (obj), TYPE_AVR_CPU) +#define AVR_CPU_GET_CLASS(obj) \ + OBJECT_GET_CLASS(AVRCPUClass, (obj), TYPE_AVR_CPU) + +/** + * AVRCPUClass: + * @parent_realize: The parent class' realize handler. + * @parent_reset: The parent class' reset handler. + * @vr: Version Register value. + * + * A AVR CPU model. + */ +typedef struct AVRCPUClass { + /*< private >*/ + CPUClass parent_class; + /*< public >*/ + DeviceRealize parent_realize; + void (*parent_reset)(CPUState *cpu); +} AVRCPUClass; + +typedef struct AVRCPU AVRCPU; + + +#endif /* !defined (QEMU_AVR_CPU_QOM_H) */ diff --git a/target/avr/cpu.h b/target/avr/cpu.h new file mode 100644 index 0000000000..b74bcf01ae --- /dev/null +++ b/target/avr/cpu.h @@ -0,0 +1,258 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#ifndef QEMU_AVR_CPU_H +#define QEMU_AVR_CPU_H + +#include "cpu-qom.h" +#include "exec/cpu-defs.h" + +#define TCG_GUEST_DEFAULT_MO 0 +#define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU +#define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX) +#define CPU_RESOLVING_TYPE TYPE_AVR_CPU + +/* + * AVR has two memory spaces, data & code. + * e.g. both have 0 address + * ST/LD instructions access data space + * LPM/SPM and instruction fetching access code memory space + */ +#define MMU_CODE_IDX 0 +#define MMU_DATA_IDX 1 + +#define EXCP_RESET 1 +#define EXCP_INT(n) (EXCP_RESET + (n) + 1) + +/* Number of CPU registers */ +#define NUMBER_OF_CPU_REGISTERS 32 +/* Number of IO registers accessible by ld/st/in/out */ +#define NUMBER_OF_IO_REGISTERS 64 + +/* + * Offsets of AVR memory regions in host memory space. + * + * This is needed because the AVR has separate code and data address + * spaces that both have start from zero but have to go somewhere in + * host memory. + * + * It's also useful to know where some things are, like the IO registers. + */ +/* Flash program memory */ +#define OFFSET_CODE 0x00000000 +/* CPU registers, IO registers, and SRAM */ +#define OFFSET_DATA 0x00800000 +/* CPU registers specifically, these are mapped at the start of data */ +#define OFFSET_CPU_REGISTERS OFFSET_DATA +/* + * IO registers, including status register, stack pointer, and memory + * mapped peripherals, mapped just after CPU registers + */ +#define OFFSET_IO_REGISTERS (OFFSET_DATA + NUMBER_OF_CPU_REGISTERS) + +#define EF_AVR_MACH 0x7F + +typedef enum AVRFeature { + AVR_FEATURE_SRAM, + + AVR_FEATURE_1_BYTE_PC, + AVR_FEATURE_2_BYTE_PC, + AVR_FEATURE_3_BYTE_PC, + + AVR_FEATURE_1_BYTE_SP, + AVR_FEATURE_2_BYTE_SP, + + AVR_FEATURE_BREAK, + AVR_FEATURE_DES, + AVR_FEATURE_RMW, /* Read Modify Write - XCH LAC LAS LAT */ + + AVR_FEATURE_EIJMP_EICALL, + AVR_FEATURE_IJMP_ICALL, + AVR_FEATURE_JMP_CALL, + + AVR_FEATURE_ADIW_SBIW, + + AVR_FEATURE_SPM, + AVR_FEATURE_SPMX, + + AVR_FEATURE_ELPMX, + AVR_FEATURE_ELPM, + AVR_FEATURE_LPMX, + AVR_FEATURE_LPM, + + AVR_FEATURE_MOVW, + AVR_FEATURE_MUL, + AVR_FEATURE_RAMPD, + AVR_FEATURE_RAMPX, + AVR_FEATURE_RAMPY, + AVR_FEATURE_RAMPZ, +} AVRFeature; + +typedef struct CPUAVRState CPUAVRState; + +struct CPUAVRState { + uint32_t pc_w; /* 0x003fffff up to 22 bits */ + + uint32_t sregC; /* 0x00000001 1 bit */ + uint32_t sregZ; /* 0x00000001 1 bit */ + uint32_t sregN; /* 0x00000001 1 bit */ + uint32_t sregV; /* 0x00000001 1 bit */ + uint32_t sregS; /* 0x00000001 1 bit */ + uint32_t sregH; /* 0x00000001 1 bit */ + uint32_t sregT; /* 0x00000001 1 bit */ + uint32_t sregI; /* 0x00000001 1 bit */ + + uint32_t rampD; /* 0x00ff0000 8 bits */ + uint32_t rampX; /* 0x00ff0000 8 bits */ + uint32_t rampY; /* 0x00ff0000 8 bits */ + uint32_t rampZ; /* 0x00ff0000 8 bits */ + uint32_t eind; /* 0x00ff0000 8 bits */ + + uint32_t r[NUMBER_OF_CPU_REGISTERS]; /* 8 bits each */ + uint32_t sp; /* 16 bits */ + + uint32_t skip; /* if set skip instruction */ + + uint64_t intsrc; /* interrupt sources */ + bool fullacc; /* CPU/MEM if true MEM only otherwise */ + + uint32_t features; +}; + +/** + * AVRCPU: + * @env: #CPUAVRState + * + * A AVR CPU. + */ +typedef struct AVRCPU { + /*< private >*/ + CPUState parent_obj; + /*< public >*/ + + CPUNegativeOffsetState neg; + CPUAVRState env; +} AVRCPU; + +#ifndef CONFIG_USER_ONLY +extern const struct VMStateDescription vms_avr_cpu; +#endif + +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, uint8_t *buf, int reg); +int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); + +static inline int avr_feature(CPUAVRState *env, AVRFeature feature) +{ + return (env->features & (1U << feature)) !=3D 0; +} + +static inline void avr_set_feature(CPUAVRState *env, int feature) +{ + env->features |=3D (1U << feature); +} + +#define cpu_list avr_cpu_list +#define cpu_signal_handler cpu_avr_signal_handler +#define cpu_mmu_index avr_cpu_mmu_index + +static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch) +{ + return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX; +} + +void avr_cpu_tcg_init(void); + +void avr_cpu_list(void); +int cpu_avr_exec(CPUState *cpu); +int cpu_avr_signal_handler(int host_signum, void *pinfo, void *puc); +int avr_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, + int rw, int mmu_idx); +int avr_cpu_memory_rw_debug(CPUState *cs, vaddr address, uint8_t *buf, + int len, bool is_write); + +enum { + TB_FLAGS_FULL_ACCESS =3D 1, + TB_FLAGS_SKIP =3D 2, +}; + +static inline void cpu_get_tb_cpu_state(CPUAVRState *env, target_ulong *pc, + target_ulong *cs_base, uint32_t *pflags) +{ + uint32_t flags =3D 0; + + *pc =3D env->pc_w * 2; + *cs_base =3D 0; + + if (env->fullacc) { + flags |=3D TB_FLAGS_FULL_ACCESS; + } + if (env->skip) { + flags |=3D TB_FLAGS_SKIP; + } + + *pflags =3D flags; +} + +static inline int cpu_interrupts_enabled(CPUAVRState *env) +{ + return env->sregI !=3D 0; +} + +static inline uint8_t cpu_get_sreg(CPUAVRState *env) +{ + uint8_t sreg; + sreg =3D (env->sregC) << 0 + | (env->sregZ) << 1 + | (env->sregN) << 2 + | (env->sregV) << 3 + | (env->sregS) << 4 + | (env->sregH) << 5 + | (env->sregT) << 6 + | (env->sregI) << 7; + return sreg; +} + +static inline void cpu_set_sreg(CPUAVRState *env, uint8_t sreg) +{ + env->sregC =3D (sreg >> 0) & 0x01; + env->sregZ =3D (sreg >> 1) & 0x01; + env->sregN =3D (sreg >> 2) & 0x01; + env->sregV =3D (sreg >> 3) & 0x01; + env->sregS =3D (sreg >> 4) & 0x01; + env->sregH =3D (sreg >> 5) & 0x01; + env->sregT =3D (sreg >> 6) & 0x01; + env->sregI =3D (sreg >> 7) & 0x01; +} + +bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr); + +typedef CPUAVRState CPUArchState; +typedef AVRCPU ArchCPU; + +#include "exec/cpu-all.h" + +const char *avr_flags_to_cpu_type(uint32_t flags, const char *def_cpu_type= ); + +#endif /* !defined (QEMU_AVR_CPU_H) */ diff --git a/target/avr/cpu.c b/target/avr/cpu.c new file mode 100644 index 0000000000..c74c5106fe --- /dev/null +++ b/target/avr/cpu.c @@ -0,0 +1,826 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/qemu-print.h" +#include "exec/exec-all.h" +#include "cpu.h" +#include "disas/dis-asm.h" + +static void avr_cpu_set_pc(CPUState *cs, vaddr value) +{ + AVRCPU *cpu =3D AVR_CPU(cs); + + cpu->env.pc_w =3D value / 2; /* internally PC points to words */ +} + +static bool avr_cpu_has_work(CPUState *cs) +{ + AVRCPU *cpu =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + + return (cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_RE= SET)) + && cpu_interrupts_enabled(env); +} + +static void avr_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + AVRCPU *cpu =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + + env->pc_w =3D tb->pc / 2; /* internally PC points to words */ +} + +static void avr_cpu_reset(CPUState *cs) +{ + AVRCPU *cpu =3D AVR_CPU(cs); + AVRCPUClass *mcc =3D AVR_CPU_GET_CLASS(cpu); + CPUAVRState *env =3D &cpu->env; + + mcc->parent_reset(cs); + + env->pc_w =3D 0; + env->sregI =3D 1; + env->sregC =3D 0; + env->sregZ =3D 0; + env->sregN =3D 0; + env->sregV =3D 0; + env->sregS =3D 0; + env->sregH =3D 0; + env->sregT =3D 0; + + env->rampD =3D 0; + env->rampX =3D 0; + env->rampY =3D 0; + env->rampZ =3D 0; + env->eind =3D 0; + env->sp =3D 0; + + env->skip =3D 0; + + memset(env->r, 0, sizeof(env->r)); + + tlb_flush(cs); +} + +static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) +{ + info->mach =3D bfd_arch_avr; + info->print_insn =3D NULL; +} + +static void avr_cpu_realizefn(DeviceState *dev, Error **errp) +{ + CPUState *cs =3D CPU(dev); + AVRCPUClass *mcc =3D AVR_CPU_GET_CLASS(dev); + Error *local_err =3D NULL; + + cpu_exec_realizefn(cs, &local_err); + if (local_err !=3D NULL) { + error_propagate(errp, local_err); + return; + } + qemu_init_vcpu(cs); + cpu_reset(cs); + + mcc->parent_realize(dev, errp); +} + +static void avr_cpu_set_int(void *opaque, int irq, int level) +{ + AVRCPU *cpu =3D opaque; + CPUAVRState *env =3D &cpu->env; + CPUState *cs =3D CPU(cpu); + + uint64_t mask =3D (1ull << irq); + if (level) { + env->intsrc |=3D mask; + cpu_interrupt(cs, CPU_INTERRUPT_HARD); + } else { + env->intsrc &=3D ~mask; + if (env->intsrc =3D=3D 0) { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } + } +} + +static void avr_cpu_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + + cpu_set_cpustate_pointers(cpu); + +#ifndef CONFIG_USER_ONLY + /* Set the number of interrupts supported by the CPU. */ + qdev_init_gpio_in(DEVICE(cpu), avr_cpu_set_int, + sizeof(cpu->env.intsrc) * 8); +#endif +} + +static ObjectClass *avr_cpu_class_by_name(const char *cpu_model) +{ + ObjectClass *oc; + + oc =3D object_class_by_name(cpu_model); + if (object_class_dynamic_cast(oc, TYPE_AVR_CPU) =3D=3D NULL || + object_class_is_abstract(oc)) { + oc =3D NULL; + } + return oc; +} + +static void avr_cpu_dump_state(CPUState *cs, FILE *f, int flags) +{ + AVRCPU *cpu =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + int i; + + qemu_fprintf(f, "\n"); + qemu_fprintf(f, "PC: %06x\n", env->pc_w); + qemu_fprintf(f, "SP: %04x\n", env->sp); + qemu_fprintf(f, "rampD: %02x\n", env->rampD >> 16); + qemu_fprintf(f, "rampX: %02x\n", env->rampX >> 16); + qemu_fprintf(f, "rampY: %02x\n", env->rampY >> 16); + qemu_fprintf(f, "rampZ: %02x\n", env->rampZ >> 16); + qemu_fprintf(f, "EIND: %02x\n", env->eind >> 16); + qemu_fprintf(f, "X: %02x%02x\n", env->r[27], env->r[26]); + qemu_fprintf(f, "Y: %02x%02x\n", env->r[29], env->r[28]); + qemu_fprintf(f, "Z: %02x%02x\n", env->r[31], env->r[30]); + qemu_fprintf(f, "SREG: [ %c %c %c %c %c %c %c %c ]\n", + env->sregI ? 'I' : '-', + env->sregT ? 'T' : '-', + env->sregH ? 'H' : '-', + env->sregS ? 'S' : '-', + env->sregV ? 'V' : '-', + env->sregN ? '-' : 'N', /* Zf has negative logic */ + env->sregZ ? 'Z' : '-', + env->sregC ? 'I' : '-'); + qemu_fprintf(f, "SKIP: %02x\n", env->skip); + + qemu_fprintf(f, "\n"); + for (i =3D 0; i < ARRAY_SIZE(env->r); i++) { + qemu_fprintf(f, "R[%02d]: %02x ", i, env->r[i]); + + if ((i % 8) =3D=3D 7) { + qemu_fprintf(f, "\n"); + } + } + qemu_fprintf(f, "\n"); +} + +static void avr_cpu_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + CPUClass *cc =3D CPU_CLASS(oc); + AVRCPUClass *mcc =3D AVR_CPU_CLASS(oc); + + mcc->parent_realize =3D dc->realize; + dc->realize =3D avr_cpu_realizefn; + + mcc->parent_reset =3D cc->reset; + cc->reset =3D avr_cpu_reset; + + cc->class_by_name =3D avr_cpu_class_by_name; + + cc->has_work =3D avr_cpu_has_work; + cc->do_interrupt =3D avr_cpu_do_interrupt; + cc->cpu_exec_interrupt =3D avr_cpu_exec_interrupt; + cc->dump_state =3D avr_cpu_dump_state; + cc->set_pc =3D avr_cpu_set_pc; +#if !defined(CONFIG_USER_ONLY) + cc->memory_rw_debug =3D avr_cpu_memory_rw_debug; +#endif +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault =3D avr_cpu_handle_mmu_fault; +#else + cc->get_phys_page_debug =3D avr_cpu_get_phys_page_debug; + cc->vmsd =3D &vms_avr_cpu; +#endif + cc->disas_set_info =3D avr_cpu_disas_set_info; + cc->tlb_fill =3D avr_cpu_tlb_fill; + cc->tcg_initialize =3D avr_cpu_tcg_init; + cc->synchronize_from_tb =3D avr_cpu_synchronize_from_tb; + cc->gdb_read_register =3D avr_cpu_gdb_read_register; + cc->gdb_write_register =3D avr_cpu_gdb_write_register; + cc->gdb_num_core_regs =3D 35; + cc->gdb_core_xml_file =3D "avr-cpu.xml"; +} + +/* + * Setting features of AVR core type avr1 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * at90s1200, attiny11, attiny12, attiny15, attiny28 + */ +static void avr_avr1_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); +} + +/* + * Setting features of AVR core type avr2 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * at90s2313, at90s2323, at90s2333, at90s2343, attiny22, attiny26, at90s44= 14, + * at90s4433, at90s4434, at90s8515, at90c8534, at90s8535 + */ +static void avr_avr2_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); +} + +/* + * Setting features of AVR core type avr25 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * ata5272, ata6616c, attiny13, attiny13a, attiny2313, attiny2313a, attiny= 24, + * attiny24a, attiny4313, attiny44, attiny44a, attiny441, attiny84, attiny= 84a, + * attiny25, attiny45, attiny85, attiny261, attiny261a, attiny461, attiny4= 61a, + * attiny861, attiny861a, attiny43u, attiny87, attiny48, attiny88, attiny8= 28, + * attiny841, at86rf401 + */ +static void avr_avr25_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); +} + +/* + * Setting features of AVR core type avr3 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * at43usb355, at76c711 + */ +static void avr_avr3_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); +} + +/* + * Setting features of AVR core type avr31 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atmega103, at43usb320 + */ +static void avr_avr31_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_RAMPZ); + avr_set_feature(env, AVR_FEATURE_ELPM); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); +} + +/* + * Setting features of AVR core type avr35 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * ata5505, ata6617c, ata664251, at90usb82, at90usb162, atmega8u2, atmega1= 6u2, + * atmega32u2, attiny167, attiny1634 + */ +static void avr_avr35_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); +} + +/* + * Setting features of AVR core type avr4 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * ata6285, ata6286, ata6289, ata6612c, atmega8, atmega8a, atmega48, atmeg= a48a, + * atmega48p, atmega48pa, atmega48pb, atmega88, atmega88a, atmega88p, + * atmega88pa, atmega88pb, atmega8515, atmega8535, atmega8hva, at90pwm1, + * at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, at90pwm81 + */ +static void avr_avr4_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); +} + +/* + * Setting features of AVR core type avr5 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * ata5702m322, ata5782, ata5790, ata5790n, ata5791, ata5795, ata5831, ata= 6613c, + * ata6614q, ata8210, ata8510, atmega16, atmega16a, atmega161, atmega162, + * atmega163, atmega164a, atmega164p, atmega164pa, atmega165, atmega165a, + * atmega165p, atmega165pa, atmega168, atmega168a, atmega168p, atmega168pa, + * atmega168pb, atmega169, atmega169a, atmega169p, atmega169pa, atmega16hv= b, + * atmega16hvbrevb, atmega16m1, atmega16u4, atmega32a, atmega32, atmega323, + * atmega324a, atmega324p, atmega324pa, atmega325, atmega325a, atmega325p, + * atmega325pa, atmega3250, atmega3250a, atmega3250p, atmega3250pa, atmega= 328, + * atmega328p, atmega328pb, atmega329, atmega329a, atmega329p, atmega329pa, + * atmega3290, atmega3290a, atmega3290p, atmega3290pa, atmega32c1, atmega3= 2m1, + * atmega32u4, atmega32u6, atmega406, atmega64, atmega64a, atmega640, atme= ga644, + * atmega644a, atmega644p, atmega644pa, atmega645, atmega645a, atmega645p, + * atmega6450, atmega6450a, atmega6450p, atmega649, atmega649a, atmega649p, + * atmega6490, atmega16hva, atmega16hva2, atmega32hvb, atmega6490a, atmega= 6490p, + * atmega64c1, atmega64m1, atmega64hve, atmega64hve2, atmega64rfr2, + * atmega644rfr2, atmega32hvbrevb, at90can32, at90can64, at90pwm161, at90p= wm216, + * at90pwm316, at90scr100, at90usb646, at90usb647, at94k, m3000 + */ +static void avr_avr5_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); +} + +/* + * Setting features of AVR core type avr51 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atmega128, atmega128a, atmega1280, atmega1281, atmega1284, atmega1284p, + * atmega128rfa1, atmega128rfr2, atmega1284rfr2, at90can128, at90usb1286, + * at90usb1287 + */ +static void avr_avr51_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_RAMPZ); + avr_set_feature(env, AVR_FEATURE_ELPMX); + avr_set_feature(env, AVR_FEATURE_ELPM); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); +} + +/* + * Setting features of AVR core type avr6 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atmega2560, atmega2561, atmega256rfr2, atmega2564rfr2 + */ +static void avr_avr6_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_3_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_RAMPZ); + avr_set_feature(env, AVR_FEATURE_EIJMP_EICALL); + avr_set_feature(env, AVR_FEATURE_ELPMX); + avr_set_feature(env, AVR_FEATURE_ELPM); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); +} + +/* + * Setting features of AVR core type avrtiny + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * attiny4, attiny5, attiny9, attiny10, attiny20, attiny40 + */ +static void avr_avrtiny_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_1_BYTE_SP); +} + +/* + * Setting features of AVR core type xmega2 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atxmega8e5, atxmega16a4, atxmega16d4, atxmega16e5, atxmega32a4, atxmega= 32c3, + * atxmega32d3, atxmega32d4, atxmega16a4u, atxmega16c4, atxmega32a4u, + * atxmega32c4, atxmega32e5 + */ +static void avr_xmega2_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); + avr_set_feature(env, AVR_FEATURE_RMW); +} + +/* + * Setting features of AVR core type xmega3 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * attiny212, attiny214, attiny412, attiny414, attiny416, attiny417, attin= y814, + * attiny816, attiny817, attiny1614, attiny1616, attiny1617, attiny3214, + * attiny3216, attiny3217, atmega808, atmega809, atmega1608, atmega1609, + * atmega3208, atmega3209, atmega4808, atmega4809 + */ +static void avr_xmega3_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); + avr_set_feature(env, AVR_FEATURE_RMW); +} + +/* + * Setting features of AVR core type xmega4 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atxmega64a3, atxmega64d3, atxmega64a3u, atxmega64a4u, atxmega64b1, + * atxmega64b3, atxmega64c3, atxmega64d4 + */ +static void avr_xmega4_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_ELPMX); + avr_set_feature(env, AVR_FEATURE_ELPM); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); + avr_set_feature(env, AVR_FEATURE_RMW); +} + +/* + * Setting features of AVR core type xmega5 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atxmega64a1, atxmega64a1u + */ +static void avr_xmega5_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_2_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_RAMPD); + avr_set_feature(env, AVR_FEATURE_RAMPX); + avr_set_feature(env, AVR_FEATURE_RAMPY); + avr_set_feature(env, AVR_FEATURE_RAMPZ); + avr_set_feature(env, AVR_FEATURE_ELPMX); + avr_set_feature(env, AVR_FEATURE_ELPM); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); + avr_set_feature(env, AVR_FEATURE_RMW); +} + +/* + * Setting features of AVR core type xmega6 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atxmega128a3, atxmega128d3, atxmega192a3, atxmega192d3, atxmega256a3, + * atxmega256a3b, atxmega256a3bu, atxmega256d3, atxmega128a3u, atxmega128b= 1, + * atxmega128b3, atxmega128c3, atxmega128d4, atxmega192a3u, atxmega192c3, + * atxmega256a3u, atxmega256c3, atxmega384c3, atxmega384d3 + */ +static void avr_xmega6_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_3_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_RAMPZ); + avr_set_feature(env, AVR_FEATURE_EIJMP_EICALL); + avr_set_feature(env, AVR_FEATURE_ELPMX); + avr_set_feature(env, AVR_FEATURE_ELPM); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); + avr_set_feature(env, AVR_FEATURE_RMW); +} + +/* + * Setting features of AVR core type xmega7 + * -------------------------------------- + * + * This type of AVR core is present in the following AVR MCUs: + * + * atxmega128a1, atxmega128a1u, atxmega128a4u + */ +static void avr_xmega7_initfn(Object *obj) +{ + AVRCPU *cpu =3D AVR_CPU(obj); + CPUAVRState *env =3D &cpu->env; + + avr_set_feature(env, AVR_FEATURE_LPM); + avr_set_feature(env, AVR_FEATURE_IJMP_ICALL); + avr_set_feature(env, AVR_FEATURE_ADIW_SBIW); + avr_set_feature(env, AVR_FEATURE_SRAM); + avr_set_feature(env, AVR_FEATURE_BREAK); + + avr_set_feature(env, AVR_FEATURE_3_BYTE_PC); + avr_set_feature(env, AVR_FEATURE_2_BYTE_SP); + avr_set_feature(env, AVR_FEATURE_RAMPD); + avr_set_feature(env, AVR_FEATURE_RAMPX); + avr_set_feature(env, AVR_FEATURE_RAMPY); + avr_set_feature(env, AVR_FEATURE_RAMPZ); + avr_set_feature(env, AVR_FEATURE_EIJMP_EICALL); + avr_set_feature(env, AVR_FEATURE_ELPMX); + avr_set_feature(env, AVR_FEATURE_ELPM); + avr_set_feature(env, AVR_FEATURE_JMP_CALL); + avr_set_feature(env, AVR_FEATURE_LPMX); + avr_set_feature(env, AVR_FEATURE_MOVW); + avr_set_feature(env, AVR_FEATURE_MUL); + avr_set_feature(env, AVR_FEATURE_RMW); +} + +typedef struct AVRCPUInfo { + const char *name; + void (*initfn)(Object *obj); +} AVRCPUInfo; + + +static void avr_cpu_list_entry(gpointer data, gpointer user_data) +{ + const char *typename =3D object_class_get_name(OBJECT_CLASS(data)); + + qemu_printf("%s\n", typename); +} + +void avr_cpu_list(void) +{ + GSList *list; + list =3D object_class_get_list_sorted(TYPE_AVR_CPU, false); + g_slist_foreach(list, avr_cpu_list_entry, NULL); + g_slist_free(list); +} + +#define DEFINE_AVR_CPU_TYPE(model, initfn) \ + { \ + .parent =3D TYPE_AVR_CPU, \ + .instance_init =3D initfn, \ + .name =3D AVR_CPU_TYPE_NAME(model), \ + } + +static const TypeInfo avr_cpu_type_info[] =3D { + { + .name =3D TYPE_AVR_CPU, + .parent =3D TYPE_CPU, + .instance_size =3D sizeof(AVRCPU), + .instance_init =3D avr_cpu_initfn, + .class_size =3D sizeof(AVRCPUClass), + .class_init =3D avr_cpu_class_init, + .abstract =3D true, + }, + DEFINE_AVR_CPU_TYPE("avrtiny", avr_avrtiny_initfn), + DEFINE_AVR_CPU_TYPE("avr1", avr_avr1_initfn), + DEFINE_AVR_CPU_TYPE("avr2", avr_avr2_initfn), + DEFINE_AVR_CPU_TYPE("avr25", avr_avr25_initfn), + DEFINE_AVR_CPU_TYPE("avr3", avr_avr3_initfn), + DEFINE_AVR_CPU_TYPE("avr31", avr_avr31_initfn), + DEFINE_AVR_CPU_TYPE("avr35", avr_avr35_initfn), + DEFINE_AVR_CPU_TYPE("avr4", avr_avr4_initfn), + DEFINE_AVR_CPU_TYPE("avr5", avr_avr5_initfn), + DEFINE_AVR_CPU_TYPE("avr51", avr_avr51_initfn), + DEFINE_AVR_CPU_TYPE("avr6", avr_avr6_initfn), + DEFINE_AVR_CPU_TYPE("xmega2", avr_xmega2_initfn), + DEFINE_AVR_CPU_TYPE("xmega3", avr_xmega3_initfn), + DEFINE_AVR_CPU_TYPE("xmega4", avr_xmega4_initfn), + DEFINE_AVR_CPU_TYPE("xmega5", avr_xmega5_initfn), + DEFINE_AVR_CPU_TYPE("xmega6", avr_xmega6_initfn), + DEFINE_AVR_CPU_TYPE("xmega7", avr_xmega7_initfn), +}; + +const char *avr_flags_to_cpu_type(uint32_t flags, const char *def_cpu_type) +{ + switch (flags & EF_AVR_MACH) { + case bfd_mach_avr1: + return AVR_CPU_TYPE_NAME("avr1"); + case bfd_mach_avr2: + return AVR_CPU_TYPE_NAME("avr2"); + case bfd_mach_avr25: + return AVR_CPU_TYPE_NAME("avr25"); + case bfd_mach_avr3: + return AVR_CPU_TYPE_NAME("avr3"); + case bfd_mach_avr31: + return AVR_CPU_TYPE_NAME("avr31"); + case bfd_mach_avr35: + return AVR_CPU_TYPE_NAME("avr35"); + case bfd_mach_avr4: + return AVR_CPU_TYPE_NAME("avr4"); + case bfd_mach_avr5: + return AVR_CPU_TYPE_NAME("avr5"); + case bfd_mach_avr51: + return AVR_CPU_TYPE_NAME("avr51"); + case bfd_mach_avr6: + return AVR_CPU_TYPE_NAME("avr6"); + case bfd_mach_avrtiny: + return AVR_CPU_TYPE_NAME("avrtiny"); + case bfd_mach_avrxmega2: + return AVR_CPU_TYPE_NAME("xmega2"); + case bfd_mach_avrxmega3: + return AVR_CPU_TYPE_NAME("xmega3"); + case bfd_mach_avrxmega4: + return AVR_CPU_TYPE_NAME("xmega4"); + case bfd_mach_avrxmega5: + return AVR_CPU_TYPE_NAME("xmega5"); + case bfd_mach_avrxmega6: + return AVR_CPU_TYPE_NAME("xmega6"); + case bfd_mach_avrxmega7: + return AVR_CPU_TYPE_NAME("xmega7"); + default: + return def_cpu_type; + } +} + +DEFINE_TYPES(avr_cpu_type_info) diff --git a/target/avr/gdbstub.c b/target/avr/gdbstub.c new file mode 100644 index 0000000000..733184c08f --- /dev/null +++ b/target/avr/gdbstub.c @@ -0,0 +1,84 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#include "qemu/osdep.h" +#include "exec/gdbstub.h" + +int avr_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +{ + AVRCPU *cpu =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + + /* R */ + if (n < 32) { + return gdb_get_reg8(mem_buf, env->r[n]); + } + + /* SREG */ + if (n =3D=3D 32) { + uint8_t sreg =3D cpu_get_sreg(env); + + return gdb_get_reg8(mem_buf, sreg); + } + + /* SP */ + if (n =3D=3D 33) { + return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff); + } + + /* PC */ + if (n =3D=3D 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 =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + + /* R */ + if (n < 32) { + env->r[n] =3D *mem_buf; + return 1; + } + + /* SREG */ + if (n =3D=3D 32) { + cpu_set_sreg(env, *mem_buf); + return 1; + } + + /* SP */ + if (n =3D=3D 33) { + env->sp =3D lduw_p(mem_buf); + return 2; + } + + /* PC */ + if (n =3D=3D 34) { + env->pc_w =3D ldl_p(mem_buf) / 2; + return 4; + } + + return 0; +} diff --git a/target/avr/machine.c b/target/avr/machine.c new file mode 100644 index 0000000000..ba44bd042b --- /dev/null +++ b/target/avr/machine.c @@ -0,0 +1,121 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "migration/cpu.h" + +static int get_sreg(QEMUFile *f, void *opaque, size_t size, + const VMStateField *field) +{ + CPUAVRState *env =3D opaque; + uint8_t sreg; + + sreg =3D qemu_get_byte(f); + cpu_set_sreg(env, sreg); + return 0; +} + +static int put_sreg( + QEMUFile *f, void *opaque, size_t size, + const VMStateField *field, QJSON *vmdesc) +{ + CPUAVRState *env =3D opaque; + uint8_t sreg =3D cpu_get_sreg(env); + + qemu_put_byte(f, sreg); + return 0; +} + +static const VMStateInfo vms_sreg =3D { + .name =3D "sreg", + .get =3D get_sreg, + .put =3D put_sreg, +}; + +static int get_segment( + QEMUFile *f, void *opaque, size_t size, const VMStateField *field) +{ + uint32_t *ramp =3D opaque; + uint8_t temp; + + temp =3D qemu_get_byte(f); + *ramp =3D ((uint32_t)temp) << 16; + return 0; +} + +static int put_segment( + QEMUFile *f, void *opaque, size_t size, + const VMStateField *field, QJSON *vmdesc) +{ + uint32_t *ramp =3D opaque; + uint8_t temp =3D *ramp >> 16; + + qemu_put_byte(f, temp); + return 0; +} + +static const VMStateInfo vms_rampD =3D { + .name =3D "rampD", + .get =3D get_segment, + .put =3D put_segment, +}; +static const VMStateInfo vms_rampX =3D { + .name =3D "rampX", + .get =3D get_segment, + .put =3D put_segment, +}; +static const VMStateInfo vms_rampY =3D { + .name =3D "rampY", + .get =3D get_segment, + .put =3D put_segment, +}; +static const VMStateInfo vms_rampZ =3D { + .name =3D "rampZ", + .get =3D get_segment, + .put =3D put_segment, +}; +static const VMStateInfo vms_eind =3D { + .name =3D "eind", + .get =3D get_segment, + .put =3D put_segment, +}; + +const VMStateDescription vms_avr_cpu =3D { + .name =3D "cpu", + .version_id =3D 0, + .minimum_version_id =3D 0, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(env.pc_w, AVRCPU), + VMSTATE_UINT32(env.sp, AVRCPU), + VMSTATE_UINT32(env.skip, AVRCPU), + + VMSTATE_UINT32_ARRAY(env.r, AVRCPU, NUMBER_OF_CPU_REGISTERS), + + VMSTATE_SINGLE(env, AVRCPU, 0, vms_sreg, CPUAVRState), + VMSTATE_SINGLE(env.rampD, AVRCPU, 0, vms_rampD, uint32_t), + VMSTATE_SINGLE(env.rampX, AVRCPU, 0, vms_rampX, uint32_t), + VMSTATE_SINGLE(env.rampY, AVRCPU, 0, vms_rampY, uint32_t), + VMSTATE_SINGLE(env.rampZ, AVRCPU, 0, vms_rampZ, uint32_t), + VMSTATE_SINGLE(env.eind, AVRCPU, 0, vms_eind, uint32_t), + + VMSTATE_END_OF_LIST() + } +}; 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375532; cv=none; d=zohomail.com; s=zohoarc; b=HNHhLvoMGRSiqpvPi3O3lioWwDtCFMBU3zUyOrpjcJYJ5zAVG3dmVNZnsb8KQz1KS1iffwnFuS6sSV9GnF854bcp7s0WPLKSunXOk4SmVhvuMjaOB6RAFHQZ/yrKW+IXYFFx4B2doJfHeOq8SJXBOMr0tj94yeitJyRJvEqWPz0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375532; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=BFMvBIwEmzMpT6j62QfwS0B1jIXEni64EJzW7QdABNk=; b=Y0Isi0W5t6XENNZOoCjM3Yq8jwWbk2+AqUR5xWPR1roixL9KYQ759MNwQjGgJmtZ3upQNYqZec4nHftKcGdl0mRQ6EGzLTASPGJioPhMAdbXmlrfzwjuQBBTh6mGBI7BVL3z/MUgS6YL5sfUkUKOjG+IEP5JNBi0Lk2LFslsKwM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375532470717.533484622666; Sat, 18 Jan 2020 11:25:32 -0800 (PST) Received: from localhost ([::1]:44109 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istit-0002gE-4J for importer@patchew.org; Sat, 18 Jan 2020 14:25:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49615) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istcK-0002o7-4v for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istcH-0003cJ-UZ for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:44 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:42579) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istcH-0003bg-My for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:41 -0500 Received: by mail-wr1-x441.google.com with SMTP id q6so25639758wro.9 for ; Sat, 18 Jan 2020 11:18:41 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.18.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:18:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BFMvBIwEmzMpT6j62QfwS0B1jIXEni64EJzW7QdABNk=; b=K8ijRS29tVbmFm80mf6EnCWuSWWo1EEYBiobPhyQAuoj49MonPLJar7VwF++WyELU7 2WMyW7vJ10nYifMZnGRlwigOxHAe+zgF7P8ej5bsA5yBb8x8e89YUTVs5ZAT3cPxlcZ7 qR0I3C0nx1pDLgmyIqV7cprYDJkWYxYxSJcc9ILmu7bmf8yZHTZGIkkTMr/vXQa2i2ZV 6J0R1Ttq4jwHdkLOaJreYVGaM6SEJQtkcrZP9kLg1/ABnY3z9WQqOp+Q3cuworBgmCYa d43m9lpDhFbzENLUlrelzbnKln7wGcHnTo8YOMTLqlJMtnx+joDBrH61hS9CdmfOLsfp 9CnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BFMvBIwEmzMpT6j62QfwS0B1jIXEni64EJzW7QdABNk=; b=dhfVfErwx+NtQ8XTlyfG4sT7Rz/HyMx9g9dTwxUTolw4UNAo2Fmu6Yzoq6im2FxHfL 7vOw394PDGyeRLGUs86+WULKnrw7ch3Od9zHvQqixRz9ek5OlMZkk2do5MWekkRiK7Dg 1Wb3bS40mTCsTAiw0leoeq95ES6qQKuZCWGP+eDjHKYxRy9cyyr12hgtwJ6Zz2hwYee6 02DK0raDyATMEZtHypE52/bMl8+xaQoo31xKVMADRVN/W2XhB3Sg5WXDPHBq+pqAh1RG ZpaYy+J+eBoQCoUtwIkl3BZJtZtwSCJbElASxVYFYduBQ4OMv9DOEQbDcsMW0PQ/FNYV BVbw== X-Gm-Message-State: APjAAAXPul/6T+0mWnLS5lJ52/kjzjpq8Mcr4yG/6SlNnBd+Y5A6oIoD L4adxIOE5eVazj9AqqaruReguE3lB5JecY9U X-Google-Smtp-Source: APXvYqwQe3iJCHl3Mba4SycrbbCj/D4lC/5W2NBUobegVQf5ruc/+kfIOSnwxR+P5SmTXNzHF21/WQ== X-Received: by 2002:adf:b605:: with SMTP id f5mr9376207wre.383.1579375120445; Sat, 18 Jan 2020 11:18:40 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 02/21] target/avr: Add instruction helpers Date: Sat, 18 Jan 2020 21:13:57 +0200 Message-Id: <20200118191416.19934-3-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Stubs for unimplemented instructions and helpers for instructions that need= to interact with QEMU. SPM and WDR are unimplemented because they require emulation of complex per= ipherals. The implementation of SLEEP is very limited due to the lack of peripherals = to generate wake interrupts. Memory access instructions are implemented here because some address ranges= actually refer to CPU registers. Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/helper.h | 29 ++++ target/avr/helper.c | 347 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 376 insertions(+) create mode 100644 target/avr/helper.h create mode 100644 target/avr/helper.c diff --git a/target/avr/helper.h b/target/avr/helper.h new file mode 100644 index 0000000000..bf087504a8 --- /dev/null +++ b/target/avr/helper.h @@ -0,0 +1,29 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +DEF_HELPER_1(wdr, void, env) +DEF_HELPER_1(debug, void, env) +DEF_HELPER_1(break, void, env) +DEF_HELPER_1(sleep, void, env) +DEF_HELPER_1(unsupported, void, env) +DEF_HELPER_3(outb, void, env, i32, i32) +DEF_HELPER_2(inb, tl, env, i32) +DEF_HELPER_3(fullwr, void, env, i32, i32) +DEF_HELPER_2(fullrd, tl, env, i32) diff --git a/target/avr/helper.c b/target/avr/helper.c new file mode 100644 index 0000000000..c43a4b7340 --- /dev/null +++ b/target/avr/helper.c @@ -0,0 +1,347 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "exec/helper-proto.h" + +bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + bool ret =3D false; + CPUClass *cc =3D CPU_GET_CLASS(cs); + AVRCPU *cpu =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + + if (interrupt_request & CPU_INTERRUPT_RESET) { + if (cpu_interrupts_enabled(env)) { + cs->exception_index =3D EXCP_RESET; + cc->do_interrupt(cs); + + cs->interrupt_request &=3D ~CPU_INTERRUPT_RESET; + + ret =3D true; + } + } + if (interrupt_request & CPU_INTERRUPT_HARD) { + if (cpu_interrupts_enabled(env) && env->intsrc !=3D 0) { + int index =3D ctz32(env->intsrc); + cs->exception_index =3D EXCP_INT(index); + cc->do_interrupt(cs); + + env->intsrc &=3D env->intsrc - 1; /* clear the interrupt */ + cs->interrupt_request &=3D ~CPU_INTERRUPT_HARD; + + ret =3D true; + } + } + return ret; +} + +void avr_cpu_do_interrupt(CPUState *cs) +{ + AVRCPU *cpu =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + + uint32_t ret =3D env->pc_w; + int vector =3D 0; + int size =3D avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1; + int base =3D 0; + + if (cs->exception_index =3D=3D EXCP_RESET) { + vector =3D 0; + } else if (env->intsrc !=3D 0) { + vector =3D ctz32(env->intsrc) + 1; + } + + if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) { + cpu_stb_data(env, env->sp--, (ret & 0x0000ff)); + cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8); + cpu_stb_data(env, env->sp--, (ret & 0xff0000) >> 16); + } else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) { + cpu_stb_data(env, env->sp--, (ret & 0x0000ff)); + cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8); + } else { + cpu_stb_data(env, env->sp--, (ret & 0x0000ff)); + } + + env->pc_w =3D base + vector * size; + env->sregI =3D 0; /* clear Global Interrupt Flag */ + + cs->exception_index =3D -1; +} + +int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf, + int len, bool is_write) +{ + return cpu_memory_rw_debug(cs, addr, buf, len, is_write); +} + +hwaddr avr_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) +{ + return addr; /* I assume 1:1 address correspondance */ +} + +int avr_cpu_handle_mmu_fault( + CPUState *cs, vaddr address, int size, int rw, int mmu_idx) +{ + /* currently it's assumed that this will never happen */ + cs->exception_index =3D EXCP_DEBUG; + cpu_dump_state(cs, stderr, 0); + return 1; +} + +bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr) +{ + int prot =3D 0; + MemTxAttrs attrs =3D {}; + uint32_t paddr; + + address &=3D TARGET_PAGE_MASK; + + if (mmu_idx =3D=3D MMU_CODE_IDX) { + /* access to code in flash */ + paddr =3D OFFSET_CODE + address; + prot =3D PAGE_READ | PAGE_EXEC; + if (paddr + TARGET_PAGE_SIZE > OFFSET_DATA) { + error_report("execution left flash memory"); + exit(1); + } + } else if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS)= { + /* + * access to CPU registers, exit and rebuilt this TB to use full a= ccess + * incase it touches specially handled registers like SREG or SP + */ + AVRCPU *cpu =3D AVR_CPU(cs); + CPUAVRState *env =3D &cpu->env; + env->fullacc =3D 1; + cpu_loop_exit_restore(cs, retaddr); + } else { + /* access to memory. nothing special */ + paddr =3D OFFSET_DATA + address; + prot =3D PAGE_READ | PAGE_WRITE; + } + + tlb_set_page_with_attrs( + cs, address, paddr, attrs, prot, mmu_idx, TARGET_PAGE_SIZE); + + return true; +} + +void helper_sleep(CPUAVRState *env) +{ + CPUState *cs =3D env_cpu(env); + + cs->exception_index =3D EXCP_HLT; + cpu_loop_exit(cs); +} + +void helper_unsupported(CPUAVRState *env) +{ + CPUState *cs =3D env_cpu(env); + + /* + * I count not find what happens on the real platform, so + * it's EXCP_DEBUG for meanwhile + */ + cs->exception_index =3D EXCP_DEBUG; + if (qemu_loglevel_mask(LOG_UNIMP)) { + qemu_log("UNSUPPORTED\n"); + cpu_dump_state(cs, stderr, 0); + } + cpu_loop_exit(cs); +} + +void helper_debug(CPUAVRState *env) +{ + CPUState *cs =3D env_cpu(env); + + cs->exception_index =3D EXCP_DEBUG; + cpu_loop_exit(cs); +} + +void helper_break(CPUAVRState *env) +{ + CPUState *cs =3D env_cpu(env); + + cs->exception_index =3D EXCP_DEBUG; + cpu_loop_exit(cs); +} + +void helper_wdr(CPUAVRState *env) +{ + CPUState *cs =3D env_cpu(env); + + /* WD is not implemented yet, placeholder */ + cs->exception_index =3D EXCP_DEBUG; + cpu_loop_exit(cs); +} + +/* + * This function implements IN instruction + * + * It does the following + * a. if an IO register belongs to CPU, its value is read and returned + * b. otherwise io address is translated to mem address and physical memo= ry + * is read. + * c. it caches the value for sake of SBI, SBIC, SBIS & CBI implementation + * + */ +target_ulong helper_inb(CPUAVRState *env, uint32_t port) +{ + target_ulong data =3D 0; + + switch (port) { + case 0x38: /* RAMPD */ + data =3D 0xff & (env->rampD >> 16); + break; + case 0x39: /* RAMPX */ + data =3D 0xff & (env->rampX >> 16); + break; + case 0x3a: /* RAMPY */ + data =3D 0xff & (env->rampY >> 16); + break; + case 0x3b: /* RAMPZ */ + data =3D 0xff & (env->rampZ >> 16); + break; + case 0x3c: /* EIND */ + data =3D 0xff & (env->eind >> 16); + break; + case 0x3d: /* SPL */ + data =3D env->sp & 0x00ff; + break; + case 0x3e: /* SPH */ + data =3D env->sp >> 8; + break; + case 0x3f: /* SREG */ + data =3D cpu_get_sreg(env); + break; + default: + /* not a special register, pass to normal memory access */ + cpu_physical_memory_read(OFFSET_IO_REGISTERS + port, &data, 1); + } + + return data; +} + +/* + * This function implements OUT instruction + * + * It does the following + * a. if an IO register belongs to CPU, its value is written into the re= gister + * b. otherwise io address is translated to mem address and physical mem= ory + * is written. + * c. it caches the value for sake of SBI, SBIC, SBIS & CBI implementati= on + * + */ +void helper_outb(CPUAVRState *env, uint32_t port, uint32_t data) +{ + data &=3D 0x000000ff; + + switch (port) { + case 0x38: /* RAMPD */ + if (avr_feature(env, AVR_FEATURE_RAMPD)) { + env->rampD =3D (data & 0xff) << 16; + } + break; + case 0x39: /* RAMPX */ + if (avr_feature(env, AVR_FEATURE_RAMPX)) { + env->rampX =3D (data & 0xff) << 16; + } + break; + case 0x3a: /* RAMPY */ + if (avr_feature(env, AVR_FEATURE_RAMPY)) { + env->rampY =3D (data & 0xff) << 16; + } + break; + case 0x3b: /* RAMPZ */ + if (avr_feature(env, AVR_FEATURE_RAMPZ)) { + env->rampZ =3D (data & 0xff) << 16; + } + break; + case 0x3c: /* EIDN */ + env->eind =3D (data & 0xff) << 16; + break; + case 0x3d: /* SPL */ + env->sp =3D (env->sp & 0xff00) | (data); + break; + case 0x3e: /* SPH */ + if (avr_feature(env, AVR_FEATURE_2_BYTE_SP)) { + env->sp =3D (env->sp & 0x00ff) | (data << 8); + } + break; + case 0x3f: /* SREG */ + cpu_set_sreg(env, data); + break; + default: + /* not a special register, pass to normal memory access */ + cpu_physical_memory_write(OFFSET_IO_REGISTERS + port, &data, 1); + } +} + +/* + * this function implements LD instruction when there is a posibility to = read + * from a CPU register + */ +target_ulong helper_fullrd(CPUAVRState *env, uint32_t addr) +{ + uint8_t data; + + env->fullacc =3D false; + + if (addr < NUMBER_OF_CPU_REGISTERS) { + /* CPU registers */ + data =3D env->r[addr]; + } else if (addr < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) { + /* IO registers */ + data =3D helper_inb(env, addr - NUMBER_OF_CPU_REGISTERS); + } else { + /* memory */ + cpu_physical_memory_read(OFFSET_DATA + addr, &data, 1); + } + return data; +} + +/* + * this function implements ST instruction when there is a posibility to = write + * into a CPU register + */ +void helper_fullwr(CPUAVRState *env, uint32_t data, uint32_t addr) +{ + env->fullacc =3D false; + + /* Following logic assumes this: */ + assert(OFFSET_CPU_REGISTERS =3D=3D OFFSET_DATA); + assert(OFFSET_IO_REGISTERS =3D=3D OFFSET_CPU_REGISTERS + + NUMBER_OF_CPU_REGISTERS); + + if (addr < NUMBER_OF_CPU_REGISTERS) { + /* CPU registers */ + env->r[addr] =3D data; + } else if (addr < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) { + /* IO registers */ + helper_outb(env, addr - NUMBER_OF_CPU_REGISTERS, data); + } else { + /* memory */ + cpu_physical_memory_write(OFFSET_DATA + addr, &data, 1); + } +} --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375674; cv=none; d=zohomail.com; s=zohoarc; b=dg8EuXbkSjwdPiouiNA2d2YRqbGVuk88pDaMNqq4ixMaKA7ONjFwmodVPc3KQA+fERBdz8RMkGVwHsT6z2jhYyq11yD9tWS0gJEO6El0+zllJG5eVZyS9YCy3V1lwhrgVIGPxbadVsiD3GzquQLo1hhlm5ZqOj3fh1sK+tgTCys= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375674; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=GX/AGeaj9ABxhp4/AZJflicRhmKLYIGNABhlODWYu6w=; b=jwY5495ElNcfyMswq9bsoJCWP1mLjMot5chswcYV5aEMCcn1nkHOibJXQMVBa3liBn+C3EdinSt6els6It5QBHQtdJgwD/YqnVkHyzvzpgagIlB3mL4RHvTasSGWKI1ZGJToJNkC6UrfBv7tulYpGJeXe+3RqOBp7WP2OSCCnA4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375674218984.6292765840061; Sat, 18 Jan 2020 11:27:54 -0800 (PST) Received: from localhost ([::1]:44142 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istlA-0005hM-VY for importer@patchew.org; Sat, 18 Jan 2020 14:27:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49648) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istcR-0002yn-Ei for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istcP-0003jT-SJ for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:51 -0500 Received: from mail-wm1-x329.google.com ([2a00:1450:4864:20::329]:35360) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istcP-0003iO-LW for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:18:49 -0500 Received: by mail-wm1-x329.google.com with SMTP id p17so10846730wmb.0 for ; Sat, 18 Jan 2020 11:18:49 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.18.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:18:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=GX/AGeaj9ABxhp4/AZJflicRhmKLYIGNABhlODWYu6w=; b=MEP3tboUil220q2pElFrPCZqTZ6SksqZXeqkStt21a5XgWj+vUgYqs67qEQbzH7POb KzQnTQH1MwmQGI2qfTee3DfIjd8lD+JKYJ5F/Q0spkkA/drGArKiQmEbnr6IWGERBvDn BYEUUGKwAm5CO72hOQD3nrrKshKMWyJsNahrvEY/fULFZurx5g/oHLVPzwQgtAWUxmrp c9V2PN2SR+aUHa5/9lMaF2wmKO7mkvuGAsxu0qgzQ0Cn/QKivPz7palKjOMYvp4sWfoR 419G2BvfwIvfzD77N0bsU7mT1QtClieVX1khaIlnFl5EN5a0Ni4X12ZsU9vDUMsb3ria H31A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GX/AGeaj9ABxhp4/AZJflicRhmKLYIGNABhlODWYu6w=; b=YglGkVjtN5ddMg3liYLKqIcpo4zgoQJ0mlsqc/hfMR1QTMGti9s10I2cg4dKSFmoRc mMvPkaX9KGkC2D9El9SgI6F1HnWqgD/+6whID9VSs1WgPGJ7Q9FVadbvxzEtzXk02Ko/ iiiXn8qeN0pBWiNoK2fLVBGZ/sY9DmnGlZg3Lw/H2eCgqRMu11dXJn5jCM5kbIBKXg7Q /waFfVYAUTHXjrQdo1epfFXPfb8V5QESiLdyngXxm843CNKHPfmZuUGUOBCGQkybDhrQ Am1PLbtzTScPmufAjVXP4N+xGl5OyfefA1US81Z8wc834DlfJo39AjbKc8MOaJxZ4Y/X eY0w== X-Gm-Message-State: APjAAAXZMtNMYEoxa1xX1iNdr5OnWFoN4x43ivvmg1jqSDeDREgC2xWt mFgOc4rmn9hqq91yu56GkTDGUL4Dav3I7cA3 X-Google-Smtp-Source: APXvYqwvw84WPk7OkZkF6rIToFN5xMR0s/S6F3rKwgUlEDIRCPKoXng0dgHcd+MIk34TgyHMx5yfGw== X-Received: by 2002:a05:600c:2050:: with SMTP id p16mr10800801wmg.176.1579375128441; Sat, 18 Jan 2020 11:18:48 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 03/21] target/avr: Add instruction translation - Registers definition Date: Sat, 18 Jan 2020 21:13:58 +0200 Message-Id: <20200118191416.19934-4-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::329 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Signed-off-by: Michael Rolnik Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/translate.c | 172 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 target/avr/translate.c diff --git a/target/avr/translate.c b/target/avr/translate.c new file mode 100644 index 0000000000..241083dc2d --- /dev/null +++ b/target/avr/translate.c @@ -0,0 +1,172 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +#include "qemu/osdep.h" +#include "qemu/qemu-print.h" +#include "tcg/tcg.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "tcg/tcg-op.h" +#include "exec/cpu_ldst.h" +#include "exec/helper-proto.h" +#include "exec/helper-gen.h" +#include "exec/log.h" +#include "exec/translator.h" +#include "exec/gen-icount.h" + +/* + * Define if you want a BREAK instruction translated to a breakpoint + * Active debugging connection is assumed + * This is for + * https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tes= ts + * tests + */ +#undef BREAKPOINT_ON_BREAK + +static TCGv cpu_pc; + +static TCGv cpu_Cf; +static TCGv cpu_Zf; +static TCGv cpu_Nf; +static TCGv cpu_Vf; +static TCGv cpu_Sf; +static TCGv cpu_Hf; +static TCGv cpu_Tf; +static TCGv cpu_If; + +static TCGv cpu_rampD; +static TCGv cpu_rampX; +static TCGv cpu_rampY; +static TCGv cpu_rampZ; + +static TCGv cpu_r[NUMBER_OF_CPU_REGISTERS]; +static TCGv cpu_eind; +static TCGv cpu_sp; + +static TCGv cpu_skip; + +static const char reg_names[NUMBER_OF_CPU_REGISTERS][8] =3D { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", +}; +#define REG(x) (cpu_r[x]) + +enum { + DISAS_EXIT =3D DISAS_TARGET_0, /* We want return to the cpu main lo= op. */ + DISAS_LOOKUP =3D DISAS_TARGET_1, /* We have a variable condition exit= . */ + DISAS_CHAIN =3D DISAS_TARGET_2, /* We have a single condition exit. = */ +}; + +typedef struct DisasContext DisasContext; + +/* This is the state at translation time. */ +struct DisasContext { + TranslationBlock *tb; + + CPUAVRState *env; + CPUState *cs; + + target_long npc; + uint32_t opcode; + + /* Routine used to access memory */ + int memidx; + int bstate; + int singlestep; + + /* + * some AVR instructions can make the following instruction to be skip= ped + * Let's name those instructions + * A - instruction that can skip the next one + * B - instruction that can be skipped. this depends on executio= n of A + * there are two scenarios + * 1. A and B belong to the same translation block + * 2. A is the last instruction in the translation block and B is the = last + * + * following variables are used to simplify the skipping logic, they a= re + * used in the following manner (sketch) + * + * TCGLabel *skip_label =3D NULL; + * if (ctx.skip_cond !=3D TCG_COND_NEVER) { + * skip_label =3D gen_new_label(); + * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label); + * } + * + * if (free_skip_var0) { + * tcg_temp_free(skip_var0); + * free_skip_var0 =3D false; + * } + * + * translate(&ctx); + * + * if (skip_label) { + * gen_set_label(skip_label); + * } + */ + TCGv skip_var0; + TCGv skip_var1; + TCGCond skip_cond; + bool free_skip_var0; +}; + +static int to_regs_16_31_by_one(DisasContext *ctx, int indx) +{ + return 16 + (indx % 16); +} + +static int to_regs_16_23_by_one(DisasContext *ctx, int indx) +{ + return 16 + (indx % 8); +} +static int to_regs_24_30_by_two(DisasContext *ctx, int indx) +{ + return 24 + (indx % 4) * 2; +} +static int to_regs_00_30_by_two(DisasContext *ctx, int indx) +{ + return (indx % 16) * 2; +} + +static uint16_t next_word(DisasContext *ctx) +{ + return cpu_lduw_code(ctx->env, ctx->npc++ * 2); +} + +static int append_16(DisasContext *ctx, int x) +{ + return x << 16 | next_word(ctx); +} + + +static bool avr_have_feature(DisasContext *ctx, int feature) +{ + if (!avr_feature(ctx->env, feature)) { + gen_helper_unsupported(cpu_env); + ctx->bstate =3D DISAS_NORETURN; + return false; + } + return true; +} + +static bool decode_insn(DisasContext *ctx, uint16_t insn); +#include "decode_insn.inc.c" + --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375723; cv=none; d=zohomail.com; s=zohoarc; b=lglTyTSdaElCyB0hkiNaeneJkUv8E6GsCjCYnOKFUJZRtWDFtsu6t6Oo/R6430TR1R+58JE5dQYxZvJfjppq6Qvc5lDvLzYOp0YWM392QBy4Ok8hZ0/dxnD6Ao+na3SEYLveOtas/Er4dmLGEZL5u6HOUkddf88dA7Cu7gDfASg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375723; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zFA0LudFOT1Zw3OZ8f7EAsVJq4Bf1CkoXJBEaQ3VlYg=; b=hr0KZjW8Qut1dpIz+GmfVEgCJHDSmBxP288QaSaWCgATFfgcafbgOfgYoEtVUk34SwLs7QrZ3+HoH8oCIm22f1p4bQguvLmW7SMbQl9LIb5eaUm7TOEfdwfP7DFSHat/B2wFsQDyeFBOoJV/nneoOBq4Y7RGBuvPXaXlf8FeGC0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375723293732.7469008323856; Sat, 18 Jan 2020 11:28:43 -0800 (PST) Received: from localhost ([::1]:44150 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istlx-00073S-Ip for importer@patchew.org; Sat, 18 Jan 2020 14:28:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49720) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istcx-0003VU-Gp for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:19:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istcs-0004CB-78 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:19:23 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:38896) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istcr-0004BW-T6 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:19:18 -0500 Received: by mail-wr1-x441.google.com with SMTP id y17so25749390wrh.5 for ; Sat, 18 Jan 2020 11:19:17 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.18.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:19:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zFA0LudFOT1Zw3OZ8f7EAsVJq4Bf1CkoXJBEaQ3VlYg=; b=M8nR7ZklCvJXqiYA76kkgr+uSb4Em24LXUMUUkyROV1nVCSvfVtXB2kMOMFrRMNp8G i9tVPNZqACxGNaLeRX6Olzz3MffCe57D6QJW0Eebpvo2qx6yBapXJHH+yG0y+bm6DJ8L ib/3vUK5yYRvUmtmYEFEd4ec9KBxE3zCwOLh/RXLXmY5Yv5mr6bXHL5RYrSqezBgQ0GH DPCuIn9RHs2c1EZaUxYBpjDYH+uEDP3FiqVykpfhOChXD8qhLy8QhnbfvatLwdE9AXgW CzBHBrlCEGS02kDnr/1Hxned9eJnKXvNgDtZLsaTXG7BLl2Vk3+GSiZMW3h9peCxOdVY nR9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zFA0LudFOT1Zw3OZ8f7EAsVJq4Bf1CkoXJBEaQ3VlYg=; b=qGz5ln8mvHHKXFvKyZ2htgUK258Vlf7621REDP2wmstudxFw/4cXv+UHXvlShyLScr 7XrwwrOaKtCDI+DSKWH5JmfGx6xGagKnm2hBRm+G2Yo0/fJSAayvYiV4Jjt8qxzjT9hL PGbsucR45jVlJG6itJlRQjxj6GpFGnZwXm9TXUyFYRHwNz0Ldu3g41/piRgnIQC5nXgs 2kQH0W0L1QNJlemRcl3tg2Ee1mI47FKQpEaejIqls6KffjIDNve78nq+tIZvuR4Ao+gl M46dBKn6EN/b/O69VfhSeVDaLpjSzpTS1N8Sun5s0tQPINYP8IAR5BSkzDx70cLUfsfr nVeg== X-Gm-Message-State: APjAAAWfLLtPMu5pzKis8jt75DfwKFtSQd6kzraT/jaqNYHLih1QEasX E/Q7URIuIRoKX8mWE1mpO6/xOOg5Uf+NPGWc X-Google-Smtp-Source: APXvYqzG5TnZHDjnoAhnsVUK0nRZjPXGdoJUFBRfRVaNJZ3hp7TFHHcf1xB3Hb+PT1Zxh6hyade99Q== X-Received: by 2002:adf:fe90:: with SMTP id l16mr9859758wrr.265.1579375156122; Sat, 18 Jan 2020 11:19:16 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 04/21] target/avr: Add instruction translation - Arithmetic and Logic Instructions Date: Sat, 18 Jan 2020 21:13:59 +0200 Message-Id: <20200118191416.19934-5-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) This includes: - ADD, ADC, ADIW - SBIW, SUB, SUBI, SBC, SBCI - AND, ANDI - OR, ORI, EOR - COM, NEG - INC, DEC - MUL, MULS, MULSU - FMUL, FMULS, FMULSU - DES Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/translate.c | 751 +++++++++++++++++++++++++++++++++++++++++ target/avr/insn.decode | 93 +++++ 2 files changed, 844 insertions(+) create mode 100644 target/avr/insn.decode diff --git a/target/avr/translate.c b/target/avr/translate.c index 241083dc2d..00fb3f5350 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -170,3 +170,754 @@ static bool avr_have_feature(DisasContext *ctx, int f= eature) static bool decode_insn(DisasContext *ctx, uint16_t insn); #include "decode_insn.inc.c" =20 +/* + * Arithmetic Instructions + */ + +static void gen_add_CHf(TCGv R, TCGv Rd, TCGv Rr) +{ + TCGv t1 =3D tcg_temp_new_i32(); + TCGv t2 =3D tcg_temp_new_i32(); + TCGv t3 =3D tcg_temp_new_i32(); + + tcg_gen_and_tl(t1, Rd, Rr); /* t1 =3D Rd & Rr */ + tcg_gen_andc_tl(t2, Rd, R); /* t2 =3D Rd & ~R */ + tcg_gen_andc_tl(t3, Rr, R); /* t3 =3D Rr & ~R */ + tcg_gen_or_tl(t1, t1, t2); /* t1 =3D t1 | t2 | t3 */ + tcg_gen_or_tl(t1, t1, t3); + tcg_gen_shri_tl(cpu_Cf, t1, 7); /* Cf =3D t1(7) */ + tcg_gen_shri_tl(cpu_Hf, t1, 3); /* Hf =3D t1(3) */ + tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1); + + tcg_temp_free_i32(t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + + +static void gen_add_Vf(TCGv R, TCGv Rd, TCGv Rr) +{ + TCGv t1 =3D tcg_temp_new_i32(); + TCGv t2 =3D tcg_temp_new_i32(); + + /* t1 =3D Rd & Rr & ~R | ~Rd & ~Rr & R */ + /* =3D (Rd ^ R) & ~(Rd ^ Rr) */ + tcg_gen_xor_tl(t1, Rd, R); + tcg_gen_xor_tl(t2, Rd, Rr); + tcg_gen_andc_tl(t1, t1, t2); + tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf =3D t1(7) */ + + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + + +static void gen_sub_CHf(TCGv R, TCGv Rd, TCGv Rr) +{ + TCGv t1 =3D tcg_temp_new_i32(); + TCGv t2 =3D tcg_temp_new_i32(); + TCGv t3 =3D tcg_temp_new_i32(); + + tcg_gen_not_tl(t1, Rd); /* t1 =3D ~Rd */ + tcg_gen_and_tl(t2, t1, Rr); /* t2 =3D ~Rd & Rr */ + tcg_gen_or_tl(t3, t1, Rr); /* t3 =3D (~Rd | Rr) & R */ + tcg_gen_and_tl(t3, t3, R); + tcg_gen_or_tl(t2, t2, t3); /* t2 =3D ~Rd & Rr | ~Rd & R | R & Rr */ + tcg_gen_shri_tl(cpu_Cf, t2, 7); /* Cf =3D t2(7) */ + tcg_gen_shri_tl(cpu_Hf, t2, 3); /* Hf =3D t2(3) */ + tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1); + + tcg_temp_free_i32(t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + + +static void gen_sub_Vf(TCGv R, TCGv Rd, TCGv Rr) +{ + TCGv t1 =3D tcg_temp_new_i32(); + TCGv t2 =3D tcg_temp_new_i32(); + + /* t1 =3D Rd & ~Rr & ~R | ~Rd & Rr & R */ + /* =3D (Rd ^ R) & (Rd ^ R) */ + tcg_gen_xor_tl(t1, Rd, R); + tcg_gen_xor_tl(t2, Rd, Rr); + tcg_gen_and_tl(t1, t1, t2); + tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf =3D t1(7) */ + + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + + +static void gen_NSf(TCGv R) +{ + tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf =3D R(7) */ + tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf =3D Nf ^ Vf */ +} + + +static void gen_ZNSf(TCGv R) +{ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf =3D R(7) */ + tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf =3D Nf ^ Vf */ +} + +/* + * Adds two registers without the C Flag and places the result in the + * destination register Rd. + */ +static bool trans_ADD(DisasContext *ctx, arg_ADD *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_add_tl(R, Rd, Rr); /* Rd =3D Rd + Rr */ + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_add_CHf(R, Rd, Rr); + gen_add_Vf(R, Rd, Rr); + gen_ZNSf(R); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(R); + + return true; +} + +/* + * Adds two registers and the contents of the C Flag and places the resul= t in + * the destination register Rd. + */ +static bool trans_ADC(DisasContext *ctx, arg_ADC *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_add_tl(R, Rd, Rr); /* R =3D Rd + Rr + Cf */ + tcg_gen_add_tl(R, R, cpu_Cf); + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_add_CHf(R, Rd, Rr); + gen_add_Vf(R, Rd, Rr); + gen_ZNSf(R); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(R); + + return true; +} + +/* + * Adds an immediate value (0 - 63) to a register pair and places the res= ult + * in the register pair. This instruction operates on the upper four regi= ster + * pairs, and is well suited for operations on the pointer registers. Th= is + * instruction is not available in all devices. Refer to the device speci= fic + * instruction set summary. + */ +static bool trans_ADIW(DisasContext *ctx, arg_ADIW *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_ADIW_SBIW)) { + return true; + } + + TCGv RdL =3D cpu_r[a->rd]; + TCGv RdH =3D cpu_r[a->rd + 1]; + int Imm =3D (a->imm); + TCGv R =3D tcg_temp_new_i32(); + TCGv Rd =3D tcg_temp_new_i32(); + + tcg_gen_deposit_tl(Rd, RdL, RdH, 8, 8); /* Rd =3D RdH:RdL */ + tcg_gen_addi_tl(R, Rd, Imm); /* R =3D Rd + Imm */ + tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + /* update status register */ + tcg_gen_andc_tl(cpu_Cf, Rd, R); /* Cf =3D Rd & ~R */ + tcg_gen_shri_tl(cpu_Cf, cpu_Cf, 15); + tcg_gen_andc_tl(cpu_Vf, R, Rd); /* Vf =3D R & ~Rd */ + tcg_gen_shri_tl(cpu_Vf, cpu_Vf, 15); + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + tcg_gen_shri_tl(cpu_Nf, R, 15); /* Nf =3D R(15) */ + tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf);/* Sf =3D Nf ^ Vf */ + /* update output registers */ + tcg_gen_andi_tl(RdL, R, 0xff); + tcg_gen_shri_tl(RdH, R, 8); + + tcg_temp_free_i32(Rd); + tcg_temp_free_i32(R); + + return true; +} + +/* + * Subtracts two registers and places the result in the destination + * register Rd. + */ +static bool trans_SUB(DisasContext *ctx, arg_SUB *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_sub_tl(R, Rd, Rr); /* R =3D Rd - Rr */ + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + tcg_gen_andc_tl(cpu_Cf, Rd, R); /* Cf =3D Rd & ~R */ + gen_sub_CHf(R, Rd, Rr); + gen_sub_Vf(R, Rd, Rr); + gen_ZNSf(R); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(R); + + return true; +} + +/* + * Subtracts a register and a constant and places the result in the + * destination register Rd. This instruction is working on Register R16 t= o R31 + * and is very well suited for operations on the X, Y, and Z-pointers. + */ +static bool trans_SUBI(DisasContext *ctx, arg_SUBI *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D tcg_const_i32(a->imm); + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_sub_tl(R, Rd, Rr); /* R =3D Rd - Imm */ + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_sub_CHf(R, Rd, Rr); + gen_sub_Vf(R, Rd, Rr); + gen_ZNSf(R); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(R); + tcg_temp_free_i32(Rr); + + return true; +} + +/* + * Subtracts two registers and subtracts with the C Flag and places the + * result in the destination register Rd. + */ +static bool trans_SBC(DisasContext *ctx, arg_SBC *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + TCGv zero =3D tcg_const_i32(0); + + tcg_gen_sub_tl(R, Rd, Rr); /* R =3D Rd - Rr - Cf */ + tcg_gen_sub_tl(R, R, cpu_Cf); + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_sub_CHf(R, Rd, Rr); + gen_sub_Vf(R, Rd, Rr); + gen_NSf(R); + + /* + * Previous value remains unchanged when the result is zero; + * cleared otherwise. + */ + tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(zero); + tcg_temp_free_i32(R); + + return true; +} + +/* + * SBCI -- Subtract Immediate with Carry + */ +static bool trans_SBCI(DisasContext *ctx, arg_SBCI *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D tcg_const_i32(a->imm); + TCGv R =3D tcg_temp_new_i32(); + TCGv zero =3D tcg_const_i32(0); + + tcg_gen_sub_tl(R, Rd, Rr); /* R =3D Rd - Rr - Cf */ + tcg_gen_sub_tl(R, R, cpu_Cf); + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_sub_CHf(R, Rd, Rr); + gen_sub_Vf(R, Rd, Rr); + gen_NSf(R); + + /* + * Previous value remains unchanged when the result is zero; + * cleared otherwise. + */ + tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(zero); + tcg_temp_free_i32(R); + tcg_temp_free_i32(Rr); + + return true; +} + +/* + * Subtracts an immediate value (0-63) from a register pair and places the + * result in the register pair. This instruction operates on the upper fo= ur + * register pairs, and is well suited for operations on the Pointer Regis= ters. + * This instruction is not available in all devices. Refer to the device + * specific instruction set summary. + */ +static bool trans_SBIW(DisasContext *ctx, arg_SBIW *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_ADIW_SBIW)) { + return true; + } + + TCGv RdL =3D cpu_r[a->rd]; + TCGv RdH =3D cpu_r[a->rd + 1]; + int Imm =3D (a->imm); + TCGv R =3D tcg_temp_new_i32(); + TCGv Rd =3D tcg_temp_new_i32(); + + tcg_gen_deposit_tl(Rd, RdL, RdH, 8, 8); /* Rd =3D RdH:RdL */ + tcg_gen_subi_tl(R, Rd, Imm); /* R =3D Rd - Imm */ + tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + /* update status register */ + tcg_gen_andc_tl(cpu_Cf, R, Rd); + tcg_gen_shri_tl(cpu_Cf, cpu_Cf, 15); /* Cf =3D R & ~Rd */ + tcg_gen_andc_tl(cpu_Vf, Rd, R); + tcg_gen_shri_tl(cpu_Vf, cpu_Vf, 15); /* Vf =3D Rd & ~R */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + tcg_gen_shri_tl(cpu_Nf, R, 15); /* Nf =3D R(15) */ + tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf =3D Nf ^ Vf */ + /* update output registers */ + tcg_gen_andi_tl(RdL, R, 0xff); + tcg_gen_shri_tl(RdH, R, 8); + + tcg_temp_free_i32(Rd); + tcg_temp_free_i32(R); + + return true; +} + +/* + * Performs the logical AND between the contents of register Rd and regis= ter + * Rr and places the result in the destination register Rd. + */ +static bool trans_AND(DisasContext *ctx, arg_AND *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_and_tl(R, Rd, Rr); /* Rd =3D Rd and Rr */ + /* update status register */ + tcg_gen_movi_tl(cpu_Vf, 0); /* Vf =3D 0 */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + gen_ZNSf(R); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(R); + + return true; +} + +/* + * Performs the logical AND between the contents of register Rd and a con= stant + * and places the result in the destination register Rd. + */ +static bool trans_ANDI(DisasContext *ctx, arg_ANDI *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + int Imm =3D (a->imm); + + tcg_gen_andi_tl(Rd, Rd, Imm); /* Rd =3D Rd & Imm */ + /* update status register */ + tcg_gen_movi_tl(cpu_Vf, 0x00); /* Vf =3D 0 */ + gen_ZNSf(Rd); + + return true; +} + +/* + * Performs the logical OR between the contents of register Rd and regist= er + * Rr and places the result in the destination register Rd. + */ +static bool trans_OR(DisasContext *ctx, arg_OR *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_or_tl(R, Rd, Rr); + /* update status register */ + tcg_gen_movi_tl(cpu_Vf, 0); + gen_ZNSf(R); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(R); + + return true; +} + +/* + * Performs the logical OR between the contents of register Rd and a + * constant and places the result in the destination register Rd. + */ +static bool trans_ORI(DisasContext *ctx, arg_ORI *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + int Imm =3D (a->imm); + + tcg_gen_ori_tl(Rd, Rd, Imm); /* Rd =3D Rd | Imm */ + /* update status register */ + tcg_gen_movi_tl(cpu_Vf, 0x00); /* Vf =3D 0 */ + gen_ZNSf(Rd); + + return true; +} + +/* + * Performs the logical EOR between the contents of register Rd and + * register Rr and places the result in the destination register Rd. + */ +static bool trans_EOR(DisasContext *ctx, arg_EOR *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + + tcg_gen_xor_tl(Rd, Rd, Rr); + /* update status register */ + tcg_gen_movi_tl(cpu_Vf, 0); + gen_ZNSf(Rd); + + return true; +} + +/* + * Clears the specified bits in register Rd. Performs the logical AND + * between the contents of register Rd and the complement of the constant= mask + * K. The result will be placed in register Rd. + */ +static bool trans_COM(DisasContext *ctx, arg_COM *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_xori_tl(Rd, Rd, 0xff); + /* update status register */ + tcg_gen_movi_tl(cpu_Cf, 1); /* Cf =3D 1 */ + tcg_gen_movi_tl(cpu_Vf, 0); /* Vf =3D 0 */ + gen_ZNSf(Rd); + + tcg_temp_free_i32(R); + + return true; +} + +/* + * Replaces the contents of register Rd with its two's complement; the + * value $80 is left unchanged. + */ +static bool trans_NEG(DisasContext *ctx, arg_NEG *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv t0 =3D tcg_const_i32(0); + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_sub_tl(R, t0, Rd); /* R =3D 0 - Rd */ + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_sub_CHf(R, t0, Rd); + gen_sub_Vf(R, t0, Rd); + gen_ZNSf(R); + /* update output registers */ + tcg_gen_mov_tl(Rd, R); + + tcg_temp_free_i32(t0); + tcg_temp_free_i32(R); + + return true; +} + +/* + * Adds one -1- to the contents of register Rd and places the result in t= he + * destination register Rd. The C Flag in SREG is not affected by the + * operation, thus allowing the INC instruction to be used on a loop coun= ter in + * multiple-precision computations. When operating on unsigned numbers, = only + * BREQ and BRNE branches can be expected to perform consistently. When + * operating on two's complement values, all signed branches are availabl= e. + */ +static bool trans_INC(DisasContext *ctx, arg_INC *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + + tcg_gen_addi_tl(Rd, Rd, 1); + tcg_gen_andi_tl(Rd, Rd, 0xff); + /* update status register */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Vf, Rd, 0x80); /* Vf =3D Rd =3D= =3D 0x80 */ + gen_ZNSf(Rd); + + return true; +} + +/* + * Subtracts one -1- from the contents of register Rd and places the resu= lt + * in the destination register Rd. The C Flag in SREG is not affected by= the + * operation, thus allowing the DEC instruction to be used on a loop coun= ter in + * multiple-precision computations. When operating on unsigned values, o= nly + * BREQ and BRNE branches can be expected to perform consistently. When + * operating on two's complement values, all signed branches are availabl= e. + */ +static bool trans_DEC(DisasContext *ctx, arg_DEC *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + + tcg_gen_subi_tl(Rd, Rd, 1); /* Rd =3D Rd - 1 */ + tcg_gen_andi_tl(Rd, Rd, 0xff); /* make it 8 bits */ + /* update status register */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Vf, Rd, 0x7f); /* Vf =3D Rd =3D= =3D 0x7f */ + gen_ZNSf(Rd); + + return true; +} + +/* + * This instruction performs 8-bit x 8-bit -> 16-bit unsigned multiplicat= ion. + */ +static bool trans_MUL(DisasContext *ctx, arg_MUL *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { + return true; + } + + TCGv R0 =3D cpu_r[0]; + TCGv R1 =3D cpu_r[1]; + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_mul_tl(R, Rd, Rr); /* R =3D Rd * Rr */ + tcg_gen_andi_tl(R0, R, 0xff); + tcg_gen_shri_tl(R1, R, 8); + /* update status register */ + tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf =3D R(15) */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + + tcg_temp_free_i32(R); + + return true; +} + +/* + * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplicatio= n. + */ +static bool trans_MULS(DisasContext *ctx, arg_MULS *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { + return true; + } + + TCGv R0 =3D cpu_r[0]; + TCGv R1 =3D cpu_r[1]; + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + TCGv t0 =3D tcg_temp_new_i32(); + TCGv t1 =3D tcg_temp_new_i32(); + + tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_ext8s_tl(t1, Rr); /* make Rr full 32 bit signed */ + tcg_gen_mul_tl(R, t0, t1); /* R =3D Rd * Rr */ + tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + tcg_gen_andi_tl(R0, R, 0xff); + tcg_gen_shri_tl(R1, R, 8); + /* update status register */ + tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf =3D R(15) */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(R); + + return true; +} + +/* + * This instruction performs 8-bit x 8-bit -> 16-bit multiplication of a + * signed and an unsigned number. + */ +static bool trans_MULSU(DisasContext *ctx, arg_MULSU *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { + return true; + } + + TCGv R0 =3D cpu_r[0]; + TCGv R1 =3D cpu_r[1]; + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + TCGv t0 =3D tcg_temp_new_i32(); + + tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_mul_tl(R, t0, Rr); /* R =3D Rd * Rr */ + tcg_gen_andi_tl(R, R, 0xffff); /* make R 16 bits */ + tcg_gen_andi_tl(R0, R, 0xff); + tcg_gen_shri_tl(R1, R, 8); + /* update status register */ + tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf =3D R(15) */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + + tcg_temp_free_i32(t0); + tcg_temp_free_i32(R); + + return true; +} + +/* + * This instruction performs 8-bit x 8-bit -> 16-bit unsigned + * multiplication and shifts the result one bit left. + */ +static bool trans_FMUL(DisasContext *ctx, arg_FMUL *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { + return true; + } + + TCGv R0 =3D cpu_r[0]; + TCGv R1 =3D cpu_r[1]; + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_mul_tl(R, Rd, Rr); /* R =3D Rd * Rr */ + /* update status register */ + tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf =3D R(15) */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + /* update output registers */ + tcg_gen_shli_tl(R, R, 1); + tcg_gen_andi_tl(R0, R, 0xff); + tcg_gen_shri_tl(R1, R, 8); + tcg_gen_andi_tl(R1, R1, 0xff); + + + tcg_temp_free_i32(R); + + return true; +} + +/* + * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication + * and shifts the result one bit left. + */ +static bool trans_FMULS(DisasContext *ctx, arg_FMULS *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { + return true; + } + + TCGv R0 =3D cpu_r[0]; + TCGv R1 =3D cpu_r[1]; + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + TCGv t0 =3D tcg_temp_new_i32(); + TCGv t1 =3D tcg_temp_new_i32(); + + tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_ext8s_tl(t1, Rr); /* make Rr full 32 bit signed */ + tcg_gen_mul_tl(R, t0, t1); /* R =3D Rd * Rr */ + tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + /* update status register */ + tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf =3D R(15) */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + /* update output registers */ + tcg_gen_shli_tl(R, R, 1); + tcg_gen_andi_tl(R0, R, 0xff); + tcg_gen_shri_tl(R1, R, 8); + tcg_gen_andi_tl(R1, R1, 0xff); + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(R); + + return true; +} + +/* + * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication + * and shifts the result one bit left. + */ +static bool trans_FMULSU(DisasContext *ctx, arg_FMULSU *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { + return true; + } + + TCGv R0 =3D cpu_r[0]; + TCGv R1 =3D cpu_r[1]; + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + TCGv t0 =3D tcg_temp_new_i32(); + + tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_mul_tl(R, t0, Rr); /* R =3D Rd * Rr */ + tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + /* update status register */ + tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf =3D R(15) */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + /* update output registers */ + tcg_gen_shli_tl(R, R, 1); + tcg_gen_andi_tl(R0, R, 0xff); + tcg_gen_shri_tl(R1, R, 8); + tcg_gen_andi_tl(R1, R1, 0xff); + + tcg_temp_free_i32(t0); + tcg_temp_free_i32(R); + + return true; +} + +/* + * The module is an instruction set extension to the AVR CPU, performing + * DES iterations. The 64-bit data block (plaintext or ciphertext) is pla= ced in + * the CPU register file, registers R0-R7, where LSB of data is placed in= LSB + * of R0 and MSB of data is placed in MSB of R7. The full 64-bit key (inc= luding + * parity bits) is placed in registers R8- R15, organized in the register= file + * with LSB of key in LSB of R8 and MSB of key in MSB of R15. Executing o= ne DES + * instruction performs one round in the DES algorithm. Sixteen rounds mu= st be + * executed in increasing order to form the correct DES ciphertext or + * plaintext. Intermediate results are stored in the register file (R0-R1= 5) + * after each DES instruction. The instruction's operand (K) determines w= hich + * round is executed, and the half carry flag (H) determines whether encr= yption + * or decryption is performed. The DES algorithm is described in + * "Specifications for the Data Encryption Standard" (Federal Information + * Processing Standards Publication 46). Intermediate results in this + * implementation differ from the standard because the initial permutatio= n and + * the inverse initial permutation are performed each iteration. This doe= s not + * affect the result in the final ciphertext or plaintext, but reduces + * execution time. + */ +static bool trans_DES(DisasContext *ctx, arg_DES *a) +{ + /* TODO */ + if (!avr_have_feature(ctx, AVR_FEATURE_DES)) { + return true; + } + + return true; +} diff --git a/target/avr/insn.decode b/target/avr/insn.decode new file mode 100644 index 0000000000..9c71ed6b2f --- /dev/null +++ b/target/avr/insn.decode @@ -0,0 +1,93 @@ +# +# AVR instruction decode definitions. +# +# Copyright (c) 2019 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 . +# + +# +# regs_16_31_by_one =3D [16 .. 31] +# regs_16_23_by_one =3D [16 .. 23] +# regs_24_30_by_two =3D [24, 26, 28, 30] +# regs_00_30_by_two =3D [0, 2, 4, 6, 8, .. 30] + +%rd 4:5 +%rr 9:1 0:4 + +%rd_a 4:4 !function=3Dto_regs_16_31_by_o= ne +%rd_b 4:3 !function=3Dto_regs_16_23_by_o= ne +%rd_c 4:2 !function=3Dto_regs_24_30_by_t= wo +%rd_d 4:4 !function=3Dto_regs_00_30_by_t= wo +%rr_a 0:4 !function=3Dto_regs_16_31_by_o= ne +%rr_b 0:3 !function=3Dto_regs_16_23_by_o= ne +%rr_d 0:4 !function=3Dto_regs_00_30_by_t= wo + +%imm6 6:2 0:4 +%imm8 8:4 0:4 + +%io_imm 9:2 0:4 +%ldst_d_imm 13:1 10:2 0:3 + +# The 22-bit immediate is partially in the opcode word, +# and partially in the next. Use append_16 to build the +# complete 22-bit value. +%imm_call 4:5 0:1 !function=3Dappend_16 + + +&rd_rr rd rr +&rd_imm rd imm + +@op_rd_rr .... .. . ..... .... &rd_rr rd=3D%rd rr=3D%rr +@op_rd_imm6 .... .... .. .. .... &rd_imm rd=3D%rd_c imm=3D%= imm6 +@op_rd_imm8 .... .... .... .... &rd_imm rd=3D%rd_a imm=3D%= imm8 +@op_bit .... .... . bit:3 .... +@op_bit_imm .... .. imm:s7 bit:3 +@fmul .... .... . ... . ... &rd_rr rd=3D%rd_b rr=3D%r= r_b +@io_rd_imm .... . .. ..... .... &rd_imm rd=3D%rd imm=3D%io= _imm +@ldst_d .. . . .. . rd:5 . ... &rd_imm imm=3D%ldst_d_imm + +# The 16-bit immediate is completely in the next word. +# Fields cannot be defined with no bits, so we cannot play +# the same trick and append to a zero-bit value. +# Defer reading the immediate until trans_{LDS,STS}. +@ldst_s .... ... rd:5 .... imm=3D0 + +# +# Arithmetic Instructions +# +ADD 0000 11 . ..... .... @op_rd_rr +ADC 0001 11 . ..... .... @op_rd_rr +ADIW 1001 0110 .. .. .... @op_rd_imm6 +SUB 0001 10 . ..... .... @op_rd_rr +SUBI 0101 .... .... .... @op_rd_imm8 +SBC 0000 10 . ..... .... @op_rd_rr +SBCI 0100 .... .... .... @op_rd_imm8 +SBIW 1001 0111 .. .. .... @op_rd_imm6 +AND 0010 00 . ..... .... @op_rd_rr +ANDI 0111 .... .... .... @op_rd_imm8 +OR 0010 10 . ..... .... @op_rd_rr +ORI 0110 .... .... .... @op_rd_imm8 +EOR 0010 01 . ..... .... @op_rd_rr +COM 1001 010 rd:5 0000 +NEG 1001 010 rd:5 0001 +INC 1001 010 rd:5 0011 +DEC 1001 010 rd:5 1010 +MUL 1001 11 . ..... .... @op_rd_rr +MULS 0000 0010 .... .... &rd_rr rd=3D%rd_a rr=3D%r= r_a +MULSU 0000 0011 0 ... 0 ... @fmul +FMUL 0000 0011 0 ... 1 ... @fmul +FMULS 0000 0011 1 ... 0 ... @fmul +FMULSU 0000 0011 1 ... 1 ... @fmul +DES 1001 0100 imm:4 1011 --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375783; cv=none; d=zohomail.com; s=zohoarc; b=gx1ty4bkx1umYxrCXZ6rpmw8OahHVPlhkVY/rsxqzTyHAjTSH7xal0q1I7LIKhuF/Yo5uwL/vahd/LnsOKL6uuQuWnrrHshgooDDdw0SdDOiADPeRQxCCZnvXGWXd8oei/U+LUOSutP3JaJe4tlvytPqJLVR8Z2+vQ0VSZp08oQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375783; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=DhL1KYjNsXz5yXsdegQ7yg1vjGWtwMZnmHkf+B5dxv8=; b=ipEEXeo7rSUL4ypCMDIF0mhQeOmRNeuGu04LQJFSkzrddbvYKx8JcIoIY6MjCPVN/vdrdPjXbwdzZC1QUdR9b1CEXSEGAtqXicWhJbWV2YyzVzdL2xA+6TeUiKh6020FETLJnFocFaF7kqH/D9brNzoCSif7idmgTDTr5f/RVak= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375783051930.3602145911342; Sat, 18 Jan 2020 11:29:43 -0800 (PST) Received: from localhost ([::1]:44158 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istmv-0008KW-RO for importer@patchew.org; Sat, 18 Jan 2020 14:29:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49762) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istdF-0003qd-Gm for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:19:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istdD-0004vY-3G for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:19:41 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:40465) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istdC-0004uB-Pr for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:19:39 -0500 Received: by mail-wm1-x344.google.com with SMTP id t14so10782056wmi.5 for ; Sat, 18 Jan 2020 11:19:38 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.19.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:19:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DhL1KYjNsXz5yXsdegQ7yg1vjGWtwMZnmHkf+B5dxv8=; b=SW7N93+/k2NriW3g1W9a1Co1oY3ZGTmsoY6/8iT9pZeEJf93j+fwjKb2nQQXEwTB6C Ef7JSzDH1HndncKC3ujDsk5dmKbIwGo7vlOMhO6dB1VTVMM+FVoOXPwI3h4p2elRuj4Y eqgXHBhoHZoRmXpbBc/XFIh5Dr0uKrShgDEzR7YuTxF5awT6mZlGWJr/rjgLRQ3Z1BMg Y+Pzy5JOdgf8YmVxsMbHsJu7ROyScaysNuejs5kQrXOT/TQIU9V3cb/4NeD9TDsQzR8Q 11/9qa1en4ncVGtC5G8DKShQFd+nBSzc0GG+U7MJHy2z9oW9S1+9FY5U+jkJ3XkkJelc yHtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DhL1KYjNsXz5yXsdegQ7yg1vjGWtwMZnmHkf+B5dxv8=; b=O9+1oxA8xawYeWb0lyp3cqnwGZmfrBCxmghr1MT0Qj3ftiY/IS9rzmDFdqouD4/FQc n4IrGHQjo+oOhhYtuxq1NWsRW62b4UzJqjlvGbq00t73vRoidil37CBv92TVjJNiqPNy SgdywcEqTJY4pnfFMSEPzZYS22FWmlP+UxC//yAeLFJvUI2JjHdYzZgxhsd3p7RkbPaQ 10e7L0Lqc3qD1fXs/y2y9Zhy8S+x3OyZyl6ezJ5I6mdEmt8ELg0TpkPSe4LktaCk6XVC U5W7cpbUCmezcKguwN9XDLoidmQGnUv56K0YW0Y6BdrP9RvgbOTYS9bc7p0gr3qA4ogd ob5A== X-Gm-Message-State: APjAAAXy5DACSPrrQKFjzPNFFoSyhqkcV+herfxyWBF7Dl7i+lpQ53yf oCaf1AGmkHaBFhkhPwvLdDdI51eeIZrawNTR X-Google-Smtp-Source: APXvYqzoMpcDp23tfhXTCvXk3JG+9qN5u8o9Fa/vo/tXwcwjygmYn29CvBfVo7zxN52ELrjNfI8Ycg== X-Received: by 2002:a7b:c759:: with SMTP id w25mr10737520wmk.15.1579375177167; Sat, 18 Jan 2020 11:19:37 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 05/21] target/avr: Add instruction translation - Branch Instructions Date: Sat, 18 Jan 2020 21:14:00 +0200 Message-Id: <20200118191416.19934-6-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) This includes: - RJMP, IJMP, EIJMP, JMP - RCALL, ICALL, EICALL, CALL - RET, RETI - CPSE, CP, CPC, CPI - SBRC, SBRS, SBIC, SBIS - BRBC, BRBS Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/translate.c | 533 +++++++++++++++++++++++++++++++++++++++++ target/avr/insn.decode | 24 ++ 2 files changed, 557 insertions(+) diff --git a/target/avr/translate.c b/target/avr/translate.c index 00fb3f5350..475f502e72 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -921,3 +921,536 @@ static bool trans_DES(DisasContext *ctx, arg_DES *a) =20 return true; } + +/* + * Branch Instructions + */ +static void gen_jmp_ez(DisasContext *ctx) +{ + tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8); + tcg_gen_or_tl(cpu_pc, cpu_pc, cpu_eind); + ctx->bstate =3D DISAS_LOOKUP; +} + +static void gen_jmp_z(DisasContext *ctx) +{ + tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8); + ctx->bstate =3D DISAS_LOOKUP; +} + +static void gen_push_ret(DisasContext *ctx, int ret) +{ + if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) { + + TCGv t0 =3D tcg_const_i32((ret & 0x0000ff)); + + tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_UB); + tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + + tcg_temp_free_i32(t0); + } else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) { + + TCGv t0 =3D tcg_const_i32((ret & 0x00ffff)); + + tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_BEUW); + tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + + tcg_temp_free_i32(t0); + + } else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) { + + TCGv lo =3D tcg_const_i32((ret & 0x0000ff)); + TCGv hi =3D tcg_const_i32((ret & 0xffff00) >> 8); + + tcg_gen_qemu_st_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB); + tcg_gen_subi_tl(cpu_sp, cpu_sp, 2); + tcg_gen_qemu_st_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW); + tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + + tcg_temp_free_i32(lo); + tcg_temp_free_i32(hi); + } +} + +static void gen_pop_ret(DisasContext *ctx, TCGv ret) +{ + if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) { + tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_UB); + } else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) { + tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_BEUW); + tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); + } else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) { + TCGv lo =3D tcg_temp_new_i32(); + TCGv hi =3D tcg_temp_new_i32(); + + tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_qemu_ld_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW); + + tcg_gen_addi_tl(cpu_sp, cpu_sp, 2); + tcg_gen_qemu_ld_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB); + + tcg_gen_deposit_tl(ret, lo, hi, 8, 16); + + tcg_temp_free_i32(lo); + tcg_temp_free_i32(hi); + } +} + +static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) +{ + TranslationBlock *tb =3D ctx->tb; + + if (ctx->singlestep =3D=3D 0) { + tcg_gen_goto_tb(n); + tcg_gen_movi_i32(cpu_pc, dest); + tcg_gen_exit_tb(tb, n); + } else { + tcg_gen_movi_i32(cpu_pc, dest); + gen_helper_debug(cpu_env); + tcg_gen_exit_tb(NULL, 0); + } + ctx->bstate =3D DISAS_NORETURN; +} + +/* + * Relative jump to an address within PC - 2K +1 and PC + 2K (words). For + * AVR microcontrollers with Program memory not exceeding 4K words (8KB) = this + * instruction can address the entire memory from every address location.= See + * also JMP. + */ +static bool trans_RJMP(DisasContext *ctx, arg_RJMP *a) +{ + int dst =3D ctx->npc + a->imm; + + gen_goto_tb(ctx, 0, dst); + + return true; +} + +/* + * Indirect jump to the address pointed to by the Z (16 bits) Pointer + * Register in the Register File. The Z-pointer Register is 16 bits wide = and + * allows jump within the lowest 64K words (128KB) section of Program mem= ory. + * This instruction is not available in all devices. Refer to the device + * specific instruction set summary. + */ +static bool trans_IJMP(DisasContext *ctx, arg_IJMP *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_IJMP_ICALL)) { + return true; + } + + gen_jmp_z(ctx); + + return true; +} + +/* + * Indirect jump to the address pointed to by the Z (16 bits) Pointer + * Register in the Register File and the EIND Register in the I/O space. = This + * instruction allows for indirect jumps to the entire 4M (words) Program + * memory space. See also IJMP. This instruction is not available in all + * devices. Refer to the device specific instruction set summary. + */ +static bool trans_EIJMP(DisasContext *ctx, arg_EIJMP *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_EIJMP_EICALL)) { + return true; + } + + gen_jmp_ez(ctx); + return true; +} + +/* + * Jump to an address within the entire 4M (words) Program memory. See al= so + * RJMP. This instruction is not available in all devices. Refer to the = device + * specific instruction set summary.0 + */ +static bool trans_JMP(DisasContext *ctx, arg_JMP *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_JMP_CALL)) { + return true; + } + + gen_goto_tb(ctx, 0, a->imm); + + return true; +} + +/* + * Relative call to an address within PC - 2K + 1 and PC + 2K (words). The + * return address (the instruction after the RCALL) is stored onto the St= ack. + * See also CALL. For AVR microcontrollers with Program memory not exceed= ing 4K + * words (8KB) this instruction can address the entire memory from every + * address location. The Stack Pointer uses a post-decrement scheme during + * RCALL. + */ +static bool trans_RCALL(DisasContext *ctx, arg_RCALL *a) +{ + int ret =3D ctx->npc; + int dst =3D ctx->npc + a->imm; + + gen_push_ret(ctx, ret); + gen_goto_tb(ctx, 0, dst); + + return true; +} + +/* + * Calls to a subroutine within the entire 4M (words) Program memory. The + * return address (to the instruction after the CALL) will be stored onto= the + * Stack. See also RCALL. The Stack Pointer uses a post-decrement scheme = during + * CALL. This instruction is not available in all devices. Refer to the = device + * specific instruction set summary. + */ +static bool trans_ICALL(DisasContext *ctx, arg_ICALL *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_IJMP_ICALL)) { + return true; + } + + int ret =3D ctx->npc; + + gen_push_ret(ctx, ret); + gen_jmp_z(ctx); + + return true; +} + +/* + * Indirect call of a subroutine pointed to by the Z (16 bits) Pointer + * Register in the Register File and the EIND Register in the I/O space. = This + * instruction allows for indirect calls to the entire 4M (words) Program + * memory space. See also ICALL. The Stack Pointer uses a post-decrement = scheme + * during EICALL. This instruction is not available in all devices. Refe= r to + * the device specific instruction set summary. + */ +static bool trans_EICALL(DisasContext *ctx, arg_EICALL *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_EIJMP_EICALL)) { + return true; + } + + int ret =3D ctx->npc; + + gen_push_ret(ctx, ret); + gen_jmp_ez(ctx); + return true; +} + +/* + * Calls to a subroutine within the entire Program memory. The return + * address (to the instruction after the CALL) will be stored onto the St= ack. + * (See also RCALL). The Stack Pointer uses a post-decrement scheme during + * CALL. This instruction is not available in all devices. Refer to the = device + * specific instruction set summary. + */ +static bool trans_CALL(DisasContext *ctx, arg_CALL *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_JMP_CALL)) { + return true; + } + + int Imm =3D a->imm; + int ret =3D ctx->npc; + + gen_push_ret(ctx, ret); + gen_goto_tb(ctx, 0, Imm); + + return true; +} + +/* + * Returns from subroutine. The return address is loaded from the STACK. + * The Stack Pointer uses a preincrement scheme during RET. + */ +static bool trans_RET(DisasContext *ctx, arg_RET *a) +{ + gen_pop_ret(ctx, cpu_pc); + + ctx->bstate =3D DISAS_LOOKUP; + return true; +} + +/* + * Returns from interrupt. The return address is loaded from the STACK and + * the Global Interrupt Flag is set. Note that the Status Register is not + * automatically stored when entering an interrupt routine, and it is not + * restored when returning from an interrupt routine. This must be handle= d by + * the application program. The Stack Pointer uses a pre-increment scheme + * during RETI. + */ +static bool trans_RETI(DisasContext *ctx, arg_RETI *a) +{ + gen_pop_ret(ctx, cpu_pc); + tcg_gen_movi_tl(cpu_If, 1); + + /* Need to return to main loop to re-evaluate interrupts. */ + ctx->bstate =3D DISAS_EXIT; + return true; +} + +/* + * This instruction performs a compare between two registers Rd and Rr, a= nd + * skips the next instruction if Rd =3D Rr. + */ +static bool trans_CPSE(DisasContext *ctx, arg_CPSE *a) +{ + ctx->skip_cond =3D TCG_COND_EQ; + ctx->skip_var0 =3D cpu_r[a->rd]; + ctx->skip_var1 =3D cpu_r[a->rr]; + return true; +} + +/* + * This instruction performs a compare between two registers Rd and Rr. + * None of the registers are changed. All conditional branches can be used + * after this instruction. + */ +static bool trans_CP(DisasContext *ctx, arg_CP *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_sub_tl(R, Rd, Rr); /* R =3D Rd - Rr */ + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + + /* update status register */ + gen_sub_CHf(R, Rd, Rr); + gen_sub_Vf(R, Rd, Rr); + gen_ZNSf(R); + + tcg_temp_free_i32(R); + + return true; +} + +/* + * This instruction performs a compare between two registers Rd and Rr and + * also takes into account the previous carry. None of the registers are + * changed. All conditional branches can be used after this instruction. + */ +static bool trans_CPC(DisasContext *ctx, arg_CPC *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + TCGv R =3D tcg_temp_new_i32(); + TCGv zero =3D tcg_const_i32(0); + + tcg_gen_sub_tl(R, Rd, Rr); /* R =3D Rd - Rr - Cf */ + tcg_gen_sub_tl(R, R, cpu_Cf); + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_sub_CHf(R, Rd, Rr); + gen_sub_Vf(R, Rd, Rr); + gen_NSf(R); + + /* + * Previous value remains unchanged when the result is zero; + * cleared otherwise. + */ + tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero); + + tcg_temp_free_i32(zero); + tcg_temp_free_i32(R); + + return true; +} + +/* + * This instruction performs a compare between register Rd and a constant. + * The register is not changed. All conditional branches can be used afte= r this + * instruction. + */ +static bool trans_CPI(DisasContext *ctx, arg_CPI *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + int Imm =3D a->imm; + TCGv Rr =3D tcg_const_i32(Imm); + TCGv R =3D tcg_temp_new_i32(); + + tcg_gen_sub_tl(R, Rd, Rr); /* R =3D Rd - Rr */ + tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + /* update status register */ + gen_sub_CHf(R, Rd, Rr); + gen_sub_Vf(R, Rd, Rr); + gen_ZNSf(R); + + tcg_temp_free_i32(R); + tcg_temp_free_i32(Rr); + + return true; +} + +/* + * This instruction tests a single bit in a register and skips the next + * instruction if the bit is cleared. + */ +static bool trans_SBRC(DisasContext *ctx, arg_SBRC *a) +{ + TCGv Rr =3D cpu_r[a->rr]; + + ctx->skip_cond =3D TCG_COND_EQ; + ctx->skip_var0 =3D tcg_temp_new(); + ctx->free_skip_var0 =3D true; + + tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit); + return true; +} + +/* + * This instruction tests a single bit in a register and skips the next + * instruction if the bit is set. + */ +static bool trans_SBRS(DisasContext *ctx, arg_SBRS *a) +{ + TCGv Rr =3D cpu_r[a->rr]; + + ctx->skip_cond =3D TCG_COND_NE; + ctx->skip_var0 =3D tcg_temp_new(); + ctx->free_skip_var0 =3D true; + + tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit); + return true; +} + +/* + * This instruction tests a single bit in an I/O Register and skips the + * next instruction if the bit is cleared. This instruction operates on t= he + * lower 32 I/O Registers -- addresses 0-31. + */ +static bool trans_SBIC(DisasContext *ctx, arg_SBIC *a) +{ + TCGv temp =3D tcg_const_i32(a->reg); + + gen_helper_inb(temp, cpu_env, temp); + tcg_gen_andi_tl(temp, temp, 1 << a->bit); + ctx->skip_cond =3D TCG_COND_EQ; + ctx->skip_var0 =3D temp; + ctx->free_skip_var0 =3D true; + + return true; +} + +/* + * This instruction tests a single bit in an I/O Register and skips the + * next instruction if the bit is set. This instruction operates on the l= ower + * 32 I/O Registers -- addresses 0-31. + */ +static bool trans_SBIS(DisasContext *ctx, arg_SBIS *a) +{ + TCGv temp =3D tcg_const_i32(a->reg); + + gen_helper_inb(temp, cpu_env, temp); + tcg_gen_andi_tl(temp, temp, 1 << a->bit); + ctx->skip_cond =3D TCG_COND_NE; + ctx->skip_var0 =3D temp; + ctx->free_skip_var0 =3D true; + + return true; +} + +/* + * Conditional relative branch. Tests a single bit in SREG and branches + * relatively to PC if the bit is cleared. This instruction branches rela= tively + * to PC in either direction (PC - 63 < =3D destination <=3D PC + 64). The + * parameter k is the offset from PC and is represented in two's compleme= nt + * form. + */ +static bool trans_BRBC(DisasContext *ctx, arg_BRBC *a) +{ + TCGLabel *not_taken =3D gen_new_label(); + + TCGv var; + + switch (a->bit) { + case 0x00: + var =3D cpu_Cf; + break; + case 0x01: + var =3D cpu_Zf; + break; + case 0x02: + var =3D cpu_Nf; + break; + case 0x03: + var =3D cpu_Vf; + break; + case 0x04: + var =3D cpu_Sf; + break; + case 0x05: + var =3D cpu_Hf; + break; + case 0x06: + var =3D cpu_Tf; + break; + case 0x07: + var =3D cpu_If; + break; + default: + g_assert_not_reached(); + } + + tcg_gen_brcondi_i32(TCG_COND_NE, var, 0, not_taken); + gen_goto_tb(ctx, 0, ctx->npc + a->imm); + gen_set_label(not_taken); + + ctx->bstate =3D DISAS_CHAIN; + return true; +} + +/* + * Conditional relative branch. Tests a single bit in SREG and branches + * relatively to PC if the bit is set. This instruction branches relative= ly to + * PC in either direction (PC - 63 < =3D destination <=3D PC + 64). The p= arameter k + * is the offset from PC and is represented in two's complement form. + */ +static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a) +{ + TCGLabel *not_taken =3D gen_new_label(); + + TCGv var; + + switch (a->bit) { + case 0x00: + var =3D cpu_Cf; + break; + case 0x01: + var =3D cpu_Zf; + break; + case 0x02: + var =3D cpu_Nf; + break; + case 0x03: + var =3D cpu_Vf; + break; + case 0x04: + var =3D cpu_Sf; + break; + case 0x05: + var =3D cpu_Hf; + break; + case 0x06: + var =3D cpu_Tf; + break; + case 0x07: + var =3D cpu_If; + break; + default: + g_assert_not_reached(); + } + + tcg_gen_brcondi_i32(TCG_COND_EQ, var, 0, not_taken); + gen_goto_tb(ctx, 0, ctx->npc + a->imm); + gen_set_label(not_taken); + + ctx->bstate =3D DISAS_CHAIN; + return true; +} + diff --git a/target/avr/insn.decode b/target/avr/insn.decode index 9c71ed6b2f..32034c10d2 100644 --- a/target/avr/insn.decode +++ b/target/avr/insn.decode @@ -91,3 +91,27 @@ FMUL 0000 0011 0 ... 1 ... @fmul FMULS 0000 0011 1 ... 0 ... @fmul FMULSU 0000 0011 1 ... 1 ... @fmul DES 1001 0100 imm:4 1011 + +# +# Branch Instructions +# +RJMP 1100 imm:s12 +IJMP 1001 0100 0000 1001 +EIJMP 1001 0100 0001 1001 +JMP 1001 010 ..... 110 . imm=3D%imm_call +RCALL 1101 imm:s12 +ICALL 1001 0101 0000 1001 +EICALL 1001 0101 0001 1001 +CALL 1001 010 ..... 111 . imm=3D%imm_call +RET 1001 0101 0000 1000 +RETI 1001 0101 0001 1000 +CPSE 0001 00 . ..... .... @op_rd_rr +CP 0001 01 . ..... .... @op_rd_rr +CPC 0000 01 . ..... .... @op_rd_rr +CPI 0011 .... .... .... @op_rd_imm8 +SBRC 1111 110 rr:5 0 bit:3 +SBRS 1111 111 rr:5 0 bit:3 +SBIC 1001 1001 reg:5 bit:3 +SBIS 1001 1011 reg:5 bit:3 +BRBS 1111 00 ....... ... @op_bit_imm +BRBC 1111 01 ....... ... @op_bit_imm --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375521; cv=none; d=zohomail.com; s=zohoarc; b=OCuuVaDiqJDafZTTOmTOLdB6aZdmNV9s888K3/D8q8EhpHdSIeAns+mK6EUDUneWGnMeX4w7lLhL/56VyZq079qQYXSfGdhzHohK8cWeJpvLWl4ZuAhsFvg+RUBpXRNV0piU19+aKidsB4bXy4uXre4O3q+EKXzCnJcQ1xj4Plc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375521; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=79FdDzUb0Ed8UW1ac9Wy6gHeBkCezV8IPatkquZ18Dg=; b=VrKaDY+lttenCqTXQhR4lAZqr91hBzQ6a2an+KjTJV7Zq+sadNehLZjEBbQIYudwVtWJUNGgh6tW/C0kJa0ak2GlhR0oDEUrzDkwWiUlvJBaF8M7L/uidV9PhFmg+4byItfwRdZIX3goePWqmRzIHzWlWAim+Aou0Kgr5U3joj0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375521407697.4127676664835; Sat, 18 Jan 2020 11:25:21 -0800 (PST) Received: from localhost ([::1]:44106 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istih-0002EF-8M for importer@patchew.org; Sat, 18 Jan 2020 14:25:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49845) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istdc-00049t-UW for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istdY-00063y-G9 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:04 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:52408) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istdU-00060K-QT for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:00 -0500 Received: by mail-wm1-x343.google.com with SMTP id p9so10576629wmc.2 for ; Sat, 18 Jan 2020 11:19:56 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.19.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:19:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=79FdDzUb0Ed8UW1ac9Wy6gHeBkCezV8IPatkquZ18Dg=; b=GZGzfbPdt9nn8S2ki6Kirxk2qt15klniYzH/gtsIT0O4zS9Yu3pMqASYDmuUJ08N8y 1erXriclsKaE7MUflfhWDWGekY4xbCY+bYZkrD8ZlQ/OiAWB/jESxR/VO7a1LGZwQGlO 9G7RgwT9Lil2W8+1Q4x5Rpcl0+PZ2Onh19YWeM/VSTG6Jqm6HRnjvUF9xT6q/X/z0xNo SrshYZutxw5z0wcMuRWSn7I3ZYz+Q0kzH29zZPdKKN1lv/5AQJooZYmXtGGzDHkvJkBj ZTsdmV0HXEPUtdbePUaBWiPh9leDu01lLPgE+xCjbxp7ho0MFs+bfGBfwxbvsnUU/uYL U9tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=79FdDzUb0Ed8UW1ac9Wy6gHeBkCezV8IPatkquZ18Dg=; b=Ci2D+Ck6nwlu8LgJVeqTsPPttqz90I/kB8LPumcIRZgNunogFRQ0GL9Ck1Dcd9z863 Jfv679ozTK5flfcwfdqLgc10zhRHw/AnHXAHmw9WQo4xCnAvQrAfZPG/h+XBA3L5c+VM x5+YtBxQ+GHeq7bCdTxf3cudFO0L6sIQEm9MjibiWiY/jQl6EroWA7Mu31hXpnsppefT FxzLEtbCJHXVf5/VaIOJI/4I+g3zaA4rE+jY1m8TH23cxfLM+emXpgSZahHK3AzzFtuc r4GivrZlvpwMRNfY+xBdMDFg3CpVN9VJtmG2vmYje7Kc7P9jubmZ3CfZoUGebZfuB6kk 8pBg== X-Gm-Message-State: APjAAAUGnBCfhS1n/nf7akDllwAbsQQPlFs6PxliUf7FqRd4ksQkhCKZ Ja/7CkTo4MY7yagZOX1TRRt3mZgNwzD4bPRg X-Google-Smtp-Source: APXvYqyn2l8uKkwGNYVy+hjg2jIgcdbY/qgvXZKw4L0i5p1iegF7xK78AFYiqI6NleRIgQRaf1Y8ng== X-Received: by 2002:a1c:4008:: with SMTP id n8mr10914376wma.121.1579375194893; Sat, 18 Jan 2020 11:19:54 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 06/21] target/avr: Add instruction translation - Data Transfer Instructions Date: Sat, 18 Jan 2020 21:14:01 +0200 Message-Id: <20200118191416.19934-7-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) This includes: - MOV, MOVW - LDI, LDS LDX LDY LDZ - LDDY, LDDZ - STS, STX STY STZ - STDY, STDZ - LPM, LPMX - ELPM, ELPMX - SPM, SPMX - IN, OUT - PUSH, POP - XCH - LAS, LAC LAT Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/translate.c | 986 +++++++++++++++++++++++++++++++++++++++++ target/avr/insn.decode | 43 ++ 2 files changed, 1029 insertions(+) diff --git a/target/avr/translate.c b/target/avr/translate.c index 475f502e72..4a62d9312a 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -1454,3 +1454,989 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS = *a) return true; } =20 +/* + * Data Transfer Instructions + */ + +/* + * in the gen_set_addr & gen_get_addr functions + * H assumed to be in 0x00ff0000 format + * M assumed to be in 0x000000ff format + * L assumed to be in 0x000000ff format + */ +static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L) +{ + + tcg_gen_andi_tl(L, addr, 0x000000ff); + + tcg_gen_andi_tl(M, addr, 0x0000ff00); + tcg_gen_shri_tl(M, M, 8); + + tcg_gen_andi_tl(H, addr, 0x00ff0000); +} + +static void gen_set_xaddr(TCGv addr) +{ + gen_set_addr(addr, cpu_rampX, cpu_r[27], cpu_r[26]); +} + +static void gen_set_yaddr(TCGv addr) +{ + gen_set_addr(addr, cpu_rampY, cpu_r[29], cpu_r[28]); +} + +static void gen_set_zaddr(TCGv addr) +{ + gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]); +} + +static TCGv gen_get_addr(TCGv H, TCGv M, TCGv L) +{ + TCGv addr =3D tcg_temp_new_i32(); + + tcg_gen_deposit_tl(addr, M, H, 8, 8); + tcg_gen_deposit_tl(addr, L, addr, 8, 16); + + return addr; +} + +static TCGv gen_get_xaddr(void) +{ + return gen_get_addr(cpu_rampX, cpu_r[27], cpu_r[26]); +} + +static TCGv gen_get_yaddr(void) +{ + return gen_get_addr(cpu_rampY, cpu_r[29], cpu_r[28]); +} + +static TCGv gen_get_zaddr(void) +{ + return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]); +} + +/* + * Load one byte indirect from data space to register and stores an clear + * the bits in data space specified by the register. The instruction can = only + * be used towards internal SRAM. The data location is pointed to by the= Z (16 + * bits) Pointer Register in the Register File. Memory access is limited = to the + * current data segment of 64KB. To access another data segment in device= s with + * more than 64KB data space, the RAMPZ in register in the I/O area has t= o be + * changed. The Z-pointer Register is left unchanged by the operation. T= his + * instruction is especially suited for clearing status bits stored in SR= AM. + */ +static void gen_data_store(DisasContext *ctx, TCGv data, TCGv addr) +{ + if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) { + gen_helper_fullwr(cpu_env, data, addr); + } else { + tcg_gen_qemu_st8(data, addr, MMU_DATA_IDX); /* mem[addr] =3D data = */ + } +} + +static void gen_data_load(DisasContext *ctx, TCGv data, TCGv addr) +{ + if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) { + gen_helper_fullrd(data, cpu_env, addr); + } else { + tcg_gen_qemu_ld8u(data, addr, MMU_DATA_IDX); /* data =3D mem[addr]= */ + } +} + +/* + * This instruction makes a copy of one register into another. The source + * register Rr is left unchanged, while the destination register Rd is lo= aded + * with a copy of Rr. + */ +static bool trans_MOV(DisasContext *ctx, arg_MOV *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv Rr =3D cpu_r[a->rr]; + + tcg_gen_mov_tl(Rd, Rr); + + return true; +} + +/* + * This instruction makes a copy of one register pair into another regist= er + * pair. The source register pair Rr+1:Rr is left unchanged, while the + * destination register pair Rd+1:Rd is loaded with a copy of Rr + 1:Rr. = This + * instruction is not available in all devices. Refer to the device speci= fic + * instruction set summary. + */ +static bool trans_MOVW(DisasContext *ctx, arg_MOVW *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_MOVW)) { + return true; + } + + TCGv RdL =3D cpu_r[a->rd]; + TCGv RdH =3D cpu_r[a->rd + 1]; + TCGv RrL =3D cpu_r[a->rr]; + TCGv RrH =3D cpu_r[a->rr + 1]; + + tcg_gen_mov_tl(RdH, RrH); + tcg_gen_mov_tl(RdL, RrL); + + return true; +} + +/* + * Loads an 8 bit constant directly to register 16 to 31. + */ +static bool trans_LDI(DisasContext *ctx, arg_LDI *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + int imm =3D a->imm; + + tcg_gen_movi_tl(Rd, imm); + + return true; +} + +/* + * Loads one byte from the data space to a register. For parts with SRAM, + * the data space consists of the Register File, I/O memory and internal = SRAM + * (and external SRAM if applicable). For parts without SRAM, the data sp= ace + * consists of the register file only. The EEPROM has a separate address = space. + * A 16-bit address must be supplied. Memory access is limited to the cur= rent + * data segment of 64KB. The LDS instruction uses the RAMPD Register to a= ccess + * memory above 64KB. To access another data segment in devices with more= than + * 64KB data space, the RAMPD in register in the I/O area has to be chang= ed. + * This instruction is not available in all devices. Refer to the device + * specific instruction set summary. + */ +static bool trans_LDS(DisasContext *ctx, arg_LDS *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D tcg_temp_new_i32(); + TCGv H =3D cpu_rampD; + a->imm =3D next_word(ctx); + + tcg_gen_mov_tl(addr, H); /* addr =3D H:M:L */ + tcg_gen_shli_tl(addr, addr, 16); + tcg_gen_ori_tl(addr, addr, a->imm); + + gen_data_load(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Loads one byte indirect from the data space to a register. For parts + * with SRAM, the data space consists of the Register File, I/O memory and + * internal SRAM (and external SRAM if applicable). For parts without SRA= M, the + * data space consists of the Register File only. In some parts the Flash + * Memory has been mapped to the data space and can be read using this co= mmand. + * The EEPROM has a separate address space. The data location is pointed= to by + * the X (16 bits) Pointer Register in the Register File. Memory access is + * limited to the current data segment of 64KB. To access another data se= gment + * in devices with more than 64KB data space, the RAMPX in register in th= e I/O + * area has to be changed. The X-pointer Register can either be left unc= hanged + * by the operation, or it can be post-incremented or predecremented. Th= ese + * features are especially suited for accessing arrays, tables, and Stack + * Pointer usage of the X-pointer Register. Note that only the low byte o= f the + * X-pointer is updated in devices with no more than 256 bytes data space= . For + * such devices, the high byte of the pointer is not used by this instruc= tion + * and can be used for other purposes. The RAMPX Register in the I/O area= is + * updated in parts with more than 64KB data space or more than 64KB Prog= ram + * memory, and the increment/decrement is added to the entire 24-bit addr= ess on + * such devices. Not all variants of this instruction is available in all + * devices. Refer to the device specific instruction set summary. In the + * Reduced Core tinyAVR the LD instruction can be used to achieve the same + * operation as LPM since the program memory is mapped to the data memory + * space. + */ +static bool trans_LDX1(DisasContext *ctx, arg_LDX1 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_xaddr(); + + gen_data_load(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LDX2(DisasContext *ctx, arg_LDX2 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_xaddr(); + + gen_data_load(ctx, Rd, addr); + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + + gen_set_xaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LDX3(DisasContext *ctx, arg_LDX3 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_xaddr(); + + tcg_gen_subi_tl(addr, addr, 1); /* addr =3D addr - 1 */ + gen_data_load(ctx, Rd, addr); + gen_set_xaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Loads one byte indirect with or without displacement from the data spa= ce + * to a register. For parts with SRAM, the data space consists of the Reg= ister + * File, I/O memory and internal SRAM (and external SRAM if applicable). = For + * parts without SRAM, the data space consists of the Register File only.= In + * some parts the Flash Memory has been mapped to the data space and can = be + * read using this command. The EEPROM has a separate address space. The= data + * location is pointed to by the Y (16 bits) Pointer Register in the Regi= ster + * File. Memory access is limited to the current data segment of 64KB. To + * access another data segment in devices with more than 64KB data space,= the + * RAMPY in register in the I/O area has to be changed. The Y-pointer Re= gister + * can either be left unchanged by the operation, or it can be post-incre= mented + * or predecremented. These features are especially suited for accessing + * arrays, tables, and Stack Pointer usage of the Y-pointer Register. Not= e that + * only the low byte of the Y-pointer is updated in devices with no more = than + * 256 bytes data space. For such devices, the high byte of the pointer i= s not + * used by this instruction and can be used for other purposes. The RAMPY + * Register in the I/O area is updated in parts with more than 64KB data = space + * or more than 64KB Program memory, and the increment/decrement/displace= ment + * is added to the entire 24-bit address on such devices. Not all varian= ts of + * this instruction is available in all devices. Refer to the device spec= ific + * instruction set summary. In the Reduced Core tinyAVR the LD instructi= on can + * be used to achieve the same operation as LPM since the program memory = is + * mapped to the data memory space. + */ +static bool trans_LDY2(DisasContext *ctx, arg_LDY2 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_yaddr(); + + gen_data_load(ctx, Rd, addr); + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + + gen_set_yaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LDY3(DisasContext *ctx, arg_LDY3 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_yaddr(); + + tcg_gen_subi_tl(addr, addr, 1); /* addr =3D addr - 1 */ + gen_data_load(ctx, Rd, addr); + gen_set_yaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LDDY(DisasContext *ctx, arg_LDDY *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_yaddr(); + + tcg_gen_addi_tl(addr, addr, a->imm); /* addr =3D addr + q */ + gen_data_load(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Loads one byte indirect with or without displacement from the data spa= ce + * to a register. For parts with SRAM, the data space consists of the Reg= ister + * File, I/O memory and internal SRAM (and external SRAM if applicable). = For + * parts without SRAM, the data space consists of the Register File only.= In + * some parts the Flash Memory has been mapped to the data space and can = be + * read using this command. The EEPROM has a separate address space. The= data + * location is pointed to by the Z (16 bits) Pointer Register in the Regi= ster + * File. Memory access is limited to the current data segment of 64KB. To + * access another data segment in devices with more than 64KB data space,= the + * RAMPZ in register in the I/O area has to be changed. The Z-pointer Re= gister + * can either be left unchanged by the operation, or it can be post-incre= mented + * or predecremented. These features are especially suited for Stack Poi= nter + * usage of the Z-pointer Register, however because the Z-pointer Registe= r can + * be used for indirect subroutine calls, indirect jumps and table lookup= , it + * is often more convenient to use the X or Y-pointer as a dedicated Stack + * Pointer. Note that only the low byte of the Z-pointer is updated in de= vices + * with no more than 256 bytes data space. For such devices, the high byt= e of + * the pointer is not used by this instruction and can be used for other + * purposes. The RAMPZ Register in the I/O area is updated in parts with = more + * than 64KB data space or more than 64KB Program memory, and the + * increment/decrement/displacement is added to the entire 24-bit address= on + * such devices. Not all variants of this instruction is available in all + * devices. Refer to the device specific instruction set summary. In the + * Reduced Core tinyAVR the LD instruction can be used to achieve the same + * operation as LPM since the program memory is mapped to the data memory + * space. For using the Z-pointer for table lookup in Program memory see= the + * LPM and ELPM instructions. + */ +static bool trans_LDZ2(DisasContext *ctx, arg_LDZ2 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + gen_data_load(ctx, Rd, addr); + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + + gen_set_zaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LDZ3(DisasContext *ctx, arg_LDZ3 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + tcg_gen_subi_tl(addr, addr, 1); /* addr =3D addr - 1 */ + gen_data_load(ctx, Rd, addr); + + gen_set_zaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LDDZ(DisasContext *ctx, arg_LDDZ *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + tcg_gen_addi_tl(addr, addr, a->imm); /* addr =3D addr + q */ + gen_data_load(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Stores one byte from a Register to the data space. For parts with SRAM, + * the data space consists of the Register File, I/O memory and internal = SRAM + * (and external SRAM if applicable). For parts without SRAM, the data sp= ace + * consists of the Register File only. The EEPROM has a separate address = space. + * A 16-bit address must be supplied. Memory access is limited to the cur= rent + * data segment of 64KB. The STS instruction uses the RAMPD Register to a= ccess + * memory above 64KB. To access another data segment in devices with more= than + * 64KB data space, the RAMPD in register in the I/O area has to be chang= ed. + * This instruction is not available in all devices. Refer to the device + * specific instruction set summary. + */ +static bool trans_STS(DisasContext *ctx, arg_STS *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D tcg_temp_new_i32(); + TCGv H =3D cpu_rampD; + a->imm =3D next_word(ctx); + + tcg_gen_mov_tl(addr, H); /* addr =3D H:M:L */ + tcg_gen_shli_tl(addr, addr, 16); + tcg_gen_ori_tl(addr, addr, a->imm); + gen_data_store(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Stores one byte indirect from a register to data space. For parts with = SRAM, + * the data space consists of the Register File, I/O memory, and internal = SRAM + * (and external SRAM if applicable). For parts without SRAM, the data spa= ce + * consists of the Register File only. The EEPROM has a separate address s= pace. + * + * The data location is pointed to by the X (16 bits) Pointer Register in = the + * Register File. Memory access is limited to the current data segment of = 64KB. + * To access another data segment in devices with more than 64KB data spac= e, the + * RAMPX in register in the I/O area has to be changed. + * + * The X-pointer Register can either be left unchanged by the operation, o= r it + * can be post-incremented or pre-decremented. These features are especial= ly + * suited for accessing arrays, tables, and Stack Pointer usage of the + * X-pointer Register. Note that only the low byte of the X-pointer is upd= ated + * in devices with no more than 256 bytes data space. For such devices, th= e high + * byte of the pointer is not used by this instruction and can be used for= other + * purposes. The RAMPX Register in the I/O area is updated in parts with m= ore + * than 64KB data space or more than 64KB Program memory, and the incremen= t / + * decrement is added to the entire 24-bit address on such devices. + */ +static bool trans_STX1(DisasContext *ctx, arg_STX1 *a) +{ + TCGv Rd =3D cpu_r[a->rr]; + TCGv addr =3D gen_get_xaddr(); + + gen_data_store(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_STX2(DisasContext *ctx, arg_STX2 *a) +{ + TCGv Rd =3D cpu_r[a->rr]; + TCGv addr =3D gen_get_xaddr(); + + gen_data_store(ctx, Rd, addr); + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + gen_set_xaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_STX3(DisasContext *ctx, arg_STX3 *a) +{ + TCGv Rd =3D cpu_r[a->rr]; + TCGv addr =3D gen_get_xaddr(); + + tcg_gen_subi_tl(addr, addr, 1); /* addr =3D addr - 1 */ + gen_data_store(ctx, Rd, addr); + gen_set_xaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Stores one byte indirect with or without displacement from a register t= o data + * space. For parts with SRAM, the data space consists of the Register Fil= e, I/O + * memory, and internal SRAM (and external SRAM if applicable). For parts + * without SRAM, the data space consists of the Register File only. The EE= PROM + * has a separate address space. + * + * The data location is pointed to by the Y (16 bits) Pointer Register in = the + * Register File. Memory access is limited to the current data segment of = 64KB. + * To access another data segment in devices with more than 64KB data spac= e, the + * RAMPY in register in the I/O area has to be changed. + * + * The Y-pointer Register can either be left unchanged by the operation, o= r it + * can be post-incremented or pre-decremented. These features are especial= ly + * suited for accessing arrays, tables, and Stack Pointer usage of the Y-p= ointer + * Register. Note that only the low byte of the Y-pointer is updated in de= vices + * with no more than 256 bytes data space. For such devices, the high byte= of + * the pointer is not used by this instruction and can be used for other + * purposes. The RAMPY Register in the I/O area is updated in parts with m= ore + * than 64KB data space or more than 64KB Program memory, and the incremen= t / + * decrement / displacement is added to the entire 24-bit address on such + * devices. + */ +static bool trans_STY2(DisasContext *ctx, arg_STY2 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_yaddr(); + + gen_data_store(ctx, Rd, addr); + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + gen_set_yaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_STY3(DisasContext *ctx, arg_STY3 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_yaddr(); + + tcg_gen_subi_tl(addr, addr, 1); /* addr =3D addr - 1 */ + gen_data_store(ctx, Rd, addr); + gen_set_yaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_STDY(DisasContext *ctx, arg_STDY *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_yaddr(); + + tcg_gen_addi_tl(addr, addr, a->imm); /* addr =3D addr + q */ + gen_data_store(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Stores one byte indirect with or without displacement from a register t= o data + * space. For parts with SRAM, the data space consists of the Register Fil= e, I/O + * memory, and internal SRAM (and external SRAM if applicable). For parts + * without SRAM, the data space consists of the Register File only. The EE= PROM + * has a separate address space. + * + * The data location is pointed to by the Y (16 bits) Pointer Register in = the + * Register File. Memory access is limited to the current data segment of = 64KB. + * To access another data segment in devices with more than 64KB data spac= e, the + * RAMPY in register in the I/O area has to be changed. + * + * The Y-pointer Register can either be left unchanged by the operation, o= r it + * can be post-incremented or pre-decremented. These features are especial= ly + * suited for accessing arrays, tables, and Stack Pointer usage of the Y-p= ointer + * Register. Note that only the low byte of the Y-pointer is updated in de= vices + * with no more than 256 bytes data space. For such devices, the high byte= of + * the pointer is not used by this instruction and can be used for other + * purposes. The RAMPY Register in the I/O area is updated in parts with m= ore + * than 64KB data space or more than 64KB Program memory, and the incremen= t / + * decrement / displacement is added to the entire 24-bit address on such + * devices. + */ +static bool trans_STZ2(DisasContext *ctx, arg_STZ2 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + gen_data_store(ctx, Rd, addr); + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + + gen_set_zaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_STZ3(DisasContext *ctx, arg_STZ3 *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + tcg_gen_subi_tl(addr, addr, 1); /* addr =3D addr - 1 */ + gen_data_store(ctx, Rd, addr); + + gen_set_zaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_STDZ(DisasContext *ctx, arg_STDZ *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + tcg_gen_addi_tl(addr, addr, a->imm); /* addr =3D addr + q */ + gen_data_store(ctx, Rd, addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Loads one byte pointed to by the Z-register into the destination + * register Rd. This instruction features a 100% space effective constant + * initialization or constant data fetch. The Program memory is organized= in + * 16-bit words while the Z-pointer is a byte address. Thus, the least + * significant bit of the Z-pointer selects either low byte (ZLSB =3D 0) = or high + * byte (ZLSB =3D 1). This instruction can address the first 64KB (32K wo= rds) of + * Program memory. The Zpointer Register can either be left unchanged by = the + * operation, or it can be incremented. The incrementation does not apply= to + * the RAMPZ Register. + * + * Devices with Self-Programming capability can use the LPM instruction t= o read + * the Fuse and Lock bit values. + */ +static bool trans_LPM1(DisasContext *ctx, arg_LPM1 *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_LPM)) { + return true; + } + + TCGv Rd =3D cpu_r[0]; + TCGv addr =3D tcg_temp_new_i32(); + TCGv H =3D cpu_r[31]; + TCGv L =3D cpu_r[30]; + + tcg_gen_shli_tl(addr, H, 8); /* addr =3D H:L */ + tcg_gen_or_tl(addr, addr, L); + tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd =3D mem[addr] */ + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LPM2(DisasContext *ctx, arg_LPM2 *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_LPM)) { + return true; + } + + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D tcg_temp_new_i32(); + TCGv H =3D cpu_r[31]; + TCGv L =3D cpu_r[30]; + + tcg_gen_shli_tl(addr, H, 8); /* addr =3D H:L */ + tcg_gen_or_tl(addr, addr, L); + tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd =3D mem[addr] */ + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_LPMX(DisasContext *ctx, arg_LPMX *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_LPMX)) { + return true; + } + + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D tcg_temp_new_i32(); + TCGv H =3D cpu_r[31]; + TCGv L =3D cpu_r[30]; + + tcg_gen_shli_tl(addr, H, 8); /* addr =3D H:L */ + tcg_gen_or_tl(addr, addr, L); + tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd =3D mem[addr] */ + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + tcg_gen_andi_tl(L, addr, 0xff); + tcg_gen_shri_tl(addr, addr, 8); + tcg_gen_andi_tl(H, addr, 0xff); + + tcg_temp_free_i32(addr); + + return true; +} + + +/* + * Loads one byte pointed to by the Z-register and the RAMPZ Register in + * the I/O space, and places this byte in the destination register Rd. Th= is + * instruction features a 100% space effective constant initialization or + * constant data fetch. The Program memory is organized in 16-bit words w= hile + * the Z-pointer is a byte address. Thus, the least significant bit of the + * Z-pointer selects either low byte (ZLSB =3D 0) or high byte (ZLSB =3D = 1). This + * instruction can address the entire Program memory space. The Z-pointer + * Register can either be left unchanged by the operation, or it can be + * incremented. The incrementation applies to the entire 24-bit concatena= tion + * of the RAMPZ and Z-pointer Registers. + * + * Devices with Self-Programming capability can use the ELPM instruction = to + * read the Fuse and Lock bit value. + */ +static bool trans_ELPM1(DisasContext *ctx, arg_ELPM1 *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_ELPM)) { + return true; + } + + TCGv Rd =3D cpu_r[0]; + TCGv addr =3D gen_get_zaddr(); + + tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd =3D mem[addr] */ + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_ELPM2(DisasContext *ctx, arg_ELPM2 *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_ELPM)) { + return true; + } + + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd =3D mem[addr] */ + + tcg_temp_free_i32(addr); + + return true; +} + +static bool trans_ELPMX(DisasContext *ctx, arg_ELPMX *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_ELPMX)) { + return true; + } + + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + + tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd =3D mem[addr] */ + tcg_gen_addi_tl(addr, addr, 1); /* addr =3D addr + 1 */ + gen_set_zaddr(addr); + + tcg_temp_free_i32(addr); + + return true; +} + +/* + * SPM can be used to erase a page in the Program memory, to write a page + * in the Program memory (that is already erased), and to set Boot Loader= Lock + * bits. In some devices, the Program memory can be written one word at a= time, + * in other devices an entire page can be programmed simultaneously after= first + * filling a temporary page buffer. In all cases, the Program memory must= be + * erased one page at a time. When erasing the Program memory, the RAMPZ = and + * Z-register are used as page address. When writing the Program memory, = the + * RAMPZ and Z-register are used as page or word address, and the R1:R0 + * register pair is used as data(1). When setting the Boot Loader Lock bi= ts, + * the R1:R0 register pair is used as data. Refer to the device documenta= tion + * for detailed description of SPM usage. This instruction can address the + * entire Program memory. + * + * The SPM instruction is not available in all devices. Refer to the devi= ce + * specific instruction set summary. + * + * Note: 1. R1 determines the instruction high byte, and R0 determines the + * instruction low byte. + */ +static bool trans_SPM(DisasContext *ctx, arg_SPM *a) +{ + /* TODO */ + if (!avr_have_feature(ctx, AVR_FEATURE_SPM)) { + return true; + } + + return true; +} + +static bool trans_SPMX(DisasContext *ctx, arg_SPMX *a) +{ + /* TODO */ + if (!avr_have_feature(ctx, AVR_FEATURE_SPMX)) { + return true; + } + + return true; +} + +/* + * Loads data from the I/O Space (Ports, Timers, Configuration Registers, + * etc.) into register Rd in the Register File. + */ +static bool trans_IN(DisasContext *ctx, arg_IN *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv port =3D tcg_const_i32(a->imm); + + gen_helper_inb(Rd, cpu_env, port); + + tcg_temp_free_i32(port); + + return true; +} + +/* + * Stores data from register Rr in the Register File to I/O Space (Ports, + * Timers, Configuration Registers, etc.). + */ +static bool trans_OUT(DisasContext *ctx, arg_OUT *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv port =3D tcg_const_i32(a->imm); + + gen_helper_outb(cpu_env, port, Rd); + + tcg_temp_free_i32(port); + + return true; +} + +/* + * This instruction stores the contents of register Rr on the STACK. The + * Stack Pointer is post-decremented by 1 after the PUSH. This instructi= on is + * not available in all devices. Refer to the device specific instruction= set + * summary. + */ +static bool trans_PUSH(DisasContext *ctx, arg_PUSH *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + + gen_data_store(ctx, Rd, cpu_sp); + tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + + return true; +} + +/* + * This instruction loads register Rd with a byte from the STACK. The Sta= ck + * Pointer is pre-incremented by 1 before the POP. This instruction is n= ot + * available in all devices. Refer to the device specific instruction set + * summary. + */ +static bool trans_POP(DisasContext *ctx, arg_POP *a) +{ + /* + * Using a temp to work around some strange behaviour: + * tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); + * gen_data_load(ctx, Rd, cpu_sp); + * seems to cause the add to happen twice. + * This doesn't happen if either the add or the load is removed. + */ + TCGv t1 =3D tcg_temp_new_i32(); + TCGv Rd =3D cpu_r[a->rd]; + + tcg_gen_addi_tl(t1, cpu_sp, 1); + gen_data_load(ctx, Rd, t1); + tcg_gen_mov_tl(cpu_sp, t1); + + return true; +} + +/* + * Exchanges one byte indirect between register and data space. The data + * location is pointed to by the Z (16 bits) Pointer Register in the Regi= ster + * File. Memory access is limited to the current data segment of 64KB. To + * access another data segment in devices with more than 64KB data space,= the + * RAMPZ in register in the I/O area has to be changed. + * + * The Z-pointer Register is left unchanged by the operation. This instru= ction + * is especially suited for writing/reading status bits stored in SRAM. + */ +static bool trans_XCH(DisasContext *ctx, arg_XCH *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { + return true; + } + + TCGv Rd =3D cpu_r[a->rd]; + TCGv t0 =3D tcg_temp_new_i32(); + TCGv addr =3D gen_get_zaddr(); + + gen_data_load(ctx, t0, addr); + gen_data_store(ctx, Rd, addr); + tcg_gen_mov_tl(Rd, t0); + + tcg_temp_free_i32(t0); + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Load one byte indirect from data space to register and set bits in data + * space specified by the register. The instruction can only be used towa= rds + * internal SRAM. The data location is pointed to by the Z (16 bits) Poi= nter + * Register in the Register File. Memory access is limited to the current= data + * segment of 64KB. To access another data segment in devices with more t= han + * 64KB data space, the RAMPZ in register in the I/O area has to be chang= ed. + * + * The Z-pointer Register is left unchanged by the operation. This instru= ction + * is especially suited for setting status bits stored in SRAM. + */ +static bool trans_LAS(DisasContext *ctx, arg_LAS *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { + return true; + } + + TCGv Rr =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + TCGv t0 =3D tcg_temp_new_i32(); + TCGv t1 =3D tcg_temp_new_i32(); + + gen_data_load(ctx, t0, addr); /* t0 =3D mem[addr] */ + tcg_gen_or_tl(t1, t0, Rr); + tcg_gen_mov_tl(Rr, t0); /* Rr =3D t0 */ + gen_data_store(ctx, t1, addr); /* mem[addr] =3D t1 */ + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(addr); + + return true; +} + +/* + * Load one byte indirect from data space to register and stores and clear + * the bits in data space specified by the register. The instruction can + * only be used towards internal SRAM. The data location is pointed to by + * the Z (16 bits) Pointer Register in the Register File. Memory access is + * limited to the current data segment of 64KB. To access another data + * segment in devices with more than 64KB data space, the RAMPZ in regist= er + * in the I/O area has to be changed. + * + * The Z-pointer Register is left unchanged by the operation. This instru= ction + * is especially suited for clearing status bits stored in SRAM. + */ +static bool trans_LAC(DisasContext *ctx, arg_LAC *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { + return true; + } + + TCGv Rr =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + TCGv t0 =3D tcg_temp_new_i32(); + TCGv t1 =3D tcg_temp_new_i32(); + + gen_data_load(ctx, t0, addr); /* t0 =3D mem[addr] */ + tcg_gen_andc_tl(t1, t0, Rr); /* t1 =3D t0 & (0xff - Rr) =3D t0 & ~Rr */ + tcg_gen_mov_tl(Rr, t0); /* Rr =3D t0 */ + gen_data_store(ctx, t1, addr); /* mem[addr] =3D t1 */ + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(addr); + + return true; +} + + +/* + * Load one byte indirect from data space to register and toggles bits in + * the data space specified by the register. The instruction can only be= used + * towards SRAM. The data location is pointed to by the Z (16 bits) Poin= ter + * Register in the Register File. Memory access is limited to the current= data + * segment of 64KB. To access another data segment in devices with more t= han + * 64KB data space, the RAMPZ in register in the I/O area has to be chang= ed. + * + * The Z-pointer Register is left unchanged by the operation. This instru= ction + * is especially suited for changing status bits stored in SRAM. + */ +static bool trans_LAT(DisasContext *ctx, arg_LAT *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { + return true; + } + + TCGv Rd =3D cpu_r[a->rd]; + TCGv addr =3D gen_get_zaddr(); + TCGv t0 =3D tcg_temp_new_i32(); + TCGv t1 =3D tcg_temp_new_i32(); + + gen_data_load(ctx, t0, addr); /* t0 =3D mem[addr] */ + tcg_gen_xor_tl(t1, t0, Rd); + tcg_gen_mov_tl(Rd, t0); /* Rd =3D t0 */ + gen_data_store(ctx, t1, addr); /* mem[addr] =3D t1 */ + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(addr); + + return true; +} diff --git a/target/avr/insn.decode b/target/avr/insn.decode index 32034c10d2..3f9304f8b0 100644 --- a/target/avr/insn.decode +++ b/target/avr/insn.decode @@ -115,3 +115,46 @@ SBIC 1001 1001 reg:5 bit:3 SBIS 1001 1011 reg:5 bit:3 BRBS 1111 00 ....... ... @op_bit_imm BRBC 1111 01 ....... ... @op_bit_imm + +# +# Data Transfer Instructions +# +MOV 0010 11 . ..... .... @op_rd_rr +MOVW 0000 0001 .... .... &rd_rr rd=3D%rd_d rr=3D%r= r_d +LDI 1110 .... .... .... @op_rd_imm8 +LDS 1001 000 ..... 0000 @ldst_s +LDX1 1001 000 rd:5 1100 +LDX2 1001 000 rd:5 1101 +LDX3 1001 000 rd:5 1110 +LDY2 1001 000 rd:5 1001 +LDY3 1001 000 rd:5 1010 +LDZ2 1001 000 rd:5 0001 +LDZ3 1001 000 rd:5 0010 +LDDY 10 . 0 .. 0 ..... 1 ... @ldst_d +LDDZ 10 . 0 .. 0 ..... 0 ... @ldst_d +STS 1001 001 ..... 0000 @ldst_s +STX1 1001 001 rr:5 1100 +STX2 1001 001 rr:5 1101 +STX3 1001 001 rr:5 1110 +STY2 1001 001 rd:5 1001 +STY3 1001 001 rd:5 1010 +STZ2 1001 001 rd:5 0001 +STZ3 1001 001 rd:5 0010 +STDY 10 . 0 .. 1 ..... 1 ... @ldst_d +STDZ 10 . 0 .. 1 ..... 0 ... @ldst_d +LPM1 1001 0101 1100 1000 +LPM2 1001 000 rd:5 0100 +LPMX 1001 000 rd:5 0101 +ELPM1 1001 0101 1101 1000 +ELPM2 1001 000 rd:5 0110 +ELPMX 1001 000 rd:5 0111 +SPM 1001 0101 1110 1000 +SPMX 1001 0101 1111 1000 +IN 1011 0 .. ..... .... @io_rd_imm +OUT 1011 1 .. ..... .... @io_rd_imm +PUSH 1001 001 rd:5 1111 +POP 1001 000 rd:5 1111 +XCH 1001 001 rd:5 0100 +LAC 1001 001 rd:5 0110 +LAS 1001 001 rd:5 0101 +LAT 1001 001 rd:5 0111 --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376006; cv=none; d=zohomail.com; s=zohoarc; b=UIvht3GNbAw+8vpdNtFYKJ1xO6QI7xSOyLKk1+zFnCrJN6gY3743ieg+0e/HAp0wIBaNJ/fbzXx4HSk6Cq+2DMGVCkPz9vxvTcAFxH4kBOsfOn2JslZmnzElP3ixN9b2bN+h42G77kJW9xIx1+QRTFCkYxZYmuo/x16IRg2lflg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376006; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=462i1Ag4o0cfxhQVfRSys4sY7nSXMyI7nbnWCXem7s4=; b=Mgcc/9nUg8XwEs8R+wQWyem+XVSjv1r9o1hHw3i/QEt9Y1JjX3AUoYfvMTZEGHT/tsCWrh+FYaem7NsRKB5VjZpVokbB6UynZYpzXpwpaARZOBlPHAULcofE7cM2YxEuaSNCfA4adAuYVIOZFnekE/JBu5v9iqgytANH8cSUlZQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 157937600653351.19662032360088; Sat, 18 Jan 2020 11:33:26 -0800 (PST) Received: from localhost ([::1]:44206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istqX-0003e8-5G for importer@patchew.org; Sat, 18 Jan 2020 14:33:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49856) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istdd-0004Ak-F5 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istdb-00067O-MM for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:05 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:40156) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istdb-00066V-Fz for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:03 -0500 Received: by mail-wr1-x443.google.com with SMTP id c14so25717617wrn.7 for ; Sat, 18 Jan 2020 11:20:03 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.19.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:20:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=462i1Ag4o0cfxhQVfRSys4sY7nSXMyI7nbnWCXem7s4=; b=E2iqmkpIyyacXS8n9yD4JtEGIbA+m+6IvS7I9NB0DEDZDPoSkpG/0Kcm8MXhpTxKWL 96pDaDHoSTLGOmOlasuIZGmRsynJENiQcWFWNMw6z2r/4Ct8x+ToZqSb9vDtEhKa6Bci RPu0dPigQqEEnr0lhGYJcEeQunJSF5IoFdE/3APM3WIYT0SagCmc7E00VRAt/ZUjX4Gl gz+LRpx5GHOmnaS1YBAnJdWj2E1wAmQ6HXtoo5VGEFGkIuW5jRFYXpCoobYq24KabaSS 2clXThVXCBmnPjO8249jIu2yTyL1wDm6ukkDsfhSDZu5b9gCSVlONN1Fgs1GVntI+jj1 MJ3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=462i1Ag4o0cfxhQVfRSys4sY7nSXMyI7nbnWCXem7s4=; b=Zpx903+TIEwy/btJXw6Qs3VMnfs2ukwdt6UM37P/fhhVYCzKkNHOW/Aiwz8b0AKGut y6gKbZbE7b/AwgzvlWqZSTyS0RJFlL9Py1kB3V8o1X5bRUiPSEkWVa4D5AnxxVHlK3ft 9fsPoDwdNAjFlPtBBdZOKUZsZtWVu1TbakxRD/g3iIwuDd5l9kueryiqtzqGJUzZHPHf v4Sv/vOadSSQjAjgxRMEZ7ndgrKlwcDat5dgsxrOyFU/rCyLiXJmP7aLKLSjdls2U4NY nXSJIF0X69qTScnP193PPRYVKmQjTom/JFzfRRqrp1kt8E/ywGveF8QYL43fgvxejPLA XePA== X-Gm-Message-State: APjAAAVbpNEAIrClqWLwilqoKBgSX8wN2BTME2lXneIlORIaa27NrCd4 W+XGE5CpCS41kCClA1ObQf7Z1+wowY7nrnTZ X-Google-Smtp-Source: APXvYqwtJyBcK3D3EdMyBqxO6msb8+sGhERMzcO94IOOkkNIZ0Ajv464IKm97hPiYKKYYPrN4/DrsQ== X-Received: by 2002:a5d:6692:: with SMTP id l18mr9476704wru.382.1579375202191; Sat, 18 Jan 2020 11:20:02 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 07/21] target/avr: Add instruction translation - Bit and Bit-test Instructions Date: Sat, 18 Jan 2020 21:14:02 +0200 Message-Id: <20200118191416.19934-8-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) This includes: - LSR, ROR - ASR - SWAP - SBI, CBI - BST, BLD - BSET, BCLR Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/translate.c | 241 +++++++++++++++++++++++++++++++++++++++++ target/avr/insn.decode | 14 +++ 2 files changed, 255 insertions(+) diff --git a/target/avr/translate.c b/target/avr/translate.c index 4a62d9312a..58775af17c 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -2440,3 +2440,244 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a) =20 return true; } + +/* + * Bit and Bit-test Instructions + */ +static void gen_rshift_ZNVSf(TCGv R) +{ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf =3D R =3D=3D 0 */ + tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf =3D R(7) */ + tcg_gen_xor_tl(cpu_Vf, cpu_Nf, cpu_Cf); + tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf =3D Nf ^ Vf */ +} + +/* + * Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 = is + * loaded into the C Flag of the SREG. This operation effectively divides= an + * unsigned value by two. The C Flag can be used to round the result. + */ +static bool trans_LSR(DisasContext *ctx, arg_LSR *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + + tcg_gen_andi_tl(cpu_Cf, Rd, 1); + tcg_gen_shri_tl(Rd, Rd, 1); + /* update status register */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, Rd, 0); /* Zf =3D Rd =3D=3D 0= */ + tcg_gen_movi_tl(cpu_Nf, 0); + tcg_gen_mov_tl(cpu_Vf, cpu_Cf); + tcg_gen_mov_tl(cpu_Sf, cpu_Vf); + + return true; +} + +/* + * Shifts all bits in Rd one place to the right. The C Flag is shifted in= to + * bit 7 of Rd. Bit 0 is shifted into the C Flag. This operation, combin= ed + * with ASR, effectively divides multi-byte signed values by two. Combine= d with + * LSR it effectively divides multi-byte unsigned values by two. The Carr= y Flag + * can be used to round the result. + */ +static bool trans_ROR(DisasContext *ctx, arg_ROR *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv t0 =3D tcg_temp_new_i32(); + + tcg_gen_shli_tl(t0, cpu_Cf, 7); + /* update status register */ + tcg_gen_andi_tl(cpu_Cf, Rd, 1); + /* update output register */ + tcg_gen_shri_tl(Rd, Rd, 1); + tcg_gen_or_tl(Rd, Rd, t0); + /* update status register */ + gen_rshift_ZNVSf(Rd); + + tcg_temp_free_i32(t0); + + return true; +} + +/* + * Shifts all bits in Rd one place to the right. Bit 7 is held constant. = Bit 0 + * is loaded into the C Flag of the SREG. This operation effectively divi= des a + * signed value by two without changing its sign. The Carry Flag can be u= sed to + * round the result. + */ +static bool trans_ASR(DisasContext *ctx, arg_ASR *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv t0 =3D tcg_temp_new_i32(); + + /* update status register */ + tcg_gen_andi_tl(cpu_Cf, Rd, 1); /* Cf =3D Rd(0) */ + /* update output register */ + tcg_gen_andi_tl(t0, Rd, 0x80); /* Rd =3D (Rd & 0x80) | (Rd >> 1) */ + tcg_gen_shri_tl(Rd, Rd, 1); + tcg_gen_or_tl(Rd, Rd, t0); + /* update status register */ + gen_rshift_ZNVSf(Rd); + + tcg_temp_free_i32(t0); + + return true; +} + +/* + * Swaps high and low nibbles in a register. + */ +static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv t0 =3D tcg_temp_new_i32(); + TCGv t1 =3D tcg_temp_new_i32(); + + tcg_gen_andi_tl(t0, Rd, 0x0f); + tcg_gen_shli_tl(t0, t0, 4); + tcg_gen_andi_tl(t1, Rd, 0xf0); + tcg_gen_shri_tl(t1, t1, 4); + tcg_gen_or_tl(Rd, t0, t1); + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + + return true; +} + +/* + * Sets a specified bit in an I/O Register. This instruction operates on + * the lower 32 I/O Registers -- addresses 0-31. + */ +static bool trans_SBI(DisasContext *ctx, arg_SBI *a) +{ + TCGv data =3D tcg_temp_new_i32(); + TCGv port =3D tcg_const_i32(a->reg); + + gen_helper_inb(data, cpu_env, port); + tcg_gen_ori_tl(data, data, 1 << a->bit); + gen_helper_outb(cpu_env, port, data); + + tcg_temp_free_i32(port); + tcg_temp_free_i32(data); + + return true; +} + +/* + * Clears a specified bit in an I/O Register. This instruction operates on + * the lower 32 I/O Registers -- addresses 0-31. + */ +static bool trans_CBI(DisasContext *ctx, arg_CBI *a) +{ + TCGv data =3D tcg_temp_new_i32(); + TCGv port =3D tcg_const_i32(a->reg); + + gen_helper_inb(data, cpu_env, port); + tcg_gen_andi_tl(data, data, ~(1 << a->bit)); + gen_helper_outb(cpu_env, port, data); + + tcg_temp_free_i32(data); + tcg_temp_free_i32(port); + + return true; +} + +/* + * Stores bit b from Rd to the T Flag in SREG (Status Register). + */ +static bool trans_BST(DisasContext *ctx, arg_BST *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + + tcg_gen_andi_tl(cpu_Tf, Rd, 1 << a->bit); + tcg_gen_shri_tl(cpu_Tf, cpu_Tf, a->bit); + + return true; +} + +/* + * Copies the T Flag in the SREG (Status Register) to bit b in register R= d. + */ +static bool trans_BLD(DisasContext *ctx, arg_BLD *a) +{ + TCGv Rd =3D cpu_r[a->rd]; + TCGv t1 =3D tcg_temp_new_i32(); + + tcg_gen_andi_tl(Rd, Rd, ~(1u << a->bit)); /* clear bit */ + tcg_gen_shli_tl(t1, cpu_Tf, a->bit); /* create mask */ + tcg_gen_or_tl(Rd, Rd, t1); + + tcg_temp_free_i32(t1); + + return true; +} + +/* + * Sets a single Flag or bit in SREG. + */ +static bool trans_BSET(DisasContext *ctx, arg_BSET *a) +{ + switch (a->bit) { + case 0x00: + tcg_gen_movi_tl(cpu_Cf, 0x01); + break; + case 0x01: + tcg_gen_movi_tl(cpu_Zf, 0x01); + break; + case 0x02: + tcg_gen_movi_tl(cpu_Nf, 0x01); + break; + case 0x03: + tcg_gen_movi_tl(cpu_Vf, 0x01); + break; + case 0x04: + tcg_gen_movi_tl(cpu_Sf, 0x01); + break; + case 0x05: + tcg_gen_movi_tl(cpu_Hf, 0x01); + break; + case 0x06: + tcg_gen_movi_tl(cpu_Tf, 0x01); + break; + case 0x07: + tcg_gen_movi_tl(cpu_If, 0x01); + break; + } + + return true; +} + +/* + * Clears a single Flag in SREG. + */ +static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a) +{ + switch (a->bit) { + case 0x00: + tcg_gen_movi_tl(cpu_Cf, 0x00); + break; + case 0x01: + tcg_gen_movi_tl(cpu_Zf, 0x00); + break; + case 0x02: + tcg_gen_movi_tl(cpu_Nf, 0x00); + break; + case 0x03: + tcg_gen_movi_tl(cpu_Vf, 0x00); + break; + case 0x04: + tcg_gen_movi_tl(cpu_Sf, 0x00); + break; + case 0x05: + tcg_gen_movi_tl(cpu_Hf, 0x00); + break; + case 0x06: + tcg_gen_movi_tl(cpu_Tf, 0x00); + break; + case 0x07: + tcg_gen_movi_tl(cpu_If, 0x00); + break; + } + + return true; +} diff --git a/target/avr/insn.decode b/target/avr/insn.decode index 3f9304f8b0..4ee55862b2 100644 --- a/target/avr/insn.decode +++ b/target/avr/insn.decode @@ -158,3 +158,17 @@ XCH 1001 001 rd:5 0100 LAC 1001 001 rd:5 0110 LAS 1001 001 rd:5 0101 LAT 1001 001 rd:5 0111 + +# +# Bit and Bit-test Instructions +# +LSR 1001 010 rd:5 0110 +ROR 1001 010 rd:5 0111 +ASR 1001 010 rd:5 0101 +SWAP 1001 010 rd:5 0010 +SBI 1001 1010 reg:5 bit:3 +CBI 1001 1000 reg:5 bit:3 +BST 1111 101 rd:5 0 bit:3 +BLD 1111 100 rd:5 0 bit:3 +BSET 1001 0100 0 bit:3 1000 +BCLR 1001 0100 1 bit:3 1000 --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375663; cv=none; d=zohomail.com; s=zohoarc; b=UizrhsyLaKRPfI6khLl9uY2sR9U/coSKsVzrVgKo9Jw44qlDh4brSF+TKacsNj80af1jDDRP5ilIp9HBmnYI4t6S480mnyAvCcjGol99TOeSuo2wd5z4vd48GCdfuRYaXdQAXilK6xobDhWMVEun9i3gYseGBxlpHtq0ziSM6ro= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375663; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=CeCJIWj7KEsbYgi+WRu8j/SFE70+Y+4bb7FIq+Fj++s=; b=WzA2X20W10WcplcLFu777GZLVQ13YY9krdpg0jlwyueD5E7PoRr5TeXF2MT1N4v3ySpxI0dVeVi89OlonpkJqv8CGmdpI3oG2p7btnwTvbLXLmLZom/FEBK9AZJ3I8Cc9sEuLLpMAcg8+dYmYvdMj2y6idjKwYVH43mKUYUmXyg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375663118811.4221679309877; Sat, 18 Jan 2020 11:27:43 -0800 (PST) Received: from localhost ([::1]:44138 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istkz-0005NU-Mr for importer@patchew.org; Sat, 18 Jan 2020 14:27:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49895) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istdk-0004Ks-GH for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istdj-0006Fq-4x for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:12 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:34106) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istdi-0006Dm-VA for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:11 -0500 Received: by mail-wr1-x443.google.com with SMTP id t2so25742136wrr.1 for ; Sat, 18 Jan 2020 11:20:10 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.20.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:20:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CeCJIWj7KEsbYgi+WRu8j/SFE70+Y+4bb7FIq+Fj++s=; b=gvdph8/6CB7tTUmABDfI0RjsCMG37bjnGz3rwyKw1W+w3mDD56nAQmOEZN5jSrIAPj xE6LogXs8tyffxrek24+k9QtYg5AD4RBCz4SdHmqPh6Lp6Nz8IyjZVQWXsPgIMzDFeV6 3Q7t5ScyIdIvrpLNnxlGOf0SF61hgxva+IZtAGdNopKPSrxWqyhyJmTeWJ/Itlznv7cV XSkQSnsdXnhTpCP/WQfyTDWqXM47DEXTpi/NZN7aXYo5Fo3/gLRXoI/yjYc9OcW4BZQ5 M86v8KJqphXw49za2YLTfohlzjxZgrKBe2gWoio6ikzBJdeN4wwju3tFPuh400Tc/rNj AIVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CeCJIWj7KEsbYgi+WRu8j/SFE70+Y+4bb7FIq+Fj++s=; b=o1PwXuIltN683U67BRehRL+mAbmHthQs0bRcF+PRkeMDZepfzI8J47X6qtc2uOvz6m H+FtVDHHXlisN5ehqjfv+GNvCAHSiaflSQTnBiE6MP2d2JwoXLAAYiGEat7z1/NNzBQC YBIWr5RLgWclt8v5dUHrPXYwGrcRmPjsDxLTiXh2UsPav4NCbckAhrdPKjPPn0JsjNqk 02KrUPKnKCMNVKFPx0QN/66vZmnAyWk6VBdwcY8Zv6vVdMg/jjlWNtLfdUyejjfKBqSV cVr6u58NSTGwH4UxzbXo5LO/qGcSORJwL38l05yj3cdlmXMhJLer3Ll3h5ODL2Pl49j3 3LRA== X-Gm-Message-State: APjAAAXXw+nDwDrVhiQ5Safi+1iNoLNrUKMjL9ogQDTAShGoLjxO9Rss l+i0bw7tFJO8VPFTVjzea6g3sxXSD7YyBYgB X-Google-Smtp-Source: APXvYqxZV4ciit8T30CCoHZjmYWHZUER8dFKWpM6SUHv0nG+UCCB9jaWrXBDqJJpOpPsL+tgKRXWhw== X-Received: by 2002:adf:e6d2:: with SMTP id y18mr9769815wrm.262.1579375209751; Sat, 18 Jan 2020 11:20:09 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 08/21] target/avr: Add instruction translation - MCU Control Instructions Date: Sat, 18 Jan 2020 21:14:03 +0200 Message-Id: <20200118191416.19934-9-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This includes: - BREAK - NOP - SLEEP - WDR Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/translate.c | 68 ++++++++++++++++++++++++++++++++++++++++++ target/avr/insn.decode | 9 ++++++ 2 files changed, 77 insertions(+) diff --git a/target/avr/translate.c b/target/avr/translate.c index 58775af17c..4c680070e2 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -2681,3 +2681,71 @@ static bool trans_BCLR(DisasContext *ctx, arg_BCLR *= a) =20 return true; } + +/* + * MCU Control Instructions + */ + +/* + * The BREAK instruction is used by the On-chip Debug system, and is + * normally not used in the application software. When the BREAK instruct= ion is + * executed, the AVR CPU is set in the Stopped Mode. This gives the On-ch= ip + * Debugger access to internal resources. If any Lock bits are set, or e= ither + * the JTAGEN or OCDEN Fuses are unprogrammed, the CPU will treat the BRE= AK + * instruction as a NOP and will not enter the Stopped mode. This instru= ction + * is not available in all devices. Refer to the device specific instruct= ion + * set summary. + */ +static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a) +{ + if (!avr_have_feature(ctx, AVR_FEATURE_BREAK)) { + return true; + } + +#ifdef BREAKPOINT_ON_BREAK + tcg_gen_movi_tl(cpu_pc, ctx->npc - 1); + gen_helper_debug(cpu_env); + ctx->bstate =3D DISAS_EXIT; +#else + /* NOP */ +#endif + + return true; +} + + +/* + * This instruction performs a single cycle No Operation. + */ +static bool trans_NOP(DisasContext *ctx, arg_NOP *a) +{ + + /* NOP */ + + return true; +} + + +/* + * This instruction sets the circuit in sleep mode defined by the MCU + * Control Register. + */ +static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a) +{ + gen_helper_sleep(cpu_env); + ctx->bstate =3D DISAS_NORETURN; + return true; +} + + +/* + * This instruction resets the Watchdog Timer. This instruction must be + * executed within a limited time given by the WD prescaler. See the Watc= hdog + * Timer hardware specification. + */ +static bool trans_WDR(DisasContext *ctx, arg_WDR *a) +{ + gen_helper_wdr(cpu_env); + + return true; +} diff --git a/target/avr/insn.decode b/target/avr/insn.decode index 4ee55862b2..0e4ec9ddf0 100644 --- a/target/avr/insn.decode +++ b/target/avr/insn.decode @@ -172,3 +172,12 @@ BST 1111 101 rd:5 0 bit:3 BLD 1111 100 rd:5 0 bit:3 BSET 1001 0100 0 bit:3 1000 BCLR 1001 0100 1 bit:3 1000 + +# +# MCU Control Instructions +# +BREAK 1001 0101 1001 1000 +NOP 0000 0000 0000 0000 +SLEEP 1001 0101 1000 1000 +WDR 1001 0101 1010 1000 + --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375770; cv=none; d=zohomail.com; s=zohoarc; b=X+BnYhqWUUOS7XgX39DJ7VR4qCw55LrO2qwE1dygLPMSnnd3XGAflb3jTIOoVpWoICaaKecdZ/6P1j2oiVXrPyxHXgvjILa/n61aG8l3PBLWs35A13w3qF3VzpmjeXdFOrUiL6s+5y81H++VJa7Qjy8X1VXvizoo5NbOdiVEP5E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375770; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=5yfz9MQo280PT/NsGT7YR9biuc52GxSK6GWnkktDRwc=; b=LJ4WfISHcYRBBGZ30RJYAD8c/NnhWrrVGhX5EFe0Qiouetwoh0VrBmhnXlXjPOQaKSR6YZsq1vR/PcaDwiy30+RRzz7ps1j5ph8S9E/PJxA21kGf6Mj6DhGYQ0aXFVPMZHN2VMg5dEkiTRrUPgWTJAljoFqTxEcBpj4NIQYM05g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375770294399.5866364128158; Sat, 18 Jan 2020 11:29:30 -0800 (PST) Received: from localhost ([::1]:44154 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istmi-00083y-S8 for importer@patchew.org; Sat, 18 Jan 2020 14:29:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49925) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istdx-0004ZY-Ga for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istdv-0006V7-Uc for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:25 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:36028) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istdv-0006UQ-NS for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:23 -0500 Received: by mail-wm1-x342.google.com with SMTP id p17so10835837wma.1 for ; Sat, 18 Jan 2020 11:20:23 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.20.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:20:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5yfz9MQo280PT/NsGT7YR9biuc52GxSK6GWnkktDRwc=; b=sSfET0ThVxbxOMAnVvGcz3tqR5Nl1at90AP4B+lXQ1Ti+w6m/XYmr6FTRreAjw1XgY jPRvkG3xO/cB4byJYyeXqe7WKekn5LU0guYllvR/MM4MZKCoMYo1bl5md49//LY5WwiH p3KB1RXs0yztEfGzAf8jYVB39bbJHolHeYAZjgiNc013mu1Ut4ItXe+PnoJIWa63Hf9K dvknSfcm/HXLC/X5M1pFb6Q70iZo9flTmkTa1DE5Uxwb+ecZFtyDg1PLJmNWasPiW4yf yyLmG8PwTYyVdlQZyKnBcGP1fv2gfjPAevCCofbD5CD667CR0KwrPPg9lGa9xzmqQple y9cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5yfz9MQo280PT/NsGT7YR9biuc52GxSK6GWnkktDRwc=; b=lOwxZI6m9lkuScZuY5LBbTQ/rk7gSTNvbr8cQ0hPwkP58SOTMp+HGN91DBtw09A5cn 3Efd3K2THYpPwZV8laGBz/6lfakj5ox8y82Ymoqmh+O+0P2VRQq4kfz0mE4cDNEI2gxb dMuFuPEjQ8ERBgFxce+ard/vaUfzZY6VNeMgNF/FS2H7j1+zr+IccZW18482YJVZJrr0 SbC++2xAO3Qkf0dMJkY3e7Myu5+EJWg5a8AteIkDPhKcEhqY1zaUww1IlZusvmXxcQp4 ca2kxLr4LPVdGG4Zrz/i/aIBehfSzzwwnyeEs1ots9fxlZDpDYPtn5ScClZek9fy75tN rvWA== X-Gm-Message-State: APjAAAWeMfJSP5Tm8z8h4sm0POYqO+Qc8uxHH78/neMsEtehM5ci6U9m ctv/gHZXji1lT1c0sVc0aOVN2a/FfRzPABX4 X-Google-Smtp-Source: APXvYqwYzWZQ19XFyIRk7zKDyp8gWEetzZXjJH/mvWwmISrcvsfB0cEvDnVSslfNa8lBYTkQ+ThVXQ== X-Received: by 2002:a05:600c:2050:: with SMTP id p16mr10804773wmg.176.1579375222475; Sat, 18 Jan 2020 11:20:22 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 09/21] target/avr: Add instruction translation - CPU main translation function Date: Sat, 18 Jan 2020 21:14:04 +0200 Message-Id: <20200118191416.19934-10-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::342 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Co-developed-by: Richard Henderson Co-developed-by: Michael Rolnik Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/translate.c | 234 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) diff --git a/target/avr/translate.c b/target/avr/translate.c index 4c680070e2..af88bb2e5a 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -2749,3 +2749,237 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a) =20 return true; } + + +void avr_cpu_tcg_init(void) +{ + int i; + +#define AVR_REG_OFFS(x) offsetof(CPUAVRState, x) + cpu_pc =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(pc_w), "pc"); + cpu_Cf =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregC), "Cf"); + cpu_Zf =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregZ), "Zf"); + cpu_Nf =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregN), "Nf"); + cpu_Vf =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregV), "Vf"); + cpu_Sf =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregS), "Sf"); + cpu_Hf =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregH), "Hf"); + cpu_Tf =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregT), "Tf"); + cpu_If =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregI), "If"); + cpu_rampD =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampD), "ra= mpD"); + cpu_rampX =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampX), "ra= mpX"); + cpu_rampY =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampY), "ra= mpY"); + cpu_rampZ =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampZ), "ra= mpZ"); + cpu_eind =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(eind), "eind= "); + cpu_sp =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sp), "sp"); + cpu_skip =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(skip), "skip= "); + + for (i =3D 0; i < NUMBER_OF_CPU_REGISTERS; i++) { + cpu_r[i] =3D tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(r[i]), + reg_names[i]); + } +#undef AVR_REG_OFFS +} + +static void translate(DisasContext *ctx) +{ + uint32_t opcode =3D next_word(ctx); + + if (!decode_insn(ctx, opcode)) { + gen_helper_unsupported(cpu_env); + ctx->bstate =3D DISAS_NORETURN; + } +} + +/* Standardize the cpu_skip condition to NE. */ +static bool canonicalize_skip(DisasContext *ctx) +{ + switch (ctx->skip_cond) { + case TCG_COND_NEVER: + /* Normal case: cpu_skip is known to be false. */ + return false; + + case TCG_COND_ALWAYS: + /* + * Breakpoint case: cpu_skip is known to be true, via TB_FLAGS_SKI= P. + * The breakpoint is on the instruction being skipped, at the start + * of the TranslationBlock. No need to update. + */ + return false; + + case TCG_COND_NE: + if (ctx->skip_var1 =3D=3D NULL) { + tcg_gen_mov_tl(cpu_skip, ctx->skip_var0); + } else { + tcg_gen_xor_tl(cpu_skip, ctx->skip_var0, ctx->skip_var1); + ctx->skip_var1 =3D NULL; + } + break; + + default: + /* Convert to a NE condition vs 0. */ + if (ctx->skip_var1 =3D=3D NULL) { + tcg_gen_setcondi_tl(ctx->skip_cond, cpu_skip, ctx->skip_var0, = 0); + } else { + tcg_gen_setcond_tl(ctx->skip_cond, cpu_skip, + ctx->skip_var0, ctx->skip_var1); + ctx->skip_var1 =3D NULL; + } + ctx->skip_cond =3D TCG_COND_NE; + break; + } + if (ctx->free_skip_var0) { + tcg_temp_free(ctx->skip_var0); + ctx->free_skip_var0 =3D false; + } + ctx->skip_var0 =3D cpu_skip; + return true; +} + +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_ins= ns) +{ + CPUAVRState *env =3D cs->env_ptr; + DisasContext ctx =3D { + .tb =3D tb, + .cs =3D cs, + .env =3D env, + .memidx =3D 0, + .bstate =3D DISAS_NEXT, + .skip_cond =3D TCG_COND_NEVER, + .singlestep =3D cs->singlestep_enabled, + }; + target_ulong pc_start =3D tb->pc / 2; + int num_insns =3D 0; + + if (tb->flags & TB_FLAGS_FULL_ACCESS) { + /* + * This flag is set by ST/LD instruction we will regenerate it ONLY + * with mem/cpu memory access instead of mem access + */ + max_insns =3D 1; + } + if (ctx.singlestep) { + max_insns =3D 1; + } + + gen_tb_start(tb); + + ctx.npc =3D pc_start; + if (tb->flags & TB_FLAGS_SKIP) { + ctx.skip_cond =3D TCG_COND_ALWAYS; + ctx.skip_var0 =3D cpu_skip; + } + + do { + TCGLabel *skip_label =3D NULL; + + /* translate current instruction */ + tcg_gen_insn_start(ctx.npc); + num_insns++; + + /* + * this is due to some strange GDB behavior + * let's assume main has address 0x100 + * b main - sets breakpoint at address 0x00000100 (code) + * b *0x100 - sets breakpoint at address 0x00800100 (data) + */ + if (unlikely(!ctx.singlestep && + (cpu_breakpoint_test(cs, OFFSET_CODE + ctx.npc * 2, BP_ANY= ) || + cpu_breakpoint_test(cs, OFFSET_DATA + ctx.npc * 2, BP_ANY= )))) { + canonicalize_skip(&ctx); + tcg_gen_movi_tl(cpu_pc, ctx.npc); + gen_helper_debug(cpu_env); + goto done_generating; + } + + /* Conditionally skip the next instruction, if indicated. */ + if (ctx.skip_cond !=3D TCG_COND_NEVER) { + skip_label =3D gen_new_label(); + if (ctx.skip_var0 =3D=3D cpu_skip) { + /* + * Copy cpu_skip so that we may zero it before the branch. + * This ensures that cpu_skip is non-zero after the label + * if and only if the skipped insn itself sets a skip. + */ + ctx.free_skip_var0 =3D true; + ctx.skip_var0 =3D tcg_temp_new(); + tcg_gen_mov_tl(ctx.skip_var0, cpu_skip); + tcg_gen_movi_tl(cpu_skip, 0); + } + if (ctx.skip_var1 =3D=3D NULL) { + tcg_gen_brcondi_tl(ctx.skip_cond, ctx.skip_var0, 0, skip_l= abel); + } else { + tcg_gen_brcond_tl(ctx.skip_cond, ctx.skip_var0, + ctx.skip_var1, skip_label); + ctx.skip_var1 =3D NULL; + } + if (ctx.free_skip_var0) { + tcg_temp_free(ctx.skip_var0); + ctx.free_skip_var0 =3D false; + } + ctx.skip_cond =3D TCG_COND_NEVER; + ctx.skip_var0 =3D NULL; + } + + translate(&ctx); + + if (skip_label) { + canonicalize_skip(&ctx); + gen_set_label(skip_label); + if (ctx.bstate =3D=3D DISAS_NORETURN) { + ctx.bstate =3D DISAS_CHAIN; + } + } + } while (ctx.bstate =3D=3D DISAS_NEXT + && num_insns < max_insns + && (ctx.npc - pc_start) * 2 < TARGET_PAGE_SIZE - 4 + && !tcg_op_buf_full()); + + if (tb->cflags & CF_LAST_IO) { + gen_io_end(); + } + + bool nonconst_skip =3D canonicalize_skip(&ctx); + + switch (ctx.bstate) { + case DISAS_NORETURN: + assert(!nonconst_skip); + break; + case DISAS_NEXT: + case DISAS_TOO_MANY: + case DISAS_CHAIN: + if (!nonconst_skip) { + /* Note gen_goto_tb checks singlestep. */ + gen_goto_tb(&ctx, 1, ctx.npc); + break; + } + tcg_gen_movi_tl(cpu_pc, ctx.npc); + /* fall through */ + case DISAS_LOOKUP: + if (!ctx.singlestep) { + tcg_gen_lookup_and_goto_ptr(); + break; + } + /* fall through */ + case DISAS_EXIT: + if (ctx.singlestep) { + gen_helper_debug(cpu_env); + } else { + tcg_gen_exit_tb(NULL, 0); + } + break; + default: + g_assert_not_reached(); + } + +done_generating: + gen_tb_end(tb, num_insns); + + tb->size =3D (ctx.npc - pc_start) * 2; + tb->icount =3D num_insns; +} + +void restore_state_to_opc(CPUAVRState *env, TranslationBlock *tb, + target_ulong *data) +{ + env->pc_w =3D data[0]; +} --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375948; cv=none; d=zohomail.com; s=zohoarc; b=C4dvVcVFuVORlboJhS3C+2Oe8XQMH3OeEQ5/SeqG8oKW2d6ut/rjLmXdlNSem18IflIhv+Vpch80o7LtE4vXZMs01H/O7IVr8Ylg/5z3sbGvwacLhTqC5zhCcZ04OaDvA4BoYUK29dNBtD9A/I+ujvijcbOlSfGBzXhEdr5CtOQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375948; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=5V6Be4G/oll22UJxabfrS+rieHJsL8aN2Zn+VbHYymY=; b=eUXJsJM818LkPbiDfeOrteUwXl6b6R/+cnDJ7tENoy0UaiPpPnV0t6uIINe6ySSDC1lnd2VIXxvhJ0AqzAhzxLYFsdowKVqK3AjDN0ptBqA9Al10zbY1QsVH6FPf/5sbrSWaJaBu/ie+UjB/OJgQPHOWjqoGTjDz5Z0s8nnhaVs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375948558878.0207905741232; Sat, 18 Jan 2020 11:32:28 -0800 (PST) Received: from localhost ([::1]:44196 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istpb-0002Y8-0K for importer@patchew.org; Sat, 18 Jan 2020 14:32:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49978) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isteC-0004oL-Qt for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isteA-0006hi-Qc for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:40 -0500 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]:45559) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isteA-0006fs-IK for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:38 -0500 Received: by mail-wr1-x42f.google.com with SMTP id j42so25686520wrj.12 for ; Sat, 18 Jan 2020 11:20:37 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.20.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:20:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5V6Be4G/oll22UJxabfrS+rieHJsL8aN2Zn+VbHYymY=; b=P1ZOCYYTedWFL6nx1Wqe1o0vmagp84R0hUpMlMFBVM8+anFleGxLo2RKypKBsbDWNG ms8s2sBaptOCMU30pLrWODgCdi/wXLA+lO7je0YYp4epQe8JBBOActYrJWWISTT8/sm0 fjUUxIP4NZYtOcSI1LI3yKEk/NKxzWFBD0gJ8AbgqE6fNk1fukp+10gyEkSsWP+arktU lIeF45mzFCTYJ0z9rqXly8STKy6BmkNvFDePEIxv51sgteJziZ6qcxgAjy7e7Z4iH4L2 mzgbRfuJD0u6pjGS1t/AUsR4qeyX7Wx9wk34JNBk6KgPabGWTOuvdRqQn858iRNw2doK HPQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5V6Be4G/oll22UJxabfrS+rieHJsL8aN2Zn+VbHYymY=; b=axhOGjUvc+UqCcS0nZzTRBYmiHtaMLZ5QBq+xr9ITlwiKgssVEXYSESYvSIZfz2nsO gMfyfR+pBdQlr3ws5FJAO8K0hmZlsS1sEVMsVdBj/D7zMDPY1yTdFmf5LrFWyD71HLpA PwXB69oDmUWH8xMH118xaD6pPXCZ+vrhEFy7MGru9+QhLaNgdBf3vVd7SrBooexVYhm2 bA25XQ2O1PHPRoZzDpT4nrmxpTSKLIHX+XcWWYOY6p/MjsqbEvO+XdnH5CFurE5qwRqA 4kKfC9A1WP1I7dVQLhFwk6kswgDAhcRPil17G3H/l0yV2/yDzigrsoCDOHUh6lZ1ZkO8 2NhA== X-Gm-Message-State: APjAAAX3NiERtR0+yeH3Ao6F/s6jILPU3VjkNGj1DScWvt6JYo8F2q6V BOAzKOtsuyFC2WsUayW9LKxfMWq+mQ3Rlkjs X-Google-Smtp-Source: APXvYqx0Bsi72iZDLVrMXGVm00eIpgNSdtNz9F81kFkeHwvo4rvMt/zSZOJW9eZH5KhN/WPzbWShoA== X-Received: by 2002:a5d:6ac3:: with SMTP id u3mr10273875wrw.25.1579375235849; Sat, 18 Jan 2020 11:20:35 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 10/21] target/avr: Add instruction disassembly function Date: Sat, 18 Jan 2020 21:14:05 +0200 Message-Id: <20200118191416.19934-11-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42f X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Provide function disassembles executed instruction when `-d in_asm` is provided Example: `./avr-softmmu/qemu-system-avr -bios free-rtos/Demo/AVR_ATMega2560_GCC/demo= .elf -d in_asm` will produce something like the following ``` ... IN: 0x0000014a: CALL 0x3808 IN: main 0x00003808: CALL 0x4b4 IN: vParTestInitialise 0x000004b4: LDI r24, 255 0x000004b6: STS r24, 0 0x000004b8: MULS r16, r20 0x000004ba: OUT $1, r24 0x000004bc: LDS r24, 0 0x000004be: MULS r16, r20 0x000004c0: OUT $2, r24 0x000004c2: RET ... ``` Signed-off-by: Michael Rolnik Suggested-by: Richard Henderson Suggested-by: Philippe Mathieu-Daud=C3=A9 Suggested-by: Aleksandar Markovic Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- target/avr/cpu.h | 1 + target/avr/cpu.c | 2 +- target/avr/disas.c | 245 +++++++++++++++++++++++++++++++++++++++++ target/avr/translate.c | 12 ++ 4 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 target/avr/disas.c diff --git a/target/avr/cpu.h b/target/avr/cpu.h index b74bcf01ae..af89b6611e 100644 --- a/target/avr/cpu.h +++ b/target/avr/cpu.h @@ -160,6 +160,7 @@ 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, uint8_t *buf, int reg); int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); +int avr_print_insn(bfd_vma addr, disassemble_info *info); =20 static inline int avr_feature(CPUAVRState *env, AVRFeature feature) { diff --git a/target/avr/cpu.c b/target/avr/cpu.c index c74c5106fe..fa51f771c0 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c @@ -84,7 +84,7 @@ static void avr_cpu_reset(CPUState *cs) static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) { info->mach =3D bfd_arch_avr; - info->print_insn =3D NULL; + info->print_insn =3D avr_print_insn; } =20 static void avr_cpu_realizefn(DeviceState *dev, Error **errp) diff --git a/target/avr/disas.c b/target/avr/disas.c new file mode 100644 index 0000000000..f3fa3d6bef --- /dev/null +++ b/target/avr/disas.c @@ -0,0 +1,245 @@ +/* + * AVR disassembler + * + * Copyright (c) 2019 Richard Henderson + * Copyright (c) 2019 Michael Rolnik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" + +typedef struct { + disassemble_info *info; + uint16_t next_word; + bool next_word_used; +} DisasContext; + +static int to_regs_16_31_by_one(DisasContext *ctx, int indx) +{ + return 16 + (indx % 16); +} + +static int to_regs_16_23_by_one(DisasContext *ctx, int indx) +{ + return 16 + (indx % 8); +} +static int to_regs_24_30_by_two(DisasContext *ctx, int indx) +{ + return 24 + (indx % 4) * 2; +} +static int to_regs_00_30_by_two(DisasContext *ctx, int indx) +{ + return (indx % 16) * 2; +} + +static uint16_t next_word(DisasContext *ctx) +{ + ctx->next_word_used =3D true; + return ctx->next_word; +} + +static int append_16(DisasContext *ctx, int x) +{ + return x << 16 | next_word(ctx); +} + + +/* Include the auto-generated decoder. */ +static bool decode_insn(DisasContext *ctx, uint16_t insn); +#include "decode_insn.inc.c" + +#define output(mnemonic, format, ...) \ + (pctx->info->fprintf_func(pctx->info->stream, "%-9s " format, \ + mnemonic, ##__VA_ARGS__)) + +int avr_print_insn(bfd_vma addr, disassemble_info *info) +{ + DisasContext ctx; + DisasContext *pctx =3D &ctx; + bfd_byte buffer[4]; + uint16_t insn; + int status; + + ctx.info =3D info; + + status =3D info->read_memory_func(addr, buffer, 4, info); + if (status !=3D 0) { + info->memory_error_func(status, addr, info); + return -1; + } + insn =3D bfd_getl16(buffer); + ctx.next_word =3D bfd_getl16(buffer + 2); + ctx.next_word_used =3D false; + + if (!decode_insn(&ctx, insn)) { + output(".db", "0x%02x, 0x%02x", buffer[0], buffer[1]); + } + + return ctx.next_word_used ? 4 : 2; +} + + +#define INSN(opcode, format, ...) \ +static bool trans_##opcode(DisasContext *pctx, arg_##opcode * a) \ +{ \ + output(#opcode, format, ##__VA_ARGS__); \ + return true; \ +} + +#define INSN_MNEMONIC(opcode, mnemonic, format, ...) \ +static bool trans_##opcode(DisasContext *pctx, arg_##opcode * a) \ +{ \ + output(mnemonic, format, ##__VA_ARGS__); \ + return true; \ +} + +/* + * C Z N V S H T I + * 0 1 2 3 4 5 6 7 + */ +static const char *brbc[] =3D { + "BRCC", "BRNE", "BRPL", "BRVC", "BRGE", "BRHC", "BRTC", "BRID" +}; + +static const char *brbs[] =3D { + "BRCS", "BREQ", "BRMI", "BRVS", "BRLT", "BRHS", "BRTS", "BRIE" +}; + +static const char *bset[] =3D { + "SEC", "SEZ", "SEN", "SEZ", "SES", "SEH", "SET", "SEI" +}; + +static const char *bclr[] =3D { + "CLC", "CLZ", "CLN", "CLZ", "CLS", "CLH", "CLT", "CLI" +}; + +/* + * Arithmetic Instructions + */ +INSN(ADD, "r%d, r%d", a->rd, a->rr) +INSN(ADC, "r%d, r%d", a->rd, a->rr) +INSN(ADIW, "r%d:r%d, %d", a->rd + 1, a->rd, a->imm) +INSN(SUB, "r%d, r%d", a->rd, a->rr) +INSN(SUBI, "r%d, %d", a->rd, a->imm) +INSN(SBC, "r%d, r%d", a->rd, a->rr) +INSN(SBCI, "r%d, %d", a->rd, a->imm) +INSN(SBIW, "r%d:r%d, %d", a->rd + 1, a->rd, a->imm) +INSN(AND, "r%d, r%d", a->rd, a->rr) +INSN(ANDI, "r%d, %d", a->rd, a->imm) +INSN(OR, "r%d, r%d", a->rd, a->rr) +INSN(ORI, "r%d, %d", a->rd, a->imm) +INSN(EOR, "r%d, r%d", a->rd, a->rr) +INSN(COM, "r%d", a->rd) +INSN(NEG, "r%d", a->rd) +INSN(INC, "r%d", a->rd) +INSN(DEC, "r%d", a->rd) +INSN(MUL, "r%d, r%d", a->rd, a->rr) +INSN(MULS, "r%d, r%d", a->rd, a->rr) +INSN(MULSU, "r%d, r%d", a->rd, a->rr) +INSN(FMUL, "r%d, r%d", a->rd, a->rr) +INSN(FMULS, "r%d, r%d", a->rd, a->rr) +INSN(FMULSU, "r%d, r%d", a->rd, a->rr) +INSN(DES, "%d", a->imm) + +/* + * Branch Instructions + */ +INSN(RJMP, ".%+d", a->imm * 2) +INSN(IJMP, "") +INSN(EIJMP, "") +INSN(JMP, "0x%x", a->imm * 2) +INSN(RCALL, ".%+d", a->imm * 2) +INSN(ICALL, "") +INSN(EICALL, "") +INSN(CALL, "0x%x", a->imm * 2) +INSN(RET, "") +INSN(RETI, "") +INSN(CPSE, "r%d, r%d", a->rd, a->rr) +INSN(CP, "r%d, r%d", a->rd, a->rr) +INSN(CPC, "r%d, r%d", a->rd, a->rr) +INSN(CPI, "r%d, %d", a->rd, a->imm) +INSN(SBRC, "r%d, %d", a->rr, a->bit) +INSN(SBRS, "r%d, %d", a->rr, a->bit) +INSN(SBIC, "$%d, %d", a->reg, a->bit) +INSN(SBIS, "$%d, %d", a->reg, a->bit) +INSN_MNEMONIC(BRBS, brbs[a->bit], ".%+d", a->imm * 2) +INSN_MNEMONIC(BRBC, brbc[a->bit], ".%+d", a->imm * 2) + +/* + * Data Transfer Instructions + */ +INSN(MOV, "r%d, r%d", a->rd, a->rr) +INSN(MOVW, "r%d:r%d, r%d:r%d", a->rd + 1, a->rd, a->rr + 1, a->rr) +INSN(LDI, "r%d, %d", a->rd, a->imm) +INSN(LDS, "r%d, %d", a->rd, a->imm) +INSN(LDX1, "r%d, X", a->rd) +INSN(LDX2, "r%d, X+", a->rd) +INSN(LDX3, "r%d, -X", a->rd) +INSN(LDY2, "r%d, Y+", a->rd) +INSN(LDY3, "r%d, -Y", a->rd) +INSN(LDZ2, "r%d, Z+", a->rd) +INSN(LDZ3, "r%d, -Z", a->rd) +INSN(LDDY, "r%d, Y+%d", a->rd, a->imm) +INSN(LDDZ, "r%d, Z+%d", a->rd, a->imm) +INSN(STS, "r%d, %d", a->rd, a->imm) +INSN(STX1, "r%d, X", a->rr) +INSN(STX2, "r%d, X+", a->rr) +INSN(STX3, "r%d, -X", a->rr) +INSN(STY2, "r%d, Y+", a->rd) +INSN(STY3, "r%d, -Y", a->rd) +INSN(STZ2, "r%d, Z+", a->rd) +INSN(STZ3, "r%d, -Z", a->rd) +INSN(STDY, "r%d, Y+%d", a->rd, a->imm) +INSN(STDZ, "r%d, Z+%d", a->rd, a->imm) +INSN(LPM1, "") +INSN(LPM2, "r%d, Z", a->rd) +INSN(LPMX, "r%d, Z+", a->rd) +INSN(ELPM1, "") +INSN(ELPM2, "r%d, Z", a->rd) +INSN(ELPMX, "r%d, Z+", a->rd) +INSN(SPM, "") +INSN(SPMX, "Z+") +INSN(IN, "r%d, $%d", a->rd, a->imm) +INSN(OUT, "$%d, r%d", a->imm, a->rd) +INSN(PUSH, "r%d", a->rd) +INSN(POP, "r%d", a->rd) +INSN(XCH, "Z, r%d", a->rd) +INSN(LAC, "Z, r%d", a->rd) +INSN(LAS, "Z, r%d", a->rd) +INSN(LAT, "Z, r%d", a->rd) + +/* + * Bit and Bit-test Instructions + */ +INSN(LSR, "r%d", a->rd) +INSN(ROR, "r%d", a->rd) +INSN(ASR, "r%d", a->rd) +INSN(SWAP, "r%d", a->rd) +INSN(SBI, "$%d, %d", a->reg, a->bit) +INSN(CBI, "%d, %d", a->reg, a->bit) +INSN(BST, "r%d, %d", a->rd, a->bit) +INSN(BLD, "r%d, %d", a->rd, a->bit) +INSN_MNEMONIC(BSET, bset[a->bit], "") +INSN_MNEMONIC(BCLR, bclr[a->bit], "") + +/* + * MCU Control Instructions + */ +INSN(BREAK, "") +INSN(NOP, "") +INSN(SLEEP, "") +INSN(WDR, "") + diff --git a/target/avr/translate.c b/target/avr/translate.c index af88bb2e5a..064eee0ffb 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -2976,6 +2976,18 @@ done_generating: =20 tb->size =3D (ctx.npc - pc_start) * 2; tb->icount =3D num_insns; + +#ifdef DEBUG_DISAS + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(tb->pc)) { + FILE *fd; + fd =3D qemu_log_lock(); + qemu_log("IN: %s\n", lookup_symbol(tb->pc)); + log_target_disas(cs, tb->pc, tb->size); + qemu_log("\n"); + qemu_log_unlock(fd); + } +#endif } =20 void restore_state_to_opc(CPUAVRState *env, TranslationBlock *tb, --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376258; cv=none; d=zohomail.com; s=zohoarc; b=GMcMaCBMzrgLuVVFnoRULnQLWeBtxaqlf5PxZ23EBja5JAv5Oytnd1dyG51eJy3TSbCCMe1ZnsJvzy+RPg2keyqaMFd5KbjMSOWivnihuMlwTPFWy9fx1QM7ZTl/q0KBPpLXUlg2y6udHlGng0icvswVPzG3kBBS2NbTbqVo3yo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376258; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=fiDJnfw8KuN71OMSUCFWBmBl80J4Xx3JLR0YGBv3k54=; b=Ib3pjitIkjAUxf4HfRTW6Sdex02kmTzbnKkfATcJ65gC9qROB75TU+sHjh0h5z3NwAHoUE6fpTv8ZT66WzNsBe0s6f3WE9HsnOuldW8ya+E/v+FivGG5y0/0cEaQImuJrFbj4IVZ1LnP22ByOJQp2NRPVIUggCyO8BKCgTEHe9Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376258601803.4092690386306; Sat, 18 Jan 2020 11:37:38 -0800 (PST) Received: from localhost ([::1]:44248 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istub-0007sT-1K for importer@patchew.org; Sat, 18 Jan 2020 14:37:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49997) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isteM-00053D-CY for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isteJ-0006op-5K for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:50 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:51123) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isteI-0006o3-UQ for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:47 -0500 Received: by mail-wm1-x342.google.com with SMTP id a5so10574531wmb.0 for ; Sat, 18 Jan 2020 11:20:46 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.20.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:20:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=fiDJnfw8KuN71OMSUCFWBmBl80J4Xx3JLR0YGBv3k54=; b=GUk7o4y0ZFc9GnrJfYAM1QD33VxsACwJ7DOtKg9OtVszPF5iFZcsX2mn/Ib99LU0Rv XlbdJolBQ5DZCyIR8rHqgU435IWuh1CGlO0taNIs5rYrsF2wJa3FNeNTanxyVbABfU09 CB0HuLyFGgh+c8co86Filsg51KQb281PRqvMRRDRxbualGAz1URFdsFOEyBJcw8x+yDG p0G3T6GbhZbZ+EABF1tS5WA+M8svAdUMi9vtx6uecD7EkjzyjGRADAC73qlc721qBbmk CyS+h5fEQnN3U4CXpMiA2js9T5qtRiyyhx5uykVTP0bFqIIJr78Ws9UBz3wd5+P2LgQH wWtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fiDJnfw8KuN71OMSUCFWBmBl80J4Xx3JLR0YGBv3k54=; b=qLkNie0q3/AcvaMPDn4Dp5nPoyoyaUSwY2K8e8RPnqN9psJmzI4mCfQgJ3hFKhIDvJ hFw6m62hd9ujwfkqDRCViF0r0aoy/xbOyhC4DvfLNl2BILOB1G+3ypcdpyXFdq8PI/S9 KBRyEj6sz6fBBYFLOqIoSaAoKR1uYZ7TVu4dT8tj183ekI0y3FUm1p+Rm6vQoulwTfqY xiZbbIENZ0uzvjY4qRF0BI/5fEoFMfEL7DMD8g5rJgViNdeKaax/fRSXYDLOFkWMVsX6 a1njHMNjeZN+Vd/X2i3rSP9tLs0DtS+deI/iWH/SMc4dHIUnR8OLKxXFsWiS1rqU/83S uAjQ== X-Gm-Message-State: APjAAAXvT72+YyvOGP6vfVJyaF4fpg6k8IUxKwTY2jHAOHJDncAn7KaP ughJNhJnnJ0dtBoRbMScAaX5ezaxFLrbErMG X-Google-Smtp-Source: APXvYqystTy81xTz8hzL2DmKpg0PR1yi6ursiuXshFS9ySuEGAk59m1U2oQ+CcHxD2uHC/Y0QTU/uw== X-Received: by 2002:a05:600c:2551:: with SMTP id e17mr10753960wma.26.1579375245655; Sat, 18 Jan 2020 11:20:45 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 11/21] hw/avr: Add limited support for USART peripheral Date: Sat, 18 Jan 2020 21:14:06 +0200 Message-Id: <20200118191416.19934-12-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::342 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, Sarah Harris , dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" These were designed to facilitate testing but should provide enough functio= n to be useful in other contexts. Only a subset of the functions of each peripheral is implemented, mainly du= e to the lack of a standard way to handle electrical connections (like GPIO= pins). Signed-off-by: Sarah Harris Tested-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/char/avr_usart.h | 93 +++++++++++ hw/char/avr_usart.c | 320 ++++++++++++++++++++++++++++++++++++ hw/char/Kconfig | 3 + hw/char/Makefile.objs | 1 + 4 files changed, 417 insertions(+) create mode 100644 include/hw/char/avr_usart.h create mode 100644 hw/char/avr_usart.c diff --git a/include/hw/char/avr_usart.h b/include/hw/char/avr_usart.h new file mode 100644 index 0000000000..467e97e8c0 --- /dev/null +++ b/include/hw/char/avr_usart.h @@ -0,0 +1,93 @@ +/* + * AVR USART + * + * Copyright (c) 2018 University of Kent + * Author: Sarah Harris + * + * 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 + * + */ + +#ifndef HW_AVR_USART_H +#define HW_AVR_USART_H + +#include "hw/sysbus.h" +#include "chardev/char-fe.h" +#include "hw/hw.h" + +/* Offsets of registers. */ +#define USART_DR 0x06 +#define USART_CSRA 0x00 +#define USART_CSRB 0x01 +#define USART_CSRC 0x02 +#define USART_BRRH 0x05 +#define USART_BRRL 0x04 + +/* Relevant bits in regiters. */ +#define USART_CSRA_RXC (1 << 7) +#define USART_CSRA_TXC (1 << 6) +#define USART_CSRA_DRE (1 << 5) +#define USART_CSRA_MPCM (1 << 0) + +#define USART_CSRB_RXCIE (1 << 7) +#define USART_CSRB_TXCIE (1 << 6) +#define USART_CSRB_DREIE (1 << 5) +#define USART_CSRB_RXEN (1 << 4) +#define USART_CSRB_TXEN (1 << 3) +#define USART_CSRB_CSZ2 (1 << 2) +#define USART_CSRB_RXB8 (1 << 1) +#define USART_CSRB_TXB8 (1 << 0) + +#define USART_CSRC_MSEL1 (1 << 7) +#define USART_CSRC_MSEL0 (1 << 6) +#define USART_CSRC_PM1 (1 << 5) +#define USART_CSRC_PM0 (1 << 4) +#define USART_CSRC_CSZ1 (1 << 2) +#define USART_CSRC_CSZ0 (1 << 1) + +#define TYPE_AVR_USART "avr-usart" +#define AVR_USART(obj) \ + OBJECT_CHECK(AVRUsartState, (obj), TYPE_AVR_USART) + +typedef struct { + /* */ + SysBusDevice parent_obj; + + /* */ + MemoryRegion mmio; + + CharBackend chr; + + bool enabled; + + uint8_t data; + bool data_valid; + uint8_t char_mask; + /* Control and Status Registers */ + uint8_t csra; + uint8_t csrb; + uint8_t csrc; + /* Baud Rate Registers (low/high byte) */ + uint8_t brrh; + uint8_t brrl; + + /* Receive Complete */ + qemu_irq rxc_irq; + /* Transmit Complete */ + qemu_irq txc_irq; + /* Data Register Empty */ + qemu_irq dre_irq; +} AVRUsartState; + +#endif /* HW_AVR_USART_H */ diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c new file mode 100644 index 0000000000..cb307fe23d --- /dev/null +++ b/hw/char/avr_usart.c @@ -0,0 +1,320 @@ +/* + * AVR USART + * + * Copyright (c) 2018 University of Kent + * Author: Sarah Harris + * + * 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 + * + */ + +#include "qemu/osdep.h" +#include "hw/char/avr_usart.h" +#include "qemu/log.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" + +static int avr_usart_can_receive(void *opaque) +{ + AVRUsartState *usart =3D opaque; + + if (usart->data_valid || !(usart->csrb & USART_CSRB_RXEN)) { + return 0; + } + return 1; +} + +static void avr_usart_receive(void *opaque, const uint8_t *buffer, int siz= e) +{ + AVRUsartState *usart =3D opaque; + assert(size =3D=3D 1); + assert(!usart->data_valid); + usart->data =3D buffer[0]; + usart->data_valid =3D true; + usart->csra |=3D USART_CSRA_RXC; + if (usart->csrb & USART_CSRB_RXCIE) { + qemu_set_irq(usart->rxc_irq, 1); + } +} + +static void update_char_mask(AVRUsartState *usart) +{ + uint8_t mode =3D ((usart->csrc & USART_CSRC_CSZ0) ? 1 : 0) | + ((usart->csrc & USART_CSRC_CSZ1) ? 2 : 0) | + ((usart->csrb & USART_CSRB_CSZ2) ? 4 : 0); + switch (mode) { + case 0: + usart->char_mask =3D 0b11111; + break; + case 1: + usart->char_mask =3D 0b111111; + break; + case 2: + usart->char_mask =3D 0b1111111; + break; + case 3: + usart->char_mask =3D 0b11111111; + break; + case 4: + /* Fallthrough. */ + case 5: + /* Fallthrough. */ + case 6: + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: Reserved character size 0x%x\n", + __func__, + mode); + break; + case 7: + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: Nine bit character size not supported (forcing eight)\n", + __func__); + usart->char_mask =3D 0b11111111; + break; + default: + assert(0); + } +} + +static void avr_usart_reset(DeviceState *dev) +{ + AVRUsartState *usart =3D AVR_USART(dev); + usart->data_valid =3D false; + usart->csra =3D 0b00100000; + usart->csrb =3D 0b00000000; + usart->csrc =3D 0b00000110; + usart->brrl =3D 0; + usart->brrh =3D 0; + update_char_mask(usart); + qemu_set_irq(usart->rxc_irq, 0); + qemu_set_irq(usart->txc_irq, 0); + qemu_set_irq(usart->dre_irq, 0); +} + +static uint64_t avr_usart_read(void *opaque, hwaddr addr, unsigned int siz= e) +{ + AVRUsartState *usart =3D opaque; + uint8_t data; + assert(size =3D=3D 1); + + if (!usart->enabled) { + return 0; + } + + switch (addr) { + case USART_DR: + if (!(usart->csrb & USART_CSRB_RXEN)) { + /* Receiver disabled, ignore. */ + return 0; + } + if (usart->data_valid) { + data =3D usart->data & usart->char_mask; + usart->data_valid =3D false; + } else { + data =3D 0; + } + usart->csra &=3D 0xff ^ USART_CSRA_RXC; + qemu_set_irq(usart->rxc_irq, 0); + qemu_chr_fe_accept_input(&usart->chr); + return data; + case USART_CSRA: + return usart->csra; + case USART_CSRB: + return usart->csrb; + case USART_CSRC: + return usart->csrc; + case USART_BRRL: + return usart->brrl; + case USART_BRRH: + return usart->brrh; + default: + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: Bad offset 0x%"HWADDR_PRIx"\n", + __func__, + addr); + } + return 0; +} + +static void avr_usart_write(void *opaque, hwaddr addr, uint64_t value, + unsigned int size) +{ + AVRUsartState *usart =3D opaque; + uint8_t mask; + uint8_t data; + assert((value & 0xff) =3D=3D value); + assert(size =3D=3D 1); + + if (!usart->enabled) { + return; + } + + switch (addr) { + case USART_DR: + if (!(usart->csrb & USART_CSRB_TXEN)) { + /* Transmitter disabled, ignore. */ + return; + } + usart->csra |=3D USART_CSRA_TXC; + usart->csra |=3D USART_CSRA_DRE; + if (usart->csrb & USART_CSRB_TXCIE) { + qemu_set_irq(usart->txc_irq, 1); + usart->csra &=3D 0xff ^ USART_CSRA_TXC; + } + if (usart->csrb & USART_CSRB_DREIE) { + qemu_set_irq(usart->dre_irq, 1); + } + data =3D value; + qemu_chr_fe_write_all(&usart->chr, &data, 1); + break; + case USART_CSRA: + mask =3D 0b01000011; + /* Mask read-only bits. */ + value =3D (value & mask) | (usart->csra & (0xff ^ mask)); + usart->csra =3D value; + if (value & USART_CSRA_TXC) { + usart->csra ^=3D USART_CSRA_TXC; + qemu_set_irq(usart->txc_irq, 0); + } + if (value & USART_CSRA_MPCM) { + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: MPCM not supported by USART\n", + __func__); + } + break; + case USART_CSRB: + mask =3D 0b11111101; + /* Mask read-only bits. */ + value =3D (value & mask) | (usart->csrb & (0xff ^ mask)); + usart->csrb =3D value; + if (!(value & USART_CSRB_RXEN)) { + /* Receiver disabled, flush input buffer. */ + usart->data_valid =3D false; + } + qemu_set_irq(usart->rxc_irq, + ((value & USART_CSRB_RXCIE) && + (usart->csra & USART_CSRA_RXC)) ? 1 : 0); + qemu_set_irq(usart->txc_irq, + ((value & USART_CSRB_TXCIE) && + (usart->csra & USART_CSRA_TXC)) ? 1 : 0); + qemu_set_irq(usart->dre_irq, + ((value & USART_CSRB_DREIE) && + (usart->csra & USART_CSRA_DRE)) ? 1 : 0); + update_char_mask(usart); + break; + case USART_CSRC: + usart->csrc =3D value; + if ((value & USART_CSRC_MSEL1) && (value & USART_CSRC_MSEL0)) { + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: SPI mode not supported by USART\n", + __func__); + } + if ((value & USART_CSRC_MSEL1) && !(value & USART_CSRC_MSEL0)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad USART mode\n", __func_= _); + } + if (!(value & USART_CSRC_PM1) && (value & USART_CSRC_PM0)) { + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: Bad USART parity mode\n", + __func__); + } + update_char_mask(usart); + break; + case USART_BRRL: + usart->brrl =3D value; + break; + case USART_BRRH: + usart->brrh =3D value & 0b00001111; + break; + default: + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: Bad offset 0x%"HWADDR_PRIx"\n", + __func__, + addr); + } +} + +static const MemoryRegionOps avr_usart_ops =3D { + .read =3D avr_usart_read, + .write =3D avr_usart_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl =3D {.min_access_size =3D 1, .max_access_size =3D 1} +}; + +static Property avr_usart_properties[] =3D { + DEFINE_PROP_CHR("chardev", AVRUsartState, chr), + DEFINE_PROP_END_OF_LIST(), +}; + +static void avr_usart_pr(void *opaque, int irq, int level) +{ + AVRUsartState *s =3D AVR_USART(opaque); + + s->enabled =3D !level; + + if (!s->enabled) { + avr_usart_reset(DEVICE(s)); + } +} + +static void avr_usart_init(Object *obj) +{ + AVRUsartState *s =3D AVR_USART(obj); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rxc_irq); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->dre_irq); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->txc_irq); + memory_region_init_io(&s->mmio, obj, &avr_usart_ops, s, TYPE_AVR_USART= , 8); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); + qdev_init_gpio_in(DEVICE(s), avr_usart_pr, 1); + s->enabled =3D true; +} + +static void avr_usart_realize(DeviceState *dev, Error **errp) +{ + AVRUsartState *s =3D AVR_USART(dev); + qemu_chr_fe_set_handlers(&s->chr, avr_usart_can_receive, + avr_usart_receive, NULL, NULL, + s, NULL, true); + avr_usart_reset(dev); +} + +static void avr_usart_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->reset =3D avr_usart_reset; + dc->props =3D avr_usart_properties; + dc->realize =3D avr_usart_realize; +} + +static const TypeInfo avr_usart_info =3D { + .name =3D TYPE_AVR_USART, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(AVRUsartState), + .instance_init =3D avr_usart_init, + .class_init =3D avr_usart_class_init, +}; + +static void avr_usart_register_types(void) +{ + type_register_static(&avr_usart_info); +} + +type_init(avr_usart_register_types) diff --git a/hw/char/Kconfig b/hw/char/Kconfig index 40e7a8b8bb..331b20983f 100644 --- a/hw/char/Kconfig +++ b/hw/char/Kconfig @@ -46,3 +46,6 @@ config SCLPCONSOLE =20 config TERMINAL3270 bool + +config AVR_USART + bool diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs index 02d8a66925..f05c1f5667 100644 --- a/hw/char/Makefile.objs +++ b/hw/char/Makefile.objs @@ -21,6 +21,7 @@ obj-$(CONFIG_PSERIES) +=3D spapr_vty.o obj-$(CONFIG_DIGIC) +=3D digic-uart.o obj-$(CONFIG_STM32F2XX_USART) +=3D stm32f2xx_usart.o obj-$(CONFIG_RASPI) +=3D bcm2835_aux.o +common-obj-$(CONFIG_AVR_USART) +=3D avr_usart.o =20 common-obj-$(CONFIG_CMSDK_APB_UART) +=3D cmsdk-apb-uart.o common-obj-$(CONFIG_ETRAXFS) +=3D etraxfs_ser.o --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375888; cv=none; d=zohomail.com; s=zohoarc; b=WcBOaAwWArWPM770STrOixxo2O7OceAmrJaYksUJjdnBpWUKqrotFqHb96GXkBHa5SRJmP1z/Wup279OlTEOfEQwiLrn9XAQHsx4PRxU+Bvhym/l38yLGfq/BQEUy41QgFMgqB6Y5bPnYCSSCFAYURIStF0mfl0uBd8XGY+G4d4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375888; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=BC7TK3KXLb/XVS80ZiFsTIhysVwX6Pf/+PKiMgs9VdQ=; b=bg36Jyil1CoY9aK0RZptGsQ3Mj2y9/0g36u5lEnQ9aiVRyLSgsSuOpd7b6yitZVEjg1Sz5fKi/DUB5tqpQPgQ/nalazd8yjNWuNDtQrpqGTbrVT73Q+uEdI3rBr+mg6Gtrjml8DF1r/CP4viIwlgQ//t0Zr21S5vehIqIZh0Xc4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375887992494.04895675278283; Sat, 18 Jan 2020 11:31:27 -0800 (PST) Received: from localhost ([::1]:44190 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istoc-0001SC-Cr for importer@patchew.org; Sat, 18 Jan 2020 14:31:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50011) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isteY-0005Lj-Qw for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isteW-00070J-2Z for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:02 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:41623) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isteV-0006za-PQ for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:00 -0500 Received: by mail-wr1-x444.google.com with SMTP id c9so25730309wrw.8 for ; Sat, 18 Jan 2020 11:20:59 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.20.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:20:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BC7TK3KXLb/XVS80ZiFsTIhysVwX6Pf/+PKiMgs9VdQ=; b=VcXcfmeY2U5CmIx5uXqb0+R8DsIc3Bv1/UQBuQKh3xzBieeZSWomBya0ni+tV0FCxa mvch7iiX4fpOavBS6wtLRim3EKNeFBiUaRg9yYO234wEzRQQR1/XIr/SberNgrjocWfk 8tOGSL8NiWakaTfx7AfzjKTkmuyF6Kwa2gb4HDDYzzuPo7wFq/DB0satTu84qecqZfmR +AGFvofG/Q1d2QOygxaiKG7hTPA5WP/PEBkJoEFt0xP6rzpwd21PW9qAQdzE3vv3rlEm P1K/iaqVnQniQIHb2REMpj4PTJu4jDqhN3CIfGoofJMGp03/EnkjGHdN59IAL/GVGM3j HbRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BC7TK3KXLb/XVS80ZiFsTIhysVwX6Pf/+PKiMgs9VdQ=; b=NPoAuXvEv2DGl7xJWCkmFEQ7pc0fltdwtSIz3Ux2jS7xbHNxBp60G9l/tgOQ6F0hrk gB2XYcMbL7XzSo7X+dhYtyPailAOHguNyxBvonmdvLz2420TvPAthvInNEAbRzjb80aS 6/UEEyWGHUeI0kbe7X1e8SoeqQJ55eCzvlVmlqQjMptxzjJ8tJy83uBjJIdAakCMf0OS ZDBcTtpQRBM6CMkpenhy0Bu/+IGe/+WiUdl1PAl++kHAVEAkCOFmT3kzfuZOJT5nNJ3K tFiHqbsinmD9VNYF0qyQUfQQnuNSU9n0kMTL1vdwM2F31d2JVkPVn5bmQSAAW0bOuokd FyhQ== X-Gm-Message-State: APjAAAVHy2H3KTrmk6jmM9/08yVhThA1yG7JO72mg2rJqNjPVvFXrQ8+ CImSS+jkImYeaJqzw2TaOraBvjP3SZIYTxH6 X-Google-Smtp-Source: APXvYqy+iY6CjVXiB2kOToBD3Gqx4bADDzZhUuR1w3SRcjJdUOL3OocSqw3C+ziBIVJEOcnWxMkqwQ== X-Received: by 2002:a5d:6344:: with SMTP id b4mr9803699wrw.414.1579375258201; Sat, 18 Jan 2020 11:20:58 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 12/21] hw/avr: Add limited support for 16 bit timer peripheral Date: Sat, 18 Jan 2020 21:14:07 +0200 Message-Id: <20200118191416.19934-13-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, Sarah Harris , dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" These were designed to facilitate testing but should provide enough functio= n to be useful in other contexts. Only a subset of the functions of each peripheral is implemented, mainly du= e to the lack of a standard way to handle electrical connections (like GPIO= pins). Signed-off-by: Sarah Harris Tested-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/timer/avr_timer16.h | 94 +++++ hw/timer/avr_timer16.c | 602 +++++++++++++++++++++++++++++++++ hw/timer/Kconfig | 3 + hw/timer/Makefile.objs | 2 + 4 files changed, 701 insertions(+) create mode 100644 include/hw/timer/avr_timer16.h create mode 100644 hw/timer/avr_timer16.c diff --git a/include/hw/timer/avr_timer16.h b/include/hw/timer/avr_timer16.h new file mode 100644 index 0000000000..4ae0c64a34 --- /dev/null +++ b/include/hw/timer/avr_timer16.h @@ -0,0 +1,94 @@ +/* + * AVR 16 bit timer + * + * Copyright (c) 2018 University of Kent + * Author: Ed Robbins + * + * 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 + * + */ + +/* + * Driver for 16 bit timers on 8 bit AVR devices. + * Note: + * On ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 = bit + */ + +#ifndef AVR_TIMER16_H +#define AVR_TIMER16_H + +#include "hw/sysbus.h" +#include "qemu/timer.h" +#include "hw/hw.h" + +enum NextInterrupt { + OVERFLOW, + COMPA, + COMPB, + COMPC, + CAPT +}; + +#define TYPE_AVR_TIMER16 "avr-timer16" +#define AVR_TIMER16(obj) \ + OBJECT_CHECK(AVRTimer16State, (obj), TYPE_AVR_TIMER16) + +typedef struct AVRTimer16State { + /* */ + SysBusDevice parent_obj; + + /* */ + MemoryRegion iomem; + MemoryRegion imsk_iomem; + MemoryRegion ifr_iomem; + QEMUTimer *timer; + qemu_irq capt_irq; + qemu_irq compa_irq; + qemu_irq compb_irq; + qemu_irq compc_irq; + qemu_irq ovf_irq; + + bool enabled; + + /* registers */ + uint8_t cra; + uint8_t crb; + uint8_t crc; + uint8_t cntl; + uint8_t cnth; + uint8_t icrl; + uint8_t icrh; + uint8_t ocral; + uint8_t ocrah; + uint8_t ocrbl; + uint8_t ocrbh; + uint8_t ocrcl; + uint8_t ocrch; + /* + * Reads and writes to CNT and ICR utilise a bizarre temporary + * register, which we emulate + */ + uint8_t rtmp; + uint8_t imsk; + uint8_t ifr; + + uint8_t id; + uint64_t cpu_freq_hz; + uint64_t freq_hz; + uint64_t period_ns; + uint64_t reset_time_ns; + enum NextInterrupt next_interrupt; +} AVRTimer16State; + +#endif /* AVR_TIMER16_H */ diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c new file mode 100644 index 0000000000..aea1bf009e --- /dev/null +++ b/hw/timer/avr_timer16.c @@ -0,0 +1,602 @@ +/* + * AVR 16 bit timer + * + * Copyright (c) 2018 University of Kent + * Author: Ed Robbins + * + * 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 + * + */ + +/* + * Driver for 16 bit timers on 8 bit AVR devices. + * Note: + * ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit + */ + +/* + * XXX TODO: Power Reduction Register support + * prescaler pause support + * PWM modes, GPIO, output capture pins, input compare pin + */ + +#include "qemu/osdep.h" +#include "hw/timer/avr_timer16.h" +#include "qemu/log.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" + +/* Register offsets */ +#define T16_CRA 0x0 +#define T16_CRB 0x1 +#define T16_CRC 0x2 +#define T16_CNTL 0x4 +#define T16_CNTH 0x5 +#define T16_ICRL 0x6 +#define T16_ICRH 0x7 +#define T16_OCRAL 0x8 +#define T16_OCRAH 0x9 +#define T16_OCRBL 0xa +#define T16_OCRBH 0xb +#define T16_OCRCL 0xc +#define T16_OCRCH 0xd + +/* Field masks */ +#define T16_CRA_WGM01 0x3 +#define T16_CRA_COMC 0xc +#define T16_CRA_COMB 0x30 +#define T16_CRA_COMA 0xc0 +#define T16_CRA_OC_CONF \ + (T16_CRA_COMA | T16_CRA_COMB | T16_CRA_COMC) + +#define T16_CRB_CS 0x7 +#define T16_CRB_WGM23 0x18 +#define T16_CRB_ICES 0x40 +#define T16_CRB_ICNC 0x80 + +#define T16_CRC_FOCC 0x20 +#define T16_CRC_FOCB 0x40 +#define T16_CRC_FOCA 0x80 + +/* Fields masks both TIMSK and TIFR (interrupt mask/flag registers) */ +#define T16_INT_TOV 0x1 /* Timer overflow */ +#define T16_INT_OCA 0x2 /* Output compare A */ +#define T16_INT_OCB 0x4 /* Output compare B */ +#define T16_INT_OCC 0x8 /* Output compare C */ +#define T16_INT_IC 0x20 /* Input capture */ + +/* Clock source values */ +#define T16_CLKSRC_STOPPED 0 +#define T16_CLKSRC_DIV1 1 +#define T16_CLKSRC_DIV8 2 +#define T16_CLKSRC_DIV64 3 +#define T16_CLKSRC_DIV256 4 +#define T16_CLKSRC_DIV1024 5 +#define T16_CLKSRC_EXT_FALLING 6 +#define T16_CLKSRC_EXT_RISING 7 + +/* Timer mode values (not including PWM modes) */ +#define T16_MODE_NORMAL 0 +#define T16_MODE_CTC_OCRA 4 +#define T16_MODE_CTC_ICR 12 + +/* Accessors */ +#define CLKSRC(t16) (t16->crb & T16_CRB_CS) +#define MODE(t16) (((t16->crb & T16_CRB_WGM23) >> 1) | \ + (t16->cra & T16_CRA_WGM01)) +#define CNT(t16) VAL16(t16->cntl, t16->cnth) +#define OCRA(t16) VAL16(t16->ocral, t16->ocrah) +#define OCRB(t16) VAL16(t16->ocrbl, t16->ocrbh) +#define OCRC(t16) VAL16(t16->ocrcl, t16->ocrch) +#define ICR(t16) VAL16(t16->icrl, t16->icrh) + +/* Helper macros */ +#define VAL16(l, h) ((h << 8) | l) +#define ERROR(fmt, args...) \ + qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## args) +#define DB_PRINT(fmt, args...) /* Nothing */ +/*#define DB_PRINT(fmt, args...) printf("%s: " fmt "\n", __func__, ## args= )*/ + +static inline int64_t avr_timer16_ns_to_ticks(AVRTimer16State *t16, int64_= t t) +{ + if (t16->period_ns =3D=3D 0) { + return 0; + } + return t / t16->period_ns; +} + +static void avr_timer16_update_cnt(AVRTimer16State *t16) +{ + uint16_t cnt; + cnt =3D avr_timer16_ns_to_ticks(t16, qemu_clock_get_ns(QEMU_CLOCK_VIRT= UAL) - + t16->reset_time_ns); + t16->cntl =3D (uint8_t)(cnt & 0xff); + t16->cnth =3D (uint8_t)((cnt & 0xff00) >> 8); +} + +static inline void avr_timer16_recalc_reset_time(AVRTimer16State *t16) +{ + t16->reset_time_ns =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - + CNT(t16) * t16->period_ns; +} + +static void avr_timer16_clock_reset(AVRTimer16State *t16) +{ + t16->cntl =3D 0; + t16->cnth =3D 0; + t16->reset_time_ns =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); +} + +static void avr_timer16_clksrc_update(AVRTimer16State *t16) +{ + uint16_t divider =3D 0; + switch (CLKSRC(t16)) { + case T16_CLKSRC_EXT_FALLING: + case T16_CLKSRC_EXT_RISING: + ERROR("external clock source unsupported"); + goto end; + case T16_CLKSRC_STOPPED: + goto end; + case T16_CLKSRC_DIV1: + divider =3D 1; + break; + case T16_CLKSRC_DIV8: + divider =3D 8; + break; + case T16_CLKSRC_DIV64: + divider =3D 64; + break; + case T16_CLKSRC_DIV256: + divider =3D 256; + break; + case T16_CLKSRC_DIV1024: + divider =3D 1024; + break; + default: + goto end; + } + t16->freq_hz =3D t16->cpu_freq_hz / divider; + t16->period_ns =3D NANOSECONDS_PER_SECOND / t16->freq_hz; + DB_PRINT("Timer frequency %" PRIu64 " hz, period %" PRIu64 " ns (%f s)= ", + t16->freq_hz, t16->period_ns, 1 / (double)t16->freq_hz); +end: + return; +} + +static void avr_timer16_set_alarm(AVRTimer16State *t16) +{ + if (CLKSRC(t16) =3D=3D T16_CLKSRC_EXT_FALLING || + CLKSRC(t16) =3D=3D T16_CLKSRC_EXT_RISING || + CLKSRC(t16) =3D=3D T16_CLKSRC_STOPPED) { + /* Timer is disabled or set to external clock source (unsupported)= */ + goto end; + } + + uint64_t alarm_offset =3D 0xffff; + enum NextInterrupt next_interrupt =3D OVERFLOW; + + switch (MODE(t16)) { + case T16_MODE_NORMAL: + /* Normal mode */ + if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) && + (t16->imsk & T16_INT_OCA)) { + alarm_offset =3D OCRA(t16); + next_interrupt =3D COMPA; + } + break; + case T16_MODE_CTC_OCRA: + /* CTC mode, top =3D ocra */ + if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16)) { + alarm_offset =3D OCRA(t16); + next_interrupt =3D COMPA; + } + break; + case T16_MODE_CTC_ICR: + /* CTC mode, top =3D icr */ + if (ICR(t16) < alarm_offset && ICR(t16) > CNT(t16)) { + alarm_offset =3D ICR(t16); + next_interrupt =3D CAPT; + } + if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) && + (t16->imsk & T16_INT_OCA)) { + alarm_offset =3D OCRA(t16); + next_interrupt =3D COMPA; + } + break; + default: + ERROR("pwm modes are unsupported"); + goto end; + } + if (OCRB(t16) < alarm_offset && OCRB(t16) > CNT(t16) && + (t16->imsk & T16_INT_OCB)) { + alarm_offset =3D OCRB(t16); + next_interrupt =3D COMPB; + } + if (OCRC(t16) < alarm_offset && OCRB(t16) > CNT(t16) && + (t16->imsk & T16_INT_OCC)) { + alarm_offset =3D OCRB(t16); + next_interrupt =3D COMPC; + } + alarm_offset -=3D CNT(t16); + + t16->next_interrupt =3D next_interrupt; + uint64_t alarm_ns =3D + t16->reset_time_ns + ((CNT(t16) + alarm_offset) * t16->period_ns); + timer_mod(t16->timer, alarm_ns); + + DB_PRINT("next alarm %" PRIu64 " ns from now", + alarm_offset * t16->period_ns); + +end: + return; +} + +static void avr_timer16_interrupt(void *opaque) +{ + AVRTimer16State *t16 =3D opaque; + uint8_t mode =3D MODE(t16); + + avr_timer16_update_cnt(t16); + + if (CLKSRC(t16) =3D=3D T16_CLKSRC_EXT_FALLING || + CLKSRC(t16) =3D=3D T16_CLKSRC_EXT_RISING || + CLKSRC(t16) =3D=3D T16_CLKSRC_STOPPED) { + /* Timer is disabled or set to external clock source (unsupported)= */ + return; + } + + DB_PRINT("interrupt, cnt =3D %d", CNT(t16)); + + /* Counter overflow */ + if (t16->next_interrupt =3D=3D OVERFLOW) { + DB_PRINT("0xffff overflow"); + avr_timer16_clock_reset(t16); + if (t16->imsk & T16_INT_TOV) { + t16->ifr |=3D T16_INT_TOV; + qemu_set_irq(t16->ovf_irq, 1); + } + } + /* Check for ocra overflow in CTC mode */ + if (mode =3D=3D T16_MODE_CTC_OCRA && t16->next_interrupt =3D=3D COMPA)= { + DB_PRINT("CTC OCRA overflow"); + avr_timer16_clock_reset(t16); + } + /* Check for icr overflow in CTC mode */ + if (mode =3D=3D T16_MODE_CTC_ICR && t16->next_interrupt =3D=3D CAPT) { + DB_PRINT("CTC ICR overflow"); + avr_timer16_clock_reset(t16); + if (t16->imsk & T16_INT_IC) { + t16->ifr |=3D T16_INT_IC; + qemu_set_irq(t16->capt_irq, 1); + } + } + /* Check for output compare interrupts */ + if (t16->imsk & T16_INT_OCA && t16->next_interrupt =3D=3D COMPA) { + t16->ifr |=3D T16_INT_OCA; + qemu_set_irq(t16->compa_irq, 1); + } + if (t16->imsk & T16_INT_OCB && t16->next_interrupt =3D=3D COMPB) { + t16->ifr |=3D T16_INT_OCB; + qemu_set_irq(t16->compb_irq, 1); + } + if (t16->imsk & T16_INT_OCC && t16->next_interrupt =3D=3D COMPC) { + t16->ifr |=3D T16_INT_OCC; + qemu_set_irq(t16->compc_irq, 1); + } + avr_timer16_set_alarm(t16); +} + +static void avr_timer16_reset(DeviceState *dev) +{ + AVRTimer16State *t16 =3D AVR_TIMER16(dev); + + avr_timer16_clock_reset(t16); + avr_timer16_clksrc_update(t16); + avr_timer16_set_alarm(t16); + + qemu_set_irq(t16->capt_irq, 0); + qemu_set_irq(t16->compa_irq, 0); + qemu_set_irq(t16->compb_irq, 0); + qemu_set_irq(t16->compc_irq, 0); + qemu_set_irq(t16->ovf_irq, 0); +} + +static uint64_t avr_timer16_read(void *opaque, hwaddr offset, unsigned siz= e) +{ + assert(size =3D=3D 1); + AVRTimer16State *t16 =3D opaque; + uint8_t retval =3D 0; + + switch (offset) { + case T16_CRA: + retval =3D t16->cra; + break; + case T16_CRB: + retval =3D t16->crb; + break; + case T16_CRC: + retval =3D t16->crc; + break; + case T16_CNTL: + avr_timer16_update_cnt(t16); + t16->rtmp =3D t16->cnth; + retval =3D t16->cntl; + break; + case T16_CNTH: + retval =3D t16->rtmp; + break; + case T16_ICRL: + /* + * The timer copies cnt to icr when the input capture pin changes + * state or when the analog comparator has a match. We don't + * emulate this behaviour. We do support it's use for defining a + * TOP value in T16_MODE_CTC_ICR + */ + t16->rtmp =3D t16->icrh; + retval =3D t16->icrl; + break; + case T16_ICRH: + retval =3D t16->rtmp; + break; + case T16_OCRAL: + retval =3D t16->ocral; + break; + case T16_OCRAH: + retval =3D t16->ocrah; + break; + case T16_OCRBL: + retval =3D t16->ocrbl; + break; + case T16_OCRBH: + retval =3D t16->ocrbh; + break; + case T16_OCRCL: + retval =3D t16->ocrcl; + break; + case T16_OCRCH: + retval =3D t16->ocrch; + break; + default: + break; + } + return (uint64_t)retval; +} + +static void avr_timer16_write(void *opaque, hwaddr offset, + uint64_t val64, unsigned size) +{ + assert(size =3D=3D 1); + AVRTimer16State *t16 =3D opaque; + uint8_t val8 =3D (uint8_t)val64; + uint8_t prev_clk_src =3D CLKSRC(t16); + + DB_PRINT("write %d to offset %d", val8, (uint8_t)offset); + + switch (offset) { + case T16_CRA: + t16->cra =3D val8; + if (t16->cra & T16_CRA_OC_CONF) { + ERROR("output compare pins unsupported"); + } + break; + case T16_CRB: + t16->crb =3D val8; + if (t16->crb & T16_CRB_ICNC) { + ERROR("input capture noise canceller unsupported"); + } + if (t16->crb & T16_CRB_ICES) { + ERROR("input capture unsupported"); + } + if (CLKSRC(t16) !=3D prev_clk_src) { + avr_timer16_clksrc_update(t16); + if (prev_clk_src =3D=3D T16_CLKSRC_STOPPED) { + t16->reset_time_ns =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUA= L); + } + } + break; + case T16_CRC: + t16->crc =3D val8; + ERROR("output compare pins unsupported"); + break; + case T16_CNTL: + /* + * CNT is the 16-bit counter value, it must be read/written via + * a temporary register (rtmp) to make the read/write atomic. + */ + /* ICR also has this behaviour, and shares rtmp */ + /* + * Writing CNT blocks compare matches for one clock cycle. + * Writing CNT to TOP or to an OCR value (if in use) will + * skip the relevant interrupt + */ + t16->cntl =3D val8; + t16->cnth =3D t16->rtmp; + avr_timer16_recalc_reset_time(t16); + break; + case T16_CNTH: + t16->rtmp =3D val8; + break; + case T16_ICRL: + /* ICR can only be written in mode T16_MODE_CTC_ICR */ + if (MODE(t16) =3D=3D T16_MODE_CTC_ICR) { + t16->icrl =3D val8; + t16->icrh =3D t16->rtmp; + } + break; + case T16_ICRH: + if (MODE(t16) =3D=3D T16_MODE_CTC_ICR) { + t16->rtmp =3D val8; + } + break; + case T16_OCRAL: + /* + * OCRn cause the relevant output compare flag to be raised, and + * trigger an interrupt, when CNT is equal to the value here + */ + t16->ocral =3D val8; + break; + case T16_OCRAH: + t16->ocrah =3D val8; + break; + case T16_OCRBL: + t16->ocrbl =3D val8; + break; + case T16_OCRBH: + t16->ocrbh =3D val8; + break; + case T16_OCRCL: + t16->ocrcl =3D val8; + break; + case T16_OCRCH: + t16->ocrch =3D val8; + break; + default: + break; + } + avr_timer16_set_alarm(t16); +} + +static uint64_t avr_timer16_imsk_read(void *opaque, + hwaddr offset, + unsigned size) +{ + assert(size =3D=3D 1); + AVRTimer16State *t16 =3D opaque; + if (offset !=3D 0) { + return 0; + } + return t16->imsk; +} + +static void avr_timer16_imsk_write(void *opaque, hwaddr offset, + uint64_t val64, unsigned size) +{ + assert(size =3D=3D 1); + AVRTimer16State *t16 =3D opaque; + if (offset !=3D 0) { + return; + } + t16->imsk =3D (uint8_t)val64; +} + +static uint64_t avr_timer16_ifr_read(void *opaque, + hwaddr offset, + unsigned size) +{ + assert(size =3D=3D 1); + AVRTimer16State *t16 =3D opaque; + if (offset !=3D 0) { + return 0; + } + return t16->ifr; +} + +static void avr_timer16_ifr_write(void *opaque, hwaddr offset, + uint64_t val64, unsigned size) +{ + assert(size =3D=3D 1); + AVRTimer16State *t16 =3D opaque; + if (offset !=3D 0) { + return; + } + t16->ifr =3D (uint8_t)val64; +} + +static const MemoryRegionOps avr_timer16_ops =3D { + .read =3D avr_timer16_read, + .write =3D avr_timer16_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl =3D {.max_access_size =3D 1} +}; + +static const MemoryRegionOps avr_timer16_imsk_ops =3D { + .read =3D avr_timer16_imsk_read, + .write =3D avr_timer16_imsk_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl =3D {.max_access_size =3D 1} +}; + +static const MemoryRegionOps avr_timer16_ifr_ops =3D { + .read =3D avr_timer16_ifr_read, + .write =3D avr_timer16_ifr_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl =3D {.max_access_size =3D 1} +}; + +static Property avr_timer16_properties[] =3D { + DEFINE_PROP_UINT8("id", struct AVRTimer16State, id, 0), + DEFINE_PROP_UINT64("cpu-frequency-hz", struct AVRTimer16State, + cpu_freq_hz, 20000000), + DEFINE_PROP_END_OF_LIST(), +}; + +static void avr_timer16_pr(void *opaque, int irq, int level) +{ + AVRTimer16State *s =3D AVR_TIMER16(opaque); + + s->enabled =3D !level; + + if (!s->enabled) { + avr_timer16_reset(DEVICE(s)); + } +} + +static void avr_timer16_init(Object *obj) +{ + AVRTimer16State *s =3D AVR_TIMER16(obj); + + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->capt_irq); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compa_irq); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compb_irq); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compc_irq); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->ovf_irq); + + memory_region_init_io(&s->iomem, obj, &avr_timer16_ops, + s, TYPE_AVR_TIMER16, 0xe); + memory_region_init_io(&s->imsk_iomem, obj, &avr_timer16_imsk_ops, + s, TYPE_AVR_TIMER16, 0x1); + memory_region_init_io(&s->ifr_iomem, obj, &avr_timer16_ifr_ops, + s, TYPE_AVR_TIMER16, 0x1); + + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->imsk_iomem); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->ifr_iomem); + qdev_init_gpio_in(DEVICE(s), avr_timer16_pr, 1); + + s->timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, avr_timer16_interrupt, s= ); + s->enabled =3D true; +} + +static void avr_timer16_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->reset =3D avr_timer16_reset; + dc->props =3D avr_timer16_properties; +} + +static const TypeInfo avr_timer16_info =3D { + .name =3D TYPE_AVR_TIMER16, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(AVRTimer16State), + .instance_init =3D avr_timer16_init, + .class_init =3D avr_timer16_class_init, +}; + +static void avr_timer16_register_types(void) +{ + type_register_static(&avr_timer16_info); +} + +type_init(avr_timer16_register_types) diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig index 59b3f44d69..2521056dc8 100644 --- a/hw/timer/Kconfig +++ b/hw/timer/Kconfig @@ -35,3 +35,6 @@ config CMSDK_APB_TIMER config CMSDK_APB_DUALTIMER bool select PTIMER + +config AVR_TIMER16 + bool diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index dece235fd7..af0913ca3b 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -35,3 +35,5 @@ common-obj-$(CONFIG_CMSDK_APB_TIMER) +=3D cmsdk-apb-timer= .o common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) +=3D cmsdk-apb-dualtimer.o common-obj-$(CONFIG_MSF2) +=3D mss-timer.o common-obj-$(CONFIG_RASPI) +=3D bcm2835_systmr.o + +obj-$(CONFIG_AVR_TIMER16) +=3D avr_timer16.o --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376059; cv=none; d=zohomail.com; s=zohoarc; b=NAfy7liPnZawWNmdBnSkiF6RNjkYIEHoJZiFW6e/+/xLu2IoCxVRVqQhDTNhsexBKQLWB/c76p00Hb3OtroyWiBAm1vw95EXIhbOKQ7s+ze71xVNtAYl18hiq+gt4wERCJh807dgbB5Tbv+cgtQY3zhmzJwFrU/rVBNB80IhtEI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376059; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=f0Dp6GGDhBgnTynbqKq3B4A9OGC9gPqHD+W52wlMqDQ=; b=Xs15mn5u5pKCb1q9ko/949yhis6ghfLa3v607LItQLQmV5k387e8XInWY/q69zbud75VwICao+SB4NJquiWK5H64UM9UOzG4if2Mh12JwQ6d1ukRex4a1kWeWApQYUtTk+4bAc2U6fiUNEuu07XMu0xc16jcBvwTy4rHP6OhKiA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376059306346.7582691153468; Sat, 18 Jan 2020 11:34:19 -0800 (PST) Received: from localhost ([::1]:44212 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istrN-0004VF-KA for importer@patchew.org; Sat, 18 Jan 2020 14:34:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50031) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isteb-0005QW-V6 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istea-000749-7c for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:05 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:38968) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istea-00073R-0p for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:04 -0500 Received: by mail-wm1-x344.google.com with SMTP id 20so10815088wmj.4 for ; Sat, 18 Jan 2020 11:21:03 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.20.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=f0Dp6GGDhBgnTynbqKq3B4A9OGC9gPqHD+W52wlMqDQ=; b=QO5GzDsloym+/hNaz1n2WF3h2aqL3vhWs/9aSMmD7YyOa9fO9FmgSCLLZCeTveMyAU JJ6rDK21hEipE8xau2ifxBg0vZaws2mJeXkNZwpeWMsPd0yjU3AtxwG//ZhcMVQvi+Yl 9Tk4XvwQ39XHLpJqjvj6SjYanKQDcgZA8Mdj8GR861+ZRIUNDbCBwE7nrmD1Cldvhj5C inDEMORecCPQKXDzbiscogVDB1D2uB7AwxbV0/PgC+PZay8f7cZ4og2t2mOoNjbKN+FH 9Ieqj1UZNu8i1jv49fuKbedq1tmjzkD1N7WxoBIfmhQ6+vFnl3zXjz7DZOC4qmsp3ZEy Ikfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=f0Dp6GGDhBgnTynbqKq3B4A9OGC9gPqHD+W52wlMqDQ=; b=HdcTKyIV6QgWFdC2wE2vUoW/kZJmTLzYZ6hFvAhJTY4t/F36NR4zBJphra469o5LHk KGdgqz1ZGPqsiL4UJuBR+07JzaKeoOSXqmEtljSEIEik9I+b2xdU0TWw277ki/dhrV6s dzwH78eSlz+rjMkEb4msx5+9a3MRRHbgnsdhU3bDVEdjiLNR7zqSo0O/HmmgxYxtTLYO LIUINcFK/iRKXjDMB87kRfY+CACWSE0A3JNZC2Ph2YBbs/Ld2ybglFWk0UlCBeiQIwnp awMJitQmd7heuDXJIBELmzfwuxR5CJRk4mip+ZcRxxrPXlkdq12CoVP1FX+/+K34+kxt wq2w== X-Gm-Message-State: APjAAAWDl30v33T1KQJjiDwiylX96UTbMqOcAot2bZovVfy+87nonPo6 e5izm/+Ta/5H6PW7xO+kDIje6TP/ZEpmQT1E X-Google-Smtp-Source: APXvYqzTo81wqKMf2MxAtr5D6NpLwKaXLU+/ITZTQnZncsPDRYhbM1Ki13ncn6lkruuEjgC03czTTg== X-Received: by 2002:a05:600c:2551:: with SMTP id e17mr10754711wma.26.1579375262827; Sat, 18 Jan 2020 11:21:02 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 13/21] hw/avr: Add dummy mask device Date: Sat, 18 Jan 2020 21:14:08 +0200 Message-Id: <20200118191416.19934-14-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This is a simple device of just one register, whenver this register is written it calls qemu_set_irq function for each of 8 bits/IRQs.. It is used to implement AVR Power Reduction Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/misc/avr_mask.h | 47 ++++++++++++++++ hw/misc/avr_mask.c | 112 +++++++++++++++++++++++++++++++++++++ hw/misc/Kconfig | 3 + hw/misc/Makefile.objs | 2 + 4 files changed, 164 insertions(+) create mode 100644 include/hw/misc/avr_mask.h create mode 100644 hw/misc/avr_mask.c diff --git a/include/hw/misc/avr_mask.h b/include/hw/misc/avr_mask.h new file mode 100644 index 0000000000..d3e21972d8 --- /dev/null +++ b/include/hw/misc/avr_mask.h @@ -0,0 +1,47 @@ +/* + * AVR Power Reduction + * + * Copyright (c) 2019 Michael Rolnik + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ + +#ifndef HW_avr_mask_H +#define HW_avr_mask_H + +#include "hw/sysbus.h" +#include "chardev/char-fe.h" +#include "hw/hw.h" + + +#define TYPE_AVR_MASK "avr-mask" +#define AVR_MASK(obj) OBJECT_CHECK(AVRMaskState, (obj), TYPE_AVR_MASK) + +typedef struct { + /* */ + SysBusDevice parent_obj; + + /* */ + MemoryRegion iomem; + + uint8_t val; + qemu_irq irq[8]; +} AVRMaskState; + +#endif /* HW_avr_mask_H */ diff --git a/hw/misc/avr_mask.c b/hw/misc/avr_mask.c new file mode 100644 index 0000000000..3af82ed9c1 --- /dev/null +++ b/hw/misc/avr_mask.c @@ -0,0 +1,112 @@ +/* + * AVR Power Reduction + * + * Copyright (c) 2019 Michael Rolnik + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/misc/avr_mask.h" +#include "qemu/log.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" + +#define DB_PRINT(fmt, args...) /* Nothing */ +/*#define DB_PRINT(fmt, args...) printf("%s: " fmt "\n", __func__, ## args= )*/ + +static void avr_mask_reset(DeviceState *dev) +{ + AVRMaskState *s =3D AVR_MASK(dev); + + s->val =3D 0x00; + + for (int i =3D 0; i < 8; i++) { + qemu_set_irq(s->irq[i], 0); + } +} + +static uint64_t avr_mask_read(void *opaque, hwaddr offset, unsigned size) +{ + assert(size =3D=3D 1); + assert(offset =3D=3D 0); + AVRMaskState *s =3D opaque; + + return (uint64_t)s->val; +} + +static void avr_mask_write(void *opaque, hwaddr offset, + uint64_t val64, unsigned size) +{ + assert(size =3D=3D 1); + assert(offset =3D=3D 0); + AVRMaskState *s =3D opaque; + uint8_t val8 =3D val64; + + DB_PRINT("write %d to offset %d", val8, (uint8_t)offset); + + s->val =3D val8; + for (int i =3D 0; i < 8; i++) { + qemu_set_irq(s->irq[i], (val8 & (1 << i)) !=3D 0); + } +} + +static const MemoryRegionOps avr_mask_ops =3D { + .read =3D avr_mask_read, + .write =3D avr_mask_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl =3D {.max_access_size =3D 1} +}; + +static void avr_mask_init(Object *dev) +{ + AVRMaskState *s =3D AVR_MASK(dev); + SysBusDevice *busdev =3D SYS_BUS_DEVICE(dev); + + memory_region_init_io(&s->iomem, dev, &avr_mask_ops, s, TYPE_AVR_MASK, + 0x01); + sysbus_init_mmio(busdev, &s->iomem); + + for (int i =3D 0; i < 8; i++) { + sysbus_init_irq(busdev, &s->irq[i]); + } + s->val =3D 0x00; +} + +static void avr_mask_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->reset =3D avr_mask_reset; +} + +static const TypeInfo avr_mask_info =3D { + .name =3D TYPE_AVR_MASK, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(AVRMaskState), + .class_init =3D avr_mask_class_init, + .instance_init =3D avr_mask_init, +}; + +static void avr_mask_register_types(void) +{ + type_register_static(&avr_mask_info); +} + +type_init(avr_mask_register_types) diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index bdd77d8020..74a1e9a241 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -131,4 +131,7 @@ config MAC_VIA select MOS6522 select ADB =20 +config AVR_MASK + bool + source macio/Kconfig diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index da993f45b7..bbf17f651b 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -85,3 +85,5 @@ common-obj-$(CONFIG_NRF51_SOC) +=3D nrf51_rng.o obj-$(CONFIG_MAC_VIA) +=3D mac_via.o =20 common-obj-$(CONFIG_GRLIB) +=3D grlib_ahb_apb_pnp.o + +obj-$(CONFIG_AVR_MASK) +=3D avr_mask.o --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579375403; cv=none; d=zohomail.com; s=zohoarc; b=fZImp4Q1ovit1T3ZCV6/ZRfNOBId9ci2wnaQTAr07uYydWLU6J5vMqP5vpb8meZOcTP0kEqrLKC6LcdHxZ3alsnlOufIYlBY7stEcbi6v2WEeiTJ6QlZk4dunxvPoanX9ymNMkyC2x1QuTb0wvjdoS3kkkP5i2vOs0WTS3UPGzc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579375403; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=n4ogxL9ww5ASh3Tg5MWXRxTePtUFwNm0rVgxIjuoSLQ=; b=B0qqviInM7TxtvCFJB6R6fiKAUnpkO/OdsbsoSRZk7Ax4EyW4z5RLBQ0GJSe3a9cRHj6LhJHMIfZNU2NxCUSvzrro7CJn7oaM05Ocx1/mFYTxk0ahRy8k7J1MnHvSJRZ9z6NkVqMEi21O24y7jkPuA74TAqciQDKBLVzWTuHr1c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579375403343269.7257721819992; Sat, 18 Jan 2020 11:23:23 -0800 (PST) Received: from localhost ([::1]:44062 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istgn-0007rO-PD for importer@patchew.org; Sat, 18 Jan 2020 14:23:21 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50043) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isteo-0005gx-AP for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istel-0007F9-MH for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:18 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:46708) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istel-0007DD-Ch for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:15 -0500 Received: by mail-wr1-x441.google.com with SMTP id z7so25685172wrl.13 for ; Sat, 18 Jan 2020 11:21:15 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=n4ogxL9ww5ASh3Tg5MWXRxTePtUFwNm0rVgxIjuoSLQ=; b=NkC0JNuO0nTA8QNaNStKpww4Z3JAaGPCZxh3qa2nN14QvHq+prpLpRFmXctNQZAVhk UsMdj76V3kNRVtsoWgnsInyHa8ZFsQExoEP3/ra6MvL1rBVbGTmErJYaPzIoIBHLN99d AnFac9dDWuebaBMTZ9ARxGKO7JDmI5immt/ec0qzO1wRglj61xFkA74MhZjFzjxKv5eW n+TY2cVNd8XXDSCyTMOkRObstXm5d9asF05ti92U0vX5raMC1/KKJ+UzxMIe3+gHafYZ C2K3PrVNdBNprXGmi6AZ7o03Z5oeKoAoa4QxZcR74cS+BosPgvUtIVLz4rbnL+hYN1eW uQww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=n4ogxL9ww5ASh3Tg5MWXRxTePtUFwNm0rVgxIjuoSLQ=; b=SstWD4Iws4G67qLoom8zyQA/tAnxqAS7uU9KuYFcb6l+tJsENn4ypFkvoNrdRyApmG KyM55DaVbAE6qT8cGzseYbaafsKqC8FxUa+8oedDYSBAH7I9hpy2sbNg1uclLmPerkQi eN+xrd24umEVoFibstCYamI8pYKXDb0RXke6403eNgp7qHgjiYvo69rw46X6PT97gZ6N hmFbEQMg1Z1IRQNy1C4temdSizt8R29fjdTTlBDrsFpEae6zujtuGcqeyx7wFHF70Ibb RBjynvh+5ugE26XRzSAbybcUsHwCAM31WFU4zhH1S6UCfBgjOthGTLzLDH9D5rBdUtTw 0Viw== X-Gm-Message-State: APjAAAVbQzD5Yv7LpdqtoytLmZp3hpxXPoQLqCfQHi3K/LEijdFH+czn st/gwkM1xBW9jnPyl1l23VzS3wlOs0ZkflmW X-Google-Smtp-Source: APXvYqzUwUxN+MqFaUtOzooJtKw1+hoeNNdR9BA0aToAcHeSLi67YzTd25tnVzfeE7RuZ5mG2qk4qA== X-Received: by 2002:a5d:6692:: with SMTP id l18mr9480155wru.382.1579375273728; Sat, 18 Jan 2020 11:21:13 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 14/21] hw/avr: Add example board configuration Date: Sat, 18 Jan 2020 21:14:09 +0200 Message-Id: <20200118191416.19934-15-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) A simple board setup that configures an AVR CPU to run a given firmware ima= ge. This is all that's useful to implement without peripheral emulation as AVR = CPUs include a lot of on-board peripherals. NOTE: this is not a real board !!!! NOTE: it's used for CPU testing!!!! Signed-off-by: Michael Rolnik Reviewed-by: Aleksandar Markovic Nacked-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- include/elf.h | 2 + include/hw/elf_ops.h | 6 +- include/hw/loader.h | 6 +- hw/avr/sample.c | 295 +++++++++++++++++++++++++++++++++++++++++++ hw/core/loader.c | 15 ++- hw/riscv/boot.c | 2 +- hw/Kconfig | 1 + hw/avr/Kconfig | 6 + hw/avr/Makefile.objs | 1 + 9 files changed, 323 insertions(+), 11 deletions(-) create mode 100644 hw/avr/sample.c create mode 100644 hw/avr/Kconfig create mode 100644 hw/avr/Makefile.objs diff --git a/include/elf.h b/include/elf.h index 3501e0c8d0..53cdfa23b7 100644 --- a/include/elf.h +++ b/include/elf.h @@ -202,6 +202,8 @@ typedef struct mips_elf_abiflags_v0 { #define EM_MOXIE 223 /* Moxie processor family */ #define EM_MOXIE_OLD 0xFEED =20 +#define EM_AVR 83 /* AVR 8-bit microcontroller */ + /* This is the info that is needed to parse the dynamic section of the fil= e */ #define DT_NULL 0 #define DT_NEEDED 1 diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index e07d276df7..70de85fa72 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -316,7 +316,8 @@ static int glue(load_elf, SZ)(const char *name, int fd, void *translate_opaque, int must_swab, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, - int elf_machine, int clear_lsb, int data_swa= b, + uint32_t *pe_flags, int elf_machine, + int clear_lsb, int data_swab, AddressSpace *as, bool load_rom, symbol_fn_t sym_cb) { @@ -594,6 +595,9 @@ static int glue(load_elf, SZ)(const char *name, int fd, } } =20 + if (pe_flags) { + *pe_flags =3D (uint32_t)(elf_sword)ehdr.e_flags; + } if (lowaddr) *lowaddr =3D (uint64_t)(elf_sword)low; if (highaddr) diff --git a/include/hw/loader.h b/include/hw/loader.h index 48a96cd559..22b59e15ba 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -101,6 +101,7 @@ const char *load_elf_strerror(int error); * @pentry: Populated with program entry point. Ignored if NULL. * @lowaddr: Populated with lowest loaded address. Ignored if NULL. * @highaddr: Populated with highest loaded address. Ignored if NULL. + * @pe_flags: Populated with e_flags. Ignore if NULL. * @bigendian: Expected ELF endianness. 0 for LE otherwise BE * @elf_machine: Expected ELF machine type * @clear_lsb: Set to mask off LSB of addresses (Some architectures use @@ -131,8 +132,9 @@ int load_elf_ram_sym(const char *filename, uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, - uint64_t *lowaddr, uint64_t *highaddr, int big_endian, - int elf_machine, int clear_lsb, int data_swab, + uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pe_f= lags, + int big_endian, int elf_machine, + int clear_lsb, int data_swab, AddressSpace *as, bool load_rom, symbol_fn_t sym_cb); =20 /** load_elf_ram: diff --git a/hw/avr/sample.c b/hw/avr/sample.c new file mode 100644 index 0000000000..95094a8d6c --- /dev/null +++ b/hw/avr/sample.c @@ -0,0 +1,295 @@ +/* + * QEMU AVR CPU + * + * Copyright (c) 2019 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 + * + */ + +/* + * NOTE: + * This is not a real AVR board, this is an example! + * The CPU is an approximation of an ATmega2560, but is missing vario= us + * built-in peripherals. + * + * This example board loads provided binary file into flash memory and + * executes it from 0x00000000 address in the code memory space. + * + * Currently used for AVR CPU validation + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" +#include "hw/hw.h" +#include "sysemu/sysemu.h" +#include "sysemu/qtest.h" +#include "ui/console.h" +#include "hw/boards.h" +#include "hw/loader.h" +#include "qemu/error-report.h" +#include "exec/address-spaces.h" +#include "include/hw/sysbus.h" +#include "include/hw/char/avr_usart.h" +#include "include/hw/timer/avr_timer16.h" +#include "include/hw/misc/avr_mask.h" +#include "elf.h" +#include "hw/misc/unimp.h" + +#define SIZE_FLASH 0x00040000 +#define SIZE_SRAM 0x00002000 +/* + * Size of additional "external" memory, as if the AVR were configured to = use + * an external RAM chip. + * Note that the configuration registers that normally enable this feature= are + * unimplemented. + */ +#define SIZE_EXMEM 0x00000000 + +/* Offsets of peripherals in emulated memory space (i.e. not host addresse= s) */ +#define PRR0_BASE 0x64 +#define PRR1_BASE 0x65 +#define USART_BASE 0xc0 +#define TIMER1_BASE 0x80 +#define TIMER1_IMSK_BASE 0x6f +#define TIMER1_IFR_BASE 0x36 + +/* Interrupt numbers used by peripherals */ +#define USART_RXC_IRQ 24 +#define USART_DRE_IRQ 25 +#define USART_TXC_IRQ 26 + +#define TIMER1_CAPT_IRQ 15 +#define TIMER1_COMPA_IRQ 16 +#define TIMER1_COMPB_IRQ 17 +#define TIMER1_COMPC_IRQ 18 +#define TIMER1_OVF_IRQ 19 + +/* Power reduction */ +#define PRR1_BIT_PRTIM5 0x05 /* Timer/Counter5 */ +#define PRR1_BIT_PRTIM4 0x04 /* Timer/Counter4 */ +#define PRR1_BIT_PRTIM3 0x03 /* Timer/Counter3 */ +#define PRR1_BIT_PRUSART3 0x02 /* USART3 */ +#define PRR1_BIT_PRUSART2 0x01 /* USART2 */ +#define PRR1_BIT_PRUSART1 0x00 /* USART1 */ + +#define PRR0_BIT_PRTWI 0x06 /* TWI */ +#define PRR0_BIT_PRTIM2 0x05 /* Timer/Counter2 */ +#define PRR0_BIT_PRTIM0 0x04 /* Timer/Counter0 */ +#define PRR0_BIT_PRTIM1 0x03 /* Timer/Counter1 */ +#define PRR0_BIT_PRSPI 0x02 /* Serial Peripheral Interface */ +#define PRR0_BIT_PRUSART0 0x01 /* USART0 */ +#define PRR0_BIT_PRADC 0x00 /* ADC */ + +#define configCPU_CLOCK_HZ ((unsigned long)16000000) + +typedef struct { + MachineClass parent; +} SampleMachineClass; + +typedef struct { + MachineState parent; + MemoryRegion *ram; + MemoryRegion *flash; + AVRUsartState *usart0; + AVRTimer16State *timer1; + AVRMaskState *prr[2]; +} SampleMachineState; + +#define TYPE_SAMPLE_MACHINE MACHINE_TYPE_NAME("sample") + +#define SAMPLE_MACHINE(obj) \ + OBJECT_CHECK(SampleMachineState, obj, TYPE_SAMPLE_MACHINE) +#define SAMPLE_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SampleMachineClass, obj, TYPE_SAMPLE_MACHINE) +#define SAMPLE_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(SampleMachineClass, klass, TYPE_SAMPLE_MACHINE) + +static void sample_init(MachineState *machine) +{ + SampleMachineState *sms =3D SAMPLE_MACHINE(machine); + MemoryRegion *system_memory =3D get_system_memory(); + AVRCPU *cpu; + const char *firmware =3D NULL; + const char *filename =3D NULL; + const char *cpu_type =3D NULL; + uint32_t e_flags; + int bytes_loaded; + SysBusDevice *busdev; + DeviceState *cpudev; + + system_memory =3D get_system_memory(); + sms->ram =3D g_new(MemoryRegion, 1); + sms->flash =3D g_new(MemoryRegion, 1); + + /* if ELF file is provided, determine CPU type reading ELF e_flags */ + cpu_type =3D machine->cpu_type; + firmware =3D machine->firmware; + if (firmware !=3D NULL) { + filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware); + if (filename =3D=3D NULL) { + error_report("Unable to find %s", firmware); + exit(1); + } + + bytes_loaded =3D load_elf_ram_sym(filename, NULL, NULL, NULL, NULL= , NULL, + NULL, &e_flags, 0, EM_AVR, 0, 0, NULL, 0, 0); + if (bytes_loaded > 0) { + cpu_type =3D avr_flags_to_cpu_type(e_flags, cpu_type); + } + } + + cpu =3D AVR_CPU(cpu_create(cpu_type)); + cpudev =3D DEVICE(cpu); + + memory_region_init_rom(sms->flash, NULL, "avr.flash", SIZE_FLASH, + &error_fatal); + memory_region_add_subregion(system_memory, OFFSET_CODE, sms->flash); + + /* following are atmel2560 device */ + create_unimplemented_device("usart 3", OFFSET_DATA + 0x0130, 0x0007); + create_unimplemented_device("timer-counter-16bit 5", + OFFSET_DATA + 0x0120, 0x000e); + create_unimplemented_device("gpio L", OFFSET_DATA + 0x0109, 0x0003); + create_unimplemented_device("gpio K", OFFSET_DATA + 0x0106, 0x0003); + create_unimplemented_device("gpio J", OFFSET_DATA + 0x0103, 0x0003); + create_unimplemented_device("gpio H", OFFSET_DATA + 0x0100, 0x0003); + create_unimplemented_device("usart 2", OFFSET_DATA + 0x00d0, 0x0007); + create_unimplemented_device("usart 1", OFFSET_DATA + 0x00c8, 0x0007); + create_unimplemented_device("twi", OFFSET_DATA + 0x00b8, 0x0006); + create_unimplemented_device("timer-counter-async-8bit 2", + OFFSET_DATA + 0x00b0, 0x0007); + create_unimplemented_device("timer-counter-16bit 4", + OFFSET_DATA + 0x00a0, 0x000e); + create_unimplemented_device("timer-counter-16bit 3", + OFFSET_DATA + 0x0090, 0x000e); + create_unimplemented_device("ac / adc", + OFFSET_DATA + 0x0078, 0x0008); + create_unimplemented_device("ext-mem-iface", + OFFSET_DATA + 0x0074, 0x0002); + create_unimplemented_device("int-controller", + OFFSET_DATA + 0x0068, 0x0006); + create_unimplemented_device("sys", + OFFSET_DATA + 0x0060, 0x0007); + create_unimplemented_device("spi", + OFFSET_DATA + 0x004c, 0x0003); + create_unimplemented_device("ext-mem-iface", + OFFSET_DATA + 0x004a, 0x0002); + create_unimplemented_device("timer-counter-pwm-8bit 0", + OFFSET_DATA + 0x0044, 0x0005); + create_unimplemented_device("ext-mem-iface", + OFFSET_DATA + 0x003e, 0x0005); + create_unimplemented_device("int-controller", + OFFSET_DATA + 0x0035, 0x0009); + create_unimplemented_device("gpio G", OFFSET_DATA + 0x0032, 0x0003); + create_unimplemented_device("gpio F", OFFSET_DATA + 0x002f, 0x0003); + create_unimplemented_device("gpio E", OFFSET_DATA + 0x002c, 0x0003); + create_unimplemented_device("gpio D", OFFSET_DATA + 0x0029, 0x0003); + create_unimplemented_device("gpio C", OFFSET_DATA + 0x0026, 0x0003); + create_unimplemented_device("gpio B", OFFSET_DATA + 0x0023, 0x0003); + create_unimplemented_device("gpio A", OFFSET_DATA + 0x0020, 0x0003); + + memory_region_allocate_system_memory( + sms->ram, NULL, "avr.ram", SIZE_SRAM + SIZE_EXMEM); + memory_region_add_subregion(system_memory, OFFSET_DATA + 0x200, sms->r= am); + + /* Power Reduction built-in peripheral */ + sms->prr[0] =3D AVR_MASK(sysbus_create_simple(TYPE_AVR_MASK, + OFFSET_DATA + PRR0_BASE, NULL)); + sms->prr[1] =3D AVR_MASK(sysbus_create_simple(TYPE_AVR_MASK, + OFFSET_DATA + PRR1_BASE, NULL)); + + /* USART 0 built-in peripheral */ + sms->usart0 =3D AVR_USART(object_new(TYPE_AVR_USART)); + busdev =3D SYS_BUS_DEVICE(sms->usart0); + qdev_prop_set_chr(DEVICE(sms->usart0), "chardev", serial_hd(0)); + object_property_set_bool(OBJECT(sms->usart0), true, "realized", + &error_fatal); + sysbus_mmio_map(busdev, 0, OFFSET_DATA + USART_BASE); + /* + * These IRQ numbers don't match the datasheet because we're counting = from + * zero and not including reset. + */ + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(cpudev, USART_RXC_IRQ)); + sysbus_connect_irq(busdev, 1, qdev_get_gpio_in(cpudev, USART_DRE_IRQ)); + sysbus_connect_irq(busdev, 2, qdev_get_gpio_in(cpudev, USART_TXC_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(sms->prr[1]), PRR1_BIT_PRUSART1, + qdev_get_gpio_in(DEVICE(sms->usart0), 0)); + + /* Timer 1 built-in periphal */ + sms->timer1 =3D AVR_TIMER16(object_new(TYPE_AVR_TIMER16)); + object_property_set_uint(OBJECT(sms->timer1), 1, "id", &error_abort); + object_property_set_uint(OBJECT(sms->timer1), configCPU_CLOCK_HZ, + "cpu-frequency-hz", &error_abort); + object_property_set_bool(OBJECT(sms->timer1), true, "realized", + &error_fatal); + busdev =3D SYS_BUS_DEVICE(sms->timer1); + sysbus_mmio_map(busdev, 0, OFFSET_DATA + TIMER1_BASE); + sysbus_mmio_map(busdev, 1, OFFSET_DATA + TIMER1_IMSK_BASE); + sysbus_mmio_map(busdev, 2, OFFSET_DATA + TIMER1_IFR_BASE); + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(cpudev, TIMER1_CAPT_IRQ= )); + sysbus_connect_irq(busdev, 1, qdev_get_gpio_in(cpudev, TIMER1_COMPA_IR= Q)); + sysbus_connect_irq(busdev, 2, qdev_get_gpio_in(cpudev, TIMER1_COMPB_IR= Q)); + sysbus_connect_irq(busdev, 3, qdev_get_gpio_in(cpudev, TIMER1_COMPC_IR= Q)); + sysbus_connect_irq(busdev, 4, qdev_get_gpio_in(cpudev, TIMER1_OVF_IRQ)= ); + sysbus_connect_irq(SYS_BUS_DEVICE(sms->prr[0]), PRR0_BIT_PRTIM1, + qdev_get_gpio_in(DEVICE(sms->timer1), 0)); + + /* Load firmware (contents of flash) trying to auto-detect format */ + if (filename !=3D NULL) { + bytes_loaded =3D load_elf( + filename, NULL, NULL, NULL, NULL, NULL, NULL, 0, EM_NONE, 0, 0= ); + if (bytes_loaded < 0) { + bytes_loaded =3D load_image_targphys( + filename, OFFSET_CODE, SIZE_FLASH); + } + if (bytes_loaded < 0) { + error_report( + "Unable to load firmware image %s as ELF or raw binary", + firmware); + exit(1); + } + } +} + +static void sample_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc =3D MACHINE_CLASS(oc); + + mc->desc =3D "AVR sample/example board (ATmega2560)"; + mc->init =3D sample_init; + mc->default_cpus =3D 1; + mc->min_cpus =3D mc->default_cpus; + mc->max_cpus =3D mc->default_cpus; + mc->default_cpu_type =3D AVR_CPU_TYPE_NAME("avr5"); + mc->is_default =3D 1; +} + +static const TypeInfo sample_info =3D { + .name =3D TYPE_SAMPLE_MACHINE, + .parent =3D TYPE_MACHINE, + .instance_size =3D sizeof(SampleMachineState), + .class_size =3D sizeof(SampleMachineClass), + .class_init =3D sample_class_init, +}; + +static void sample_machine_init(void) +{ + type_register_static(&sample_info); +} + +type_init(sample_machine_init); diff --git a/hw/core/loader.c b/hw/core/loader.c index 5099f27dc8..9961b4423b 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -438,7 +438,7 @@ int load_elf_ram(const char *filename, { return load_elf_ram_sym(filename, elf_note_fn, translate_fn, translate_opaque, - pentry, lowaddr, highaddr, big_endian, + pentry, lowaddr, highaddr, NULL, big_endian, elf_machine, clear_lsb, data_swab, as, load_rom, NULL); } @@ -448,8 +448,9 @@ int load_elf_ram_sym(const char *filename, uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, - uint64_t *lowaddr, uint64_t *highaddr, int big_endian, - int elf_machine, int clear_lsb, int data_swab, + uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pe_f= lags, + int big_endian, int elf_machine, + int clear_lsb, int data_swab, AddressSpace *as, bool load_rom, symbol_fn_t sym_cb) { int fd, data_order, target_data_order, must_swab, ret =3D ELF_LOAD_FAI= LED; @@ -490,13 +491,13 @@ int load_elf_ram_sym(const char *filename, if (e_ident[EI_CLASS] =3D=3D ELFCLASS64) { ret =3D load_elf64(filename, fd, elf_note_fn, translate_fn, translate_opaque, must_swab, - pentry, lowaddr, highaddr, elf_machine, clear_lsb, - data_swab, as, load_rom, sym_cb); + pentry, lowaddr, highaddr, pe_flags, elf_machine, + clear_lsb, data_swab, as, load_rom, sym_cb); } else { ret =3D load_elf32(filename, fd, elf_note_fn, translate_fn, translate_opaque, must_swab, - pentry, lowaddr, highaddr, elf_machine, clear_lsb, - data_swab, as, load_rom, sym_cb); + pentry, lowaddr, highaddr, pe_flags, elf_machine, + clear_lsb, data_swab, as, load_rom, sym_cb); } =20 fail: diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 027303d2a3..746ca1f795 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -119,7 +119,7 @@ target_ulong riscv_load_kernel(const char *kernel_filen= ame, symbol_fn_t sym_cb) uint64_t kernel_entry, kernel_high; =20 if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL, - &kernel_entry, NULL, &kernel_high, 0, + &kernel_entry, NULL, &kernel_high, NULL, 0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) { return kernel_entry; } diff --git a/hw/Kconfig b/hw/Kconfig index ecf491bf04..f80dff3b75 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -43,6 +43,7 @@ source watchdog/Kconfig # arch Kconfig source arm/Kconfig source alpha/Kconfig +source avr/Kconfig source cris/Kconfig source hppa/Kconfig source i386/Kconfig diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig new file mode 100644 index 0000000000..92aa1e6afb --- /dev/null +++ b/hw/avr/Kconfig @@ -0,0 +1,6 @@ +config AVR_SAMPLE + bool + select AVR_TIMER16 + select AVR_USART + select AVR_MASK + select UNIMP diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs new file mode 100644 index 0000000000..626b7064b3 --- /dev/null +++ b/hw/avr/Makefile.objs @@ -0,0 +1 @@ +obj-y +=3D sample.o --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376235; cv=none; d=zohomail.com; s=zohoarc; b=k0BLGo3RUSlxnVVN0WXaeG8e6xuxQjB9EA04RUztA6VBcAxLCsZDlPQlAjR6VX9zqb8isvXpyggzHfG9lyrW0uEDzsLG1O3YraUdIvYr4DARh8e9JZHdA9I7DYZwsaP3xQaAqtMH6xWrBJ3/CKFcnkM401ByzGLqKSLdUWaGxSs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376235; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=FlUSLH2uEvNEQP+btvkmtajQHzIok4pqbEhuKlNXr9w=; b=bAzcE4iC7U+g7Pb/Qpu/XJIuQsdctN2M0uZyV3Wbj7pdxuJEu708fYOMXUOqJD5Zy/3yRjmXuMQOuIduYHVVKhY8XDiA/xW4YhuAAdC0igL3fwWpoa07zgwL5b2uu53JsPFpu2yu4AeTb1NdgT8oPyATFLodBpyx3SN1us2X1g4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376235738189.44957947149135; Sat, 18 Jan 2020 11:37:15 -0800 (PST) Received: from localhost ([::1]:44246 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istuE-0007Wv-7Y for importer@patchew.org; Sat, 18 Jan 2020 14:37:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50056) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istew-0005tR-QJ for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isteu-0007NK-KL for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:26 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:43740) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isteu-0007Lo-E6 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:24 -0500 Received: by mail-wr1-x444.google.com with SMTP id d16so25737973wre.10 for ; Sat, 18 Jan 2020 11:21:23 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FlUSLH2uEvNEQP+btvkmtajQHzIok4pqbEhuKlNXr9w=; b=jw4bSh4m8O03y1OtPK65fJ5UEHgDvLgOZgnTGfZm+wfw+uvaVpM+EHIGL0jts+uVvW iEZgZGZpg5wgVXp1lM681bs5A3z7W5P4bilbhTpYKfrUvkWovgXvGP+6ci0qxXB7EaNN xDrwOhuY/aQH7MmVAoXXdIq5mDaSigzOLe7ZurUmJpMuovstQZKb4RUE2tcOh+ZkN466 Mi3TBlaXAWi1WKwO2xn1d/2awDCDuQfqvgyqYyNTLKbC4OeyZ/e/6kcWUnSvBNq8vqeQ YdvOhj5NodnEKhTlqsL8/QWh8VS2tlZ1EJE5HiDlZ52t8s3X3CmF/JKIHPXh0HMJ0rGm 7Vmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FlUSLH2uEvNEQP+btvkmtajQHzIok4pqbEhuKlNXr9w=; b=Kz8AGudIzYQTwybX+3OSsQGCSJdPLx2v9PHiw+AYu6qJt8PL/eVCottnKzQ6RM6Wus uqtk+abT9VRP1AfqbX3YVs69POd112sjBbtkoNVzG+a+Zzwl2OVAQO9h4ZB8V2Gh4LKc en82qS7n3lunYkiPnuk+EZ6XpwhTWMHflj/9bcgb4UZnm90QV93UncEYMwiUE4vL+3z9 E3mO9netp7VjojCWgOPR2eKZii+Tg6BEvcQ70jytwfSOCgW5xvrSJaFr/3cxDMT9+Tt+ upUiPRlWAiYICq2dUDdsChShDR4Pr+eySO1fA7b3jTR0zHatQ6XhhEhi4ov472mFVdez Q+9w== X-Gm-Message-State: APjAAAXaAJE7+A7HF2fUaODgG2Noxs4g2Eua+k0Kx9d4nHlGkzCSXo6s m3fQS6eOm+6tJv3VdVtqsJRZ9gfMHpOj4eO7 X-Google-Smtp-Source: APXvYqyeGRmZFg7VVTsMuE1v0eCCHgYhs7WVFV/jmJp5Jpx4KvX/XL8gQ/k8oGd8uZfrhYAxArNyOw== X-Received: by 2002:a5d:6ac3:: with SMTP id u3mr10276142wrw.25.1579375282213; Sat, 18 Jan 2020 11:21:22 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 15/21] target/avr: Add section about AVR into QEMU documentation Date: Sat, 18 Jan 2020 21:14:10 +0200 Message-Id: <20200118191416.19934-16-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 --- qemu-doc.texi | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/qemu-doc.texi b/qemu-doc.texi index 39f950471f..515aacfae9 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -1741,6 +1741,7 @@ differences are mentioned in the following sections. * Microblaze System emulator:: * SH4 System emulator:: * Xtensa System emulator:: +* AVR System emulator:: @end menu =20 @node PowerPC System emulator @@ -2514,6 +2515,56 @@ so should only be used with trusted guest OS. =20 @c man end =20 +@node AVR System emulator +@section AVR System emulator +@cindex system emulation (AVR) + +Use the executable @file{qemu-system-avr} to emulates a AVR 8 bit based ma= chine having one for the following cores: avr1, avr2, avr25, avr3, avr31, a= vr35, avr4, avr5, avr51, avr6, avrtiny, xmega2, xmega3, xmega4, xmega5, xme= ga6 and xmega7. + +As for now it does not support any real MCUs. However, it does support a "= sample" board for educational and testing purposes. This "sample" board hos= ts USART & 16 bit timer devices and it's enought to run FreeRTOS based appl= icaton (like this @url{https://github.com/seharris/qemu-avr-tests/blob/mast= er/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf,,demo}) + +Following are examples of possible usages, assuming program.elf is compile= d for AVR cpu +@itemize + +@item Continious non interrupted execution +@example +qemu-system-avr -kernel program.elf +@end example + +@item Continious non interrupted execution with serial output into telnet = window +@example +qemu-system-avr -kernel program.elf -serial tcp::5678,server,nowait -nogra= phic +@end example +and then in another shell +@example +telent localhost 5678 +@end example + +@item Continious non interrupted execution with serial output into stdout +@example +qemu-system-avr -kernel program.elf -serial stdio +@end example + +@item Debugging wit GDB debugger +@example +qemu-system-avr -kernel program.elf -s -S +@end example +and then in another shell +@example +avr-gdb program.elf +@end example +and then within GDB shell +@example +target remote :1234 +@end example + +@item Print out executed instructions +@example +qemu-system-avr -kernel program.elf -d in_asm +@end example + +@end itemize + @node QEMU User space emulator @chapter QEMU User space emulator =20 --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376381; cv=none; d=zohomail.com; s=zohoarc; b=guOyLRY7rWle+a1kNRCxgq1b1BMnpdUpPaJuT1/LI3NVBnjEXQcSDQafbZCebT57RSSJz7j/DdBr20lDgrB+TmxzK28J92Q93lqXEhIwfQowv+781t02J6VJGWghQe+/KISsIyYSWC7oNvI7N7ohzRdlTka5rDq0d8rMYTGu9PM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376381; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=l4PtJ+6gxg/BxzIeZHoQ3Q5QweHN3HiWGMyl0XkFQB8=; b=H2+wcLFwoH4hQ4SNRPGUqb0xlW08yXQB2RnF2hQ16Si3zFXB63seMs1XWf0CITu6/1Ba+0lIYDbaMeYSzlL1RNn7SlqyvJYqPmle4iDOyZZlY35KmwLNbMYjue7QZHmZ9sz3udrQONliwme/p2+uuQD7eTDi9+sGZxjzZs05v+w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376381630205.49526913802686; Sat, 18 Jan 2020 11:39:41 -0800 (PST) Received: from localhost ([::1]:44282 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istwa-00024f-3F for importer@patchew.org; Sat, 18 Jan 2020 14:39:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50067) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istez-0005xS-9C for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istey-0007QC-1C for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:29 -0500 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:43229) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istex-0007PT-RT for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:27 -0500 Received: by mail-wr1-x42e.google.com with SMTP id d16so25738044wre.10 for ; Sat, 18 Jan 2020 11:21:27 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=l4PtJ+6gxg/BxzIeZHoQ3Q5QweHN3HiWGMyl0XkFQB8=; b=HlxaMx2BU2cdprxLrMujI+DRTYLY9IPX0pdZWCRrCYaZxqT0Ot/Wqwx5oaIZmqLB8+ 2I51lTwcAGqaAgdll1Yl4wP0LYjP7rzKn9FsFhpOvRk39GjTC/LorZY/ugzEVhbhaJi0 6dQZKd3poOHS5Xd4l06tdiRtRFOC0YNJBWhUe296eYL58KCZw2czpopsPMXmlE9zpqQm Q14lIMXjOGJdUhytdbM8ejchL+z9x8C9/W3PXyJOxDhtFPwRQuh5OtQSkB0eUx/6AGKe +Gk6QVlJ71dYcyehI0p0WRTSaJRS2hVh7lFfF7jdwKlmS1laQx05F2NcDrdm4hjvKZ3/ tpEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l4PtJ+6gxg/BxzIeZHoQ3Q5QweHN3HiWGMyl0XkFQB8=; b=r7Rktagvq8Y0WMocl2sYzkT0YO/hoLp67LeiIK4v41vi8lI52b7C+JQWBCz5TVgfbY SDixuFlc08VHB0i1I+sYCC/swl5Z2wE5oY/rczoK6viKB0uVCmFb4BS2j7MWtphc3lPE WUEvvtvi4smbOpe0vk6ltxzALe1WetxagDCZVCM+NX8JzjlQa+HN9fXVvK2Ma6/9X9c7 gVW3/BMdlmROoa6MaDMAWgtpQHRytoxyoLoA2RPr8hBDBqk0m1e+6myhWsC3CS5feMpG 5DFw/11kAe5ZO2cwzfu3Zl0JlzvJpB3R9xI2B0sKlyCq87Dl3R05A0eh0WPWuclucAbF mTFg== X-Gm-Message-State: APjAAAWVEiIkAu3TwIoOnAI3hoSwiR+jR6qD/69eN21iuENF33XBXShD UJgO8RND8FhASXo/KZzVUnufc4a88CdvSq2D X-Google-Smtp-Source: APXvYqzLNbU+4QuQVVV4la/Hmj9Bi5Ul3d/HndimJEeWyGgsSDMkqoQWPUrPdMm7CN8IaNXQUv/2mA== X-Received: by 2002:adf:e74f:: with SMTP id c15mr9699491wrn.274.1579375286521; Sat, 18 Jan 2020 11:21:26 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 16/21] target/avr: Register AVR support with the rest of QEMU Date: Sat, 18 Jan 2020 21:14:11 +0200 Message-Id: <20200118191416.19934-17-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42e X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Add AVR related definitions into QEMU Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Aleksandar Markovic include/disas/dis-asm.h Tested-by: Philippe Mathieu-Daud=C3=A9 --- qapi/machine.json | 3 ++- include/disas/dis-asm.h | 19 +++++++++++++++++++ include/sysemu/arch_init.h | 1 + arch_init.c | 2 ++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/qapi/machine.json b/qapi/machine.json index b3d30bc816..f2dc385167 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -21,11 +21,12 @@ # is true even for "qemu-system-x86_64". # # ppcemb: dropped in 3.1 +# avr: since 5.0 # # Since: 3.0 ## { 'enum' : 'SysEmuTarget', - 'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32', + 'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 'lm= 32', 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc', 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4', diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h index e9c7dd8eb4..79bbc8b498 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h @@ -211,6 +211,25 @@ enum bfd_architecture #define bfd_mach_m32r 0 /* backwards compatibility */ bfd_arch_mn10200, /* Matsushita MN10200 */ bfd_arch_mn10300, /* Matsushita MN10300 */ + bfd_arch_avr, /* Atmel AVR microcontrollers. */ +#define bfd_mach_avr1 1 +#define bfd_mach_avr2 2 +#define bfd_mach_avr25 25 +#define bfd_mach_avr3 3 +#define bfd_mach_avr31 31 +#define bfd_mach_avr35 35 +#define bfd_mach_avr4 4 +#define bfd_mach_avr5 5 +#define bfd_mach_avr51 51 +#define bfd_mach_avr6 6 +#define bfd_mach_avrtiny 100 +#define bfd_mach_avrxmega1 101 +#define bfd_mach_avrxmega2 102 +#define bfd_mach_avrxmega3 103 +#define bfd_mach_avrxmega4 104 +#define bfd_mach_avrxmega5 105 +#define bfd_mach_avrxmega6 106 +#define bfd_mach_avrxmega7 107 bfd_arch_cris, /* Axis CRIS */ #define bfd_mach_cris_v0_v10 255 #define bfd_mach_cris_v32 32 diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index 62c6fe4cf1..893df26ce2 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -24,6 +24,7 @@ enum { QEMU_ARCH_NIOS2 =3D (1 << 17), QEMU_ARCH_HPPA =3D (1 << 18), QEMU_ARCH_RISCV =3D (1 << 19), + QEMU_ARCH_AVR =3D (1 << 20), }; =20 extern const uint32_t arch_type; diff --git a/arch_init.c b/arch_init.c index 705d0b94ad..6a741165b2 100644 --- a/arch_init.c +++ b/arch_init.c @@ -89,6 +89,8 @@ int graphic_depth =3D 32; #define QEMU_ARCH QEMU_ARCH_UNICORE32 #elif defined(TARGET_XTENSA) #define QEMU_ARCH QEMU_ARCH_XTENSA +#elif defined(TARGET_AVR) +#define QEMU_ARCH QEMU_ARCH_AVR #endif =20 const uint32_t arch_type =3D QEMU_ARCH; --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376121; cv=none; d=zohomail.com; s=zohoarc; b=Mf+EcwT2TrYpheoi7ICBFoUaCLFY+ucRnSTfuncjm8Tv+T4diVYNc/IzSQS8mg6zwJplAFqlQe1NX6IECzp11U92pVFXUp18wO8D6dxsC/cuHbYzs0qh2RKsylpj9dPoU07BqmUvh19Z+OA5vHp1NSsdU5KDmb+ZFM28jXSXl5E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376121; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=eSJ5RiGA8vwSibEvx3Rd4fHMW4NWqPux5e84DlCysSk=; b=DSryvuzpNCQgp0W8dOzzf+B/suArHh1sA1bYppzst8Q3YqQm6qvAnK3pYOaaQ2OcvHlCPnIPlJ6U2+FVujbOLAibNwfaoMmK/nv3agNh+ZuXCIF6xzmcg3PUakS6P9zpzF/s/4/00DvSiFOU3YMXdtgI/4AcRtbSYYrBGP3bJbQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376121003581.2775586110637; Sat, 18 Jan 2020 11:35:21 -0800 (PST) Received: from localhost ([::1]:44220 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istsN-0005jm-FY for importer@patchew.org; Sat, 18 Jan 2020 14:35:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50097) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istfF-0006Eo-OR for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istfE-0007eB-Oz for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:45 -0500 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:40768) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istfD-0007cQ-Lo for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:44 -0500 Received: by mail-wr1-x433.google.com with SMTP id c14so25719812wrn.7 for ; Sat, 18 Jan 2020 11:21:43 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eSJ5RiGA8vwSibEvx3Rd4fHMW4NWqPux5e84DlCysSk=; b=W0DBqm5aNDmJIK5mu20lZ8JlSoEzsZQsZpQER1dYnw/ys+TULDdxPiu9m7xlL79oyX k1yajYgT0+WSb2Me8WWg7dIwtHt+mPNw3kmkmF5EXWGV4Sp0TtnwQPF7cPv5xEvA3imF Ze0WgNTjg9JePXndgX+OtMSLrSWP46BdY4fyYC9icOG82slb5l9dxqRqTxzYm1en6UEs 8tVYOGRzgPtt5gnqejq5OvYROplC0D1JTQ+apvxrDofde5QVwavx8jsG3xxoVBwfFQNo /kmKbSn/QSfSVwRlfgVy/UsioWc+mNupksarGiZJSTeSpGVUtmYh1wT2Nne9fri3ZLnH bJsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eSJ5RiGA8vwSibEvx3Rd4fHMW4NWqPux5e84DlCysSk=; b=VHR1kKKXskx+hQgDoe83F9quvgLWhH0+YxCWVU0bl0i1re7XUQ3C2KqRyjvMjDbFYu bTWlql6Yf/BOa5m7t9aZeVXqM8r0Q7kPnNAtYH9Baf0z6jtI9xrUNyZSmwBxqf39jpCM 4/3Tn+vd2FjOJxVhEprIVogtB7GQi9/pSsdUGsG+VWwh7rciZYXuWYDszF6LwDAnarzU GGcxyc1aYvUJPVz47BekdoYtyO6tN045kAymAUg9fiaXONnCQ+/snTHIzLQTn66j9y4j 6Jjb/MbXFuQ+MLcEmSPH/S50wNUo2/3K+Ijd+dCJrv5oPHUlxnOCLn/B9La+UBAFmfyo rliA== X-Gm-Message-State: APjAAAWUFGgzNfGhN7BrYnpEnAlbGILZdeCV19VIJOgw3jwUwLJq5ePf BCuFIY7lCXXktAyiA6vNIQT9WZfpotTA5CyR X-Google-Smtp-Source: APXvYqxO5dG8HE06ekjtP7x6HLVPJ9GeCpbre2x2yQj20TiMBHhdxz8g/3haKQEUfZERCuFs6w0WhQ== X-Received: by 2002:a5d:6692:: with SMTP id l18mr9481341wru.382.1579375302226; Sat, 18 Jan 2020 11:21:42 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 17/21] target/avr: Add machine none test Date: Sat, 18 Jan 2020 21:14:12 +0200 Message-Id: <20200118191416.19934-18-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::433 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Aleksandar Markovic Tested-by: Philippe Mathieu-Daud=C3=A9 --- tests/qtest/machine-none-test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-tes= t.c index 5953d31755..3e5c74e73e 100644 --- a/tests/qtest/machine-none-test.c +++ b/tests/qtest/machine-none-test.c @@ -27,6 +27,7 @@ static struct arch2cpu cpus_map[] =3D { /* tested targets list */ { "arm", "cortex-a15" }, { "aarch64", "cortex-a57" }, + { "avr", "avr6-avr-cpu" }, { "x86_64", "qemu64,apic-id=3D0" }, { "i386", "qemu32,apic-id=3D0" }, { "alpha", "ev67" }, --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376393; cv=none; d=zohomail.com; s=zohoarc; b=h1y0TLAveTfBu6UYI68QCsA0iiGa2gwqcKy745iI7HjUvPfA5uL7Pby+GhjwZs4/+Fu0TqyTH1O4H4vNeYlySKnGWlvTZEuM3gvmt6W1XqQsHQoQSZop13HUTn8CnBEcvZoomNQoIYuE2/HSrKzoxnYuKZ1z4C05BhMYei8ollU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376393; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=OYxzhX6CrN3trG1tXILsFerazq8eN+loUJM/YFYVzmM=; b=MwghqknK/XY1Ief+l7JXnq220qAN3YwhwEeAPlh1FKUAp7HoTay8Qe+EQ3NtKq39QYR1brcsKL2KI/yTAUjwKRafws8aCqjBhzXOEHyllpprOzY1NfEQJaA6RrzIkXcPGFCAwc350bOgfwbXVNXPPtzb7U26A+5ybRi2zoIMotg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376393770208.73671781983535; Sat, 18 Jan 2020 11:39:53 -0800 (PST) Received: from localhost ([::1]:44296 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istwm-0002S4-Lb for importer@patchew.org; Sat, 18 Jan 2020 14:39:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50113) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istfP-0006Tq-Ra for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istfO-0007m0-DI for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:55 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:45507) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istfN-0007l3-QF for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:53 -0500 Received: by mail-wr1-x441.google.com with SMTP id j42so25688146wrj.12 for ; Sat, 18 Jan 2020 11:21:53 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OYxzhX6CrN3trG1tXILsFerazq8eN+loUJM/YFYVzmM=; b=KVOipJrjQl5TChaCRq391GAiBQ8TD/BhFHgPYpzbBpRqFL/kkvChUXWjVEvSBlXR0g MUonVZIkRlLN2MOF6ZwAVlhrZtugkcnSoQVTerVgL6d3HM73TPfQlVZ+5vnetTLGLSOc bBoXi1pzs0jsxLg/lO3fD4V8qjeN2Be0ZHXGdoWz938TKrlh9sjFz2xLpMxvqCncpKZw Yw4mVVpp9jazohcnnDF6n9wiRr6rmCr+8RlmnnjglTHlWK6h/CWkaHEgeTzD2jz+w71L dJFT2LysgI6LuATnLMdaPZdQPlFC0cON4CwAzjnweJhYy6P078mfex0IJFRGCL0S0c+C lCwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OYxzhX6CrN3trG1tXILsFerazq8eN+loUJM/YFYVzmM=; b=YFPCIRIuTs9pAFpyF+qKp8pWrVJ8CD8eM3/Vf/TQBD99iNgF7r1gB9azlMURL5AtUi ytYGkHZQwBKOdzw9A5mbHgaMMugev6M1s9w/bYGpv2PoGoi9/gBDdRYvWFRrX9wnhTOP 2HNwg/DH27VPvfODYUIaTrGIabczZadrtcdXr9InZjQTpBkKgGUREykB1guX2nWCO9iD D6czb1VbLj1w62k7tmFW02aUAhBraM0rQyG3AOnFqEUcZK3PP61h7q7AK+JLOkD3ZQeb bfj+b9FMphmz2yh2U26ZvOP9kOJGgYqTPk3ZtKpQlY/VTr43adDt4Ww/taaLqGn87ZCL MEeQ== X-Gm-Message-State: APjAAAU51hDMk3nSsRO3vqaLn8g5Cj6B4ywKwGSlH/NKH9mtBP/s2/05 mB4CICremqYNYymhNMQEaOhrG/Wj4cDvsUT7 X-Google-Smtp-Source: APXvYqzUNimMhDxmDcqBwbnLP5oKE4XR6BFMtYiZLx+D9MabmPr9JQd7AiX+06kkRQQ4j1g+MB+P4g== X-Received: by 2002:adf:fd91:: with SMTP id d17mr10364807wrr.340.1579375312602; Sat, 18 Jan 2020 11:21:52 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 18/21] target/avr: Update build system Date: Sat, 18 Jan 2020 21:14:13 +0200 Message-Id: <20200118191416.19934-19-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Make AVR support buildable Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Aleksandar Markovic Tested-by: Philippe Mathieu-Daud=C3=A9 --- configure | 7 +++++++ default-configs/avr-softmmu.mak | 5 +++++ target/avr/Makefile.objs | 34 +++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 default-configs/avr-softmmu.mak create mode 100644 target/avr/Makefile.objs diff --git a/configure b/configure index 557e4382ea..94e79ca634 100755 --- a/configure +++ b/configure @@ -7612,6 +7612,10 @@ case "$target_name" in mttcg=3D"yes" gdb_xml_files=3D"aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp= .xml arm-vfp3.xml arm-neon.xml" ;; + avr) + gdb_xml_files=3D"avr-cpu.xml" + target_compiler=3D$cross_cc_avr + ;; cris) ;; hppa) @@ -7831,6 +7835,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do disas_config "ARM_A64" fi ;; + avr) + disas_config "AVR" + ;; cris) disas_config "CRIS" ;; diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.= mak new file mode 100644 index 0000000000..d1e1c28118 --- /dev/null +++ b/default-configs/avr-softmmu.mak @@ -0,0 +1,5 @@ +# Default configuration for avr-softmmu + +# Boards: +# +CONFIG_AVR_SAMPLE=3Dy diff --git a/target/avr/Makefile.objs b/target/avr/Makefile.objs new file mode 100644 index 0000000000..7523e0c6e2 --- /dev/null +++ b/target/avr/Makefile.objs @@ -0,0 +1,34 @@ +# +# QEMU AVR CPU +# +# Copyright (c) 2019 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 +# +# + +DECODETREE =3D $(SRC_PATH)/scripts/decodetree.py +decode-y =3D $(SRC_PATH)/target/avr/insn.decode + +target/avr/decode_insn.inc.c: $(decode-y) $(DECODETREE) + $(call quiet-command, \ + $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn --insnwidth 16 $<, \ + "GEN", $(TARGET_DIR)$@) + +target/avr/translate.o: target/avr/decode_insn.inc.c + +obj-y +=3D translate.o cpu.o helper.o +obj-y +=3D gdbstub.o +obj-y +=3D disas.o +obj-$(CONFIG_SOFTMMU) +=3D machine.o --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376488; cv=none; d=zohomail.com; s=zohoarc; b=RJkP8b5YERb+UqxliJqzqz438/9J8H7f3fxw9WPXvLH5osRMhmrVRegkXEwNIkf44UTwbG8ZUPTFP3y9VmaHEvVyR4Pz0lebm7yp4ObHamdAo2sy75st1qZWhjAiqPmnucP4pk4ONJOfqEbPLMhPlu20b34ss6KffwhBU6p+3a8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376488; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=z/uYPTbZi5GeID8IkJbTa8iPY1aSdd1sKIGwyUQSAnE=; b=GaveM6Ez4rMkq4hlS2FhdPTnO4AvOc4728/Vs0kpVL53onRyqJkcGQk0EP66KzFZHvxmeJyrZt4AG2KblHc7v/93UK1VOqiZrah1pYG5DvqvsfmOHE0j6TcA+IjmUVhjc3fSw1uA1tnngEj3lVS9hIuOCBChRoxX7F5cSNirN+g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376488562285.18476910031416; Sat, 18 Jan 2020 11:41:28 -0800 (PST) Received: from localhost ([::1]:44334 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istyJ-0004QS-Cz for importer@patchew.org; Sat, 18 Jan 2020 14:41:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50124) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istfR-0006W6-H5 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istfP-0007nU-QR for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:56 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:36243) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istfP-0007ma-A3 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:55 -0500 Received: by mail-wr1-x444.google.com with SMTP id z3so25753233wru.3 for ; Sat, 18 Jan 2020 11:21:55 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=z/uYPTbZi5GeID8IkJbTa8iPY1aSdd1sKIGwyUQSAnE=; b=pLtg9OI0lVjqSq7iaDvQQe47SmB+6oJY2DQ/rL3EO9m9UDjTEiUe+kZymj0n2AvWxd zmChXbuWqu7AjN0Ee5RvOeJCnFqG7ngM2t0zHraIZBygzP6SBEdLB7wJRZumetNZbvG8 ep3BIQGHdHqw4tOSW3bQWt224R19Hmvj9YtA+9Uu4Vs48clq+MwP8wSyaYHf4sSQA1oI 2qLqEtpKER0AjMEQNnj8tELR3FKuMwe1fYl4gLIRX6LXNhdzr5kyqdXP7tlE3I7XLzJ7 aW316RQyQeGVV/KbPHcoAiPYiFltDPXnIx7R4rUQwC0y17m4NXWlOZL4r2Eu2iygVnpV 7x+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=z/uYPTbZi5GeID8IkJbTa8iPY1aSdd1sKIGwyUQSAnE=; b=OTYlTbA1gzWyafj2Gc0PLA1WprPxF5srMrVutIjY3pqpCALtdBnSm8xLZ7e5z2WayF rCOiuSTnYZubRHD68DU3J3lZVn9ZyI3cXFz+ZwA9XLEO6obllmzOh5EENcfu62ie+G12 JBL76J+PIUD0/AMr0HLEaahUcNrhP/gpwSQ0Ck79loPiRh2b3BwEfUbS1DWUXh0j3n/C iCxR6zfNJZ05/BlCr0OVYPzRgbp8HGw9XH9lQOMYSGrQpz9+yNnmJcN1Qr85cc0KwdlC eqhvHDHVD5X2OESCdocPshpGnXvIVstvkFsLNn82YQ4KaqOnzc0wgw3MAbnCCaPktXXO yj4g== X-Gm-Message-State: APjAAAVgum7Q7wMTgPzhdOmIcTNr4xz3uGF17Vx0toKFpRBTta00JaWn MSWJNiFbW1rISdbnx6M26J8l8MUrjh85p7AW X-Google-Smtp-Source: APXvYqwlLaBa+vf9SfbKr2Ze4Ee4eVU4w/56rxfTcu10qUT/usYzuc1USHaRepmire0l4cm+yx/1BA== X-Received: by 2002:adf:b605:: with SMTP id f5mr9385028wre.383.1579375314144; Sat, 18 Jan 2020 11:21:54 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 19/21] target/avr: Add boot serial test Date: Sat, 18 Jan 2020 21:14:14 +0200 Message-Id: <20200118191416.19934-20-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Print out 'T' through serial port Signed-off-by: Michael Rolnik Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 Acked-by: Thomas Huth tests/Makefile.include Tested-by: Philippe Mathieu-Daud=C3=A9 --- tests/qtest/boot-serial-test.c | 10 ++++++++++ tests/qtest/Makefile.include | 2 ++ 2 files changed, 12 insertions(+) diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c index 05c7f44457..e556f09db8 100644 --- a/tests/qtest/boot-serial-test.c +++ b/tests/qtest/boot-serial-test.c @@ -16,6 +16,15 @@ #include "qemu/osdep.h" #include "libqtest.h" =20 +static const uint8_t bios_avr[] =3D { + 0x88, 0xe0, /* ldi r24, 0x08 */ + 0x80, 0x93, 0xc1, 0x00, /* sts 0x00C1, r24 ; Enable tx */ + 0x86, 0xe0, /* ldi r24, 0x06 */ + 0x80, 0x93, 0xc2, 0x00, /* sts 0x00C2, r24 ; Set the data bits to 8 */ + 0x84, 0xe5, /* ldi r24, 0x54 */ + 0x80, 0x93, 0xc6, 0x00, /* sts 0x00C6, r24 ; Output 'T' */ +}; + static const uint8_t kernel_mcf5208[] =3D { 0x41, 0xf9, 0xfc, 0x06, 0x00, 0x00, /* lea 0xfc060000,%a0 */ 0x10, 0x3c, 0x00, 0x54, /* move.b #'T',%d0 */ @@ -103,6 +112,7 @@ typedef struct testdef { =20 static testdef_t tests[] =3D { { "alpha", "clipper", "", "PCI:" }, + { "avr", "sample", "", "T", sizeof(bios_avr), NULL, bios_avr }, { "ppc", "ppce500", "", "U-Boot" }, { "ppc", "40p", "-vga none -boot d", "Trying cd:," }, { "ppc", "g3beige", "", "PowerPC,750" }, diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include index e6bb4ab28c..4817b6320f 100644 --- a/tests/qtest/Makefile.include +++ b/tests/qtest/Makefile.include @@ -65,6 +65,8 @@ check-qtest-i386-y +=3D numa-test =20 check-qtest-x86_64-y +=3D $(check-qtest-i386-y) =20 +check-qtest-avr-y +=3D boot-serial-test + check-qtest-alpha-y +=3D boot-serial-test check-qtest-alpha-$(CONFIG_VGA) +=3D display-vga-test =20 --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376305; cv=none; d=zohomail.com; s=zohoarc; b=CCqbltNRR+RgyS4FWmu+yr/tPXTZdrz5ZZ5Oa5+bobKUiDzPul3xqG+KMFTHvYDxNQTlrtmY4BYIfmZbNgKDwgaUgnwOShXBpEDYB3LDet0KxZxuX9XYoGPz68L6EK06RhmG5gKrxiIZ9B55LrCVrg5hb50j/uPVUHi6DhKTF0A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376305; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=a8XNKbJukO9kBpqm/Qv2mq3ysWrme/1jTK6NG2Oci+Q=; b=OVjKrclTHepmK1TxcyxZKT/4mEyemWKUTkyJn1LW6sLDmCYB/Rp60jiUWBUczrwJ/+fHMuvy8/g83Khd3uFX5Rn/vzM+Ui5x6bPveYizQbt4IqT5Ldq/tUSIf5wUy3YzBLaOWlWRU7uSstIdXsNydMmssJ2AnNUXKkXFKXaR6dY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376305389503.6867085264555; Sat, 18 Jan 2020 11:38:25 -0800 (PST) Received: from localhost ([::1]:44252 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istvL-00007a-SM for importer@patchew.org; Sat, 18 Jan 2020 14:38:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50140) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istfT-0006ZN-E6 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:22:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istfS-0007pq-3K for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:59 -0500 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:32999) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istfR-0007o5-Ks for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:57 -0500 Received: by mail-wm1-x32d.google.com with SMTP id d139so11830268wmd.0 for ; Sat, 18 Jan 2020 11:21:56 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=a8XNKbJukO9kBpqm/Qv2mq3ysWrme/1jTK6NG2Oci+Q=; b=gOmET2CppQ1/rlmfs6eRDVEv6ZAzXS52ZH8blnrKXX6gVt3bTMPtYss9iWS/XeCIuz lzDqDz5d2Z+ksTm51vDDt2+5KjeXBKbeogEJA3hTuXdZJ7B3fg7Veo1FPoWNqyWHadlX D+skK8AiYAeJZMLZ06pCon4KHMSkiWrx7xLmoeE2Bd5cakjdAtGR8aRaS84AvgsrW1y/ toGxWYjBjgT71+XRypAGguL27L8ev+6+PPn2QA15VRDkSIvGzREbTA2sykyYlq71/dqb 6/Mv56ilrwMHXqPXpj9SKB2nhtxShAsDZOG7bZPdMPhEFeMTmoWL2QllO6dGlOuOKy61 HV5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=a8XNKbJukO9kBpqm/Qv2mq3ysWrme/1jTK6NG2Oci+Q=; b=feLS58YotA0zQlRSbxk3N4atNHPdcHcG/CgoN7AXOBdj1aafGXq37AonoaTj4Ykvv1 iCdBfIPAOdER1/yiqVtB9mCrrTPHmkNDYIuCLMifBWVvqZU0kPPObDKi+VN41bE6MaKo eUuZj9UJ6k7pWkmHEisW10G67cJmXgcvKBozoQeaROubPDMSFQxohhtB1CczybcfHiN6 Jv1PuTQDlD6BpvuzGlNhs/1Eim8wNr6zhsLdeylivYfI/BQHRC9hSdwF/SPDpfguzhHD R5GxjqYPfaE+Xc+GGeEbhz3Bb+mqDPg1x2dVRcCqG03jfXj8TazVYSfhhhVJQbKnogj3 Fx8w== X-Gm-Message-State: APjAAAVPp1uSl9vTEviZH8m9HqqJ6ZYsOcxdAaKCWdLqcDf0/ua0hFYd pBoEhxvZTwPww/HoGLZuKf8OK4AB496R13My X-Google-Smtp-Source: APXvYqx3EWGaC5clsNKqRt4t6ffUJT7Z1W0sKYL077lh2kkIVBwFL9gwuBzP6QSSH4znkty/dDPrDQ== X-Received: by 2002:a05:600c:1009:: with SMTP id c9mr10842129wmc.162.1579375315721; Sat, 18 Jan 2020 11:21:55 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 20/21] target/avr: Add Avocado test Date: Sat, 18 Jan 2020 21:14:15 +0200 Message-Id: <20200118191416.19934-21-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32d X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) The test is based on https://github.com/seharris/qemu-avr-tests/tree/master/free-rtos/Demo demo which. If working correctly, prints 'ABCDEFGHIJKLMNOPQRSTUVWX' out. it also demostrates that timer and IRQ are working Signed-off-by: Michael Rolnik Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 Acked-by: Thomas Huth Tested-by: Philippe Mathieu-Daud=C3=A9 --- tests/acceptance/machine_avr6.py | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tests/acceptance/machine_avr6.py diff --git a/tests/acceptance/machine_avr6.py b/tests/acceptance/machine_av= r6.py new file mode 100644 index 0000000000..43501b26a3 --- /dev/null +++ b/tests/acceptance/machine_avr6.py @@ -0,0 +1,53 @@ +# +# QEMU AVR +# +# Copyright (c) 2019 Michael Rolnik +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import time + +from avocado_qemu import Test + +class AVR6Machine(Test): + timeout =3D 5 + + def test_freertos(self): + """ + :avocado: tags=3Darch:avr + :avocado: tags=3Dmachine:sample + """ + """ + https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/De= mo/AVR_ATMega2560_GCC/demo.elf + constantly prints out 'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRS= TUVWX' + """ + rom_url =3D 'https://github.com/seharris/qemu-avr-tests' + rom_sha1=3D '36c3e67b8755dcf37e06af6730ef5d477b8ed16d' + rom_url +=3D '/raw/' + rom_url +=3D rom_sha1 + rom_url +=3D '/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf' + rom_hash =3D '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4' + rom_path =3D self.fetch_asset(rom_url, asset_hash=3Drom_hash) + + self.vm.set_machine('sample') + self.vm.add_args('-bios', rom_path) + self.vm.add_args('-nographic') + self.vm.launch() + + time.sleep(2) + self.vm.shutdown() + + self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX', + self.vm.get_log()) --=20 2.17.2 (Apple Git-113) From nobody Mon May 6 02:44:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1579376548; cv=none; d=zohomail.com; s=zohoarc; b=Sv8TsDqLVCNCuYJ16Ff2oTtVyrnsoCz+IF2itB4nip7YNkpeW6WWbA5WHKtnZCXga9h5S6NdMAyyOKw/VikbpM1ODuzlakTn3MqkP2zF0MiC0ZdcsqpvzZTDNR7ayRFa5rBr5TaBxQf7FQAVdFVwmnjQFsb+XH4MWO6ELqZdnnk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579376548; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=FO1i9jNY/IqNN8OXTh2PCvWPjBwlbpfjWssHyPnRa18=; b=b7A5uCvtAnNinRxUls7WmuP03mE6G41UBiUjhx0dp1sCwq/jXRvKq/YU2ZvA8TAoz5eT6p4z0x7X7uom7wTjVtTD6lcYcsyOF8Zz+TOOh5BcusII9Cit6/vVdVAWWMS+W5NCmlbaAD8bd+t9pIz1RhQUvvTrfPklGdochEnf3cU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1579376548907293.68174877469676; Sat, 18 Jan 2020 11:42:28 -0800 (PST) Received: from localhost ([::1]:44340 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istzH-0005u8-OO for importer@patchew.org; Sat, 18 Jan 2020 14:42:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50145) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istfU-0006ae-82 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:22:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istfS-0007r8-Jk for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:22:00 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:37610) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istfS-0007pM-BK for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:21:58 -0500 Received: by mail-wm1-x342.google.com with SMTP id f129so10819862wmf.2 for ; Sat, 18 Jan 2020 11:21:58 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.21.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:21:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FO1i9jNY/IqNN8OXTh2PCvWPjBwlbpfjWssHyPnRa18=; b=qImf7M5EQ99XuQFvror3XsENnmzxKFdvcFOuudghmB2Fbla4po5PelnVkSOKQWqTbM CqmofMnjVS27k2Hq3Xqxe73CymoPiQ9sCkA9AnxKaHLsg2V124VYLEwsvEyOO6GzCwmY obQoajy017nSUZzeAirKu5+kZnxupQBHOnZqzIJPJmiYiES984LptKgnlJFZnEGy9b4N SJxUifh3uYztQOu517bLDP3SfM2+ANRiHTgcH5XWweFUiH8+WtrHj6HPFutI9/IEsyYF oY3TWtbXqyQ+Mrehf24xpJj5TeuISfus0zJGc6+wok4OXXN0qU3qxC4DhT+2nDK7sU1U x6LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FO1i9jNY/IqNN8OXTh2PCvWPjBwlbpfjWssHyPnRa18=; b=pefLSq9xmwNSkxRmQanckfDonnhE+XR6dLAbcojSF6bjRxQHxzxNyOxhwbC/zfRHl/ VQCMPNfs8m0rMelE0EjTSns+FsKo1j0zhMl9RNvksshzB9c5Pzc0MyYQm70zQVXZMp+H s6AfxZ1/4Y6HNQNDuUP2zj5h3DucxG8QJTNSU4v5P4O8+ALnvNpPZuMVNF5VVuZEtEbA oP89zdVWKfm4pCwREqOaMhcnReaYrichxpNwzl/DAIeLor7Hj6v0kVqjWfWDZYsAKEif FA0fLFjJBnxn4NIcMYEV7zgoif201VnlkB6GzWTF1fZS4zLkGx+R7IFgCTq/zatTz4oE OG6w== X-Gm-Message-State: APjAAAVHYHiq9pwxc56IGDUj7RLOQj2bgzU/odtGcDre1snIisWb+avW YYUFlT0IrvcBNjic5l8ann/5ws4VC4i965U0 X-Google-Smtp-Source: APXvYqwab2NOFlD0egcRdDcdMt2BJXDVFFyoRJY0UCiIpsXfu3DoEqD7zW89351X0RxWGK4NajO/tg== X-Received: by 2002:a1c:48c1:: with SMTP id v184mr10808505wma.5.1579375317202; Sat, 18 Jan 2020 11:21:57 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 21/21] target/avr: Update MAINTAINERS file Date: Sat, 18 Jan 2020 21:14:16 +0200 Message-Id: <20200118191416.19934-22-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::342 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Include AVR maintaners in MAINTAINERS file Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daud=C3=A9 --- MAINTAINERS | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 55d3642e6c..c70d77b1ae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -163,6 +163,15 @@ S: Maintained F: hw/arm/smmu* F: include/hw/arm/smmu* =20 +AVR TCG CPUs +M: Michael Rolnik +R: Sarah Harris +S: Maintained +F: target/avr/ +F: tests/acceptance/machine_avr6.py +F: default-configs/avr-softmmu.mak +F: gdb-xml/avr-cpu.xml + CRIS TCG CPUs M: Edgar E. Iglesias S: Maintained @@ -481,6 +490,18 @@ F: hw/*/allwinner* F: include/hw/*/allwinner* F: hw/arm/cubieboard.c =20 +AVR Machines +M: Michael Rolnik +R: Sarah Harris +S: Maintained +F: hw/avr/ +F: hw/char/avr_usart.c +F: include/hw/char/avr_usart.h +F: hw/timer/avr_timer16.c +F: include/hw/timer/avr_timer16.h +F: hw/misc/avr_mask.c +F: include/hw/misc/avr_mask.h + ARM PrimeCell and CMSDK devices M: Peter Maydell L: qemu-arm@nongnu.org --=20 2.17.2 (Apple Git-113)