root / target-i386 / mem_helper.c @ feature-archipelago
History | View | Annotate | Download (3.8 kB)
1 | 10774999 | Blue Swirl | /*
|
---|---|---|---|
2 | 10774999 | Blue Swirl | * x86 memory access helpers
|
3 | 10774999 | Blue Swirl | *
|
4 | 10774999 | Blue Swirl | * Copyright (c) 2003 Fabrice Bellard
|
5 | 10774999 | Blue Swirl | *
|
6 | 10774999 | Blue Swirl | * This library is free software; you can redistribute it and/or
|
7 | 10774999 | Blue Swirl | * modify it under the terms of the GNU Lesser General Public
|
8 | 10774999 | Blue Swirl | * License as published by the Free Software Foundation; either
|
9 | 10774999 | Blue Swirl | * version 2 of the License, or (at your option) any later version.
|
10 | 10774999 | Blue Swirl | *
|
11 | 10774999 | Blue Swirl | * This library is distributed in the hope that it will be useful,
|
12 | 10774999 | Blue Swirl | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 10774999 | Blue Swirl | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 10774999 | Blue Swirl | * Lesser General Public License for more details.
|
15 | 10774999 | Blue Swirl | *
|
16 | 10774999 | Blue Swirl | * You should have received a copy of the GNU Lesser General Public
|
17 | 10774999 | Blue Swirl | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | 10774999 | Blue Swirl | */
|
19 | 10774999 | Blue Swirl | |
20 | 10774999 | Blue Swirl | #include "cpu.h" |
21 | 10774999 | Blue Swirl | #include "helper.h" |
22 | 10774999 | Blue Swirl | |
23 | 10774999 | Blue Swirl | #if !defined(CONFIG_USER_ONLY)
|
24 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_exec.h" |
25 | 10774999 | Blue Swirl | #endif /* !defined(CONFIG_USER_ONLY) */ |
26 | 10774999 | Blue Swirl | |
27 | 10774999 | Blue Swirl | /* broken thread support */
|
28 | 10774999 | Blue Swirl | |
29 | 10774999 | Blue Swirl | static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
|
30 | 10774999 | Blue Swirl | |
31 | 10774999 | Blue Swirl | void helper_lock(void) |
32 | 10774999 | Blue Swirl | { |
33 | 10774999 | Blue Swirl | spin_lock(&global_cpu_lock); |
34 | 10774999 | Blue Swirl | } |
35 | 10774999 | Blue Swirl | |
36 | 10774999 | Blue Swirl | void helper_unlock(void) |
37 | 10774999 | Blue Swirl | { |
38 | 10774999 | Blue Swirl | spin_unlock(&global_cpu_lock); |
39 | 10774999 | Blue Swirl | } |
40 | 10774999 | Blue Swirl | |
41 | 92fc4b58 | Blue Swirl | void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
|
42 | 10774999 | Blue Swirl | { |
43 | 10774999 | Blue Swirl | uint64_t d; |
44 | 10774999 | Blue Swirl | int eflags;
|
45 | 10774999 | Blue Swirl | |
46 | f0967a1a | Blue Swirl | eflags = cpu_cc_compute_all(env, CC_OP); |
47 | 92fc4b58 | Blue Swirl | d = cpu_ldq_data(env, a0); |
48 | 00f5e6f2 | liguang | if (d == (((uint64_t)env->regs[R_EDX] << 32) | (uint32_t)env->regs[R_EAX])) { |
49 | a4165610 | liguang | cpu_stq_data(env, a0, ((uint64_t)env->regs[R_ECX] << 32) | (uint32_t)env->regs[R_EBX]);
|
50 | 10774999 | Blue Swirl | eflags |= CC_Z; |
51 | 10774999 | Blue Swirl | } else {
|
52 | 10774999 | Blue Swirl | /* always do the store */
|
53 | 92fc4b58 | Blue Swirl | cpu_stq_data(env, a0, d); |
54 | 00f5e6f2 | liguang | env->regs[R_EDX] = (uint32_t)(d >> 32);
|
55 | 4b34e3ad | liguang | env->regs[R_EAX] = (uint32_t)d; |
56 | 10774999 | Blue Swirl | eflags &= ~CC_Z; |
57 | 10774999 | Blue Swirl | } |
58 | 10774999 | Blue Swirl | CC_SRC = eflags; |
59 | 10774999 | Blue Swirl | } |
60 | 10774999 | Blue Swirl | |
61 | 10774999 | Blue Swirl | #ifdef TARGET_X86_64
|
62 | 92fc4b58 | Blue Swirl | void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
|
63 | 10774999 | Blue Swirl | { |
64 | 10774999 | Blue Swirl | uint64_t d0, d1; |
65 | 10774999 | Blue Swirl | int eflags;
|
66 | 10774999 | Blue Swirl | |
67 | 10774999 | Blue Swirl | if ((a0 & 0xf) != 0) { |
68 | 10774999 | Blue Swirl | raise_exception(env, EXCP0D_GPF); |
69 | 10774999 | Blue Swirl | } |
70 | f0967a1a | Blue Swirl | eflags = cpu_cc_compute_all(env, CC_OP); |
71 | 92fc4b58 | Blue Swirl | d0 = cpu_ldq_data(env, a0); |
72 | 92fc4b58 | Blue Swirl | d1 = cpu_ldq_data(env, a0 + 8);
|
73 | 00f5e6f2 | liguang | if (d0 == env->regs[R_EAX] && d1 == env->regs[R_EDX]) {
|
74 | 70b51365 | liguang | cpu_stq_data(env, a0, env->regs[R_EBX]); |
75 | a4165610 | liguang | cpu_stq_data(env, a0 + 8, env->regs[R_ECX]);
|
76 | 10774999 | Blue Swirl | eflags |= CC_Z; |
77 | 10774999 | Blue Swirl | } else {
|
78 | 10774999 | Blue Swirl | /* always do the store */
|
79 | 92fc4b58 | Blue Swirl | cpu_stq_data(env, a0, d0); |
80 | 92fc4b58 | Blue Swirl | cpu_stq_data(env, a0 + 8, d1);
|
81 | 00f5e6f2 | liguang | env->regs[R_EDX] = d1; |
82 | 4b34e3ad | liguang | env->regs[R_EAX] = d0; |
83 | 10774999 | Blue Swirl | eflags &= ~CC_Z; |
84 | 10774999 | Blue Swirl | } |
85 | 10774999 | Blue Swirl | CC_SRC = eflags; |
86 | 10774999 | Blue Swirl | } |
87 | 10774999 | Blue Swirl | #endif
|
88 | 10774999 | Blue Swirl | |
89 | 92fc4b58 | Blue Swirl | void helper_boundw(CPUX86State *env, target_ulong a0, int v) |
90 | 10774999 | Blue Swirl | { |
91 | 10774999 | Blue Swirl | int low, high;
|
92 | 10774999 | Blue Swirl | |
93 | 92fc4b58 | Blue Swirl | low = cpu_ldsw_data(env, a0); |
94 | 92fc4b58 | Blue Swirl | high = cpu_ldsw_data(env, a0 + 2);
|
95 | 10774999 | Blue Swirl | v = (int16_t)v; |
96 | 10774999 | Blue Swirl | if (v < low || v > high) {
|
97 | 10774999 | Blue Swirl | raise_exception(env, EXCP05_BOUND); |
98 | 10774999 | Blue Swirl | } |
99 | 10774999 | Blue Swirl | } |
100 | 10774999 | Blue Swirl | |
101 | 92fc4b58 | Blue Swirl | void helper_boundl(CPUX86State *env, target_ulong a0, int v) |
102 | 10774999 | Blue Swirl | { |
103 | 10774999 | Blue Swirl | int low, high;
|
104 | 10774999 | Blue Swirl | |
105 | 92fc4b58 | Blue Swirl | low = cpu_ldl_data(env, a0); |
106 | 92fc4b58 | Blue Swirl | high = cpu_ldl_data(env, a0 + 4);
|
107 | 10774999 | Blue Swirl | if (v < low || v > high) {
|
108 | 10774999 | Blue Swirl | raise_exception(env, EXCP05_BOUND); |
109 | 10774999 | Blue Swirl | } |
110 | 10774999 | Blue Swirl | } |
111 | 10774999 | Blue Swirl | |
112 | 10774999 | Blue Swirl | #if !defined(CONFIG_USER_ONLY)
|
113 | 10774999 | Blue Swirl | |
114 | 10774999 | Blue Swirl | #define MMUSUFFIX _mmu
|
115 | 10774999 | Blue Swirl | |
116 | 10774999 | Blue Swirl | #define SHIFT 0 |
117 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
118 | 10774999 | Blue Swirl | |
119 | 10774999 | Blue Swirl | #define SHIFT 1 |
120 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
121 | 10774999 | Blue Swirl | |
122 | 10774999 | Blue Swirl | #define SHIFT 2 |
123 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
124 | 10774999 | Blue Swirl | |
125 | 10774999 | Blue Swirl | #define SHIFT 3 |
126 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
127 | 10774999 | Blue Swirl | |
128 | 10774999 | Blue Swirl | #endif
|
129 | 10774999 | Blue Swirl | |
130 | 10774999 | Blue Swirl | #if !defined(CONFIG_USER_ONLY)
|
131 | 10774999 | Blue Swirl | /* try to fill the TLB and return an exception if error. If retaddr is
|
132 | 10774999 | Blue Swirl | NULL, it means that the function was called in C code (i.e. not
|
133 | 10774999 | Blue Swirl | from generated code or from helper.c) */
|
134 | 10774999 | Blue Swirl | /* XXX: fix it to restore all registers */
|
135 | 92fc4b58 | Blue Swirl | void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx, |
136 | 10774999 | Blue Swirl | uintptr_t retaddr) |
137 | 10774999 | Blue Swirl | { |
138 | 10774999 | Blue Swirl | int ret;
|
139 | 10774999 | Blue Swirl | |
140 | 10774999 | Blue Swirl | ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx); |
141 | 10774999 | Blue Swirl | if (ret) {
|
142 | 10774999 | Blue Swirl | if (retaddr) {
|
143 | 10774999 | Blue Swirl | /* now we have a real cpu fault */
|
144 | a8a826a3 | Blue Swirl | cpu_restore_state(env, retaddr); |
145 | 10774999 | Blue Swirl | } |
146 | 10774999 | Blue Swirl | raise_exception_err(env, env->exception_index, env->error_code); |
147 | 10774999 | Blue Swirl | } |
148 | 10774999 | Blue Swirl | } |
149 | 10774999 | Blue Swirl | #endif |