qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

syndrome.h (10484B)


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