xref: /qemu/target/alpha/mem_helper.c (revision a8a826a3c3b8c8a1c4def0e9e22b46e78e6163a0)
14c9649a9Sj_mayer /*
2c3082755SRichard Henderson  *  Helpers for loads and stores
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 
203e457172SBlue Swirl #include "cpu.h"
21a7812ae4Spbrook #include "helper.h"
224c9649a9Sj_mayer 
234c9649a9Sj_mayer 
244c9649a9Sj_mayer /* Softmmu support */
25c3082755SRichard Henderson #ifndef CONFIG_USER_ONLY
26c3082755SRichard Henderson 
272374e73eSRichard Henderson uint64_t helper_ldl_phys(uint64_t p)
284c9649a9Sj_mayer {
292374e73eSRichard Henderson     return (int32_t)ldl_phys(p);
304c9649a9Sj_mayer }
314c9649a9Sj_mayer 
322374e73eSRichard Henderson uint64_t helper_ldq_phys(uint64_t p)
334c9649a9Sj_mayer {
342374e73eSRichard Henderson     return ldq_phys(p);
358bb6e981Saurel32 }
368bb6e981Saurel32 
37c3082755SRichard Henderson uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p)
388bb6e981Saurel32 {
392374e73eSRichard Henderson     env->lock_addr = p;
402374e73eSRichard Henderson     return env->lock_value = (int32_t)ldl_phys(p);
418bb6e981Saurel32 }
428bb6e981Saurel32 
43c3082755SRichard Henderson uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p)
448bb6e981Saurel32 {
452374e73eSRichard Henderson     env->lock_addr = p;
46c3082755SRichard Henderson     return env->lock_value = ldq_phys(p);
478bb6e981Saurel32 }
488bb6e981Saurel32 
492374e73eSRichard Henderson void helper_stl_phys(uint64_t p, uint64_t v)
508bb6e981Saurel32 {
512374e73eSRichard Henderson     stl_phys(p, v);
528bb6e981Saurel32 }
538bb6e981Saurel32 
542374e73eSRichard Henderson void helper_stq_phys(uint64_t p, uint64_t v)
558bb6e981Saurel32 {
562374e73eSRichard Henderson     stq_phys(p, v);
578bb6e981Saurel32 }
588bb6e981Saurel32 
59c3082755SRichard Henderson uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
608bb6e981Saurel32 {
612374e73eSRichard Henderson     uint64_t ret = 0;
628bb6e981Saurel32 
632374e73eSRichard Henderson     if (p == env->lock_addr) {
642374e73eSRichard Henderson         int32_t old = ldl_phys(p);
652374e73eSRichard Henderson         if (old == (int32_t)env->lock_value) {
662374e73eSRichard Henderson             stl_phys(p, v);
678bb6e981Saurel32             ret = 1;
682374e73eSRichard Henderson         }
692374e73eSRichard Henderson     }
702374e73eSRichard Henderson     env->lock_addr = -1;
718bb6e981Saurel32 
728bb6e981Saurel32     return ret;
738bb6e981Saurel32 }
748bb6e981Saurel32 
75c3082755SRichard Henderson uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
768bb6e981Saurel32 {
772374e73eSRichard Henderson     uint64_t ret = 0;
788bb6e981Saurel32 
792374e73eSRichard Henderson     if (p == env->lock_addr) {
802374e73eSRichard Henderson         uint64_t old = ldq_phys(p);
812374e73eSRichard Henderson         if (old == env->lock_value) {
822374e73eSRichard Henderson             stq_phys(p, v);
838bb6e981Saurel32             ret = 1;
842374e73eSRichard Henderson         }
852374e73eSRichard Henderson     }
862374e73eSRichard Henderson     env->lock_addr = -1;
878bb6e981Saurel32 
888bb6e981Saurel32     return ret;
894c9649a9Sj_mayer }
904c9649a9Sj_mayer 
91c3082755SRichard Henderson static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
9220503968SBlue Swirl                                 int is_write, int is_user, uintptr_t retaddr)
935b450407SRichard Henderson {
945b450407SRichard Henderson     uint64_t pc;
955b450407SRichard Henderson     uint32_t insn;
965b450407SRichard Henderson 
97a8a826a3SBlue Swirl     if (retaddr) {
98a8a826a3SBlue Swirl         cpu_restore_state(env, retaddr);
99a8a826a3SBlue Swirl     }
1005b450407SRichard Henderson 
1015b450407SRichard Henderson     pc = env->pc;
102c3082755SRichard Henderson     insn = cpu_ldl_code(env, pc);
1035b450407SRichard Henderson 
1045b450407SRichard Henderson     env->trap_arg0 = addr;
1055b450407SRichard Henderson     env->trap_arg1 = insn >> 26;                /* opcode */
1065b450407SRichard Henderson     env->trap_arg2 = (insn >> 21) & 31;         /* dest regno */
107b9f0923eSRichard Henderson     env->exception_index = EXCP_UNALIGN;
108b9f0923eSRichard Henderson     env->error_code = 0;
109b9f0923eSRichard Henderson     cpu_loop_exit(env);
1105b450407SRichard Henderson }
1115b450407SRichard Henderson 
112a8170e5eSAvi Kivity void cpu_unassigned_access(CPUAlphaState *env, hwaddr addr,
113c3082755SRichard Henderson                            int is_write, int is_exec, int unused, int size)
1145b450407SRichard Henderson {
1155b450407SRichard Henderson     env->trap_arg0 = addr;
1165b450407SRichard Henderson     env->trap_arg1 = is_write;
11720503968SBlue Swirl     dynamic_excp(env, 0, EXCP_MCHK, 0);
1185b450407SRichard Henderson }
1195b450407SRichard Henderson 
1203e457172SBlue Swirl #include "softmmu_exec.h"
1213e457172SBlue Swirl 
1224c9649a9Sj_mayer #define MMUSUFFIX _mmu
1235b450407SRichard Henderson #define ALIGNED_ONLY
1244c9649a9Sj_mayer 
1254c9649a9Sj_mayer #define SHIFT 0
1264c9649a9Sj_mayer #include "softmmu_template.h"
1274c9649a9Sj_mayer 
1284c9649a9Sj_mayer #define SHIFT 1
1294c9649a9Sj_mayer #include "softmmu_template.h"
1304c9649a9Sj_mayer 
1314c9649a9Sj_mayer #define SHIFT 2
1324c9649a9Sj_mayer #include "softmmu_template.h"
1334c9649a9Sj_mayer 
1344c9649a9Sj_mayer #define SHIFT 3
1354c9649a9Sj_mayer #include "softmmu_template.h"
1364c9649a9Sj_mayer 
1374c9649a9Sj_mayer /* try to fill the TLB and return an exception if error. If retaddr is
1384c9649a9Sj_mayer    NULL, it means that the function was called in C code (i.e. not
1394c9649a9Sj_mayer    from generated code or from helper.c) */
1404c9649a9Sj_mayer /* XXX: fix it to restore all registers */
141c3082755SRichard Henderson void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write,
14220503968SBlue Swirl               int mmu_idx, uintptr_t retaddr)
1434c9649a9Sj_mayer {
1444c9649a9Sj_mayer     int ret;
1454c9649a9Sj_mayer 
14697b348e7SBlue Swirl     ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx);
1472d9671d3SRichard Henderson     if (unlikely(ret != 0)) {
148a8a826a3SBlue Swirl         if (retaddr) {
149a8a826a3SBlue Swirl             cpu_restore_state(env, retaddr);
150a8a826a3SBlue Swirl         }
1514c9649a9Sj_mayer         /* Exception index and error code are already set */
1521162c041SBlue Swirl         cpu_loop_exit(env);
1534c9649a9Sj_mayer     }
1544c9649a9Sj_mayer }
155c3082755SRichard Henderson #endif /* CONFIG_USER_ONLY */
156