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_CP14RRTTRAP            = 0x0c,
  40    EC_BTITRAP                = 0x0d,
  41    EC_ILLEGALSTATE           = 0x0e,
  42    EC_AA32_SVC               = 0x11,
  43    EC_AA32_HVC               = 0x12,
  44    EC_AA32_SMC               = 0x13,
  45    EC_AA64_SVC               = 0x15,
  46    EC_AA64_HVC               = 0x16,
  47    EC_AA64_SMC               = 0x17,
  48    EC_SYSTEMREGISTERTRAP     = 0x18,
  49    EC_SVEACCESSTRAP          = 0x19,
  50    EC_INSNABORT              = 0x20,
  51    EC_INSNABORT_SAME_EL      = 0x21,
  52    EC_PCALIGNMENT            = 0x22,
  53    EC_DATAABORT              = 0x24,
  54    EC_DATAABORT_SAME_EL      = 0x25,
  55    EC_SPALIGNMENT            = 0x26,
  56    EC_AA32_FPTRAP            = 0x28,
  57    EC_AA64_FPTRAP            = 0x2c,
  58    EC_SERROR                 = 0x2f,
  59    EC_BREAKPOINT             = 0x30,
  60    EC_BREAKPOINT_SAME_EL     = 0x31,
  61    EC_SOFTWARESTEP           = 0x32,
  62    EC_SOFTWARESTEP_SAME_EL   = 0x33,
  63    EC_WATCHPOINT             = 0x34,
  64    EC_WATCHPOINT_SAME_EL     = 0x35,
  65    EC_AA32_BKPT              = 0x38,
  66    EC_VECTORCATCH            = 0x3a,
  67    EC_AA64_BKPT              = 0x3c,
  68};
  69
  70#define ARM_EL_EC_SHIFT 26
  71#define ARM_EL_IL_SHIFT 25
  72#define ARM_EL_ISV_SHIFT 24
  73#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
  74#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
  75
  76static inline uint32_t syn_get_ec(uint32_t syn)
  77{
  78    return syn >> ARM_EL_EC_SHIFT;
  79}
  80
  81/*
  82 * Utility functions for constructing various kinds of syndrome value.
  83 * Note that in general we follow the AArch64 syndrome values; in a
  84 * few cases the value in HSR for exceptions taken to AArch32 Hyp
  85 * mode differs slightly, and we fix this up when populating HSR in
  86 * arm_cpu_do_interrupt_aarch32_hyp().
  87 * The exception is FP/SIMD access traps -- these report extra information
  88 * when taking an exception to AArch32. For those we include the extra coproc
  89 * and TA fields, and mask them out when taking the exception to AArch64.
  90 */
  91static inline uint32_t syn_uncategorized(void)
  92{
  93    return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
  94}
  95
  96static inline uint32_t syn_aa64_svc(uint32_t imm16)
  97{
  98    return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
  99}
 100
 101static inline uint32_t syn_aa64_hvc(uint32_t imm16)
 102{
 103    return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 104}
 105
 106static inline uint32_t syn_aa64_smc(uint32_t imm16)
 107{
 108    return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 109}
 110
 111static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
 112{
 113    return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
 114        | (is_16bit ? 0 : ARM_EL_IL);
 115}
 116
 117static inline uint32_t syn_aa32_hvc(uint32_t imm16)
 118{
 119    return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 120}
 121
 122static inline uint32_t syn_aa32_smc(void)
 123{
 124    return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
 125}
 126
 127static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
 128{
 129    return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 130}
 131
 132static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
 133{
 134    return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
 135        | (is_16bit ? 0 : ARM_EL_IL);
 136}
 137
 138static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
 139                                           int crn, int crm, int rt,
 140                                           int isread)
 141{
 142    return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
 143        | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
 144        | (crm << 1) | isread;
 145}
 146
 147static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
 148                                        int crn, int crm, int rt, int isread,
 149                                        bool is_16bit)
 150{
 151    return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
 152        | (is_16bit ? 0 : ARM_EL_IL)
 153        | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
 154        | (crn << 10) | (rt << 5) | (crm << 1) | isread;
 155}
 156
 157static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
 158                                        int crn, int crm, int rt, int isread,
 159                                        bool is_16bit)
 160{
 161    return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
 162        | (is_16bit ? 0 : ARM_EL_IL)
 163        | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
 164        | (crn << 10) | (rt << 5) | (crm << 1) | isread;
 165}
 166
 167static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
 168                                         int rt, int rt2, int isread,
 169                                         bool is_16bit)
 170{
 171    return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
 172        | (is_16bit ? 0 : ARM_EL_IL)
 173        | (cv << 24) | (cond << 20) | (opc1 << 16)
 174        | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
 175}
 176
 177static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
 178                                         int rt, int rt2, int isread,
 179                                         bool is_16bit)
 180{
 181    return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
 182        | (is_16bit ? 0 : ARM_EL_IL)
 183        | (cv << 24) | (cond << 20) | (opc1 << 16)
 184        | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
 185}
 186
 187static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
 188{
 189    /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 coproc == 0xa */
 190    return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
 191        | (is_16bit ? 0 : ARM_EL_IL)
 192        | (cv << 24) | (cond << 20) | 0xa;
 193}
 194
 195static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
 196{
 197    /* AArch32 SIMD trap: TA == 1 coproc == 0 */
 198    return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
 199        | (is_16bit ? 0 : ARM_EL_IL)
 200        | (cv << 24) | (cond << 20) | (1 << 5);
 201}
 202
 203static inline uint32_t syn_sve_access_trap(void)
 204{
 205    return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
 206}
 207
 208static inline uint32_t syn_pactrap(void)
 209{
 210    return EC_PACTRAP << ARM_EL_EC_SHIFT;
 211}
 212
 213static inline uint32_t syn_btitrap(int btype)
 214{
 215    return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
 216}
 217
 218static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
 219{
 220    return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 221        | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
 222}
 223
 224static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
 225                                             int ea, int cm, int s1ptw,
 226                                             int wnr, int fsc)
 227{
 228    return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 229           | ARM_EL_IL
 230           | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
 231           | (wnr << 6) | fsc;
 232}
 233
 234static inline uint32_t syn_data_abort_with_iss(int same_el,
 235                                               int sas, int sse, int srt,
 236                                               int sf, int ar,
 237                                               int ea, int cm, int s1ptw,
 238                                               int wnr, int fsc,
 239                                               bool is_16bit)
 240{
 241    return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 242           | (is_16bit ? 0 : ARM_EL_IL)
 243           | ARM_EL_ISV | (sas << 22) | (sse << 21) | (srt << 16)
 244           | (sf << 15) | (ar << 14)
 245           | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
 246}
 247
 248static inline uint32_t syn_swstep(int same_el, int isv, int ex)
 249{
 250    return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 251        | ARM_EL_IL | (isv << 24) | (ex << 6) | 0x22;
 252}
 253
 254static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
 255{
 256    return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 257        | ARM_EL_IL | (cm << 8) | (wnr << 6) | 0x22;
 258}
 259
 260static inline uint32_t syn_breakpoint(int same_el)
 261{
 262    return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 263        | ARM_EL_IL | 0x22;
 264}
 265
 266static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
 267{
 268    return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) |
 269           (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) |
 270           (cv << 24) | (cond << 20) | ti;
 271}
 272
 273#endif /* TARGET_ARM_SYNDROME_H */
 274