|
|
1.1 ! root 1: /* ! 2: * Helpers for loads and stores ! 3: * ! 4: * Copyright (c) 2007 Jocelyn Mayer ! 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: ! 23: ! 24: /* Softmmu support */ ! 25: #ifndef CONFIG_USER_ONLY ! 26: ! 27: uint64_t helper_ldl_phys(uint64_t p) ! 28: { ! 29: return (int32_t)ldl_phys(p); ! 30: } ! 31: ! 32: uint64_t helper_ldq_phys(uint64_t p) ! 33: { ! 34: return ldq_phys(p); ! 35: } ! 36: ! 37: uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p) ! 38: { ! 39: env->lock_addr = p; ! 40: return env->lock_value = (int32_t)ldl_phys(p); ! 41: } ! 42: ! 43: uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p) ! 44: { ! 45: env->lock_addr = p; ! 46: return env->lock_value = ldq_phys(p); ! 47: } ! 48: ! 49: void helper_stl_phys(uint64_t p, uint64_t v) ! 50: { ! 51: stl_phys(p, v); ! 52: } ! 53: ! 54: void helper_stq_phys(uint64_t p, uint64_t v) ! 55: { ! 56: stq_phys(p, v); ! 57: } ! 58: ! 59: uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) ! 60: { ! 61: uint64_t ret = 0; ! 62: ! 63: if (p == env->lock_addr) { ! 64: int32_t old = ldl_phys(p); ! 65: if (old == (int32_t)env->lock_value) { ! 66: stl_phys(p, v); ! 67: ret = 1; ! 68: } ! 69: } ! 70: env->lock_addr = -1; ! 71: ! 72: return ret; ! 73: } ! 74: ! 75: uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) ! 76: { ! 77: uint64_t ret = 0; ! 78: ! 79: if (p == env->lock_addr) { ! 80: uint64_t old = ldq_phys(p); ! 81: if (old == env->lock_value) { ! 82: stq_phys(p, v); ! 83: ret = 1; ! 84: } ! 85: } ! 86: env->lock_addr = -1; ! 87: ! 88: return ret; ! 89: } ! 90: ! 91: static void do_unaligned_access(CPUAlphaState *env, target_ulong addr, ! 92: int is_write, int is_user, uintptr_t retaddr) ! 93: { ! 94: uint64_t pc; ! 95: uint32_t insn; ! 96: ! 97: do_restore_state(env, retaddr); ! 98: ! 99: pc = env->pc; ! 100: insn = cpu_ldl_code(env, pc); ! 101: ! 102: env->trap_arg0 = addr; ! 103: env->trap_arg1 = insn >> 26; /* opcode */ ! 104: env->trap_arg2 = (insn >> 21) & 31; /* dest regno */ ! 105: env->exception_index = EXCP_UNALIGN; ! 106: env->error_code = 0; ! 107: cpu_loop_exit(env); ! 108: } ! 109: ! 110: void cpu_unassigned_access(CPUAlphaState *env, target_phys_addr_t addr, ! 111: int is_write, int is_exec, int unused, int size) ! 112: { ! 113: env->trap_arg0 = addr; ! 114: env->trap_arg1 = is_write; ! 115: dynamic_excp(env, 0, EXCP_MCHK, 0); ! 116: } ! 117: ! 118: #include "softmmu_exec.h" ! 119: ! 120: #define MMUSUFFIX _mmu ! 121: #define ALIGNED_ONLY ! 122: ! 123: #define SHIFT 0 ! 124: #include "softmmu_template.h" ! 125: ! 126: #define SHIFT 1 ! 127: #include "softmmu_template.h" ! 128: ! 129: #define SHIFT 2 ! 130: #include "softmmu_template.h" ! 131: ! 132: #define SHIFT 3 ! 133: #include "softmmu_template.h" ! 134: ! 135: /* try to fill the TLB and return an exception if error. If retaddr is ! 136: NULL, it means that the function was called in C code (i.e. not ! 137: from generated code or from helper.c) */ ! 138: /* XXX: fix it to restore all registers */ ! 139: void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write, ! 140: int mmu_idx, uintptr_t retaddr) ! 141: { ! 142: int ret; ! 143: ! 144: ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx); ! 145: if (unlikely(ret != 0)) { ! 146: do_restore_state(env, retaddr); ! 147: /* Exception index and error code are already set */ ! 148: cpu_loop_exit(env); ! 149: } ! 150: } ! 151: #endif /* CONFIG_USER_ONLY */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.