root / target-alpha / mem_helper.c @ 2c17449b
History | View | Annotate | Download (4.1 kB)
1 | 4c9649a9 | j_mayer | /*
|
---|---|---|---|
2 | c3082755 | Richard Henderson | * Helpers for loads and stores
|
3 | 5fafdf24 | ths | *
|
4 | 4c9649a9 | j_mayer | * Copyright (c) 2007 Jocelyn Mayer
|
5 | 4c9649a9 | j_mayer | *
|
6 | 4c9649a9 | j_mayer | * This library is free software; you can redistribute it and/or
|
7 | 4c9649a9 | j_mayer | * modify it under the terms of the GNU Lesser General Public
|
8 | 4c9649a9 | j_mayer | * License as published by the Free Software Foundation; either
|
9 | 4c9649a9 | j_mayer | * version 2 of the License, or (at your option) any later version.
|
10 | 4c9649a9 | j_mayer | *
|
11 | 4c9649a9 | j_mayer | * This library is distributed in the hope that it will be useful,
|
12 | 4c9649a9 | j_mayer | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 4c9649a9 | j_mayer | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 4c9649a9 | j_mayer | * Lesser General Public License for more details.
|
15 | 4c9649a9 | j_mayer | *
|
16 | 4c9649a9 | j_mayer | * You should have received a copy of the GNU Lesser General Public
|
17 | 8167ee88 | Blue Swirl | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | 4c9649a9 | j_mayer | */
|
19 | 4c9649a9 | j_mayer | |
20 | 3e457172 | Blue Swirl | #include "cpu.h" |
21 | a7812ae4 | pbrook | #include "helper.h" |
22 | 4c9649a9 | j_mayer | |
23 | 4c9649a9 | j_mayer | |
24 | 4c9649a9 | j_mayer | /* Softmmu support */
|
25 | c3082755 | Richard Henderson | #ifndef CONFIG_USER_ONLY
|
26 | c3082755 | Richard Henderson | |
27 | fdfba1a2 | Edgar E. Iglesias | uint64_t helper_ldl_phys(CPUAlphaState *env, uint64_t p) |
28 | 8bb6e981 | aurel32 | { |
29 | fdfba1a2 | Edgar E. Iglesias | CPUState *cs = ENV_GET_CPU(env); |
30 | fdfba1a2 | Edgar E. Iglesias | return (int32_t)ldl_phys(cs->as, p);
|
31 | 8bb6e981 | aurel32 | } |
32 | 8bb6e981 | aurel32 | |
33 | 2c17449b | Edgar E. Iglesias | uint64_t helper_ldq_phys(CPUAlphaState *env, uint64_t p) |
34 | 8bb6e981 | aurel32 | { |
35 | 2c17449b | Edgar E. Iglesias | CPUState *cs = ENV_GET_CPU(env); |
36 | 2c17449b | Edgar E. Iglesias | return ldq_phys(cs->as, p);
|
37 | 8bb6e981 | aurel32 | } |
38 | 8bb6e981 | aurel32 | |
39 | c3082755 | Richard Henderson | uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p) |
40 | 8bb6e981 | aurel32 | { |
41 | fdfba1a2 | Edgar E. Iglesias | CPUState *cs = ENV_GET_CPU(env); |
42 | 2374e73e | Richard Henderson | env->lock_addr = p; |
43 | fdfba1a2 | Edgar E. Iglesias | return env->lock_value = (int32_t)ldl_phys(cs->as, p);
|
44 | 8bb6e981 | aurel32 | } |
45 | 8bb6e981 | aurel32 | |
46 | c3082755 | Richard Henderson | uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p) |
47 | 8bb6e981 | aurel32 | { |
48 | 2c17449b | Edgar E. Iglesias | CPUState *cs = ENV_GET_CPU(env); |
49 | 2374e73e | Richard Henderson | env->lock_addr = p; |
50 | 2c17449b | Edgar E. Iglesias | return env->lock_value = ldq_phys(cs->as, p);
|
51 | 8bb6e981 | aurel32 | } |
52 | 8bb6e981 | aurel32 | |
53 | 2374e73e | Richard Henderson | void helper_stl_phys(uint64_t p, uint64_t v)
|
54 | 8bb6e981 | aurel32 | { |
55 | 2374e73e | Richard Henderson | stl_phys(p, v); |
56 | 8bb6e981 | aurel32 | } |
57 | 8bb6e981 | aurel32 | |
58 | 2374e73e | Richard Henderson | void helper_stq_phys(uint64_t p, uint64_t v)
|
59 | 8bb6e981 | aurel32 | { |
60 | 2374e73e | Richard Henderson | stq_phys(p, v); |
61 | 8bb6e981 | aurel32 | } |
62 | 8bb6e981 | aurel32 | |
63 | c3082755 | Richard Henderson | uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) |
64 | 8bb6e981 | aurel32 | { |
65 | fdfba1a2 | Edgar E. Iglesias | CPUState *cs = ENV_GET_CPU(env); |
66 | 2374e73e | Richard Henderson | uint64_t ret = 0;
|
67 | 8bb6e981 | aurel32 | |
68 | 2374e73e | Richard Henderson | if (p == env->lock_addr) {
|
69 | fdfba1a2 | Edgar E. Iglesias | int32_t old = ldl_phys(cs->as, p); |
70 | 2374e73e | Richard Henderson | if (old == (int32_t)env->lock_value) {
|
71 | 2374e73e | Richard Henderson | stl_phys(p, v); |
72 | 2374e73e | Richard Henderson | ret = 1;
|
73 | 2374e73e | Richard Henderson | } |
74 | 2374e73e | Richard Henderson | } |
75 | 2374e73e | Richard Henderson | env->lock_addr = -1;
|
76 | 8bb6e981 | aurel32 | |
77 | 8bb6e981 | aurel32 | return ret;
|
78 | 8bb6e981 | aurel32 | } |
79 | 8bb6e981 | aurel32 | |
80 | c3082755 | Richard Henderson | uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) |
81 | 8bb6e981 | aurel32 | { |
82 | 2c17449b | Edgar E. Iglesias | CPUState *cs = ENV_GET_CPU(env); |
83 | 2374e73e | Richard Henderson | uint64_t ret = 0;
|
84 | 8bb6e981 | aurel32 | |
85 | 2374e73e | Richard Henderson | if (p == env->lock_addr) {
|
86 | 2c17449b | Edgar E. Iglesias | uint64_t old = ldq_phys(cs->as, p); |
87 | 2374e73e | Richard Henderson | if (old == env->lock_value) {
|
88 | 2374e73e | Richard Henderson | stq_phys(p, v); |
89 | 2374e73e | Richard Henderson | ret = 1;
|
90 | 2374e73e | Richard Henderson | } |
91 | 2374e73e | Richard Henderson | } |
92 | 2374e73e | Richard Henderson | env->lock_addr = -1;
|
93 | 8bb6e981 | aurel32 | |
94 | 8bb6e981 | aurel32 | return ret;
|
95 | 4c9649a9 | j_mayer | } |
96 | 4c9649a9 | j_mayer | |
97 | c3082755 | Richard Henderson | static void do_unaligned_access(CPUAlphaState *env, target_ulong addr, |
98 | 20503968 | Blue Swirl | int is_write, int is_user, uintptr_t retaddr) |
99 | 5b450407 | Richard Henderson | { |
100 | 5b450407 | Richard Henderson | uint64_t pc; |
101 | 5b450407 | Richard Henderson | uint32_t insn; |
102 | 5b450407 | Richard Henderson | |
103 | a8a826a3 | Blue Swirl | if (retaddr) {
|
104 | a8a826a3 | Blue Swirl | cpu_restore_state(env, retaddr); |
105 | a8a826a3 | Blue Swirl | } |
106 | 5b450407 | Richard Henderson | |
107 | 5b450407 | Richard Henderson | pc = env->pc; |
108 | c3082755 | Richard Henderson | insn = cpu_ldl_code(env, pc); |
109 | 5b450407 | Richard Henderson | |
110 | 5b450407 | Richard Henderson | env->trap_arg0 = addr; |
111 | 5b450407 | Richard Henderson | env->trap_arg1 = insn >> 26; /* opcode */ |
112 | 5b450407 | Richard Henderson | env->trap_arg2 = (insn >> 21) & 31; /* dest regno */ |
113 | b9f0923e | Richard Henderson | env->exception_index = EXCP_UNALIGN; |
114 | b9f0923e | Richard Henderson | env->error_code = 0;
|
115 | b9f0923e | Richard Henderson | cpu_loop_exit(env); |
116 | 5b450407 | Richard Henderson | } |
117 | 5b450407 | Richard Henderson | |
118 | c658b94f | Andreas Färber | void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
|
119 | c658b94f | Andreas Färber | bool is_write, bool is_exec, int unused, |
120 | c658b94f | Andreas Färber | unsigned size)
|
121 | 5b450407 | Richard Henderson | { |
122 | c658b94f | Andreas Färber | AlphaCPU *cpu = ALPHA_CPU(cs); |
123 | c658b94f | Andreas Färber | CPUAlphaState *env = &cpu->env; |
124 | c658b94f | Andreas Färber | |
125 | 5b450407 | Richard Henderson | env->trap_arg0 = addr; |
126 | c658b94f | Andreas Färber | env->trap_arg1 = is_write ? 1 : 0; |
127 | 20503968 | Blue Swirl | dynamic_excp(env, 0, EXCP_MCHK, 0); |
128 | 5b450407 | Richard Henderson | } |
129 | 5b450407 | Richard Henderson | |
130 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_exec.h" |
131 | 3e457172 | Blue Swirl | |
132 | 4c9649a9 | j_mayer | #define MMUSUFFIX _mmu
|
133 | 5b450407 | Richard Henderson | #define ALIGNED_ONLY
|
134 | 4c9649a9 | j_mayer | |
135 | 4c9649a9 | j_mayer | #define SHIFT 0 |
136 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
137 | 4c9649a9 | j_mayer | |
138 | 4c9649a9 | j_mayer | #define SHIFT 1 |
139 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
140 | 4c9649a9 | j_mayer | |
141 | 4c9649a9 | j_mayer | #define SHIFT 2 |
142 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
143 | 4c9649a9 | j_mayer | |
144 | 4c9649a9 | j_mayer | #define SHIFT 3 |
145 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
146 | 4c9649a9 | j_mayer | |
147 | 4c9649a9 | j_mayer | /* try to fill the TLB and return an exception if error. If retaddr is
|
148 | 4c9649a9 | j_mayer | NULL, it means that the function was called in C code (i.e. not
|
149 | 4c9649a9 | j_mayer | from generated code or from helper.c) */
|
150 | 4c9649a9 | j_mayer | /* XXX: fix it to restore all registers */
|
151 | c3082755 | Richard Henderson | void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write, |
152 | 20503968 | Blue Swirl | int mmu_idx, uintptr_t retaddr)
|
153 | 4c9649a9 | j_mayer | { |
154 | 4c9649a9 | j_mayer | int ret;
|
155 | 4c9649a9 | j_mayer | |
156 | 97b348e7 | Blue Swirl | ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx); |
157 | 2d9671d3 | Richard Henderson | if (unlikely(ret != 0)) { |
158 | a8a826a3 | Blue Swirl | if (retaddr) {
|
159 | a8a826a3 | Blue Swirl | cpu_restore_state(env, retaddr); |
160 | a8a826a3 | Blue Swirl | } |
161 | 4c9649a9 | j_mayer | /* Exception index and error code are already set */
|
162 | 1162c041 | Blue Swirl | cpu_loop_exit(env); |
163 | 4c9649a9 | j_mayer | } |
164 | 4c9649a9 | j_mayer | } |
165 | c3082755 | Richard Henderson | #endif /* CONFIG_USER_ONLY */ |