14c9649a9Sj_mayer /* 24c9649a9Sj_mayer * Alpha emulation cpu helpers for qemu. 34c9649a9Sj_mayer * 44c9649a9Sj_mayer * Copyright (c) 2007 Jocelyn Mayer 54c9649a9Sj_mayer * 64c9649a9Sj_mayer * This library is free software; you can redistribute it and/or 74c9649a9Sj_mayer * modify it under the terms of the GNU Lesser General Public 84c9649a9Sj_mayer * License as published by the Free Software Foundation; either 94c9649a9Sj_mayer * version 2 of the License, or (at your option) any later version. 104c9649a9Sj_mayer * 114c9649a9Sj_mayer * This library is distributed in the hope that it will be useful, 124c9649a9Sj_mayer * but WITHOUT ANY WARRANTY; without even the implied warranty of 134c9649a9Sj_mayer * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 144c9649a9Sj_mayer * Lesser General Public License for more details. 154c9649a9Sj_mayer * 164c9649a9Sj_mayer * You should have received a copy of the GNU Lesser General Public 178167ee88SBlue Swirl * License along with this library; if not, see <http://www.gnu.org/licenses/>. 184c9649a9Sj_mayer */ 194c9649a9Sj_mayer 204c9649a9Sj_mayer #include <stdint.h> 214c9649a9Sj_mayer #include <stdlib.h> 224c9649a9Sj_mayer #include <stdio.h> 234c9649a9Sj_mayer 244c9649a9Sj_mayer #include "cpu.h" 254c9649a9Sj_mayer #include "exec-all.h" 26ba0e276dSRichard Henderson #include "softfloat.h" 27ba0e276dSRichard Henderson 28ba0e276dSRichard Henderson uint64_t cpu_alpha_load_fpcr (CPUState *env) 29ba0e276dSRichard Henderson { 308443effbSRichard Henderson uint64_t r = 0; 318443effbSRichard Henderson uint8_t t; 32ba0e276dSRichard Henderson 338443effbSRichard Henderson t = env->fpcr_exc_status; 348443effbSRichard Henderson if (t) { 358443effbSRichard Henderson r = FPCR_SUM; 368443effbSRichard Henderson if (t & float_flag_invalid) { 378443effbSRichard Henderson r |= FPCR_INV; 388443effbSRichard Henderson } 398443effbSRichard Henderson if (t & float_flag_divbyzero) { 408443effbSRichard Henderson r |= FPCR_DZE; 418443effbSRichard Henderson } 428443effbSRichard Henderson if (t & float_flag_overflow) { 438443effbSRichard Henderson r |= FPCR_OVF; 448443effbSRichard Henderson } 458443effbSRichard Henderson if (t & float_flag_underflow) { 468443effbSRichard Henderson r |= FPCR_UNF; 478443effbSRichard Henderson } 488443effbSRichard Henderson if (t & float_flag_inexact) { 498443effbSRichard Henderson r |= FPCR_INE; 508443effbSRichard Henderson } 518443effbSRichard Henderson } 52ba0e276dSRichard Henderson 538443effbSRichard Henderson t = env->fpcr_exc_mask; 548443effbSRichard Henderson if (t & float_flag_invalid) { 558443effbSRichard Henderson r |= FPCR_INVD; 568443effbSRichard Henderson } 578443effbSRichard Henderson if (t & float_flag_divbyzero) { 588443effbSRichard Henderson r |= FPCR_DZED; 598443effbSRichard Henderson } 608443effbSRichard Henderson if (t & float_flag_overflow) { 618443effbSRichard Henderson r |= FPCR_OVFD; 628443effbSRichard Henderson } 638443effbSRichard Henderson if (t & float_flag_underflow) { 648443effbSRichard Henderson r |= FPCR_UNFD; 658443effbSRichard Henderson } 668443effbSRichard Henderson if (t & float_flag_inexact) { 678443effbSRichard Henderson r |= FPCR_INED; 688443effbSRichard Henderson } 69ba0e276dSRichard Henderson 708443effbSRichard Henderson switch (env->fpcr_dyn_round) { 71ba0e276dSRichard Henderson case float_round_nearest_even: 728443effbSRichard Henderson r |= FPCR_DYN_NORMAL; 73ba0e276dSRichard Henderson break; 74ba0e276dSRichard Henderson case float_round_down: 758443effbSRichard Henderson r |= FPCR_DYN_MINUS; 76ba0e276dSRichard Henderson break; 77ba0e276dSRichard Henderson case float_round_up: 788443effbSRichard Henderson r |= FPCR_DYN_PLUS; 79ba0e276dSRichard Henderson break; 80ba0e276dSRichard Henderson case float_round_to_zero: 818443effbSRichard Henderson r |= FPCR_DYN_CHOPPED; 82ba0e276dSRichard Henderson break; 83ba0e276dSRichard Henderson } 848443effbSRichard Henderson 858443effbSRichard Henderson if (env->fpcr_dnz) { 868443effbSRichard Henderson r |= FPCR_DNZ; 878443effbSRichard Henderson } 888443effbSRichard Henderson if (env->fpcr_dnod) { 898443effbSRichard Henderson r |= FPCR_DNOD; 908443effbSRichard Henderson } 918443effbSRichard Henderson if (env->fpcr_undz) { 928443effbSRichard Henderson r |= FPCR_UNDZ; 938443effbSRichard Henderson } 948443effbSRichard Henderson 958443effbSRichard Henderson return r; 96ba0e276dSRichard Henderson } 97ba0e276dSRichard Henderson 98ba0e276dSRichard Henderson void cpu_alpha_store_fpcr (CPUState *env, uint64_t val) 99ba0e276dSRichard Henderson { 1008443effbSRichard Henderson uint8_t t; 101ba0e276dSRichard Henderson 1028443effbSRichard Henderson t = 0; 1038443effbSRichard Henderson if (val & FPCR_INV) { 1048443effbSRichard Henderson t |= float_flag_invalid; 1058443effbSRichard Henderson } 1068443effbSRichard Henderson if (val & FPCR_DZE) { 1078443effbSRichard Henderson t |= float_flag_divbyzero; 1088443effbSRichard Henderson } 1098443effbSRichard Henderson if (val & FPCR_OVF) { 1108443effbSRichard Henderson t |= float_flag_overflow; 1118443effbSRichard Henderson } 1128443effbSRichard Henderson if (val & FPCR_UNF) { 1138443effbSRichard Henderson t |= float_flag_underflow; 1148443effbSRichard Henderson } 1158443effbSRichard Henderson if (val & FPCR_INE) { 1168443effbSRichard Henderson t |= float_flag_inexact; 1178443effbSRichard Henderson } 1188443effbSRichard Henderson env->fpcr_exc_status = t; 119ba0e276dSRichard Henderson 1208443effbSRichard Henderson t = 0; 1218443effbSRichard Henderson if (val & FPCR_INVD) { 1228443effbSRichard Henderson t |= float_flag_invalid; 1238443effbSRichard Henderson } 1248443effbSRichard Henderson if (val & FPCR_DZED) { 1258443effbSRichard Henderson t |= float_flag_divbyzero; 1268443effbSRichard Henderson } 1278443effbSRichard Henderson if (val & FPCR_OVFD) { 1288443effbSRichard Henderson t |= float_flag_overflow; 1298443effbSRichard Henderson } 1308443effbSRichard Henderson if (val & FPCR_UNFD) { 1318443effbSRichard Henderson t |= float_flag_underflow; 1328443effbSRichard Henderson } 1338443effbSRichard Henderson if (val & FPCR_INED) { 1348443effbSRichard Henderson t |= float_flag_inexact; 1358443effbSRichard Henderson } 1368443effbSRichard Henderson env->fpcr_exc_mask = t; 137ba0e276dSRichard Henderson 1388443effbSRichard Henderson switch (val & FPCR_DYN_MASK) { 1398443effbSRichard Henderson case FPCR_DYN_CHOPPED: 1408443effbSRichard Henderson t = float_round_to_zero; 141ba0e276dSRichard Henderson break; 1428443effbSRichard Henderson case FPCR_DYN_MINUS: 1438443effbSRichard Henderson t = float_round_down; 144ba0e276dSRichard Henderson break; 1458443effbSRichard Henderson case FPCR_DYN_NORMAL: 1468443effbSRichard Henderson t = float_round_nearest_even; 147ba0e276dSRichard Henderson break; 1488443effbSRichard Henderson case FPCR_DYN_PLUS: 1498443effbSRichard Henderson t = float_round_up; 150ba0e276dSRichard Henderson break; 151ba0e276dSRichard Henderson } 1528443effbSRichard Henderson env->fpcr_dyn_round = t; 1538443effbSRichard Henderson 1548443effbSRichard Henderson env->fpcr_flush_to_zero 1558443effbSRichard Henderson = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD); 1568443effbSRichard Henderson 1578443effbSRichard Henderson env->fpcr_dnz = (val & FPCR_DNZ) != 0; 1588443effbSRichard Henderson env->fpcr_dnod = (val & FPCR_DNOD) != 0; 1598443effbSRichard Henderson env->fpcr_undz = (val & FPCR_UNDZ) != 0; 160ba0e276dSRichard Henderson } 1614c9649a9Sj_mayer 1624c9649a9Sj_mayer #if defined(CONFIG_USER_ONLY) 1634c9649a9Sj_mayer 1644c9649a9Sj_mayer int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 1656ebbf390Sj_mayer int mmu_idx, int is_softmmu) 1664c9649a9Sj_mayer { 1674c9649a9Sj_mayer if (rw == 2) 1684c9649a9Sj_mayer env->exception_index = EXCP_ITB_MISS; 1694c9649a9Sj_mayer else 1704c9649a9Sj_mayer env->exception_index = EXCP_DFAULT; 1714c9649a9Sj_mayer env->ipr[IPR_EXC_ADDR] = address; 1724c9649a9Sj_mayer 1734c9649a9Sj_mayer return 1; 1744c9649a9Sj_mayer } 1754c9649a9Sj_mayer 1764c9649a9Sj_mayer void do_interrupt (CPUState *env) 1774c9649a9Sj_mayer { 1784c9649a9Sj_mayer env->exception_index = -1; 1794c9649a9Sj_mayer } 1804c9649a9Sj_mayer 1814c9649a9Sj_mayer #else 1824c9649a9Sj_mayer 183c227f099SAnthony Liguori target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) 1844c9649a9Sj_mayer { 1854c9649a9Sj_mayer return -1; 1864c9649a9Sj_mayer } 1874c9649a9Sj_mayer 1884c9649a9Sj_mayer int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 1896ebbf390Sj_mayer int mmu_idx, int is_softmmu) 1904c9649a9Sj_mayer { 1914c9649a9Sj_mayer uint32_t opc; 1924c9649a9Sj_mayer 1934c9649a9Sj_mayer if (rw == 2) { 1944c9649a9Sj_mayer /* Instruction translation buffer miss */ 1954c9649a9Sj_mayer env->exception_index = EXCP_ITB_MISS; 1964c9649a9Sj_mayer } else { 1974c9649a9Sj_mayer if (env->ipr[IPR_EXC_ADDR] & 1) 1984c9649a9Sj_mayer env->exception_index = EXCP_DTB_MISS_PAL; 1994c9649a9Sj_mayer else 2004c9649a9Sj_mayer env->exception_index = EXCP_DTB_MISS_NATIVE; 2014c9649a9Sj_mayer opc = (ldl_code(env->pc) >> 21) << 4; 2024c9649a9Sj_mayer if (rw) { 2034c9649a9Sj_mayer opc |= 0x9; 2044c9649a9Sj_mayer } else { 2054c9649a9Sj_mayer opc |= 0x4; 2064c9649a9Sj_mayer } 2074c9649a9Sj_mayer env->ipr[IPR_MM_STAT] = opc; 2084c9649a9Sj_mayer } 2094c9649a9Sj_mayer 2104c9649a9Sj_mayer return 1; 2114c9649a9Sj_mayer } 2124c9649a9Sj_mayer 2134c9649a9Sj_mayer int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp) 2144c9649a9Sj_mayer { 2154c9649a9Sj_mayer uint64_t hwpcb; 2164c9649a9Sj_mayer int ret = 0; 2174c9649a9Sj_mayer 2184c9649a9Sj_mayer hwpcb = env->ipr[IPR_PCBB]; 2194c9649a9Sj_mayer switch (iprn) { 2204c9649a9Sj_mayer case IPR_ASN: 2214c9649a9Sj_mayer if (env->features & FEATURE_ASN) 2224c9649a9Sj_mayer *valp = env->ipr[IPR_ASN]; 2234c9649a9Sj_mayer else 2244c9649a9Sj_mayer *valp = 0; 2254c9649a9Sj_mayer break; 2264c9649a9Sj_mayer case IPR_ASTEN: 2274c9649a9Sj_mayer *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60; 2284c9649a9Sj_mayer break; 2294c9649a9Sj_mayer case IPR_ASTSR: 2304c9649a9Sj_mayer *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60; 2314c9649a9Sj_mayer break; 2324c9649a9Sj_mayer case IPR_DATFX: 2334c9649a9Sj_mayer /* Write only */ 2344c9649a9Sj_mayer ret = -1; 2354c9649a9Sj_mayer break; 2364c9649a9Sj_mayer case IPR_ESP: 2374c9649a9Sj_mayer if (env->features & FEATURE_SPS) 2384c9649a9Sj_mayer *valp = env->ipr[IPR_ESP]; 2394c9649a9Sj_mayer else 2404c9649a9Sj_mayer *valp = ldq_raw(hwpcb + 8); 2414c9649a9Sj_mayer break; 2424c9649a9Sj_mayer case IPR_FEN: 2434c9649a9Sj_mayer *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63; 2444c9649a9Sj_mayer break; 2454c9649a9Sj_mayer case IPR_IPIR: 2464c9649a9Sj_mayer /* Write-only */ 2474c9649a9Sj_mayer ret = -1; 2484c9649a9Sj_mayer break; 2494c9649a9Sj_mayer case IPR_IPL: 2504c9649a9Sj_mayer *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59; 2514c9649a9Sj_mayer break; 2524c9649a9Sj_mayer case IPR_KSP: 2534c9649a9Sj_mayer if (!(env->ipr[IPR_EXC_ADDR] & 1)) { 2544c9649a9Sj_mayer ret = -1; 2554c9649a9Sj_mayer } else { 2564c9649a9Sj_mayer if (env->features & FEATURE_SPS) 2574c9649a9Sj_mayer *valp = env->ipr[IPR_KSP]; 2584c9649a9Sj_mayer else 2594c9649a9Sj_mayer *valp = ldq_raw(hwpcb + 0); 2604c9649a9Sj_mayer } 2614c9649a9Sj_mayer break; 2624c9649a9Sj_mayer case IPR_MCES: 2634c9649a9Sj_mayer *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59; 2644c9649a9Sj_mayer break; 2654c9649a9Sj_mayer case IPR_PERFMON: 2664c9649a9Sj_mayer /* Implementation specific */ 2674c9649a9Sj_mayer *valp = 0; 2684c9649a9Sj_mayer break; 2694c9649a9Sj_mayer case IPR_PCBB: 2704c9649a9Sj_mayer *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16; 2714c9649a9Sj_mayer break; 2724c9649a9Sj_mayer case IPR_PRBR: 2734c9649a9Sj_mayer *valp = env->ipr[IPR_PRBR]; 2744c9649a9Sj_mayer break; 2754c9649a9Sj_mayer case IPR_PTBR: 2764c9649a9Sj_mayer *valp = env->ipr[IPR_PTBR]; 2774c9649a9Sj_mayer break; 2784c9649a9Sj_mayer case IPR_SCBB: 2794c9649a9Sj_mayer *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]); 2804c9649a9Sj_mayer break; 2814c9649a9Sj_mayer case IPR_SIRR: 2824c9649a9Sj_mayer /* Write-only */ 2834c9649a9Sj_mayer ret = -1; 2844c9649a9Sj_mayer break; 2854c9649a9Sj_mayer case IPR_SISR: 2864c9649a9Sj_mayer *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]); 2874c9649a9Sj_mayer case IPR_SSP: 2884c9649a9Sj_mayer if (env->features & FEATURE_SPS) 2894c9649a9Sj_mayer *valp = env->ipr[IPR_SSP]; 2904c9649a9Sj_mayer else 2914c9649a9Sj_mayer *valp = ldq_raw(hwpcb + 16); 2924c9649a9Sj_mayer break; 2934c9649a9Sj_mayer case IPR_SYSPTBR: 2944c9649a9Sj_mayer if (env->features & FEATURE_VIRBND) 2954c9649a9Sj_mayer *valp = env->ipr[IPR_SYSPTBR]; 2964c9649a9Sj_mayer else 2974c9649a9Sj_mayer ret = -1; 2984c9649a9Sj_mayer break; 2994c9649a9Sj_mayer case IPR_TBCHK: 3004c9649a9Sj_mayer if ((env->features & FEATURE_TBCHK)) { 3014c9649a9Sj_mayer /* XXX: TODO */ 3024c9649a9Sj_mayer *valp = 0; 3034c9649a9Sj_mayer ret = -1; 3044c9649a9Sj_mayer } else { 3054c9649a9Sj_mayer ret = -1; 3064c9649a9Sj_mayer } 3074c9649a9Sj_mayer break; 3084c9649a9Sj_mayer case IPR_TBIA: 3094c9649a9Sj_mayer /* Write-only */ 3104c9649a9Sj_mayer ret = -1; 3114c9649a9Sj_mayer break; 3124c9649a9Sj_mayer case IPR_TBIAP: 3134c9649a9Sj_mayer /* Write-only */ 3144c9649a9Sj_mayer ret = -1; 3154c9649a9Sj_mayer break; 3164c9649a9Sj_mayer case IPR_TBIS: 3174c9649a9Sj_mayer /* Write-only */ 3184c9649a9Sj_mayer ret = -1; 3194c9649a9Sj_mayer break; 3204c9649a9Sj_mayer case IPR_TBISD: 3214c9649a9Sj_mayer /* Write-only */ 3224c9649a9Sj_mayer ret = -1; 3234c9649a9Sj_mayer break; 3244c9649a9Sj_mayer case IPR_TBISI: 3254c9649a9Sj_mayer /* Write-only */ 3264c9649a9Sj_mayer ret = -1; 3274c9649a9Sj_mayer break; 3284c9649a9Sj_mayer case IPR_USP: 3294c9649a9Sj_mayer if (env->features & FEATURE_SPS) 3304c9649a9Sj_mayer *valp = env->ipr[IPR_USP]; 3314c9649a9Sj_mayer else 3324c9649a9Sj_mayer *valp = ldq_raw(hwpcb + 24); 3334c9649a9Sj_mayer break; 3344c9649a9Sj_mayer case IPR_VIRBND: 3354c9649a9Sj_mayer if (env->features & FEATURE_VIRBND) 3364c9649a9Sj_mayer *valp = env->ipr[IPR_VIRBND]; 3374c9649a9Sj_mayer else 3384c9649a9Sj_mayer ret = -1; 3394c9649a9Sj_mayer break; 3404c9649a9Sj_mayer case IPR_VPTB: 3414c9649a9Sj_mayer *valp = env->ipr[IPR_VPTB]; 3424c9649a9Sj_mayer break; 3434c9649a9Sj_mayer case IPR_WHAMI: 3444c9649a9Sj_mayer *valp = env->ipr[IPR_WHAMI]; 3454c9649a9Sj_mayer break; 3464c9649a9Sj_mayer default: 3474c9649a9Sj_mayer /* Invalid */ 3484c9649a9Sj_mayer ret = -1; 3494c9649a9Sj_mayer break; 3504c9649a9Sj_mayer } 3514c9649a9Sj_mayer 3524c9649a9Sj_mayer return ret; 3534c9649a9Sj_mayer } 3544c9649a9Sj_mayer 3554c9649a9Sj_mayer int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp) 3564c9649a9Sj_mayer { 3574c9649a9Sj_mayer uint64_t hwpcb, tmp64; 3584c9649a9Sj_mayer uint8_t tmp8; 3594c9649a9Sj_mayer int ret = 0; 3604c9649a9Sj_mayer 3614c9649a9Sj_mayer hwpcb = env->ipr[IPR_PCBB]; 3624c9649a9Sj_mayer switch (iprn) { 3634c9649a9Sj_mayer case IPR_ASN: 3644c9649a9Sj_mayer /* Read-only */ 3654c9649a9Sj_mayer ret = -1; 3664c9649a9Sj_mayer break; 3674c9649a9Sj_mayer case IPR_ASTEN: 3684c9649a9Sj_mayer tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4; 3694c9649a9Sj_mayer *oldvalp = tmp8; 3704c9649a9Sj_mayer tmp8 &= val & 0xF; 3714c9649a9Sj_mayer tmp8 |= (val >> 4) & 0xF; 3724c9649a9Sj_mayer env->ipr[IPR_ASTEN] &= ~0xF; 3734c9649a9Sj_mayer env->ipr[IPR_ASTEN] |= tmp8; 3744c9649a9Sj_mayer ret = 1; 3754c9649a9Sj_mayer break; 3764c9649a9Sj_mayer case IPR_ASTSR: 3774c9649a9Sj_mayer tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4; 3784c9649a9Sj_mayer *oldvalp = tmp8; 3794c9649a9Sj_mayer tmp8 &= val & 0xF; 3804c9649a9Sj_mayer tmp8 |= (val >> 4) & 0xF; 3814c9649a9Sj_mayer env->ipr[IPR_ASTSR] &= ~0xF; 3824c9649a9Sj_mayer env->ipr[IPR_ASTSR] |= tmp8; 3834c9649a9Sj_mayer ret = 1; 3844c9649a9Sj_mayer case IPR_DATFX: 3854c9649a9Sj_mayer env->ipr[IPR_DATFX] &= ~0x1; 3864c9649a9Sj_mayer env->ipr[IPR_DATFX] |= val & 1; 3874c9649a9Sj_mayer tmp64 = ldq_raw(hwpcb + 56); 3884c9649a9Sj_mayer tmp64 &= ~0x8000000000000000ULL; 3894c9649a9Sj_mayer tmp64 |= (val & 1) << 63; 3904c9649a9Sj_mayer stq_raw(hwpcb + 56, tmp64); 3914c9649a9Sj_mayer break; 3924c9649a9Sj_mayer case IPR_ESP: 3934c9649a9Sj_mayer if (env->features & FEATURE_SPS) 3944c9649a9Sj_mayer env->ipr[IPR_ESP] = val; 3954c9649a9Sj_mayer else 3964c9649a9Sj_mayer stq_raw(hwpcb + 8, val); 3974c9649a9Sj_mayer break; 3984c9649a9Sj_mayer case IPR_FEN: 3994c9649a9Sj_mayer env->ipr[IPR_FEN] = val & 1; 4004c9649a9Sj_mayer tmp64 = ldq_raw(hwpcb + 56); 4014c9649a9Sj_mayer tmp64 &= ~1; 4024c9649a9Sj_mayer tmp64 |= val & 1; 4034c9649a9Sj_mayer stq_raw(hwpcb + 56, tmp64); 4044c9649a9Sj_mayer break; 4054c9649a9Sj_mayer case IPR_IPIR: 4064c9649a9Sj_mayer /* XXX: TODO: Send IRQ to CPU #ir[16] */ 4074c9649a9Sj_mayer break; 4084c9649a9Sj_mayer case IPR_IPL: 4094c9649a9Sj_mayer *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59; 4104c9649a9Sj_mayer env->ipr[IPR_IPL] &= ~0x1F; 4114c9649a9Sj_mayer env->ipr[IPR_IPL] |= val & 0x1F; 4124c9649a9Sj_mayer /* XXX: may issue an interrupt or ASR _now_ */ 4134c9649a9Sj_mayer ret = 1; 4144c9649a9Sj_mayer break; 4154c9649a9Sj_mayer case IPR_KSP: 4164c9649a9Sj_mayer if (!(env->ipr[IPR_EXC_ADDR] & 1)) { 4174c9649a9Sj_mayer ret = -1; 4184c9649a9Sj_mayer } else { 4194c9649a9Sj_mayer if (env->features & FEATURE_SPS) 4204c9649a9Sj_mayer env->ipr[IPR_KSP] = val; 4214c9649a9Sj_mayer else 4224c9649a9Sj_mayer stq_raw(hwpcb + 0, val); 4234c9649a9Sj_mayer } 4244c9649a9Sj_mayer break; 4254c9649a9Sj_mayer case IPR_MCES: 4264c9649a9Sj_mayer env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18); 4274c9649a9Sj_mayer env->ipr[IPR_MCES] |= val & 0x18; 4284c9649a9Sj_mayer break; 4294c9649a9Sj_mayer case IPR_PERFMON: 4304c9649a9Sj_mayer /* Implementation specific */ 4314c9649a9Sj_mayer *oldvalp = 0; 4324c9649a9Sj_mayer ret = 1; 4334c9649a9Sj_mayer break; 4344c9649a9Sj_mayer case IPR_PCBB: 4354c9649a9Sj_mayer /* Read-only */ 4364c9649a9Sj_mayer ret = -1; 4374c9649a9Sj_mayer break; 4384c9649a9Sj_mayer case IPR_PRBR: 4394c9649a9Sj_mayer env->ipr[IPR_PRBR] = val; 4404c9649a9Sj_mayer break; 4414c9649a9Sj_mayer case IPR_PTBR: 4424c9649a9Sj_mayer /* Read-only */ 4434c9649a9Sj_mayer ret = -1; 4444c9649a9Sj_mayer break; 4454c9649a9Sj_mayer case IPR_SCBB: 4464c9649a9Sj_mayer env->ipr[IPR_SCBB] = (uint32_t)val; 4474c9649a9Sj_mayer break; 4484c9649a9Sj_mayer case IPR_SIRR: 4494c9649a9Sj_mayer if (val & 0xF) { 4504c9649a9Sj_mayer env->ipr[IPR_SISR] |= 1 << (val & 0xF); 4514c9649a9Sj_mayer /* XXX: request a software interrupt _now_ */ 4524c9649a9Sj_mayer } 4534c9649a9Sj_mayer break; 4544c9649a9Sj_mayer case IPR_SISR: 4554c9649a9Sj_mayer /* Read-only */ 4564c9649a9Sj_mayer ret = -1; 4574c9649a9Sj_mayer break; 4584c9649a9Sj_mayer case IPR_SSP: 4594c9649a9Sj_mayer if (env->features & FEATURE_SPS) 4604c9649a9Sj_mayer env->ipr[IPR_SSP] = val; 4614c9649a9Sj_mayer else 4624c9649a9Sj_mayer stq_raw(hwpcb + 16, val); 4634c9649a9Sj_mayer break; 4644c9649a9Sj_mayer case IPR_SYSPTBR: 4654c9649a9Sj_mayer if (env->features & FEATURE_VIRBND) 4664c9649a9Sj_mayer env->ipr[IPR_SYSPTBR] = val; 4674c9649a9Sj_mayer else 4684c9649a9Sj_mayer ret = -1; 469b2c58871SBlue Swirl break; 4704c9649a9Sj_mayer case IPR_TBCHK: 4714c9649a9Sj_mayer /* Read-only */ 4724c9649a9Sj_mayer ret = -1; 4734c9649a9Sj_mayer break; 4744c9649a9Sj_mayer case IPR_TBIA: 4754c9649a9Sj_mayer tlb_flush(env, 1); 4764c9649a9Sj_mayer break; 4774c9649a9Sj_mayer case IPR_TBIAP: 4784c9649a9Sj_mayer tlb_flush(env, 1); 4794c9649a9Sj_mayer break; 4804c9649a9Sj_mayer case IPR_TBIS: 4814c9649a9Sj_mayer tlb_flush_page(env, val); 4824c9649a9Sj_mayer break; 4834c9649a9Sj_mayer case IPR_TBISD: 4844c9649a9Sj_mayer tlb_flush_page(env, val); 4854c9649a9Sj_mayer break; 4864c9649a9Sj_mayer case IPR_TBISI: 4874c9649a9Sj_mayer tlb_flush_page(env, val); 4884c9649a9Sj_mayer break; 4894c9649a9Sj_mayer case IPR_USP: 4904c9649a9Sj_mayer if (env->features & FEATURE_SPS) 4914c9649a9Sj_mayer env->ipr[IPR_USP] = val; 4924c9649a9Sj_mayer else 4934c9649a9Sj_mayer stq_raw(hwpcb + 24, val); 4944c9649a9Sj_mayer break; 4954c9649a9Sj_mayer case IPR_VIRBND: 4964c9649a9Sj_mayer if (env->features & FEATURE_VIRBND) 4974c9649a9Sj_mayer env->ipr[IPR_VIRBND] = val; 4984c9649a9Sj_mayer else 4994c9649a9Sj_mayer ret = -1; 5004c9649a9Sj_mayer break; 5014c9649a9Sj_mayer case IPR_VPTB: 5024c9649a9Sj_mayer env->ipr[IPR_VPTB] = val; 5034c9649a9Sj_mayer break; 5044c9649a9Sj_mayer case IPR_WHAMI: 5054c9649a9Sj_mayer /* Read-only */ 5064c9649a9Sj_mayer ret = -1; 5074c9649a9Sj_mayer break; 5084c9649a9Sj_mayer default: 5094c9649a9Sj_mayer /* Invalid */ 5104c9649a9Sj_mayer ret = -1; 5114c9649a9Sj_mayer break; 5124c9649a9Sj_mayer } 5134c9649a9Sj_mayer 5144c9649a9Sj_mayer return ret; 5154c9649a9Sj_mayer } 5164c9649a9Sj_mayer 5174c9649a9Sj_mayer void do_interrupt (CPUState *env) 5184c9649a9Sj_mayer { 5194c9649a9Sj_mayer int excp; 5204c9649a9Sj_mayer 5214c9649a9Sj_mayer env->ipr[IPR_EXC_ADDR] = env->pc | 1; 5224c9649a9Sj_mayer excp = env->exception_index; 523ee0dc6d3SBlue Swirl env->exception_index = -1; 5244c9649a9Sj_mayer env->error_code = 0; 5254c9649a9Sj_mayer /* XXX: disable interrupts and memory mapping */ 5264c9649a9Sj_mayer if (env->ipr[IPR_PAL_BASE] != -1ULL) { 5274c9649a9Sj_mayer /* We use native PALcode */ 5284c9649a9Sj_mayer env->pc = env->ipr[IPR_PAL_BASE] + excp; 5294c9649a9Sj_mayer } else { 5304c9649a9Sj_mayer /* We use emulated PALcode */ 5314c9649a9Sj_mayer call_pal(env); 5324c9649a9Sj_mayer /* Emulate REI */ 5334c9649a9Sj_mayer env->pc = env->ipr[IPR_EXC_ADDR] & ~7; 5344c9649a9Sj_mayer env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1; 5354c9649a9Sj_mayer /* XXX: re-enable interrupts and memory mapping */ 5364c9649a9Sj_mayer } 5374c9649a9Sj_mayer } 5384c9649a9Sj_mayer #endif 5394c9649a9Sj_mayer 5404c9649a9Sj_mayer void cpu_dump_state (CPUState *env, FILE *f, 5414c9649a9Sj_mayer int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 5424c9649a9Sj_mayer int flags) 5434c9649a9Sj_mayer { 544b55266b5Sblueswir1 static const char *linux_reg_names[] = { 5454c9649a9Sj_mayer "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ", 5464c9649a9Sj_mayer "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ", 5474c9649a9Sj_mayer "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ", 5484c9649a9Sj_mayer "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero", 5494c9649a9Sj_mayer }; 5504c9649a9Sj_mayer int i; 5514c9649a9Sj_mayer 5524c9649a9Sj_mayer cpu_fprintf(f, " PC " TARGET_FMT_lx " PS " TARGET_FMT_lx "\n", 5534c9649a9Sj_mayer env->pc, env->ps); 5544c9649a9Sj_mayer for (i = 0; i < 31; i++) { 5554c9649a9Sj_mayer cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i, 5564c9649a9Sj_mayer linux_reg_names[i], env->ir[i]); 5574c9649a9Sj_mayer if ((i % 3) == 2) 5584c9649a9Sj_mayer cpu_fprintf(f, "\n"); 5594c9649a9Sj_mayer } 5606910b8f6SRichard Henderson 5616910b8f6SRichard Henderson cpu_fprintf(f, "lock_a " TARGET_FMT_lx " lock_v " TARGET_FMT_lx "\n", 5626910b8f6SRichard Henderson env->lock_addr, env->lock_value); 5636910b8f6SRichard Henderson 5644c9649a9Sj_mayer for (i = 0; i < 31; i++) { 5654c9649a9Sj_mayer cpu_fprintf(f, "FIR%02d " TARGET_FMT_lx " ", i, 5664c9649a9Sj_mayer *((uint64_t *)(&env->fir[i]))); 5674c9649a9Sj_mayer if ((i % 3) == 2) 5684c9649a9Sj_mayer cpu_fprintf(f, "\n"); 5694c9649a9Sj_mayer } 5706910b8f6SRichard Henderson cpu_fprintf(f, "\n"); 5714c9649a9Sj_mayer } 572