qemu/target/avr/cpu.h
<<
>>
Prefs
   1/*
   2 * QEMU AVR CPU
   3 *
   4 * Copyright (c) 2016-2020 Michael Rolnik
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see
  18 * <http://www.gnu.org/licenses/lgpl-2.1.html>
  19 */
  20
  21#ifndef QEMU_AVR_CPU_H
  22#define QEMU_AVR_CPU_H
  23
  24#include "cpu-qom.h"
  25#include "exec/cpu-defs.h"
  26
  27#ifdef CONFIG_USER_ONLY
  28#error "AVR 8-bit does not support user mode"
  29#endif
  30
  31#define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU
  32#define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX)
  33#define CPU_RESOLVING_TYPE TYPE_AVR_CPU
  34
  35#define TCG_GUEST_DEFAULT_MO 0
  36
  37/*
  38 * AVR has two memory spaces, data & code.
  39 * e.g. both have 0 address
  40 * ST/LD instructions access data space
  41 * LPM/SPM and instruction fetching access code memory space
  42 */
  43#define MMU_CODE_IDX 0
  44#define MMU_DATA_IDX 1
  45
  46#define EXCP_RESET 1
  47#define EXCP_INT(n) (EXCP_RESET + (n) + 1)
  48
  49/* Number of CPU registers */
  50#define NUMBER_OF_CPU_REGISTERS 32
  51/* Number of IO registers accessible by ld/st/in/out */
  52#define NUMBER_OF_IO_REGISTERS 64
  53
  54/*
  55 * Offsets of AVR memory regions in host memory space.
  56 *
  57 * This is needed because the AVR has separate code and data address
  58 * spaces that both have start from zero but have to go somewhere in
  59 * host memory.
  60 *
  61 * It's also useful to know where some things are, like the IO registers.
  62 */
  63/* Flash program memory */
  64#define OFFSET_CODE 0x00000000
  65/* CPU registers, IO registers, and SRAM */
  66#define OFFSET_DATA 0x00800000
  67/* CPU registers specifically, these are mapped at the start of data */
  68#define OFFSET_CPU_REGISTERS OFFSET_DATA
  69/*
  70 * IO registers, including status register, stack pointer, and memory
  71 * mapped peripherals, mapped just after CPU registers
  72 */
  73#define OFFSET_IO_REGISTERS (OFFSET_DATA + NUMBER_OF_CPU_REGISTERS)
  74
  75typedef enum AVRFeature {
  76    AVR_FEATURE_SRAM,
  77
  78    AVR_FEATURE_1_BYTE_PC,
  79    AVR_FEATURE_2_BYTE_PC,
  80    AVR_FEATURE_3_BYTE_PC,
  81
  82    AVR_FEATURE_1_BYTE_SP,
  83    AVR_FEATURE_2_BYTE_SP,
  84
  85    AVR_FEATURE_BREAK,
  86    AVR_FEATURE_DES,
  87    AVR_FEATURE_RMW, /* Read Modify Write - XCH LAC LAS LAT */
  88
  89    AVR_FEATURE_EIJMP_EICALL,
  90    AVR_FEATURE_IJMP_ICALL,
  91    AVR_FEATURE_JMP_CALL,
  92
  93    AVR_FEATURE_ADIW_SBIW,
  94
  95    AVR_FEATURE_SPM,
  96    AVR_FEATURE_SPMX,
  97
  98    AVR_FEATURE_ELPMX,
  99    AVR_FEATURE_ELPM,
 100    AVR_FEATURE_LPMX,
 101    AVR_FEATURE_LPM,
 102
 103    AVR_FEATURE_MOVW,
 104    AVR_FEATURE_MUL,
 105    AVR_FEATURE_RAMPD,
 106    AVR_FEATURE_RAMPX,
 107    AVR_FEATURE_RAMPY,
 108    AVR_FEATURE_RAMPZ,
 109} AVRFeature;
 110
 111typedef struct CPUArchState {
 112    uint32_t pc_w; /* 0x003fffff up to 22 bits */
 113
 114    uint32_t sregC; /* 0x00000001 1 bit */
 115    uint32_t sregZ; /* 0x00000001 1 bit */
 116    uint32_t sregN; /* 0x00000001 1 bit */
 117    uint32_t sregV; /* 0x00000001 1 bit */
 118    uint32_t sregS; /* 0x00000001 1 bit */
 119    uint32_t sregH; /* 0x00000001 1 bit */
 120    uint32_t sregT; /* 0x00000001 1 bit */
 121    uint32_t sregI; /* 0x00000001 1 bit */
 122
 123    uint32_t rampD; /* 0x00ff0000 8 bits */
 124    uint32_t rampX; /* 0x00ff0000 8 bits */
 125    uint32_t rampY; /* 0x00ff0000 8 bits */
 126    uint32_t rampZ; /* 0x00ff0000 8 bits */
 127    uint32_t eind; /* 0x00ff0000 8 bits */
 128
 129    uint32_t r[NUMBER_OF_CPU_REGISTERS]; /* 8 bits each */
 130    uint32_t sp; /* 16 bits */
 131
 132    uint32_t skip; /* if set skip instruction */
 133
 134    uint64_t intsrc; /* interrupt sources */
 135    bool fullacc; /* CPU/MEM if true MEM only otherwise */
 136
 137    uint64_t features;
 138} CPUAVRState;
 139
 140/**
 141 *  AVRCPU:
 142 *  @env: #CPUAVRState
 143 *
 144 *  A AVR CPU.
 145 */
 146struct ArchCPU {
 147    /*< private >*/
 148    CPUState parent_obj;
 149    /*< public >*/
 150
 151    CPUNegativeOffsetState neg;
 152    CPUAVRState env;
 153};
 154
 155extern const struct VMStateDescription vms_avr_cpu;
 156
 157void avr_cpu_do_interrupt(CPUState *cpu);
 158bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 159hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 160int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 161int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 162int avr_print_insn(bfd_vma addr, disassemble_info *info);
 163vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr);
 164
 165static inline int avr_feature(CPUAVRState *env, AVRFeature feature)
 166{
 167    return (env->features & (1U << feature)) != 0;
 168}
 169
 170static inline void set_avr_feature(CPUAVRState *env, int feature)
 171{
 172    env->features |= (1U << feature);
 173}
 174
 175#define cpu_list avr_cpu_list
 176#define cpu_mmu_index avr_cpu_mmu_index
 177
 178static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch)
 179{
 180    return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX;
 181}
 182
 183void avr_cpu_tcg_init(void);
 184
 185void avr_cpu_list(void);
 186int cpu_avr_exec(CPUState *cpu);
 187
 188enum {
 189    TB_FLAGS_FULL_ACCESS = 1,
 190    TB_FLAGS_SKIP = 2,
 191};
 192
 193static inline void cpu_get_tb_cpu_state(CPUAVRState *env, target_ulong *pc,
 194                                        target_ulong *cs_base, uint32_t *pflags)
 195{
 196    uint32_t flags = 0;
 197
 198    *pc = env->pc_w * 2;
 199    *cs_base = 0;
 200
 201    if (env->fullacc) {
 202        flags |= TB_FLAGS_FULL_ACCESS;
 203    }
 204    if (env->skip) {
 205        flags |= TB_FLAGS_SKIP;
 206    }
 207
 208    *pflags = flags;
 209}
 210
 211static inline int cpu_interrupts_enabled(CPUAVRState *env)
 212{
 213    return env->sregI != 0;
 214}
 215
 216static inline uint8_t cpu_get_sreg(CPUAVRState *env)
 217{
 218    uint8_t sreg;
 219    sreg = (env->sregC) << 0
 220         | (env->sregZ) << 1
 221         | (env->sregN) << 2
 222         | (env->sregV) << 3
 223         | (env->sregS) << 4
 224         | (env->sregH) << 5
 225         | (env->sregT) << 6
 226         | (env->sregI) << 7;
 227    return sreg;
 228}
 229
 230static inline void cpu_set_sreg(CPUAVRState *env, uint8_t sreg)
 231{
 232    env->sregC = (sreg >> 0) & 0x01;
 233    env->sregZ = (sreg >> 1) & 0x01;
 234    env->sregN = (sreg >> 2) & 0x01;
 235    env->sregV = (sreg >> 3) & 0x01;
 236    env->sregS = (sreg >> 4) & 0x01;
 237    env->sregH = (sreg >> 5) & 0x01;
 238    env->sregT = (sreg >> 6) & 0x01;
 239    env->sregI = (sreg >> 7) & 0x01;
 240}
 241
 242bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 243                      MMUAccessType access_type, int mmu_idx,
 244                      bool probe, uintptr_t retaddr);
 245
 246#include "exec/cpu-all.h"
 247
 248#endif /* QEMU_AVR_CPU_H */
 249