qemu/target/arm/syndrome.h
<<
>>
Prefs
   1/*
   2 * QEMU ARM CPU -- syndrome functions and types
   3 *
   4 * Copyright (c) 2014 Linaro Ltd
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version 2
   9 * of the License, or (at your option) any later version.
  10 *
  11 * This program 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
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, see
  18 * <http://www.gnu.org/licenses/gpl-2.0.html>
  19 *
  20 * This header defines functions, types, etc which need to be shared
  21 * between different source files within target/arm/ but which are
  22 * private to it and not required by the rest of QEMU.
  23 */
  24
  25#ifndef TARGET_ARM_SYNDROME_H
  26#define TARGET_ARM_SYNDROME_H
  27
  28/* Valid Syndrome Register EC field values */
  29enum arm_exception_class {
  30    EC_UNCATEGORIZED          = 0x00,
  31    EC_WFX_TRAP               = 0x01,
  32    EC_CP15RTTRAP             = 0x03,
  33    EC_CP15RRTTRAP            = 0x04,
  34    EC_CP14RTTRAP             = 0x05,
  35    EC_CP14DTTRAP             = 0x06,
  36    EC_ADVSIMDFPACCESSTRAP    = 0x07,
  37    EC_FPIDTRAP               = 0x08,
  38    EC_PACTRAP                = 0x09,
  39    EC_BXJTRAP                = 0x0a,
  40    EC_CP14RRTTRAP            = 0x0c,
  41    EC_BTITRAP                = 0x0d,
  42    EC_ILLEGALSTATE           = 0x0e,
  43    EC_AA32_SVC               = 0x11,
  44    EC_AA32_HVC               = 0x12,
  45    EC_AA32_SMC               = 0x13,
  46    EC_AA64_SVC               = 0x15,
  47    EC_AA64_HVC               = 0x16,
  48    EC_AA64_SMC               = 0x17,
  49    EC_SYSTEMREGISTERTRAP     = 0x18,
  50    EC_SVEACCESSTRAP          = 0x19,
  51    EC_INSNABORT              = 0x20,
  52    EC_INSNABORT_SAME_EL      = 0x21,
  53    EC_PCALIGNMENT            = 0x22,
  54    EC_DATAABORT              = 0x24,
  55    EC_DATAABORT_SAME_EL      = 0x25,
  56    EC_SPALIGNMENT            = 0x26,
  57    EC_AA32_FPTRAP            = 0x28,
  58    EC_AA64_FPTRAP            = 0x2c,
  59    EC_SERROR                 = 0x2f,
  60    EC_BREAKPOINT             = 0x30,
  61    EC_BREAKPOINT_SAME_EL     = 0x31,
  62    EC_SOFTWARESTEP           = 0x32,
  63    EC_SOFTWARESTEP_SAME_EL   = 0x33,
  64    EC_WATCHPOINT             = 0x34,
  65    EC_WATCHPOINT_SAME_EL     = 0x35,
  66    EC_AA32_BKPT              = 0x38,
  67    EC_VECTORCATCH            = 0x3a,
  68    EC_AA64_BKPT              = 0x3c,
  69};
  70
  71#define ARM_EL_EC_SHIFT 26
  72#define ARM_EL_IL_SHIFT 25
  73#define ARM_EL_ISV_SHIFT 24
  74#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
  75#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
  76
  77static inline uint32_t syn_get_ec(uint32_t syn)
  78{
  79    return syn >> ARM_EL_EC_SHIFT;
  80}
  81
  82/*
  83 * Utility functions for constructing various kinds of syndrome value.
  84 * Note that in general we follow the AArch64 syndrome values; in a
  85 * few cases the value in HSR for exceptions taken to AArch32 Hyp
  86 * mode differs slightly, and we fix this up when populating HSR in
  87 * arm_cpu_do_interrupt_aarch32_hyp().
  88 * The exception is FP/SIMD access traps -- these report extra information
  89 * when taking an exception to AArch32. For those we include the extra coproc
  90 * and TA fields, and mask them out when taking the exception to AArch64.
  91 */
  92static inline uint32_t syn_uncategorized(void)
  93{
  94    return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
  95}
  96
  97static inline uint32_t syn_aa64_svc(uint32_t imm16)
  98{
  99    return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 100}
 101
 102static inline uint32_t syn_aa64_hvc(uint32_t imm16)
 103{
 104    return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 105}
 106
 107static inline uint32_t syn_aa64_smc(uint32_t imm16)
 108{
 109    return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 110}
 111
 112static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
 113{
 114    return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
 115        | (is_16bit ? 0 : ARM_EL_IL);
 116}
 117
 118static inline uint32_t syn_aa32_hvc(uint32_t imm16)
 119{
 120    return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 121}
 122
 123static inline uint32_t syn_aa32_smc(void)
 124{
 125    return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
 126}
 127
 128static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
 129{
 130    return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 131}
 132
 133static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
 134{
 135    return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
 136        | (is_16bit ? 0 : ARM_EL_IL);
 137}
 138
 139static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
 140                                           int crn, int crm, int rt,
 141                                           int isread)
 142{
 143    return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
 144        | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
 145        | (crm << 1) | isread;
 146}
 147
 148static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
 149                                        int crn, int crm, int rt, int isread,
 150                                        bool is_16bit)
 151{
 152    return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
 153        | (is_16bit ? 0 : ARM_EL_IL)
 154        | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
 155        | (crn << 10) | (rt << 5) | (crm << 1) | isread;
 156}
 157
 158static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
 159                                        int crn, int crm, int rt, int isread,
 160                                        bool is_16bit)
 161{
 162    return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
 163        | (is_16bit ? 0 : ARM_EL_IL)
 164        | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
 165        | (crn << 10) | (rt << 5) | (crm << 1) | isread;
 166}
 167
 168static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
 169                                         int rt, int rt2, int isread,
 170                                         bool is_16bit)
 171{
 172    return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
 173        | (is_16bit ? 0 : ARM_EL_IL)
 174        | (cv << 24) | (cond << 20) | (opc1 << 16)
 175        | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
 176}
 177
 178static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
 179                                         int rt, int rt2, int isread,
 180                                         bool is_16bit)
 181{
 182    return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
 183        | (is_16bit ? 0 : ARM_EL_IL)
 184        | (cv << 24) | (cond << 20) | (opc1 << 16)
 185        | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
 186}
 187
 188static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
 189{
 190    /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 coproc == 0xa */
 191    return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
 192        | (is_16bit ? 0 : ARM_EL_IL)
 193        | (cv << 24) | (cond << 20) | 0xa;
 194}
 195
 196static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
 197{
 198    /* AArch32 SIMD trap: TA == 1 coproc == 0 */
 199    return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
 200        | (is_16bit ? 0 : ARM_EL_IL)
 201        | (cv << 24) | (cond << 20) | (1 << 5);
 202}
 203
 204static inline uint32_t syn_sve_access_trap(void)
 205{
 206    return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
 207}
 208
 209static inline uint32_t syn_pactrap(void)
 210{
 211    return EC_PACTRAP << ARM_EL_EC_SHIFT;
 212}
 213
 214static inline uint32_t syn_btitrap(int btype)
 215{
 216    return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
 217}
 218
 219static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
 220{
 221    return (EC_BXJTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL |
 222        (cv << 24) | (cond << 20) | rm;
 223}
 224
 225static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
 226{
 227    return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 228        | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
 229}
 230
 231static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
 232                                             int ea, int cm, int s1ptw,
 233                                             int wnr, int fsc)
 234{
 235    return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 236           | ARM_EL_IL
 237           | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
 238           | (wnr << 6) | fsc;
 239}
 240
 241static inline uint32_t syn_data_abort_with_iss(int same_el,
 242                                               int sas, int sse, int srt,
 243                                               int sf, int ar,
 244                                               int ea, int cm, int s1ptw,
 245                                               int wnr, int fsc,
 246                                               bool is_16bit)
 247{
 248    return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 249           | (is_16bit ? 0 : ARM_EL_IL)
 250           | ARM_EL_ISV | (sas << 22) | (sse << 21) | (srt << 16)
 251           | (sf << 15) | (ar << 14)
 252           | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
 253}
 254
 255static inline uint32_t syn_swstep(int same_el, int isv, int ex)
 256{
 257    return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 258        | ARM_EL_IL | (isv << 24) | (ex << 6) | 0x22;
 259}
 260
 261static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
 262{
 263    return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 264        | ARM_EL_IL | (cm << 8) | (wnr << 6) | 0x22;
 265}
 266
 267static inline uint32_t syn_breakpoint(int same_el)
 268{
 269    return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 270        | ARM_EL_IL | 0x22;
 271}
 272
 273static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
 274{
 275    return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) |
 276           (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) |
 277           (cv << 24) | (cond << 20) | ti;
 278}
 279
 280static inline uint32_t syn_illegalstate(void)
 281{
 282    return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
 283}
 284
 285#endif /* TARGET_ARM_SYNDROME_H */
 286