]> git.proxmox.com Git - qemu.git/blame - softmmu_header.h
fdc: fix FD_SR0_SEEK for non-DMA transfers and multi sectors transfers
[qemu.git] / softmmu_header.h
CommitLineData
b92e5a22
FB
1/*
2 * Software MMU support
5fafdf24 3 *
efbf29b6
BS
4 * Generate inline load/store functions for one MMU mode and data
5 * size.
6 *
7 * Generate a store function as well as signed and unsigned loads. For
8 * 32 and 64 bit cases, also generate floating point functions with
9 * the same size.
10 *
11 * Not used directly but included from softmmu_exec.h and exec-all.h.
12 *
b92e5a22
FB
13 * Copyright (c) 2003 Fabrice Bellard
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
8167ee88 26 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
b92e5a22
FB
27 */
28#if DATA_SIZE == 8
29#define SUFFIX q
61382a50 30#define USUFFIX q
b92e5a22
FB
31#define DATA_TYPE uint64_t
32#elif DATA_SIZE == 4
33#define SUFFIX l
61382a50 34#define USUFFIX l
b92e5a22
FB
35#define DATA_TYPE uint32_t
36#elif DATA_SIZE == 2
37#define SUFFIX w
61382a50 38#define USUFFIX uw
b92e5a22
FB
39#define DATA_TYPE uint16_t
40#define DATA_STYPE int16_t
41#elif DATA_SIZE == 1
42#define SUFFIX b
61382a50 43#define USUFFIX ub
b92e5a22
FB
44#define DATA_TYPE uint8_t
45#define DATA_STYPE int8_t
46#else
47#error unsupported data size
48#endif
49
6ebbf390 50#if ACCESS_TYPE < (NB_MMU_MODES)
61382a50 51
6ebbf390 52#define CPU_MMU_INDEX ACCESS_TYPE
61382a50
FB
53#define MMUSUFFIX _mmu
54
6ebbf390 55#elif ACCESS_TYPE == (NB_MMU_MODES)
61382a50 56
6ebbf390 57#define CPU_MMU_INDEX (cpu_mmu_index(env))
61382a50
FB
58#define MMUSUFFIX _mmu
59
6ebbf390 60#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
61382a50 61
6ebbf390 62#define CPU_MMU_INDEX (cpu_mmu_index(env))
61382a50
FB
63#define MMUSUFFIX _cmmu
64
b92e5a22 65#else
61382a50 66#error invalid ACCESS_TYPE
b92e5a22
FB
67#endif
68
69#if DATA_SIZE == 8
70#define RES_TYPE uint64_t
71#else
c086b783 72#define RES_TYPE uint32_t
b92e5a22
FB
73#endif
74
6ebbf390 75#if ACCESS_TYPE == (NB_MMU_MODES + 1)
84b7b8e7
FB
76#define ADDR_READ addr_code
77#else
78#define ADDR_READ addr_read
79#endif
b92e5a22 80
e16c53fa
FB
81/* generic load/store macros */
82
e141ab52 83static inline RES_TYPE
89c33337 84glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
b92e5a22 85{
4d7a0880 86 int page_index;
b92e5a22 87 RES_TYPE res;
c27004ec 88 target_ulong addr;
6ebbf390 89 int mmu_idx;
61382a50 90
c27004ec 91 addr = ptr;
4d7a0880 92 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
6ebbf390 93 mmu_idx = CPU_MMU_INDEX;
551bd27f
TS
94 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
95 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
89c33337 96 res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
b92e5a22 97 } else {
23ddbf08 98 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
b065927a 99 res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
b92e5a22
FB
100 }
101 return res;
102}
103
104#if DATA_SIZE <= 2
e141ab52 105static inline int
89c33337 106glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
b92e5a22 107{
4d7a0880 108 int res, page_index;
c27004ec 109 target_ulong addr;
6ebbf390 110 int mmu_idx;
61382a50 111
c27004ec 112 addr = ptr;
4d7a0880 113 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
6ebbf390 114 mmu_idx = CPU_MMU_INDEX;
551bd27f
TS
115 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
116 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
89c33337
BS
117 res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
118 MMUSUFFIX)(env, addr, mmu_idx);
b92e5a22 119 } else {
23ddbf08 120 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
b065927a 121 res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
b92e5a22
FB
122 }
123 return res;
124}
125#endif
126
6ebbf390 127#if ACCESS_TYPE != (NB_MMU_MODES + 1)
84b7b8e7 128
e16c53fa
FB
129/* generic store macro */
130
e141ab52 131static inline void
89c33337
BS
132glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
133 RES_TYPE v)
b92e5a22 134{
4d7a0880 135 int page_index;
c27004ec 136 target_ulong addr;
6ebbf390 137 int mmu_idx;
61382a50 138
c27004ec 139 addr = ptr;
4d7a0880 140 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
6ebbf390 141 mmu_idx = CPU_MMU_INDEX;
551bd27f
TS
142 if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
143 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
89c33337 144 glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
b92e5a22 145 } else {
23ddbf08 146 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
b065927a 147 glue(glue(st, SUFFIX), _raw)(hostaddr, v);
b92e5a22
FB
148 }
149}
150
6ebbf390 151#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
84b7b8e7 152
6ebbf390 153#if ACCESS_TYPE != (NB_MMU_MODES + 1)
e16c53fa 154
2d603d22 155#if DATA_SIZE == 8
89c33337
BS
156static inline float64 glue(cpu_ldfq, MEMSUFFIX)(CPUArchState *env,
157 target_ulong ptr)
2d603d22
FB
158{
159 union {
3f87bf69 160 float64 d;
2d603d22
FB
161 uint64_t i;
162 } u;
89c33337 163 u.i = glue(cpu_ldq, MEMSUFFIX)(env, ptr);
2d603d22
FB
164 return u.d;
165}
166
89c33337
BS
167static inline void glue(cpu_stfq, MEMSUFFIX)(CPUArchState *env,
168 target_ulong ptr, float64 v)
2d603d22
FB
169{
170 union {
3f87bf69 171 float64 d;
2d603d22
FB
172 uint64_t i;
173 } u;
174 u.d = v;
89c33337 175 glue(cpu_stq, MEMSUFFIX)(env, ptr, u.i);
2d603d22
FB
176}
177#endif /* DATA_SIZE == 8 */
178
179#if DATA_SIZE == 4
89c33337
BS
180static inline float32 glue(cpu_ldfl, MEMSUFFIX)(CPUArchState *env,
181 target_ulong ptr)
2d603d22
FB
182{
183 union {
3f87bf69 184 float32 f;
2d603d22
FB
185 uint32_t i;
186 } u;
89c33337 187 u.i = glue(cpu_ldl, MEMSUFFIX)(env, ptr);
2d603d22
FB
188 return u.f;
189}
190
89c33337
BS
191static inline void glue(cpu_stfl, MEMSUFFIX)(CPUArchState *env,
192 target_ulong ptr, float32 v)
2d603d22
FB
193{
194 union {
3f87bf69 195 float32 f;
2d603d22
FB
196 uint32_t i;
197 } u;
198 u.f = v;
89c33337 199 glue(cpu_stl, MEMSUFFIX)(env, ptr, u.i);
2d603d22
FB
200}
201#endif /* DATA_SIZE == 4 */
202
6ebbf390 203#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
84b7b8e7 204
b92e5a22
FB
205#undef RES_TYPE
206#undef DATA_TYPE
207#undef DATA_STYPE
208#undef SUFFIX
61382a50 209#undef USUFFIX
b92e5a22 210#undef DATA_SIZE
6ebbf390 211#undef CPU_MMU_INDEX
61382a50 212#undef MMUSUFFIX
84b7b8e7 213#undef ADDR_READ