]> git.proxmox.com Git - mirror_qemu.git/blame - target-alpha/mem_helper.c
vfio/pci: Pass an error object to vfio_pci_igd_opregion_init
[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 101void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
b35399bb
SS
102 MMUAccessType access_type,
103 int mmu_idx, uintptr_t retaddr)
5b450407 104{
93e22326
PB
105 AlphaCPU *cpu = ALPHA_CPU(cs);
106 CPUAlphaState *env = &cpu->env;
5b450407
RH
107 uint64_t pc;
108 uint32_t insn;
109
a8a826a3 110 if (retaddr) {
3f38f309 111 cpu_restore_state(cs, retaddr);
a8a826a3 112 }
5b450407
RH
113
114 pc = env->pc;
c3082755 115 insn = cpu_ldl_code(env, pc);
5b450407
RH
116
117 env->trap_arg0 = addr;
118 env->trap_arg1 = insn >> 26; /* opcode */
119 env->trap_arg2 = (insn >> 21) & 31; /* dest regno */
27103424 120 cs->exception_index = EXCP_UNALIGN;
b9f0923e 121 env->error_code = 0;
5638d180 122 cpu_loop_exit(cs);
5b450407
RH
123}
124
c658b94f
AF
125void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
126 bool is_write, bool is_exec, int unused,
127 unsigned size)
5b450407 128{
c658b94f
AF
129 AlphaCPU *cpu = ALPHA_CPU(cs);
130 CPUAlphaState *env = &cpu->env;
131
5b450407 132 env->trap_arg0 = addr;
c658b94f 133 env->trap_arg1 = is_write ? 1 : 0;
ba9c5de5
RH
134 cs->exception_index = EXCP_MCHK;
135 env->error_code = 0;
136
137 /* ??? We should cpu_restore_state to the faulting insn, but this hook
67cc32eb 138 does not have access to the retaddr value from the original helper.
ba9c5de5
RH
139 It's all moot until the QEMU PALcode grows an MCHK handler. */
140
141 cpu_loop_exit(cs);
5b450407
RH
142}
143
4c9649a9
JM
144/* try to fill the TLB and return an exception if error. If retaddr is
145 NULL, it means that the function was called in C code (i.e. not
146 from generated code or from helper.c) */
147/* XXX: fix it to restore all registers */
b35399bb 148void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
20503968 149 int mmu_idx, uintptr_t retaddr)
4c9649a9 150{
4c9649a9
JM
151 int ret;
152
b35399bb 153 ret = alpha_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
2d9671d3 154 if (unlikely(ret != 0)) {
a8a826a3 155 if (retaddr) {
3f38f309 156 cpu_restore_state(cs, retaddr);
a8a826a3 157 }
4c9649a9 158 /* Exception index and error code are already set */
5638d180 159 cpu_loop_exit(cs);
4c9649a9 160 }
4c9649a9 161}
c3082755 162#endif /* CONFIG_USER_ONLY */