root / softmmu_header.h @ 9c9efb6b
History | View | Annotate | Download (4.8 kB)
1 | b92e5a22 | bellard | /*
|
---|---|---|---|
2 | b92e5a22 | bellard | * Software MMU support
|
3 | 5fafdf24 | ths | *
|
4 | b92e5a22 | bellard | * Copyright (c) 2003 Fabrice Bellard
|
5 | b92e5a22 | bellard | *
|
6 | b92e5a22 | bellard | * This library is free software; you can redistribute it and/or
|
7 | b92e5a22 | bellard | * modify it under the terms of the GNU Lesser General Public
|
8 | b92e5a22 | bellard | * License as published by the Free Software Foundation; either
|
9 | b92e5a22 | bellard | * version 2 of the License, or (at your option) any later version.
|
10 | b92e5a22 | bellard | *
|
11 | b92e5a22 | bellard | * This library is distributed in the hope that it will be useful,
|
12 | b92e5a22 | bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | b92e5a22 | bellard | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | b92e5a22 | bellard | * Lesser General Public License for more details.
|
15 | b92e5a22 | bellard | *
|
16 | b92e5a22 | bellard | * 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 | b92e5a22 | bellard | */
|
19 | b92e5a22 | bellard | #if DATA_SIZE == 8 |
20 | b92e5a22 | bellard | #define SUFFIX q
|
21 | 61382a50 | bellard | #define USUFFIX q
|
22 | b92e5a22 | bellard | #define DATA_TYPE uint64_t
|
23 | b92e5a22 | bellard | #elif DATA_SIZE == 4 |
24 | b92e5a22 | bellard | #define SUFFIX l
|
25 | 61382a50 | bellard | #define USUFFIX l
|
26 | b92e5a22 | bellard | #define DATA_TYPE uint32_t
|
27 | b92e5a22 | bellard | #elif DATA_SIZE == 2 |
28 | b92e5a22 | bellard | #define SUFFIX w
|
29 | 61382a50 | bellard | #define USUFFIX uw
|
30 | b92e5a22 | bellard | #define DATA_TYPE uint16_t
|
31 | b92e5a22 | bellard | #define DATA_STYPE int16_t
|
32 | b92e5a22 | bellard | #elif DATA_SIZE == 1 |
33 | b92e5a22 | bellard | #define SUFFIX b
|
34 | 61382a50 | bellard | #define USUFFIX ub
|
35 | b92e5a22 | bellard | #define DATA_TYPE uint8_t
|
36 | b92e5a22 | bellard | #define DATA_STYPE int8_t
|
37 | b92e5a22 | bellard | #else
|
38 | b92e5a22 | bellard | #error unsupported data size
|
39 | b92e5a22 | bellard | #endif
|
40 | b92e5a22 | bellard | |
41 | 6ebbf390 | j_mayer | #if ACCESS_TYPE < (NB_MMU_MODES)
|
42 | 61382a50 | bellard | |
43 | 6ebbf390 | j_mayer | #define CPU_MMU_INDEX ACCESS_TYPE
|
44 | 61382a50 | bellard | #define MMUSUFFIX _mmu
|
45 | 61382a50 | bellard | |
46 | 6ebbf390 | j_mayer | #elif ACCESS_TYPE == (NB_MMU_MODES)
|
47 | 61382a50 | bellard | |
48 | 6ebbf390 | j_mayer | #define CPU_MMU_INDEX (cpu_mmu_index(env))
|
49 | 61382a50 | bellard | #define MMUSUFFIX _mmu
|
50 | 61382a50 | bellard | |
51 | 6ebbf390 | j_mayer | #elif ACCESS_TYPE == (NB_MMU_MODES + 1) |
52 | 61382a50 | bellard | |
53 | 6ebbf390 | j_mayer | #define CPU_MMU_INDEX (cpu_mmu_index(env))
|
54 | 61382a50 | bellard | #define MMUSUFFIX _cmmu
|
55 | 61382a50 | bellard | |
56 | b92e5a22 | bellard | #else
|
57 | 61382a50 | bellard | #error invalid ACCESS_TYPE
|
58 | b92e5a22 | bellard | #endif
|
59 | b92e5a22 | bellard | |
60 | b92e5a22 | bellard | #if DATA_SIZE == 8 |
61 | b92e5a22 | bellard | #define RES_TYPE uint64_t
|
62 | b92e5a22 | bellard | #else
|
63 | b92e5a22 | bellard | #define RES_TYPE int |
64 | b92e5a22 | bellard | #endif
|
65 | b92e5a22 | bellard | |
66 | 6ebbf390 | j_mayer | #if ACCESS_TYPE == (NB_MMU_MODES + 1) |
67 | 84b7b8e7 | bellard | #define ADDR_READ addr_code
|
68 | 84b7b8e7 | bellard | #else
|
69 | 84b7b8e7 | bellard | #define ADDR_READ addr_read
|
70 | 84b7b8e7 | bellard | #endif
|
71 | b92e5a22 | bellard | |
72 | e16c53fa | bellard | /* generic load/store macros */
|
73 | e16c53fa | bellard | |
74 | c27004ec | bellard | static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) |
75 | b92e5a22 | bellard | { |
76 | 4d7a0880 | blueswir1 | int page_index;
|
77 | b92e5a22 | bellard | RES_TYPE res; |
78 | c27004ec | bellard | target_ulong addr; |
79 | c27004ec | bellard | unsigned long physaddr; |
80 | 6ebbf390 | j_mayer | int mmu_idx;
|
81 | 61382a50 | bellard | |
82 | c27004ec | bellard | addr = ptr; |
83 | 4d7a0880 | blueswir1 | page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
84 | 6ebbf390 | j_mayer | mmu_idx = CPU_MMU_INDEX; |
85 | 551bd27f | ths | if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
|
86 | 551bd27f | ths | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
|
87 | 6ebbf390 | j_mayer | res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx); |
88 | b92e5a22 | bellard | } else {
|
89 | 4d7a0880 | blueswir1 | physaddr = addr + env->tlb_table[mmu_idx][page_index].addend; |
90 | 61382a50 | bellard | res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); |
91 | b92e5a22 | bellard | } |
92 | b92e5a22 | bellard | return res;
|
93 | b92e5a22 | bellard | } |
94 | b92e5a22 | bellard | |
95 | b92e5a22 | bellard | #if DATA_SIZE <= 2 |
96 | c27004ec | bellard | static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) |
97 | b92e5a22 | bellard | { |
98 | 4d7a0880 | blueswir1 | int res, page_index;
|
99 | c27004ec | bellard | target_ulong addr; |
100 | c27004ec | bellard | unsigned long physaddr; |
101 | 6ebbf390 | j_mayer | int mmu_idx;
|
102 | 61382a50 | bellard | |
103 | c27004ec | bellard | addr = ptr; |
104 | 4d7a0880 | blueswir1 | page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
105 | 6ebbf390 | j_mayer | mmu_idx = CPU_MMU_INDEX; |
106 | 551bd27f | ths | if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
|
107 | 551bd27f | ths | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
|
108 | 6ebbf390 | j_mayer | res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx); |
109 | b92e5a22 | bellard | } else {
|
110 | 4d7a0880 | blueswir1 | physaddr = addr + env->tlb_table[mmu_idx][page_index].addend; |
111 | b92e5a22 | bellard | res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); |
112 | b92e5a22 | bellard | } |
113 | b92e5a22 | bellard | return res;
|
114 | b92e5a22 | bellard | } |
115 | b92e5a22 | bellard | #endif
|
116 | b92e5a22 | bellard | |
117 | 6ebbf390 | j_mayer | #if ACCESS_TYPE != (NB_MMU_MODES + 1) |
118 | 84b7b8e7 | bellard | |
119 | e16c53fa | bellard | /* generic store macro */
|
120 | e16c53fa | bellard | |
121 | c27004ec | bellard | static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) |
122 | b92e5a22 | bellard | { |
123 | 4d7a0880 | blueswir1 | int page_index;
|
124 | c27004ec | bellard | target_ulong addr; |
125 | c27004ec | bellard | unsigned long physaddr; |
126 | 6ebbf390 | j_mayer | int mmu_idx;
|
127 | 61382a50 | bellard | |
128 | c27004ec | bellard | addr = ptr; |
129 | 4d7a0880 | blueswir1 | page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
130 | 6ebbf390 | j_mayer | mmu_idx = CPU_MMU_INDEX; |
131 | 551bd27f | ths | if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
|
132 | 551bd27f | ths | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
|
133 | 6ebbf390 | j_mayer | glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx); |
134 | b92e5a22 | bellard | } else {
|
135 | 4d7a0880 | blueswir1 | physaddr = addr + env->tlb_table[mmu_idx][page_index].addend; |
136 | b92e5a22 | bellard | glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); |
137 | b92e5a22 | bellard | } |
138 | b92e5a22 | bellard | } |
139 | b92e5a22 | bellard | |
140 | 6ebbf390 | j_mayer | #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ |
141 | 84b7b8e7 | bellard | |
142 | 6ebbf390 | j_mayer | #if ACCESS_TYPE != (NB_MMU_MODES + 1) |
143 | e16c53fa | bellard | |
144 | 2d603d22 | bellard | #if DATA_SIZE == 8 |
145 | 3f87bf69 | bellard | static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr) |
146 | 2d603d22 | bellard | { |
147 | 2d603d22 | bellard | union {
|
148 | 3f87bf69 | bellard | float64 d; |
149 | 2d603d22 | bellard | uint64_t i; |
150 | 2d603d22 | bellard | } u; |
151 | 2d603d22 | bellard | u.i = glue(ldq, MEMSUFFIX)(ptr); |
152 | 2d603d22 | bellard | return u.d;
|
153 | 2d603d22 | bellard | } |
154 | 2d603d22 | bellard | |
155 | 3f87bf69 | bellard | static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v) |
156 | 2d603d22 | bellard | { |
157 | 2d603d22 | bellard | union {
|
158 | 3f87bf69 | bellard | float64 d; |
159 | 2d603d22 | bellard | uint64_t i; |
160 | 2d603d22 | bellard | } u; |
161 | 2d603d22 | bellard | u.d = v; |
162 | 2d603d22 | bellard | glue(stq, MEMSUFFIX)(ptr, u.i); |
163 | 2d603d22 | bellard | } |
164 | 2d603d22 | bellard | #endif /* DATA_SIZE == 8 */ |
165 | 2d603d22 | bellard | |
166 | 2d603d22 | bellard | #if DATA_SIZE == 4 |
167 | 3f87bf69 | bellard | static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr) |
168 | 2d603d22 | bellard | { |
169 | 2d603d22 | bellard | union {
|
170 | 3f87bf69 | bellard | float32 f; |
171 | 2d603d22 | bellard | uint32_t i; |
172 | 2d603d22 | bellard | } u; |
173 | 2d603d22 | bellard | u.i = glue(ldl, MEMSUFFIX)(ptr); |
174 | 2d603d22 | bellard | return u.f;
|
175 | 2d603d22 | bellard | } |
176 | 2d603d22 | bellard | |
177 | 3f87bf69 | bellard | static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v) |
178 | 2d603d22 | bellard | { |
179 | 2d603d22 | bellard | union {
|
180 | 3f87bf69 | bellard | float32 f; |
181 | 2d603d22 | bellard | uint32_t i; |
182 | 2d603d22 | bellard | } u; |
183 | 2d603d22 | bellard | u.f = v; |
184 | 2d603d22 | bellard | glue(stl, MEMSUFFIX)(ptr, u.i); |
185 | 2d603d22 | bellard | } |
186 | 2d603d22 | bellard | #endif /* DATA_SIZE == 4 */ |
187 | 2d603d22 | bellard | |
188 | 6ebbf390 | j_mayer | #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ |
189 | 84b7b8e7 | bellard | |
190 | b92e5a22 | bellard | #undef RES_TYPE
|
191 | b92e5a22 | bellard | #undef DATA_TYPE
|
192 | b92e5a22 | bellard | #undef DATA_STYPE
|
193 | b92e5a22 | bellard | #undef SUFFIX
|
194 | 61382a50 | bellard | #undef USUFFIX
|
195 | b92e5a22 | bellard | #undef DATA_SIZE
|
196 | 6ebbf390 | j_mayer | #undef CPU_MMU_INDEX
|
197 | 61382a50 | bellard | #undef MMUSUFFIX
|
198 | 84b7b8e7 | bellard | #undef ADDR_READ |