VirtualBox

source: vbox/trunk/src/recompiler/softmmu_header.h@ 38305

Last change on this file since 38305 was 38300, checked in by vboxsync, 14 years ago

REM,PGM: Fix A20 syncing between the VMM and the recompiler.

  • Property svn:eol-style set to native
File size: 5.6 KB
Line 
1/*
2 * Software MMU support
3 *
4 * Copyright (c) 2003 Fabrice Bellard
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
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
22 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
23 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
24 * a choice of LGPL license versions is made available with the language indicating
25 * that LGPLv2 or any later version may be used, or where a choice of which version
26 * of the LGPL is applied is otherwise unspecified.
27 */
28
29#if DATA_SIZE == 8
30#define SUFFIX q
31#define USUFFIX q
32#define DATA_TYPE uint64_t
33#elif DATA_SIZE == 4
34#define SUFFIX l
35#define USUFFIX l
36#define DATA_TYPE uint32_t
37#elif DATA_SIZE == 2
38#define SUFFIX w
39#define USUFFIX uw
40#define DATA_TYPE uint16_t
41#define DATA_STYPE int16_t
42#elif DATA_SIZE == 1
43#define SUFFIX b
44#define USUFFIX ub
45#define DATA_TYPE uint8_t
46#define DATA_STYPE int8_t
47#else
48#error unsupported data size
49#endif
50
51#if ACCESS_TYPE < (NB_MMU_MODES)
52
53#define CPU_MMU_INDEX ACCESS_TYPE
54#define MMUSUFFIX _mmu
55
56#elif ACCESS_TYPE == (NB_MMU_MODES)
57
58#define CPU_MMU_INDEX (cpu_mmu_index(env))
59#define MMUSUFFIX _mmu
60
61#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
62
63#define CPU_MMU_INDEX (cpu_mmu_index(env))
64#define MMUSUFFIX _cmmu
65
66#else
67#error invalid ACCESS_TYPE
68#endif
69
70#if DATA_SIZE == 8
71#define RES_TYPE uint64_t
72#else
73#define RES_TYPE uint32_t
74#endif
75
76#if ACCESS_TYPE == (NB_MMU_MODES + 1)
77#define ADDR_READ addr_code
78#else
79#define ADDR_READ addr_read
80#endif
81
82/* generic load/store macros */
83
84static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
85{
86 int page_index;
87 RES_TYPE res;
88 target_ulong addr;
89#ifdef VBOX
90 uintptr_t physaddr;
91#else
92 unsigned long physaddr;
93#endif
94 int mmu_idx;
95
96 addr = ptr;
97 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
98 mmu_idx = CPU_MMU_INDEX;
99 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
100 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
101 res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
102 } else {
103 physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
104 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
105 }
106 return res;
107}
108
109#if DATA_SIZE <= 2
110static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
111{
112 int res, page_index;
113 target_ulong addr;
114#ifdef VBOX
115 uintptr_t physaddr;
116#else
117 unsigned long physaddr;
118#endif
119 int mmu_idx;
120
121 addr = ptr;
122 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
123 mmu_idx = CPU_MMU_INDEX;
124 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
125 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
126 res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
127 } else {
128 physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
129 res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
130 }
131 return res;
132}
133#endif
134
135#if ACCESS_TYPE != (NB_MMU_MODES + 1)
136
137/* generic store macro */
138
139static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
140{
141 int page_index;
142 target_ulong addr;
143#ifdef VBOX
144 uintptr_t physaddr;
145#else
146 unsigned long physaddr;
147#endif
148 int mmu_idx;
149
150 addr = ptr;
151 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
152 mmu_idx = CPU_MMU_INDEX;
153 if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
154 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
155 glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
156 } else {
157 physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
158 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
159 }
160}
161
162#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
163
164#if ACCESS_TYPE != (NB_MMU_MODES + 1)
165
166#if DATA_SIZE == 8
167static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
168{
169 union {
170 float64 d;
171 uint64_t i;
172 } u;
173 u.i = glue(ldq, MEMSUFFIX)(ptr);
174 return u.d;
175}
176
177static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
178{
179 union {
180 float64 d;
181 uint64_t i;
182 } u;
183 u.d = v;
184 glue(stq, MEMSUFFIX)(ptr, u.i);
185}
186#endif /* DATA_SIZE == 8 */
187
188#if DATA_SIZE == 4
189static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
190{
191 union {
192 float32 f;
193 uint32_t i;
194 } u;
195 u.i = glue(ldl, MEMSUFFIX)(ptr);
196 return u.f;
197}
198
199static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
200{
201 union {
202 float32 f;
203 uint32_t i;
204 } u;
205 u.f = v;
206 glue(stl, MEMSUFFIX)(ptr, u.i);
207}
208#endif /* DATA_SIZE == 4 */
209
210#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
211
212#undef RES_TYPE
213#undef DATA_TYPE
214#undef DATA_STYPE
215#undef SUFFIX
216#undef USUFFIX
217#undef DATA_SIZE
218#undef CPU_MMU_INDEX
219#undef MMUSUFFIX
220#undef ADDR_READ
221
222#include <iprt/assert.h>
223AssertCompileSize(uint64_t,8);
224AssertCompileSize(uint32_t,4);
225AssertCompileSize(uint16_t,2);
226AssertCompileSize(uint8_t,1);
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette