Revision dffdaf61 hw/ppc/spapr_hcall.c
b/hw/ppc/spapr_hcall.c | ||
---|---|---|
52 | 52 |
target_ulong page_shift = 12; |
53 | 53 |
target_ulong raddr; |
54 | 54 |
target_ulong i; |
55 |
uint8_t *hpte;
|
|
55 |
hwaddr hpte;
|
|
56 | 56 |
|
57 | 57 |
/* only handle 4k and 16M pages for now */ |
58 | 58 |
if (pteh & HPTE64_V_LARGE) { |
... | ... | |
97 | 97 |
} |
98 | 98 |
if (likely((flags & H_EXACT) == 0)) { |
99 | 99 |
pte_index &= ~7ULL; |
100 |
hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
|
|
100 |
hpte = pte_index * HASH_PTE_SIZE_64;
|
|
101 | 101 |
for (i = 0; ; ++i) { |
102 | 102 |
if (i == 8) { |
103 | 103 |
return H_PTEG_FULL; |
104 | 104 |
} |
105 |
if ((ldq_p(hpte) & HPTE64_V_VALID) == 0) {
|
|
105 |
if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) {
|
|
106 | 106 |
break; |
107 | 107 |
} |
108 | 108 |
hpte += HASH_PTE_SIZE_64; |
109 | 109 |
} |
110 | 110 |
} else { |
111 | 111 |
i = 0; |
112 |
hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
|
|
113 |
if (ldq_p(hpte) & HPTE64_V_VALID) {
|
|
112 |
hpte = pte_index * HASH_PTE_SIZE_64;
|
|
113 |
if (ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) {
|
|
114 | 114 |
return H_PTEG_FULL; |
115 | 115 |
} |
116 | 116 |
} |
117 |
stq_p(hpte + (HASH_PTE_SIZE_64/2), ptel);
|
|
117 |
ppc_hash64_store_hpte1(env, hpte, ptel);
|
|
118 | 118 |
/* eieio(); FIXME: need some sort of barrier for smp? */ |
119 |
stq_p(hpte, pteh);
|
|
119 |
ppc_hash64_store_hpte0(env, hpte, pteh);
|
|
120 | 120 |
|
121 | 121 |
args[0] = pte_index + i; |
122 | 122 |
return H_SUCCESS; |
... | ... | |
134 | 134 |
target_ulong flags, |
135 | 135 |
target_ulong *vp, target_ulong *rp) |
136 | 136 |
{ |
137 |
uint8_t *hpte;
|
|
137 |
hwaddr hpte;
|
|
138 | 138 |
target_ulong v, r, rb; |
139 | 139 |
|
140 | 140 |
if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) { |
141 | 141 |
return REMOVE_PARM; |
142 | 142 |
} |
143 | 143 |
|
144 |
hpte = env->external_htab + (ptex * HASH_PTE_SIZE_64);
|
|
144 |
hpte = ptex * HASH_PTE_SIZE_64;
|
|
145 | 145 |
|
146 |
v = ldq_p(hpte);
|
|
147 |
r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
|
|
146 |
v = ppc_hash64_load_hpte0(env, hpte);
|
|
147 |
r = ppc_hash64_load_hpte1(env, hpte);
|
|
148 | 148 |
|
149 | 149 |
if ((v & HPTE64_V_VALID) == 0 || |
150 | 150 |
((flags & H_AVPN) && (v & ~0x7fULL) != avpn) || |
... | ... | |
153 | 153 |
} |
154 | 154 |
*vp = v; |
155 | 155 |
*rp = r; |
156 |
stq_p(hpte, 0);
|
|
156 |
ppc_hash64_store_hpte0(env, hpte, 0);
|
|
157 | 157 |
rb = compute_tlbie_rb(v, r, ptex); |
158 | 158 |
ppc_tlb_invalidate_one(env, rb); |
159 | 159 |
return REMOVE_SUCCESS; |
... | ... | |
260 | 260 |
target_ulong flags = args[0]; |
261 | 261 |
target_ulong pte_index = args[1]; |
262 | 262 |
target_ulong avpn = args[2]; |
263 |
uint8_t *hpte;
|
|
263 |
hwaddr hpte;
|
|
264 | 264 |
target_ulong v, r, rb; |
265 | 265 |
|
266 | 266 |
if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) { |
267 | 267 |
return H_PARAMETER; |
268 | 268 |
} |
269 | 269 |
|
270 |
hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
|
|
270 |
hpte = pte_index * HASH_PTE_SIZE_64;
|
|
271 | 271 |
|
272 |
v = ldq_p(hpte);
|
|
273 |
r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
|
|
272 |
v = ppc_hash64_load_hpte0(env, hpte);
|
|
273 |
r = ppc_hash64_load_hpte1(env, hpte);
|
|
274 | 274 |
|
275 | 275 |
if ((v & HPTE64_V_VALID) == 0 || |
276 | 276 |
((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) { |
... | ... | |
283 | 283 |
r |= (flags << 48) & HPTE64_R_KEY_HI; |
284 | 284 |
r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO); |
285 | 285 |
rb = compute_tlbie_rb(v, r, pte_index); |
286 |
stq_p(hpte, v & ~HPTE64_V_VALID);
|
|
286 |
ppc_hash64_store_hpte0(env, hpte, v & ~HPTE64_V_VALID);
|
|
287 | 287 |
ppc_tlb_invalidate_one(env, rb); |
288 |
stq_p(hpte + (HASH_PTE_SIZE_64/2), r);
|
|
288 |
ppc_hash64_store_hpte1(env, hpte, r);
|
|
289 | 289 |
/* Don't need a memory barrier, due to qemu's global lock */ |
290 |
stq_p(hpte, v);
|
|
290 |
ppc_hash64_store_hpte0(env, hpte, v);
|
|
291 | 291 |
return H_SUCCESS; |
292 | 292 |
} |
293 | 293 |
|
Also available in: Unified diff