]> git.proxmox.com Git - mirror_qemu.git/blame - target-alpha/mem_helper.c
cpu: move exec-all.h inclusion out of cpu.h
[mirror_qemu.git] / target-alpha / mem_helper.c
CommitLineData
4c9649a9 1/*
c3082755 2 * Helpers for loads and stores
5fafdf24 3 *
4c9649a9
JM
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
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
4c9649a9
JM
18 */
19
e2e5e114 20#include "qemu/osdep.h"
3e457172 21#include "cpu.h"
2ef6175a 22#include "exec/helper-proto.h"
63c91552 23#include "exec/exec-all.h"
f08b6170 24#include "exec/cpu_ldst.h"
4c9649a9 25
4c9649a9 26/* Softmmu support */
c3082755
RH
27#ifndef CONFIG_USER_ONLY
28
fdfba1a2 29uint64_t helper_ldl_phys(CPUAlphaState *env, uint64_t p)
8bb6e981 30{
d2810ffd 31 CPUState *cs = CPU(alpha_env_get_cpu(env));
fdfba1a2 32 return (int32_t)ldl_phys(cs->as, p);
8bb6e981
AJ
33}
34
2c17449b 35uint64_t helper_ldq_phys(CPUAlphaState *env, uint64_t p)
8bb6e981 36{
d2810ffd 37 CPUState *cs = CPU(alpha_env_get_cpu(env));
2c17449b 38 return ldq_phys(cs->as, p);
8bb6e981
AJ
39}
40
c3082755 41uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p)
8bb6e981 42{
d2810ffd 43 CPUState *cs = CPU(alpha_env_get_cpu(env));
2374e73e 44 env->lock_addr = p;
fdfba1a2 45 return env->lock_value = (int32_t)ldl_phys(cs->as, p);
8bb6e981
AJ
46}
47
c3082755 48uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p)
8bb6e981 49{
d2810ffd 50 CPUState *cs = CPU(alpha_env_get_cpu(env));
2374e73e 51 env->lock_addr = p;
2c17449b 52 return env->lock_value = ldq_phys(cs->as, p);
8bb6e981
AJ
53}
54
ab1da857 55void helper_stl_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
8bb6e981 56{
d2810ffd 57 CPUState *cs = CPU(alpha_env_get_cpu(env));
ab1da857 58 stl_phys(cs->as, p, v);
8bb6e981
AJ
59}
60
f606604f 61void helper_stq_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
8bb6e981 62{
d2810ffd 63 CPUState *cs = CPU(alpha_env_get_cpu(env));
f606604f 64 stq_phys(cs->as, p, v);
8bb6e981
AJ
65}
66
c3082755 67uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
8bb6e981 68{
d2810ffd 69 CPUState *cs = CPU(alpha_env_get_cpu(env));
2374e73e 70 uint64_t ret = 0;
8bb6e981 71
2374e73e 72 if (p == env->lock_addr) {
fdfba1a2 73 int32_t old = ldl_phys(cs->as, p);
2374e73e 74 if (old == (int32_t)env->lock_value) {
ab1da857 75 stl_phys(cs->as, p, v);
2374e73e
RH
76 ret = 1;
77 }
78 }
79 env->lock_addr = -1;
8bb6e981
AJ
80
81 return ret;
82}
83
c3082755 84uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
8bb6e981 85{
d2810ffd 86 CPUState *cs = CPU(alpha_env_get_cpu(env));
2374e73e 87 uint64_t ret = 0;
8bb6e981 88
2374e73e 89 if (p == env->lock_addr) {
2c17449b 90 uint64_t old = ldq_phys(cs->as, p);
2374e73e 91 if (old == env->lock_value) {
f606604f 92 stq_phys(cs->as, p, v);
2374e73e
RH
93 ret = 1;
94 }
95 }
96 env->lock_addr = -1;
8bb6e981
AJ
97
98 return ret;
4c9649a9
JM
99}
100
93e22326
PB
101void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
102 int is_write, int is_user, uintptr_t retaddr)
5b450407 103{
93e22326
PB
104 AlphaCPU *cpu = ALPHA_CPU(cs);
105 CPUAlphaState *env = &cpu->env;
5b450407
RH
106 uint64_t pc;
107 uint32_t insn;
108
a8a826a3 109 if (retaddr) {
3f38f309 110 cpu_restore_state(cs, retaddr);
a8a826a3 111 }
5b450407
RH
112
113 pc = env->pc;
c3082755 114 insn = cpu_ldl_code(env, pc);
5b450407
RH
115
116 env->trap_arg0 = addr;
117 env->trap_arg1 = insn >> 26; /* opcode */
118 env->trap_arg2 = (insn >> 21) & 31; /* dest regno */
27103424 119 cs->exception_index = EXCP_UNALIGN;
b9f0923e 120 env->error_code = 0;
5638d180 121 cpu_loop_exit(cs);
5b450407
RH
122}
123
c658b94f
AF
124void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
125 bool is_write, bool is_exec, int unused,
126 unsigned size)
5b450407 127{
c658b94f
AF
128 AlphaCPU *cpu = ALPHA_CPU(cs);
129 CPUAlphaState *env = &cpu->env;
130
5b450407 131 env->trap_arg0 = addr;
c658b94f 132 env->trap_arg1 = is_write ? 1 : 0;
ba9c5de5
RH
133 cs->exception_index = EXCP_MCHK;
134 env->error_code = 0;
135
136 /* ??? We should cpu_restore_state to the faulting insn, but this hook
67cc32eb 137 does not have access to the retaddr value from the original helper.
ba9c5de5
RH
138 It's all moot until the QEMU PALcode grows an MCHK handler. */
139
140 cpu_loop_exit(cs);
5b450407
RH
141}
142
4c9649a9
JM
143/* try to fill the TLB and return an exception if error. If retaddr is
144 NULL, it means that the function was called in C code (i.e. not
145 from generated code or from helper.c) */
146/* XXX: fix it to restore all registers */
d5a11fef 147void tlb_fill(CPUState *cs, target_ulong addr, int is_write,
20503968 148 int mmu_idx, uintptr_t retaddr)
4c9649a9 149{
4c9649a9
JM
150 int ret;
151
d5a11fef 152 ret = alpha_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
2d9671d3 153 if (unlikely(ret != 0)) {
a8a826a3 154 if (retaddr) {
3f38f309 155 cpu_restore_state(cs, retaddr);
a8a826a3 156 }
4c9649a9 157 /* Exception index and error code are already set */
5638d180 158 cpu_loop_exit(cs);
4c9649a9 159 }
4c9649a9 160}
c3082755 161#endif /* CONFIG_USER_ONLY */