Annotation of qemu/target-sparc/int64_helper.c, revision 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.