Annotation of qemu/target-sparc/int64_helper.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Sparc64 interrupt helpers
                      3:  *
                      4:  *  Copyright (c) 2003-2005 Fabrice Bellard
                      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 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 <http://www.gnu.org/licenses/>.
                     18:  */
                     19: 
                     20: #include "cpu.h"
                     21: #include "helper.h"
                     22: #include "trace.h"
                     23: 
                     24: //#define DEBUG_PCALL
                     25: 
                     26: #ifdef DEBUG_PCALL
                     27: static const char * const excp_names[0x80] = {
                     28:     [TT_TFAULT] = "Instruction Access Fault",
                     29:     [TT_TMISS] = "Instruction Access MMU Miss",
                     30:     [TT_CODE_ACCESS] = "Instruction Access Error",
                     31:     [TT_ILL_INSN] = "Illegal Instruction",
                     32:     [TT_PRIV_INSN] = "Privileged Instruction",
                     33:     [TT_NFPU_INSN] = "FPU Disabled",
                     34:     [TT_FP_EXCP] = "FPU Exception",
                     35:     [TT_TOVF] = "Tag Overflow",
                     36:     [TT_CLRWIN] = "Clean Windows",
                     37:     [TT_DIV_ZERO] = "Division By Zero",
                     38:     [TT_DFAULT] = "Data Access Fault",
                     39:     [TT_DMISS] = "Data Access MMU Miss",
                     40:     [TT_DATA_ACCESS] = "Data Access Error",
                     41:     [TT_DPROT] = "Data Protection Error",
                     42:     [TT_UNALIGNED] = "Unaligned Memory Access",
                     43:     [TT_PRIV_ACT] = "Privileged Action",
                     44:     [TT_EXTINT | 0x1] = "External Interrupt 1",
                     45:     [TT_EXTINT | 0x2] = "External Interrupt 2",
                     46:     [TT_EXTINT | 0x3] = "External Interrupt 3",
                     47:     [TT_EXTINT | 0x4] = "External Interrupt 4",
                     48:     [TT_EXTINT | 0x5] = "External Interrupt 5",
                     49:     [TT_EXTINT | 0x6] = "External Interrupt 6",
                     50:     [TT_EXTINT | 0x7] = "External Interrupt 7",
                     51:     [TT_EXTINT | 0x8] = "External Interrupt 8",
                     52:     [TT_EXTINT | 0x9] = "External Interrupt 9",
                     53:     [TT_EXTINT | 0xa] = "External Interrupt 10",
                     54:     [TT_EXTINT | 0xb] = "External Interrupt 11",
                     55:     [TT_EXTINT | 0xc] = "External Interrupt 12",
                     56:     [TT_EXTINT | 0xd] = "External Interrupt 13",
                     57:     [TT_EXTINT | 0xe] = "External Interrupt 14",
                     58:     [TT_EXTINT | 0xf] = "External Interrupt 15",
                     59: };
                     60: #endif
                     61: 
                     62: void do_interrupt(CPUState *env)
                     63: {
                     64:     int intno = env->exception_index;
                     65:     trap_state *tsptr;
                     66: 
                     67: #ifdef DEBUG_PCALL
                     68:     if (qemu_loglevel_mask(CPU_LOG_INT)) {
                     69:         static int count;
                     70:         const char *name;
                     71: 
                     72:         if (intno < 0 || intno >= 0x180) {
                     73:             name = "Unknown";
                     74:         } else if (intno >= 0x100) {
                     75:             name = "Trap Instruction";
                     76:         } else if (intno >= 0xc0) {
                     77:             name = "Window Fill";
                     78:         } else if (intno >= 0x80) {
                     79:             name = "Window Spill";
                     80:         } else {
                     81:             name = excp_names[intno];
                     82:             if (!name) {
                     83:                 name = "Unknown";
                     84:             }
                     85:         }
                     86: 
                     87:         qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
                     88:                 " SP=%016" PRIx64 "\n",
                     89:                 count, name, intno,
                     90:                 env->pc,
                     91:                 env->npc, env->regwptr[6]);
                     92:         log_cpu_state(env, 0);
                     93: #if 0
                     94:         {
                     95:             int i;
                     96:             uint8_t *ptr;
                     97: 
                     98:             qemu_log("       code=");
                     99:             ptr = (uint8_t *)env->pc;
                    100:             for (i = 0; i < 16; i++) {
                    101:                 qemu_log(" %02x", ldub(ptr + i));
                    102:             }
                    103:             qemu_log("\n");
                    104:         }
                    105: #endif
                    106:         count++;
                    107:     }
                    108: #endif
                    109: #if !defined(CONFIG_USER_ONLY)
                    110:     if (env->tl >= env->maxtl) {
                    111:         cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
                    112:                   " Error state", env->exception_index, env->tl, env->maxtl);
                    113:         return;
                    114:     }
                    115: #endif
                    116:     if (env->tl < env->maxtl - 1) {
                    117:         env->tl++;
                    118:     } else {
                    119:         env->pstate |= PS_RED;
                    120:         if (env->tl < env->maxtl) {
                    121:             env->tl++;
                    122:         }
                    123:     }
                    124:     tsptr = cpu_tsptr(env);
                    125: 
                    126:     tsptr->tstate = (cpu_get_ccr(env) << 32) |
                    127:         ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
                    128:         cpu_get_cwp64(env);
                    129:     tsptr->tpc = env->pc;
                    130:     tsptr->tnpc = env->npc;
                    131:     tsptr->tt = intno;
                    132: 
                    133:     switch (intno) {
                    134:     case TT_IVEC:
                    135:         cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
                    136:         break;
                    137:     case TT_TFAULT:
                    138:     case TT_DFAULT:
                    139:     case TT_TMISS ... TT_TMISS + 3:
                    140:     case TT_DMISS ... TT_DMISS + 3:
                    141:     case TT_DPROT ... TT_DPROT + 3:
                    142:         cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
                    143:         break;
                    144:     default:
                    145:         cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
                    146:         break;
                    147:     }
                    148: 
                    149:     if (intno == TT_CLRWIN) {
                    150:         cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
                    151:     } else if ((intno & 0x1c0) == TT_SPILL) {
                    152:         cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
                    153:     } else if ((intno & 0x1c0) == TT_FILL) {
                    154:         cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
                    155:     }
                    156:     env->tbr &= ~0x7fffULL;
                    157:     env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
                    158:     env->pc = env->tbr;
                    159:     env->npc = env->pc + 4;
                    160:     env->exception_index = -1;
                    161: }
                    162: 
                    163: trap_state *cpu_tsptr(CPUState* env)
                    164: {
                    165:     return &env->ts[env->tl & MAXTL_MASK];
                    166: }
                    167: 
                    168: static bool do_modify_softint(CPUState *env, uint32_t value)
                    169: {
                    170:     if (env->softint != value) {
                    171:         env->softint = value;
                    172: #if !defined(CONFIG_USER_ONLY)
                    173:         if (cpu_interrupts_enabled(env)) {
                    174:             cpu_check_irqs(env);
                    175:         }
                    176: #endif
                    177:         return true;
                    178:     }
                    179:     return false;
                    180: }
                    181: 
                    182: void helper_set_softint(CPUState *env, uint64_t value)
                    183: {
                    184:     if (do_modify_softint(env, env->softint | (uint32_t)value)) {
                    185:         trace_int_helper_set_softint(env->softint);
                    186:     }
                    187: }
                    188: 
                    189: void helper_clear_softint(CPUState *env, uint64_t value)
                    190: {
                    191:     if (do_modify_softint(env, env->softint & (uint32_t)~value)) {
                    192:         trace_int_helper_clear_softint(env->softint);
                    193:     }
                    194: }
                    195: 
                    196: void helper_write_softint(CPUState *env, uint64_t value)
                    197: {
                    198:     if (do_modify_softint(env, (uint32_t)value)) {
                    199:         trace_int_helper_write_softint(env->softint);
                    200:     }
                    201: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.