]> git.proxmox.com Git - qemu.git/blob - target-ppc/helper.c
2944b062a520da910cf2b5063ed5c62161bbe649
[qemu.git] / target-ppc / helper.c
1 /*
2 * PowerPC emulation helpers for qemu.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
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 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <inttypes.h>
24
25 #include "cpu.h"
26 #include "exec-all.h"
27 #include "helper_regs.h"
28 #include "qemu-common.h"
29 #include "kvm.h"
30
31 //#define DEBUG_MMU
32 //#define DEBUG_BATS
33 //#define DEBUG_SLB
34 //#define DEBUG_SOFTWARE_TLB
35 //#define DUMP_PAGE_TABLES
36 //#define DEBUG_EXCEPTIONS
37 //#define FLUSH_ALL_TLBS
38
39 #ifdef DEBUG_MMU
40 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
41 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
42 #else
43 # define LOG_MMU(...) do { } while (0)
44 # define LOG_MMU_STATE(...) do { } while (0)
45 #endif
46
47
48 #ifdef DEBUG_SOFTWARE_TLB
49 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
50 #else
51 # define LOG_SWTLB(...) do { } while (0)
52 #endif
53
54 #ifdef DEBUG_BATS
55 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
56 #else
57 # define LOG_BATS(...) do { } while (0)
58 #endif
59
60 #ifdef DEBUG_SLB
61 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
62 #else
63 # define LOG_SLB(...) do { } while (0)
64 #endif
65
66 #ifdef DEBUG_EXCEPTIONS
67 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
68 #else
69 # define LOG_EXCP(...) do { } while (0)
70 #endif
71
72 /*****************************************************************************/
73 /* PowerPC Hypercall emulation */
74
75 void (*cpu_ppc_hypercall)(CPUState *);
76
77 /*****************************************************************************/
78 /* PowerPC MMU emulation */
79
80 #if defined(CONFIG_USER_ONLY)
81 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
82 int mmu_idx, int is_softmmu)
83 {
84 int exception, error_code;
85
86 if (rw == 2) {
87 exception = POWERPC_EXCP_ISI;
88 error_code = 0x40000000;
89 } else {
90 exception = POWERPC_EXCP_DSI;
91 error_code = 0x40000000;
92 if (rw)
93 error_code |= 0x02000000;
94 env->spr[SPR_DAR] = address;
95 env->spr[SPR_DSISR] = error_code;
96 }
97 env->exception_index = exception;
98 env->error_code = error_code;
99
100 return 1;
101 }
102
103 #else
104 /* Common routines used by software and hardware TLBs emulation */
105 static inline int pte_is_valid(target_ulong pte0)
106 {
107 return pte0 & 0x80000000 ? 1 : 0;
108 }
109
110 static inline void pte_invalidate(target_ulong *pte0)
111 {
112 *pte0 &= ~0x80000000;
113 }
114
115 #if defined(TARGET_PPC64)
116 static inline int pte64_is_valid(target_ulong pte0)
117 {
118 return pte0 & 0x0000000000000001ULL ? 1 : 0;
119 }
120
121 static inline void pte64_invalidate(target_ulong *pte0)
122 {
123 *pte0 &= ~0x0000000000000001ULL;
124 }
125 #endif
126
127 #define PTE_PTEM_MASK 0x7FFFFFBF
128 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
129 #if defined(TARGET_PPC64)
130 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
131 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
132 #endif
133
134 static inline int pp_check(int key, int pp, int nx)
135 {
136 int access;
137
138 /* Compute access rights */
139 /* When pp is 3/7, the result is undefined. Set it to noaccess */
140 access = 0;
141 if (key == 0) {
142 switch (pp) {
143 case 0x0:
144 case 0x1:
145 case 0x2:
146 access |= PAGE_WRITE;
147 /* No break here */
148 case 0x3:
149 case 0x6:
150 access |= PAGE_READ;
151 break;
152 }
153 } else {
154 switch (pp) {
155 case 0x0:
156 case 0x6:
157 access = 0;
158 break;
159 case 0x1:
160 case 0x3:
161 access = PAGE_READ;
162 break;
163 case 0x2:
164 access = PAGE_READ | PAGE_WRITE;
165 break;
166 }
167 }
168 if (nx == 0)
169 access |= PAGE_EXEC;
170
171 return access;
172 }
173
174 static inline int check_prot(int prot, int rw, int access_type)
175 {
176 int ret;
177
178 if (access_type == ACCESS_CODE) {
179 if (prot & PAGE_EXEC)
180 ret = 0;
181 else
182 ret = -2;
183 } else if (rw) {
184 if (prot & PAGE_WRITE)
185 ret = 0;
186 else
187 ret = -2;
188 } else {
189 if (prot & PAGE_READ)
190 ret = 0;
191 else
192 ret = -2;
193 }
194
195 return ret;
196 }
197
198 static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
199 target_ulong pte1, int h, int rw, int type)
200 {
201 target_ulong ptem, mmask;
202 int access, ret, pteh, ptev, pp;
203
204 ret = -1;
205 /* Check validity and table match */
206 #if defined(TARGET_PPC64)
207 if (is_64b) {
208 ptev = pte64_is_valid(pte0);
209 pteh = (pte0 >> 1) & 1;
210 } else
211 #endif
212 {
213 ptev = pte_is_valid(pte0);
214 pteh = (pte0 >> 6) & 1;
215 }
216 if (ptev && h == pteh) {
217 /* Check vsid & api */
218 #if defined(TARGET_PPC64)
219 if (is_64b) {
220 ptem = pte0 & PTE64_PTEM_MASK;
221 mmask = PTE64_CHECK_MASK;
222 pp = (pte1 & 0x00000003) | ((pte1 >> 61) & 0x00000004);
223 ctx->nx = (pte1 >> 2) & 1; /* No execute bit */
224 ctx->nx |= (pte1 >> 3) & 1; /* Guarded bit */
225 } else
226 #endif
227 {
228 ptem = pte0 & PTE_PTEM_MASK;
229 mmask = PTE_CHECK_MASK;
230 pp = pte1 & 0x00000003;
231 }
232 if (ptem == ctx->ptem) {
233 if (ctx->raddr != (target_phys_addr_t)-1ULL) {
234 /* all matches should have equal RPN, WIMG & PP */
235 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
236 qemu_log("Bad RPN/WIMG/PP\n");
237 return -3;
238 }
239 }
240 /* Compute access rights */
241 access = pp_check(ctx->key, pp, ctx->nx);
242 /* Keep the matching PTE informations */
243 ctx->raddr = pte1;
244 ctx->prot = access;
245 ret = check_prot(ctx->prot, rw, type);
246 if (ret == 0) {
247 /* Access granted */
248 LOG_MMU("PTE access granted !\n");
249 } else {
250 /* Access right violation */
251 LOG_MMU("PTE access rejected\n");
252 }
253 }
254 }
255
256 return ret;
257 }
258
259 static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
260 target_ulong pte1, int h, int rw, int type)
261 {
262 return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
263 }
264
265 #if defined(TARGET_PPC64)
266 static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
267 target_ulong pte1, int h, int rw, int type)
268 {
269 return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
270 }
271 #endif
272
273 static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
274 int ret, int rw)
275 {
276 int store = 0;
277
278 /* Update page flags */
279 if (!(*pte1p & 0x00000100)) {
280 /* Update accessed flag */
281 *pte1p |= 0x00000100;
282 store = 1;
283 }
284 if (!(*pte1p & 0x00000080)) {
285 if (rw == 1 && ret == 0) {
286 /* Update changed flag */
287 *pte1p |= 0x00000080;
288 store = 1;
289 } else {
290 /* Force page fault for first write access */
291 ctx->prot &= ~PAGE_WRITE;
292 }
293 }
294
295 return store;
296 }
297
298 /* Software driven TLB helpers */
299 static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
300 int is_code)
301 {
302 int nr;
303
304 /* Select TLB num in a way from address */
305 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
306 /* Select TLB way */
307 nr += env->tlb_per_way * way;
308 /* 6xx have separate TLBs for instructions and data */
309 if (is_code && env->id_tlbs == 1)
310 nr += env->nb_tlb;
311
312 return nr;
313 }
314
315 static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
316 {
317 ppc6xx_tlb_t *tlb;
318 int nr, max;
319
320 //LOG_SWTLB("Invalidate all TLBs\n");
321 /* Invalidate all defined software TLB */
322 max = env->nb_tlb;
323 if (env->id_tlbs == 1)
324 max *= 2;
325 for (nr = 0; nr < max; nr++) {
326 tlb = &env->tlb[nr].tlb6;
327 pte_invalidate(&tlb->pte0);
328 }
329 tlb_flush(env, 1);
330 }
331
332 static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env,
333 target_ulong eaddr,
334 int is_code, int match_epn)
335 {
336 #if !defined(FLUSH_ALL_TLBS)
337 ppc6xx_tlb_t *tlb;
338 int way, nr;
339
340 /* Invalidate ITLB + DTLB, all ways */
341 for (way = 0; way < env->nb_ways; way++) {
342 nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
343 tlb = &env->tlb[nr].tlb6;
344 if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
345 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr,
346 env->nb_tlb, eaddr);
347 pte_invalidate(&tlb->pte0);
348 tlb_flush_page(env, tlb->EPN);
349 }
350 }
351 #else
352 /* XXX: PowerPC specification say this is valid as well */
353 ppc6xx_tlb_invalidate_all(env);
354 #endif
355 }
356
357 static inline void ppc6xx_tlb_invalidate_virt(CPUState *env,
358 target_ulong eaddr, int is_code)
359 {
360 __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
361 }
362
363 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
364 target_ulong pte0, target_ulong pte1)
365 {
366 ppc6xx_tlb_t *tlb;
367 int nr;
368
369 nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
370 tlb = &env->tlb[nr].tlb6;
371 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
372 " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
373 /* Invalidate any pending reference in Qemu for this virtual address */
374 __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
375 tlb->pte0 = pte0;
376 tlb->pte1 = pte1;
377 tlb->EPN = EPN;
378 /* Store last way for LRU mechanism */
379 env->last_way = way;
380 }
381
382 static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
383 target_ulong eaddr, int rw, int access_type)
384 {
385 ppc6xx_tlb_t *tlb;
386 int nr, best, way;
387 int ret;
388
389 best = -1;
390 ret = -1; /* No TLB found */
391 for (way = 0; way < env->nb_ways; way++) {
392 nr = ppc6xx_tlb_getnum(env, eaddr, way,
393 access_type == ACCESS_CODE ? 1 : 0);
394 tlb = &env->tlb[nr].tlb6;
395 /* This test "emulates" the PTE index match for hardware TLBs */
396 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
397 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx
398 "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb,
399 pte_is_valid(tlb->pte0) ? "valid" : "inval",
400 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
401 continue;
402 }
403 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " "
404 TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb,
405 pte_is_valid(tlb->pte0) ? "valid" : "inval",
406 tlb->EPN, eaddr, tlb->pte1,
407 rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
408 switch (pte32_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
409 case -3:
410 /* TLB inconsistency */
411 return -1;
412 case -2:
413 /* Access violation */
414 ret = -2;
415 best = nr;
416 break;
417 case -1:
418 default:
419 /* No match */
420 break;
421 case 0:
422 /* access granted */
423 /* XXX: we should go on looping to check all TLBs consistency
424 * but we can speed-up the whole thing as the
425 * result would be undefined if TLBs are not consistent.
426 */
427 ret = 0;
428 best = nr;
429 goto done;
430 }
431 }
432 if (best != -1) {
433 done:
434 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n",
435 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
436 /* Update page flags */
437 pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);
438 }
439
440 return ret;
441 }
442
443 /* Perform BAT hit & translation */
444 static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp,
445 int *protp, target_ulong *BATu,
446 target_ulong *BATl)
447 {
448 target_ulong bl;
449 int pp, valid, prot;
450
451 bl = (*BATu & 0x00001FFC) << 15;
452 valid = 0;
453 prot = 0;
454 if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
455 ((msr_pr != 0) && (*BATu & 0x00000001))) {
456 valid = 1;
457 pp = *BATl & 0x00000003;
458 if (pp != 0) {
459 prot = PAGE_READ | PAGE_EXEC;
460 if (pp == 0x2)
461 prot |= PAGE_WRITE;
462 }
463 }
464 *blp = bl;
465 *validp = valid;
466 *protp = prot;
467 }
468
469 static inline void bat_601_size_prot(CPUState *env, target_ulong *blp,
470 int *validp, int *protp,
471 target_ulong *BATu, target_ulong *BATl)
472 {
473 target_ulong bl;
474 int key, pp, valid, prot;
475
476 bl = (*BATl & 0x0000003F) << 17;
477 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n",
478 (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
479 prot = 0;
480 valid = (*BATl >> 6) & 1;
481 if (valid) {
482 pp = *BATu & 0x00000003;
483 if (msr_pr == 0)
484 key = (*BATu >> 3) & 1;
485 else
486 key = (*BATu >> 2) & 1;
487 prot = pp_check(key, pp, 0);
488 }
489 *blp = bl;
490 *validp = valid;
491 *protp = prot;
492 }
493
494 static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
495 int rw, int type)
496 {
497 target_ulong *BATlt, *BATut, *BATu, *BATl;
498 target_ulong BEPIl, BEPIu, bl;
499 int i, valid, prot;
500 int ret = -1;
501
502 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
503 type == ACCESS_CODE ? 'I' : 'D', virtual);
504 switch (type) {
505 case ACCESS_CODE:
506 BATlt = env->IBAT[1];
507 BATut = env->IBAT[0];
508 break;
509 default:
510 BATlt = env->DBAT[1];
511 BATut = env->DBAT[0];
512 break;
513 }
514 for (i = 0; i < env->nb_BATs; i++) {
515 BATu = &BATut[i];
516 BATl = &BATlt[i];
517 BEPIu = *BATu & 0xF0000000;
518 BEPIl = *BATu & 0x0FFE0000;
519 if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
520 bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
521 } else {
522 bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
523 }
524 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
525 " BATl " TARGET_FMT_lx "\n", __func__,
526 type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
527 if ((virtual & 0xF0000000) == BEPIu &&
528 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
529 /* BAT matches */
530 if (valid != 0) {
531 /* Get physical address */
532 ctx->raddr = (*BATl & 0xF0000000) |
533 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
534 (virtual & 0x0001F000);
535 /* Compute access rights */
536 ctx->prot = prot;
537 ret = check_prot(ctx->prot, rw, type);
538 if (ret == 0)
539 LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",
540 i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
541 ctx->prot & PAGE_WRITE ? 'W' : '-');
542 break;
543 }
544 }
545 }
546 if (ret < 0) {
547 #if defined(DEBUG_BATS)
548 if (qemu_log_enabled()) {
549 LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual);
550 for (i = 0; i < 4; i++) {
551 BATu = &BATut[i];
552 BATl = &BATlt[i];
553 BEPIu = *BATu & 0xF0000000;
554 BEPIl = *BATu & 0x0FFE0000;
555 bl = (*BATu & 0x00001FFC) << 15;
556 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
557 " BATl " TARGET_FMT_lx " \n\t" TARGET_FMT_lx " "
558 TARGET_FMT_lx " " TARGET_FMT_lx "\n",
559 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
560 *BATu, *BATl, BEPIu, BEPIl, bl);
561 }
562 }
563 #endif
564 }
565 /* No hit */
566 return ret;
567 }
568
569 static inline target_phys_addr_t get_pteg_offset(CPUState *env,
570 target_phys_addr_t hash,
571 int pte_size)
572 {
573 return (hash * pte_size * 8) & env->htab_mask;
574 }
575
576 /* PTE table lookup */
577 static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
578 int rw, int type, int target_page_bits)
579 {
580 target_phys_addr_t pteg_off;
581 target_ulong pte0, pte1;
582 int i, good = -1;
583 int ret, r;
584
585 ret = -1; /* No entry found */
586 pteg_off = get_pteg_offset(env, ctx->hash[h],
587 is_64b ? HASH_PTE_SIZE_64 : HASH_PTE_SIZE_32);
588 for (i = 0; i < 8; i++) {
589 #if defined(TARGET_PPC64)
590 if (is_64b) {
591 if (env->external_htab) {
592 pte0 = ldq_p(env->external_htab + pteg_off + (i * 16));
593 pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8);
594 } else {
595 pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
596 pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
597 }
598
599 /* We have a TLB that saves 4K pages, so let's
600 * split a huge page to 4k chunks */
601 if (target_page_bits != TARGET_PAGE_BITS)
602 pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
603 & TARGET_PAGE_MASK;
604
605 r = pte64_check(ctx, pte0, pte1, h, rw, type);
606 LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
607 TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
608 pteg_off + (i * 16), pte0, pte1, (int)(pte0 & 1), h,
609 (int)((pte0 >> 1) & 1), ctx->ptem);
610 } else
611 #endif
612 {
613 if (env->external_htab) {
614 pte0 = ldl_p(env->external_htab + pteg_off + (i * 8));
615 pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4);
616 } else {
617 pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8));
618 pte1 = ldl_phys(env->htab_base + pteg_off + (i * 8) + 4);
619 }
620 r = pte32_check(ctx, pte0, pte1, h, rw, type);
621 LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
622 TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
623 pteg_off + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,
624 (int)((pte0 >> 6) & 1), ctx->ptem);
625 }
626 switch (r) {
627 case -3:
628 /* PTE inconsistency */
629 return -1;
630 case -2:
631 /* Access violation */
632 ret = -2;
633 good = i;
634 break;
635 case -1:
636 default:
637 /* No PTE match */
638 break;
639 case 0:
640 /* access granted */
641 /* XXX: we should go on looping to check all PTEs consistency
642 * but if we can speed-up the whole thing as the
643 * result would be undefined if PTEs are not consistent.
644 */
645 ret = 0;
646 good = i;
647 goto done;
648 }
649 }
650 if (good != -1) {
651 done:
652 LOG_MMU("found PTE at addr " TARGET_FMT_lx " prot=%01x ret=%d\n",
653 ctx->raddr, ctx->prot, ret);
654 /* Update page flags */
655 pte1 = ctx->raddr;
656 if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
657 #if defined(TARGET_PPC64)
658 if (is_64b) {
659 if (env->external_htab) {
660 stq_p(env->external_htab + pteg_off + (good * 16) + 8,
661 pte1);
662 } else {
663 stq_phys_notdirty(env->htab_base + pteg_off +
664 (good * 16) + 8, pte1);
665 }
666 } else
667 #endif
668 {
669 if (env->external_htab) {
670 stl_p(env->external_htab + pteg_off + (good * 8) + 4,
671 pte1);
672 } else {
673 stl_phys_notdirty(env->htab_base + pteg_off +
674 (good * 8) + 4, pte1);
675 }
676 }
677 }
678 }
679
680 return ret;
681 }
682
683 static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
684 int type, int target_page_bits)
685 {
686 #if defined(TARGET_PPC64)
687 if (env->mmu_model & POWERPC_MMU_64)
688 return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
689 #endif
690
691 return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
692 }
693
694 #if defined(TARGET_PPC64)
695 static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
696 {
697 uint64_t esid_256M, esid_1T;
698 int n;
699
700 LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
701
702 esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
703 esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
704
705 for (n = 0; n < env->slb_nr; n++) {
706 ppc_slb_t *slb = &env->slb[n];
707
708 LOG_SLB("%s: slot %d %016" PRIx64 " %016"
709 PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
710 /* We check for 1T matches on all MMUs here - if the MMU
711 * doesn't have 1T segment support, we will have prevented 1T
712 * entries from being inserted in the slbmte code. */
713 if (((slb->esid == esid_256M) &&
714 ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
715 || ((slb->esid == esid_1T) &&
716 ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) {
717 return slb;
718 }
719 }
720
721 return NULL;
722 }
723
724 void ppc_slb_invalidate_all (CPUPPCState *env)
725 {
726 int n, do_invalidate;
727
728 do_invalidate = 0;
729 /* XXX: Warning: slbia never invalidates the first segment */
730 for (n = 1; n < env->slb_nr; n++) {
731 ppc_slb_t *slb = &env->slb[n];
732
733 if (slb->esid & SLB_ESID_V) {
734 slb->esid &= ~SLB_ESID_V;
735 /* XXX: given the fact that segment size is 256 MB or 1TB,
736 * and we still don't have a tlb_flush_mask(env, n, mask)
737 * in Qemu, we just invalidate all TLBs
738 */
739 do_invalidate = 1;
740 }
741 }
742 if (do_invalidate)
743 tlb_flush(env, 1);
744 }
745
746 void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
747 {
748 ppc_slb_t *slb;
749
750 slb = slb_lookup(env, T0);
751 if (!slb) {
752 return;
753 }
754
755 if (slb->esid & SLB_ESID_V) {
756 slb->esid &= ~SLB_ESID_V;
757
758 /* XXX: given the fact that segment size is 256 MB or 1TB,
759 * and we still don't have a tlb_flush_mask(env, n, mask)
760 * in Qemu, we just invalidate all TLBs
761 */
762 tlb_flush(env, 1);
763 }
764 }
765
766 int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
767 {
768 int slot = rb & 0xfff;
769 ppc_slb_t *slb = &env->slb[slot];
770
771 if (rb & (0x1000 - env->slb_nr)) {
772 return -1; /* Reserved bits set or slot too high */
773 }
774 if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
775 return -1; /* Bad segment size */
776 }
777 if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
778 return -1; /* 1T segment on MMU that doesn't support it */
779 }
780
781 /* Mask out the slot number as we store the entry */
782 slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
783 slb->vsid = rs;
784
785 LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
786 " %016" PRIx64 "\n", __func__, slot, rb, rs,
787 slb->esid, slb->vsid);
788
789 return 0;
790 }
791
792 int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
793 {
794 int slot = rb & 0xfff;
795 ppc_slb_t *slb = &env->slb[slot];
796
797 if (slot >= env->slb_nr) {
798 return -1;
799 }
800
801 *rt = slb->esid;
802 return 0;
803 }
804
805 int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
806 {
807 int slot = rb & 0xfff;
808 ppc_slb_t *slb = &env->slb[slot];
809
810 if (slot >= env->slb_nr) {
811 return -1;
812 }
813
814 *rt = slb->vsid;
815 return 0;
816 }
817 #endif /* defined(TARGET_PPC64) */
818
819 /* Perform segment based translation */
820 static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
821 target_ulong eaddr, int rw, int type)
822 {
823 target_phys_addr_t hash;
824 target_ulong vsid;
825 int ds, pr, target_page_bits;
826 int ret, ret2;
827
828 pr = msr_pr;
829 ctx->eaddr = eaddr;
830 #if defined(TARGET_PPC64)
831 if (env->mmu_model & POWERPC_MMU_64) {
832 ppc_slb_t *slb;
833 target_ulong pageaddr;
834 int segment_bits;
835
836 LOG_MMU("Check SLBs\n");
837 slb = slb_lookup(env, eaddr);
838 if (!slb) {
839 return -5;
840 }
841
842 if (slb->vsid & SLB_VSID_B) {
843 vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
844 segment_bits = 40;
845 } else {
846 vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
847 segment_bits = 28;
848 }
849
850 target_page_bits = (slb->vsid & SLB_VSID_L)
851 ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
852 ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
853 : (slb->vsid & SLB_VSID_KS));
854 ds = 0;
855 ctx->nx = !!(slb->vsid & SLB_VSID_N);
856
857 pageaddr = eaddr & ((1ULL << segment_bits)
858 - (1ULL << target_page_bits));
859 if (slb->vsid & SLB_VSID_B) {
860 hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits);
861 } else {
862 hash = vsid ^ (pageaddr >> target_page_bits);
863 }
864 /* Only 5 bits of the page index are used in the AVPN */
865 ctx->ptem = (slb->vsid & SLB_VSID_PTEM) |
866 ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
867 } else
868 #endif /* defined(TARGET_PPC64) */
869 {
870 target_ulong sr, pgidx;
871
872 sr = env->sr[eaddr >> 28];
873 ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
874 ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
875 ds = sr & 0x80000000 ? 1 : 0;
876 ctx->nx = sr & 0x10000000 ? 1 : 0;
877 vsid = sr & 0x00FFFFFF;
878 target_page_bits = TARGET_PAGE_BITS;
879 LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
880 TARGET_FMT_lx " lr=" TARGET_FMT_lx
881 " ir=%d dr=%d pr=%d %d t=%d\n",
882 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
883 (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
884 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
885 hash = vsid ^ pgidx;
886 ctx->ptem = (vsid << 7) | (pgidx >> 10);
887 }
888 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
889 ctx->key, ds, ctx->nx, vsid);
890 ret = -1;
891 if (!ds) {
892 /* Check if instruction fetch is allowed, if needed */
893 if (type != ACCESS_CODE || ctx->nx == 0) {
894 /* Page address translation */
895 LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
896 " hash " TARGET_FMT_plx "\n",
897 env->htab_base, env->htab_mask, hash);
898 ctx->hash[0] = hash;
899 ctx->hash[1] = ~hash;
900
901 /* Initialize real address with an invalid value */
902 ctx->raddr = (target_phys_addr_t)-1ULL;
903 if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
904 env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
905 /* Software TLB search */
906 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
907 } else {
908 LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
909 " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
910 " hash=" TARGET_FMT_plx "\n",
911 env->htab_base, env->htab_mask, vsid, ctx->ptem,
912 ctx->hash[0]);
913 /* Primary table lookup */
914 ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
915 if (ret < 0) {
916 /* Secondary table lookup */
917 if (eaddr != 0xEFFFFFFF)
918 LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
919 " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
920 " hash=" TARGET_FMT_plx "\n", env->htab_base,
921 env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
922 ret2 = find_pte(env, ctx, 1, rw, type,
923 target_page_bits);
924 if (ret2 != -1)
925 ret = ret2;
926 }
927 }
928 #if defined (DUMP_PAGE_TABLES)
929 if (qemu_log_enabled()) {
930 target_phys_addr_t curaddr;
931 uint32_t a0, a1, a2, a3;
932 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
933 "\n", sdr, mask + 0x80);
934 for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
935 curaddr += 16) {
936 a0 = ldl_phys(curaddr);
937 a1 = ldl_phys(curaddr + 4);
938 a2 = ldl_phys(curaddr + 8);
939 a3 = ldl_phys(curaddr + 12);
940 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
941 qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
942 curaddr, a0, a1, a2, a3);
943 }
944 }
945 }
946 #endif
947 } else {
948 LOG_MMU("No access allowed\n");
949 ret = -3;
950 }
951 } else {
952 target_ulong sr;
953 LOG_MMU("direct store...\n");
954 /* Direct-store segment : absolutely *BUGGY* for now */
955
956 /* Direct-store implies a 32-bit MMU.
957 * Check the Segment Register's bus unit ID (BUID).
958 */
959 sr = env->sr[eaddr >> 28];
960 if ((sr & 0x1FF00000) >> 20 == 0x07f) {
961 /* Memory-forced I/O controller interface access */
962 /* If T=1 and BUID=x'07F', the 601 performs a memory access
963 * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
964 */
965 ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
966 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
967 return 0;
968 }
969
970 switch (type) {
971 case ACCESS_INT:
972 /* Integer load/store : only access allowed */
973 break;
974 case ACCESS_CODE:
975 /* No code fetch is allowed in direct-store areas */
976 return -4;
977 case ACCESS_FLOAT:
978 /* Floating point load/store */
979 return -4;
980 case ACCESS_RES:
981 /* lwarx, ldarx or srwcx. */
982 return -4;
983 case ACCESS_CACHE:
984 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
985 /* Should make the instruction do no-op.
986 * As it already do no-op, it's quite easy :-)
987 */
988 ctx->raddr = eaddr;
989 return 0;
990 case ACCESS_EXT:
991 /* eciwx or ecowx */
992 return -4;
993 default:
994 qemu_log("ERROR: instruction should not need "
995 "address translation\n");
996 return -4;
997 }
998 if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
999 ctx->raddr = eaddr;
1000 ret = 2;
1001 } else {
1002 ret = -2;
1003 }
1004 }
1005
1006 return ret;
1007 }
1008
1009 /* Generic TLB check function for embedded PowerPC implementations */
1010 int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
1011 target_phys_addr_t *raddrp,
1012 target_ulong address, uint32_t pid, int ext,
1013 int i)
1014 {
1015 target_ulong mask;
1016
1017 /* Check valid flag */
1018 if (!(tlb->prot & PAGE_VALID)) {
1019 return -1;
1020 }
1021 mask = ~(tlb->size - 1);
1022 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx
1023 " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN,
1024 mask, (uint32_t)tlb->PID, tlb->prot);
1025 /* Check PID */
1026 if (tlb->PID != 0 && tlb->PID != pid)
1027 return -1;
1028 /* Check effective address */
1029 if ((address & mask) != tlb->EPN)
1030 return -1;
1031 *raddrp = (tlb->RPN & mask) | (address & ~mask);
1032 #if (TARGET_PHYS_ADDR_BITS >= 36)
1033 if (ext) {
1034 /* Extend the physical address to 36 bits */
1035 *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
1036 }
1037 #endif
1038
1039 return 0;
1040 }
1041
1042 /* Generic TLB search function for PowerPC embedded implementations */
1043 int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
1044 {
1045 ppcemb_tlb_t *tlb;
1046 target_phys_addr_t raddr;
1047 int i, ret;
1048
1049 /* Default return value is no match */
1050 ret = -1;
1051 for (i = 0; i < env->nb_tlb; i++) {
1052 tlb = &env->tlb[i].tlbe;
1053 if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
1054 ret = i;
1055 break;
1056 }
1057 }
1058
1059 return ret;
1060 }
1061
1062 /* Helpers specific to PowerPC 40x implementations */
1063 static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
1064 {
1065 ppcemb_tlb_t *tlb;
1066 int i;
1067
1068 for (i = 0; i < env->nb_tlb; i++) {
1069 tlb = &env->tlb[i].tlbe;
1070 tlb->prot &= ~PAGE_VALID;
1071 }
1072 tlb_flush(env, 1);
1073 }
1074
1075 static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
1076 target_ulong eaddr, uint32_t pid)
1077 {
1078 #if !defined(FLUSH_ALL_TLBS)
1079 ppcemb_tlb_t *tlb;
1080 target_phys_addr_t raddr;
1081 target_ulong page, end;
1082 int i;
1083
1084 for (i = 0; i < env->nb_tlb; i++) {
1085 tlb = &env->tlb[i].tlbe;
1086 if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
1087 end = tlb->EPN + tlb->size;
1088 for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
1089 tlb_flush_page(env, page);
1090 tlb->prot &= ~PAGE_VALID;
1091 break;
1092 }
1093 }
1094 #else
1095 ppc4xx_tlb_invalidate_all(env);
1096 #endif
1097 }
1098
1099 static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1100 target_ulong address, int rw, int access_type)
1101 {
1102 ppcemb_tlb_t *tlb;
1103 target_phys_addr_t raddr;
1104 int i, ret, zsel, zpr, pr;
1105
1106 ret = -1;
1107 raddr = (target_phys_addr_t)-1ULL;
1108 pr = msr_pr;
1109 for (i = 0; i < env->nb_tlb; i++) {
1110 tlb = &env->tlb[i].tlbe;
1111 if (ppcemb_tlb_check(env, tlb, &raddr, address,
1112 env->spr[SPR_40x_PID], 0, i) < 0)
1113 continue;
1114 zsel = (tlb->attr >> 4) & 0xF;
1115 zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
1116 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1117 __func__, i, zsel, zpr, rw, tlb->attr);
1118 /* Check execute enable bit */
1119 switch (zpr) {
1120 case 0x2:
1121 if (pr != 0)
1122 goto check_perms;
1123 /* No break here */
1124 case 0x3:
1125 /* All accesses granted */
1126 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1127 ret = 0;
1128 break;
1129 case 0x0:
1130 if (pr != 0) {
1131 /* Raise Zone protection fault. */
1132 env->spr[SPR_40x_ESR] = 1 << 22;
1133 ctx->prot = 0;
1134 ret = -2;
1135 break;
1136 }
1137 /* No break here */
1138 case 0x1:
1139 check_perms:
1140 /* Check from TLB entry */
1141 ctx->prot = tlb->prot;
1142 ret = check_prot(ctx->prot, rw, access_type);
1143 if (ret == -2)
1144 env->spr[SPR_40x_ESR] = 0;
1145 break;
1146 }
1147 if (ret >= 0) {
1148 ctx->raddr = raddr;
1149 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1150 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1151 ret);
1152 return 0;
1153 }
1154 }
1155 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1156 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1157
1158 return ret;
1159 }
1160
1161 void store_40x_sler (CPUPPCState *env, uint32_t val)
1162 {
1163 /* XXX: TO BE FIXED */
1164 if (val != 0x00000000) {
1165 cpu_abort(env, "Little-endian regions are not supported by now\n");
1166 }
1167 env->spr[SPR_405_SLER] = val;
1168 }
1169
1170 static inline int mmubooke_check_tlb (CPUState *env, ppcemb_tlb_t *tlb,
1171 target_phys_addr_t *raddr, int *prot,
1172 target_ulong address, int rw,
1173 int access_type, int i)
1174 {
1175 int ret, _prot;
1176
1177 if (ppcemb_tlb_check(env, tlb, raddr, address,
1178 env->spr[SPR_BOOKE_PID],
1179 !env->nb_pids, i) >= 0) {
1180 goto found_tlb;
1181 }
1182
1183 if (env->spr[SPR_BOOKE_PID1] &&
1184 ppcemb_tlb_check(env, tlb, raddr, address,
1185 env->spr[SPR_BOOKE_PID1], 0, i) >= 0) {
1186 goto found_tlb;
1187 }
1188
1189 if (env->spr[SPR_BOOKE_PID2] &&
1190 ppcemb_tlb_check(env, tlb, raddr, address,
1191 env->spr[SPR_BOOKE_PID2], 0, i) >= 0) {
1192 goto found_tlb;
1193 }
1194
1195 LOG_SWTLB("%s: TLB entry not found\n", __func__);
1196 return -1;
1197
1198 found_tlb:
1199
1200 if (msr_pr != 0) {
1201 _prot = tlb->prot & 0xF;
1202 } else {
1203 _prot = (tlb->prot >> 4) & 0xF;
1204 }
1205
1206 /* Check the address space */
1207 if (access_type == ACCESS_CODE) {
1208 if (msr_ir != (tlb->attr & 1)) {
1209 LOG_SWTLB("%s: AS doesn't match\n", __func__);
1210 return -1;
1211 }
1212
1213 *prot = _prot;
1214 if (_prot & PAGE_EXEC) {
1215 LOG_SWTLB("%s: good TLB!\n", __func__);
1216 return 0;
1217 }
1218
1219 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot);
1220 ret = -3;
1221 } else {
1222 if (msr_dr != (tlb->attr & 1)) {
1223 LOG_SWTLB("%s: AS doesn't match\n", __func__);
1224 return -1;
1225 }
1226
1227 *prot = _prot;
1228 if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) {
1229 LOG_SWTLB("%s: found TLB!\n", __func__);
1230 return 0;
1231 }
1232
1233 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot);
1234 ret = -2;
1235 }
1236
1237 return ret;
1238 }
1239
1240 static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1241 target_ulong address, int rw,
1242 int access_type)
1243 {
1244 ppcemb_tlb_t *tlb;
1245 target_phys_addr_t raddr;
1246 int i, ret;
1247
1248 ret = -1;
1249 raddr = (target_phys_addr_t)-1ULL;
1250 for (i = 0; i < env->nb_tlb; i++) {
1251 tlb = &env->tlb[i].tlbe;
1252 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw,
1253 access_type, i);
1254 if (!ret) {
1255 break;
1256 }
1257 }
1258
1259 if (ret >= 0) {
1260 ctx->raddr = raddr;
1261 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1262 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1263 ret);
1264 } else {
1265 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1266 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1267 }
1268
1269 return ret;
1270 }
1271
1272 void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot)
1273 {
1274 int tlb_size;
1275 int i, j;
1276 ppc_tlb_t *tlb = env->tlb;
1277
1278 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1279 if (flags & (1 << i)) {
1280 tlb_size = booke206_tlb_size(env, i);
1281 for (j = 0; j < tlb_size; j++) {
1282 if (!check_iprot || !(tlb[j].tlbe.attr & MAS1_IPROT)) {
1283 tlb[j].tlbe.prot = 0;
1284 }
1285 }
1286 }
1287 tlb += booke206_tlb_size(env, i);
1288 }
1289
1290 tlb_flush(env, 1);
1291 }
1292
1293 static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
1294 target_ulong address, int rw,
1295 int access_type)
1296 {
1297 ppcemb_tlb_t *tlb;
1298 target_phys_addr_t raddr;
1299 int i, j, ret;
1300
1301 ret = -1;
1302 raddr = (target_phys_addr_t)-1ULL;
1303
1304 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1305 int ways = booke206_tlb_ways(env, i);
1306
1307 for (j = 0; j < ways; j++) {
1308 tlb = booke206_get_tlbe(env, i, address, j);
1309 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw,
1310 access_type, j);
1311 if (ret != -1) {
1312 goto found_tlb;
1313 }
1314 }
1315 }
1316
1317 found_tlb:
1318
1319 if (ret >= 0) {
1320 ctx->raddr = raddr;
1321 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1322 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1323 ret);
1324 } else {
1325 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1326 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1327 }
1328
1329 return ret;
1330 }
1331
1332 static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
1333 target_ulong eaddr, int rw)
1334 {
1335 int in_plb, ret;
1336
1337 ctx->raddr = eaddr;
1338 ctx->prot = PAGE_READ | PAGE_EXEC;
1339 ret = 0;
1340 switch (env->mmu_model) {
1341 case POWERPC_MMU_32B:
1342 case POWERPC_MMU_601:
1343 case POWERPC_MMU_SOFT_6xx:
1344 case POWERPC_MMU_SOFT_74xx:
1345 case POWERPC_MMU_SOFT_4xx:
1346 case POWERPC_MMU_REAL:
1347 case POWERPC_MMU_BOOKE:
1348 ctx->prot |= PAGE_WRITE;
1349 break;
1350 #if defined(TARGET_PPC64)
1351 case POWERPC_MMU_620:
1352 case POWERPC_MMU_64B:
1353 case POWERPC_MMU_2_06:
1354 /* Real address are 60 bits long */
1355 ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1356 ctx->prot |= PAGE_WRITE;
1357 break;
1358 #endif
1359 case POWERPC_MMU_SOFT_4xx_Z:
1360 if (unlikely(msr_pe != 0)) {
1361 /* 403 family add some particular protections,
1362 * using PBL/PBU registers for accesses with no translation.
1363 */
1364 in_plb =
1365 /* Check PLB validity */
1366 (env->pb[0] < env->pb[1] &&
1367 /* and address in plb area */
1368 eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
1369 (env->pb[2] < env->pb[3] &&
1370 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
1371 if (in_plb ^ msr_px) {
1372 /* Access in protected area */
1373 if (rw == 1) {
1374 /* Access is not allowed */
1375 ret = -2;
1376 }
1377 } else {
1378 /* Read-write access is allowed */
1379 ctx->prot |= PAGE_WRITE;
1380 }
1381 }
1382 break;
1383 case POWERPC_MMU_MPC8xx:
1384 /* XXX: TODO */
1385 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1386 break;
1387 case POWERPC_MMU_BOOKE206:
1388 cpu_abort(env, "BookE 2.06 MMU doesn't have physical real mode\n");
1389 break;
1390 default:
1391 cpu_abort(env, "Unknown or invalid MMU model\n");
1392 return -1;
1393 }
1394
1395 return ret;
1396 }
1397
1398 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1399 int rw, int access_type)
1400 {
1401 int ret;
1402
1403 #if 0
1404 qemu_log("%s\n", __func__);
1405 #endif
1406 if ((access_type == ACCESS_CODE && msr_ir == 0) ||
1407 (access_type != ACCESS_CODE && msr_dr == 0)) {
1408 if (env->mmu_model == POWERPC_MMU_BOOKE) {
1409 /* The BookE MMU always performs address translation. The
1410 IS and DS bits only affect the address space. */
1411 ret = mmubooke_get_physical_address(env, ctx, eaddr,
1412 rw, access_type);
1413 } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
1414 ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
1415 access_type);
1416 } else {
1417 /* No address translation. */
1418 ret = check_physical(env, ctx, eaddr, rw);
1419 }
1420 } else {
1421 ret = -1;
1422 switch (env->mmu_model) {
1423 case POWERPC_MMU_32B:
1424 case POWERPC_MMU_601:
1425 case POWERPC_MMU_SOFT_6xx:
1426 case POWERPC_MMU_SOFT_74xx:
1427 /* Try to find a BAT */
1428 if (env->nb_BATs != 0)
1429 ret = get_bat(env, ctx, eaddr, rw, access_type);
1430 #if defined(TARGET_PPC64)
1431 case POWERPC_MMU_620:
1432 case POWERPC_MMU_64B:
1433 case POWERPC_MMU_2_06:
1434 #endif
1435 if (ret < 0) {
1436 /* We didn't match any BAT entry or don't have BATs */
1437 ret = get_segment(env, ctx, eaddr, rw, access_type);
1438 }
1439 break;
1440 case POWERPC_MMU_SOFT_4xx:
1441 case POWERPC_MMU_SOFT_4xx_Z:
1442 ret = mmu40x_get_physical_address(env, ctx, eaddr,
1443 rw, access_type);
1444 break;
1445 case POWERPC_MMU_BOOKE:
1446 ret = mmubooke_get_physical_address(env, ctx, eaddr,
1447 rw, access_type);
1448 break;
1449 case POWERPC_MMU_BOOKE206:
1450 ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
1451 access_type);
1452 break;
1453 case POWERPC_MMU_MPC8xx:
1454 /* XXX: TODO */
1455 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1456 break;
1457 case POWERPC_MMU_REAL:
1458 cpu_abort(env, "PowerPC in real mode do not do any translation\n");
1459 return -1;
1460 default:
1461 cpu_abort(env, "Unknown or invalid MMU model\n");
1462 return -1;
1463 }
1464 }
1465 #if 0
1466 qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n",
1467 __func__, eaddr, ret, ctx->raddr);
1468 #endif
1469
1470 return ret;
1471 }
1472
1473 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1474 {
1475 mmu_ctx_t ctx;
1476
1477 if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1478 return -1;
1479
1480 return ctx.raddr & TARGET_PAGE_MASK;
1481 }
1482
1483 static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address,
1484 int rw)
1485 {
1486 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1487 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1488 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1489 env->spr[SPR_BOOKE_MAS3] = 0;
1490 env->spr[SPR_BOOKE_MAS6] = 0;
1491 env->spr[SPR_BOOKE_MAS7] = 0;
1492
1493 /* AS */
1494 if (((rw == 2) && msr_ir) || ((rw != 2) && msr_dr)) {
1495 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1496 env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1497 }
1498
1499 env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1500 env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1501
1502 switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1503 case MAS4_TIDSELD_PID0:
1504 env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID] << MAS1_TID_SHIFT;
1505 break;
1506 case MAS4_TIDSELD_PID1:
1507 env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID1] << MAS1_TID_SHIFT;
1508 break;
1509 case MAS4_TIDSELD_PID2:
1510 env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID2] << MAS1_TID_SHIFT;
1511 break;
1512 }
1513
1514 env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1515
1516 /* next victim logic */
1517 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1518 env->last_way++;
1519 env->last_way &= booke206_tlb_ways(env, 0) - 1;
1520 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1521 }
1522
1523 /* Perform address translation */
1524 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1525 int mmu_idx, int is_softmmu)
1526 {
1527 mmu_ctx_t ctx;
1528 int access_type;
1529 int ret = 0;
1530
1531 if (rw == 2) {
1532 /* code access */
1533 rw = 0;
1534 access_type = ACCESS_CODE;
1535 } else {
1536 /* data access */
1537 access_type = env->access_type;
1538 }
1539 ret = get_physical_address(env, &ctx, address, rw, access_type);
1540 if (ret == 0) {
1541 tlb_set_page(env, address & TARGET_PAGE_MASK,
1542 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1543 mmu_idx, TARGET_PAGE_SIZE);
1544 ret = 0;
1545 } else if (ret < 0) {
1546 LOG_MMU_STATE(env);
1547 if (access_type == ACCESS_CODE) {
1548 switch (ret) {
1549 case -1:
1550 /* No matches in page tables or TLB */
1551 switch (env->mmu_model) {
1552 case POWERPC_MMU_SOFT_6xx:
1553 env->exception_index = POWERPC_EXCP_IFTLB;
1554 env->error_code = 1 << 18;
1555 env->spr[SPR_IMISS] = address;
1556 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1557 goto tlb_miss;
1558 case POWERPC_MMU_SOFT_74xx:
1559 env->exception_index = POWERPC_EXCP_IFTLB;
1560 goto tlb_miss_74xx;
1561 case POWERPC_MMU_SOFT_4xx:
1562 case POWERPC_MMU_SOFT_4xx_Z:
1563 env->exception_index = POWERPC_EXCP_ITLB;
1564 env->error_code = 0;
1565 env->spr[SPR_40x_DEAR] = address;
1566 env->spr[SPR_40x_ESR] = 0x00000000;
1567 break;
1568 case POWERPC_MMU_32B:
1569 case POWERPC_MMU_601:
1570 #if defined(TARGET_PPC64)
1571 case POWERPC_MMU_620:
1572 case POWERPC_MMU_64B:
1573 case POWERPC_MMU_2_06:
1574 #endif
1575 env->exception_index = POWERPC_EXCP_ISI;
1576 env->error_code = 0x40000000;
1577 break;
1578 case POWERPC_MMU_BOOKE206:
1579 booke206_update_mas_tlb_miss(env, address, rw);
1580 /* fall through */
1581 case POWERPC_MMU_BOOKE:
1582 env->exception_index = POWERPC_EXCP_ITLB;
1583 env->error_code = 0;
1584 env->spr[SPR_BOOKE_DEAR] = address;
1585 return -1;
1586 case POWERPC_MMU_MPC8xx:
1587 /* XXX: TODO */
1588 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1589 break;
1590 case POWERPC_MMU_REAL:
1591 cpu_abort(env, "PowerPC in real mode should never raise "
1592 "any MMU exceptions\n");
1593 return -1;
1594 default:
1595 cpu_abort(env, "Unknown or invalid MMU model\n");
1596 return -1;
1597 }
1598 break;
1599 case -2:
1600 /* Access rights violation */
1601 env->exception_index = POWERPC_EXCP_ISI;
1602 env->error_code = 0x08000000;
1603 break;
1604 case -3:
1605 /* No execute protection violation */
1606 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1607 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1608 env->spr[SPR_BOOKE_ESR] = 0x00000000;
1609 }
1610 env->exception_index = POWERPC_EXCP_ISI;
1611 env->error_code = 0x10000000;
1612 break;
1613 case -4:
1614 /* Direct store exception */
1615 /* No code fetch is allowed in direct-store areas */
1616 env->exception_index = POWERPC_EXCP_ISI;
1617 env->error_code = 0x10000000;
1618 break;
1619 #if defined(TARGET_PPC64)
1620 case -5:
1621 /* No match in segment table */
1622 if (env->mmu_model == POWERPC_MMU_620) {
1623 env->exception_index = POWERPC_EXCP_ISI;
1624 /* XXX: this might be incorrect */
1625 env->error_code = 0x40000000;
1626 } else {
1627 env->exception_index = POWERPC_EXCP_ISEG;
1628 env->error_code = 0;
1629 }
1630 break;
1631 #endif
1632 }
1633 } else {
1634 switch (ret) {
1635 case -1:
1636 /* No matches in page tables or TLB */
1637 switch (env->mmu_model) {
1638 case POWERPC_MMU_SOFT_6xx:
1639 if (rw == 1) {
1640 env->exception_index = POWERPC_EXCP_DSTLB;
1641 env->error_code = 1 << 16;
1642 } else {
1643 env->exception_index = POWERPC_EXCP_DLTLB;
1644 env->error_code = 0;
1645 }
1646 env->spr[SPR_DMISS] = address;
1647 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1648 tlb_miss:
1649 env->error_code |= ctx.key << 19;
1650 env->spr[SPR_HASH1] = env->htab_base +
1651 get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32);
1652 env->spr[SPR_HASH2] = env->htab_base +
1653 get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32);
1654 break;
1655 case POWERPC_MMU_SOFT_74xx:
1656 if (rw == 1) {
1657 env->exception_index = POWERPC_EXCP_DSTLB;
1658 } else {
1659 env->exception_index = POWERPC_EXCP_DLTLB;
1660 }
1661 tlb_miss_74xx:
1662 /* Implement LRU algorithm */
1663 env->error_code = ctx.key << 19;
1664 env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
1665 ((env->last_way + 1) & (env->nb_ways - 1));
1666 env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1667 break;
1668 case POWERPC_MMU_SOFT_4xx:
1669 case POWERPC_MMU_SOFT_4xx_Z:
1670 env->exception_index = POWERPC_EXCP_DTLB;
1671 env->error_code = 0;
1672 env->spr[SPR_40x_DEAR] = address;
1673 if (rw)
1674 env->spr[SPR_40x_ESR] = 0x00800000;
1675 else
1676 env->spr[SPR_40x_ESR] = 0x00000000;
1677 break;
1678 case POWERPC_MMU_32B:
1679 case POWERPC_MMU_601:
1680 #if defined(TARGET_PPC64)
1681 case POWERPC_MMU_620:
1682 case POWERPC_MMU_64B:
1683 case POWERPC_MMU_2_06:
1684 #endif
1685 env->exception_index = POWERPC_EXCP_DSI;
1686 env->error_code = 0;
1687 env->spr[SPR_DAR] = address;
1688 if (rw == 1)
1689 env->spr[SPR_DSISR] = 0x42000000;
1690 else
1691 env->spr[SPR_DSISR] = 0x40000000;
1692 break;
1693 case POWERPC_MMU_MPC8xx:
1694 /* XXX: TODO */
1695 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1696 break;
1697 case POWERPC_MMU_BOOKE206:
1698 booke206_update_mas_tlb_miss(env, address, rw);
1699 /* fall through */
1700 case POWERPC_MMU_BOOKE:
1701 env->exception_index = POWERPC_EXCP_DTLB;
1702 env->error_code = 0;
1703 env->spr[SPR_BOOKE_DEAR] = address;
1704 env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
1705 return -1;
1706 case POWERPC_MMU_REAL:
1707 cpu_abort(env, "PowerPC in real mode should never raise "
1708 "any MMU exceptions\n");
1709 return -1;
1710 default:
1711 cpu_abort(env, "Unknown or invalid MMU model\n");
1712 return -1;
1713 }
1714 break;
1715 case -2:
1716 /* Access rights violation */
1717 env->exception_index = POWERPC_EXCP_DSI;
1718 env->error_code = 0;
1719 if (env->mmu_model == POWERPC_MMU_SOFT_4xx
1720 || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
1721 env->spr[SPR_40x_DEAR] = address;
1722 if (rw) {
1723 env->spr[SPR_40x_ESR] |= 0x00800000;
1724 }
1725 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1726 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1727 env->spr[SPR_BOOKE_DEAR] = address;
1728 env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
1729 } else {
1730 env->spr[SPR_DAR] = address;
1731 if (rw == 1) {
1732 env->spr[SPR_DSISR] = 0x0A000000;
1733 } else {
1734 env->spr[SPR_DSISR] = 0x08000000;
1735 }
1736 }
1737 break;
1738 case -4:
1739 /* Direct store exception */
1740 switch (access_type) {
1741 case ACCESS_FLOAT:
1742 /* Floating point load/store */
1743 env->exception_index = POWERPC_EXCP_ALIGN;
1744 env->error_code = POWERPC_EXCP_ALIGN_FP;
1745 env->spr[SPR_DAR] = address;
1746 break;
1747 case ACCESS_RES:
1748 /* lwarx, ldarx or stwcx. */
1749 env->exception_index = POWERPC_EXCP_DSI;
1750 env->error_code = 0;
1751 env->spr[SPR_DAR] = address;
1752 if (rw == 1)
1753 env->spr[SPR_DSISR] = 0x06000000;
1754 else
1755 env->spr[SPR_DSISR] = 0x04000000;
1756 break;
1757 case ACCESS_EXT:
1758 /* eciwx or ecowx */
1759 env->exception_index = POWERPC_EXCP_DSI;
1760 env->error_code = 0;
1761 env->spr[SPR_DAR] = address;
1762 if (rw == 1)
1763 env->spr[SPR_DSISR] = 0x06100000;
1764 else
1765 env->spr[SPR_DSISR] = 0x04100000;
1766 break;
1767 default:
1768 printf("DSI: invalid exception (%d)\n", ret);
1769 env->exception_index = POWERPC_EXCP_PROGRAM;
1770 env->error_code =
1771 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1772 env->spr[SPR_DAR] = address;
1773 break;
1774 }
1775 break;
1776 #if defined(TARGET_PPC64)
1777 case -5:
1778 /* No match in segment table */
1779 if (env->mmu_model == POWERPC_MMU_620) {
1780 env->exception_index = POWERPC_EXCP_DSI;
1781 env->error_code = 0;
1782 env->spr[SPR_DAR] = address;
1783 /* XXX: this might be incorrect */
1784 if (rw == 1)
1785 env->spr[SPR_DSISR] = 0x42000000;
1786 else
1787 env->spr[SPR_DSISR] = 0x40000000;
1788 } else {
1789 env->exception_index = POWERPC_EXCP_DSEG;
1790 env->error_code = 0;
1791 env->spr[SPR_DAR] = address;
1792 }
1793 break;
1794 #endif
1795 }
1796 }
1797 #if 0
1798 printf("%s: set exception to %d %02x\n", __func__,
1799 env->exception, env->error_code);
1800 #endif
1801 ret = 1;
1802 }
1803
1804 return ret;
1805 }
1806
1807 /*****************************************************************************/
1808 /* BATs management */
1809 #if !defined(FLUSH_ALL_TLBS)
1810 static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
1811 target_ulong mask)
1812 {
1813 target_ulong base, end, page;
1814
1815 base = BATu & ~0x0001FFFF;
1816 end = base + mask + 0x00020000;
1817 LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
1818 TARGET_FMT_lx ")\n", base, end, mask);
1819 for (page = base; page != end; page += TARGET_PAGE_SIZE)
1820 tlb_flush_page(env, page);
1821 LOG_BATS("Flush done\n");
1822 }
1823 #endif
1824
1825 static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
1826 target_ulong value)
1827 {
1828 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID,
1829 nr, ul == 0 ? 'u' : 'l', value, env->nip);
1830 }
1831
1832 void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1833 {
1834 target_ulong mask;
1835
1836 dump_store_bat(env, 'I', 0, nr, value);
1837 if (env->IBAT[0][nr] != value) {
1838 mask = (value << 15) & 0x0FFE0000UL;
1839 #if !defined(FLUSH_ALL_TLBS)
1840 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1841 #endif
1842 /* When storing valid upper BAT, mask BEPI and BRPN
1843 * and invalidate all TLBs covered by this BAT
1844 */
1845 mask = (value << 15) & 0x0FFE0000UL;
1846 env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1847 (value & ~0x0001FFFFUL & ~mask);
1848 env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1849 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1850 #if !defined(FLUSH_ALL_TLBS)
1851 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1852 #else
1853 tlb_flush(env, 1);
1854 #endif
1855 }
1856 }
1857
1858 void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1859 {
1860 dump_store_bat(env, 'I', 1, nr, value);
1861 env->IBAT[1][nr] = value;
1862 }
1863
1864 void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1865 {
1866 target_ulong mask;
1867
1868 dump_store_bat(env, 'D', 0, nr, value);
1869 if (env->DBAT[0][nr] != value) {
1870 /* When storing valid upper BAT, mask BEPI and BRPN
1871 * and invalidate all TLBs covered by this BAT
1872 */
1873 mask = (value << 15) & 0x0FFE0000UL;
1874 #if !defined(FLUSH_ALL_TLBS)
1875 do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1876 #endif
1877 mask = (value << 15) & 0x0FFE0000UL;
1878 env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1879 (value & ~0x0001FFFFUL & ~mask);
1880 env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1881 (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1882 #if !defined(FLUSH_ALL_TLBS)
1883 do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1884 #else
1885 tlb_flush(env, 1);
1886 #endif
1887 }
1888 }
1889
1890 void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1891 {
1892 dump_store_bat(env, 'D', 1, nr, value);
1893 env->DBAT[1][nr] = value;
1894 }
1895
1896 void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
1897 {
1898 target_ulong mask;
1899 #if defined(FLUSH_ALL_TLBS)
1900 int do_inval;
1901 #endif
1902
1903 dump_store_bat(env, 'I', 0, nr, value);
1904 if (env->IBAT[0][nr] != value) {
1905 #if defined(FLUSH_ALL_TLBS)
1906 do_inval = 0;
1907 #endif
1908 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1909 if (env->IBAT[1][nr] & 0x40) {
1910 /* Invalidate BAT only if it is valid */
1911 #if !defined(FLUSH_ALL_TLBS)
1912 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1913 #else
1914 do_inval = 1;
1915 #endif
1916 }
1917 /* When storing valid upper BAT, mask BEPI and BRPN
1918 * and invalidate all TLBs covered by this BAT
1919 */
1920 env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1921 (value & ~0x0001FFFFUL & ~mask);
1922 env->DBAT[0][nr] = env->IBAT[0][nr];
1923 if (env->IBAT[1][nr] & 0x40) {
1924 #if !defined(FLUSH_ALL_TLBS)
1925 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1926 #else
1927 do_inval = 1;
1928 #endif
1929 }
1930 #if defined(FLUSH_ALL_TLBS)
1931 if (do_inval)
1932 tlb_flush(env, 1);
1933 #endif
1934 }
1935 }
1936
1937 void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
1938 {
1939 target_ulong mask;
1940 #if defined(FLUSH_ALL_TLBS)
1941 int do_inval;
1942 #endif
1943
1944 dump_store_bat(env, 'I', 1, nr, value);
1945 if (env->IBAT[1][nr] != value) {
1946 #if defined(FLUSH_ALL_TLBS)
1947 do_inval = 0;
1948 #endif
1949 if (env->IBAT[1][nr] & 0x40) {
1950 #if !defined(FLUSH_ALL_TLBS)
1951 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1952 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1953 #else
1954 do_inval = 1;
1955 #endif
1956 }
1957 if (value & 0x40) {
1958 #if !defined(FLUSH_ALL_TLBS)
1959 mask = (value << 17) & 0x0FFE0000UL;
1960 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1961 #else
1962 do_inval = 1;
1963 #endif
1964 }
1965 env->IBAT[1][nr] = value;
1966 env->DBAT[1][nr] = value;
1967 #if defined(FLUSH_ALL_TLBS)
1968 if (do_inval)
1969 tlb_flush(env, 1);
1970 #endif
1971 }
1972 }
1973
1974 /*****************************************************************************/
1975 /* TLB management */
1976 void ppc_tlb_invalidate_all (CPUPPCState *env)
1977 {
1978 switch (env->mmu_model) {
1979 case POWERPC_MMU_SOFT_6xx:
1980 case POWERPC_MMU_SOFT_74xx:
1981 ppc6xx_tlb_invalidate_all(env);
1982 break;
1983 case POWERPC_MMU_SOFT_4xx:
1984 case POWERPC_MMU_SOFT_4xx_Z:
1985 ppc4xx_tlb_invalidate_all(env);
1986 break;
1987 case POWERPC_MMU_REAL:
1988 cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1989 break;
1990 case POWERPC_MMU_MPC8xx:
1991 /* XXX: TODO */
1992 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1993 break;
1994 case POWERPC_MMU_BOOKE:
1995 tlb_flush(env, 1);
1996 break;
1997 case POWERPC_MMU_BOOKE206:
1998 booke206_flush_tlb(env, -1, 0);
1999 break;
2000 case POWERPC_MMU_32B:
2001 case POWERPC_MMU_601:
2002 #if defined(TARGET_PPC64)
2003 case POWERPC_MMU_620:
2004 case POWERPC_MMU_64B:
2005 case POWERPC_MMU_2_06:
2006 #endif /* defined(TARGET_PPC64) */
2007 tlb_flush(env, 1);
2008 break;
2009 default:
2010 /* XXX: TODO */
2011 cpu_abort(env, "Unknown MMU model\n");
2012 break;
2013 }
2014 }
2015
2016 void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
2017 {
2018 #if !defined(FLUSH_ALL_TLBS)
2019 addr &= TARGET_PAGE_MASK;
2020 switch (env->mmu_model) {
2021 case POWERPC_MMU_SOFT_6xx:
2022 case POWERPC_MMU_SOFT_74xx:
2023 ppc6xx_tlb_invalidate_virt(env, addr, 0);
2024 if (env->id_tlbs == 1)
2025 ppc6xx_tlb_invalidate_virt(env, addr, 1);
2026 break;
2027 case POWERPC_MMU_SOFT_4xx:
2028 case POWERPC_MMU_SOFT_4xx_Z:
2029 ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
2030 break;
2031 case POWERPC_MMU_REAL:
2032 cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
2033 break;
2034 case POWERPC_MMU_MPC8xx:
2035 /* XXX: TODO */
2036 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
2037 break;
2038 case POWERPC_MMU_BOOKE:
2039 /* XXX: TODO */
2040 cpu_abort(env, "BookE MMU model is not implemented\n");
2041 break;
2042 case POWERPC_MMU_BOOKE206:
2043 /* XXX: TODO */
2044 cpu_abort(env, "BookE 2.06 MMU model is not implemented\n");
2045 break;
2046 case POWERPC_MMU_32B:
2047 case POWERPC_MMU_601:
2048 /* tlbie invalidate TLBs for all segments */
2049 addr &= ~((target_ulong)-1ULL << 28);
2050 /* XXX: this case should be optimized,
2051 * giving a mask to tlb_flush_page
2052 */
2053 tlb_flush_page(env, addr | (0x0 << 28));
2054 tlb_flush_page(env, addr | (0x1 << 28));
2055 tlb_flush_page(env, addr | (0x2 << 28));
2056 tlb_flush_page(env, addr | (0x3 << 28));
2057 tlb_flush_page(env, addr | (0x4 << 28));
2058 tlb_flush_page(env, addr | (0x5 << 28));
2059 tlb_flush_page(env, addr | (0x6 << 28));
2060 tlb_flush_page(env, addr | (0x7 << 28));
2061 tlb_flush_page(env, addr | (0x8 << 28));
2062 tlb_flush_page(env, addr | (0x9 << 28));
2063 tlb_flush_page(env, addr | (0xA << 28));
2064 tlb_flush_page(env, addr | (0xB << 28));
2065 tlb_flush_page(env, addr | (0xC << 28));
2066 tlb_flush_page(env, addr | (0xD << 28));
2067 tlb_flush_page(env, addr | (0xE << 28));
2068 tlb_flush_page(env, addr | (0xF << 28));
2069 break;
2070 #if defined(TARGET_PPC64)
2071 case POWERPC_MMU_620:
2072 case POWERPC_MMU_64B:
2073 case POWERPC_MMU_2_06:
2074 /* tlbie invalidate TLBs for all segments */
2075 /* XXX: given the fact that there are too many segments to invalidate,
2076 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2077 * we just invalidate all TLBs
2078 */
2079 tlb_flush(env, 1);
2080 break;
2081 #endif /* defined(TARGET_PPC64) */
2082 default:
2083 /* XXX: TODO */
2084 cpu_abort(env, "Unknown MMU model\n");
2085 break;
2086 }
2087 #else
2088 ppc_tlb_invalidate_all(env);
2089 #endif
2090 }
2091
2092 /*****************************************************************************/
2093 /* Special registers manipulation */
2094 #if defined(TARGET_PPC64)
2095 void ppc_store_asr (CPUPPCState *env, target_ulong value)
2096 {
2097 if (env->asr != value) {
2098 env->asr = value;
2099 tlb_flush(env, 1);
2100 }
2101 }
2102 #endif
2103
2104 void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
2105 {
2106 LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
2107 if (env->spr[SPR_SDR1] != value) {
2108 env->spr[SPR_SDR1] = value;
2109 #if defined(TARGET_PPC64)
2110 if (env->mmu_model & POWERPC_MMU_64) {
2111 target_ulong htabsize = value & SDR_64_HTABSIZE;
2112
2113 if (htabsize > 28) {
2114 fprintf(stderr, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2115 " stored in SDR1\n", htabsize);
2116 htabsize = 28;
2117 }
2118 env->htab_mask = (1ULL << (htabsize + 18)) - 1;
2119 env->htab_base = value & SDR_64_HTABORG;
2120 } else
2121 #endif /* defined(TARGET_PPC64) */
2122 {
2123 /* FIXME: Should check for valid HTABMASK values */
2124 env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
2125 env->htab_base = value & SDR_32_HTABORG;
2126 }
2127 tlb_flush(env, 1);
2128 }
2129 }
2130
2131 #if defined(TARGET_PPC64)
2132 target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
2133 {
2134 // XXX
2135 return 0;
2136 }
2137 #endif
2138
2139 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
2140 {
2141 LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
2142 srnum, value, env->sr[srnum]);
2143 #if defined(TARGET_PPC64)
2144 if (env->mmu_model & POWERPC_MMU_64) {
2145 uint64_t rb = 0, rs = 0;
2146
2147 /* ESID = srnum */
2148 rb |= ((uint32_t)srnum & 0xf) << 28;
2149 /* Set the valid bit */
2150 rb |= 1 << 27;
2151 /* Index = ESID */
2152 rb |= (uint32_t)srnum;
2153
2154 /* VSID = VSID */
2155 rs |= (value & 0xfffffff) << 12;
2156 /* flags = flags */
2157 rs |= ((value >> 27) & 0xf) << 8;
2158
2159 ppc_store_slb(env, rb, rs);
2160 } else
2161 #endif
2162 if (env->sr[srnum] != value) {
2163 env->sr[srnum] = value;
2164 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2165 flusing the whole TLB. */
2166 #if !defined(FLUSH_ALL_TLBS) && 0
2167 {
2168 target_ulong page, end;
2169 /* Invalidate 256 MB of virtual memory */
2170 page = (16 << 20) * srnum;
2171 end = page + (16 << 20);
2172 for (; page != end; page += TARGET_PAGE_SIZE)
2173 tlb_flush_page(env, page);
2174 }
2175 #else
2176 tlb_flush(env, 1);
2177 #endif
2178 }
2179 }
2180 #endif /* !defined (CONFIG_USER_ONLY) */
2181
2182 /* GDBstub can read and write MSR... */
2183 void ppc_store_msr (CPUPPCState *env, target_ulong value)
2184 {
2185 hreg_store_msr(env, value, 0);
2186 }
2187
2188 /*****************************************************************************/
2189 /* Exception processing */
2190 #if defined (CONFIG_USER_ONLY)
2191 void do_interrupt (CPUState *env)
2192 {
2193 env->exception_index = POWERPC_EXCP_NONE;
2194 env->error_code = 0;
2195 }
2196
2197 void ppc_hw_interrupt (CPUState *env)
2198 {
2199 env->exception_index = POWERPC_EXCP_NONE;
2200 env->error_code = 0;
2201 }
2202 #else /* defined (CONFIG_USER_ONLY) */
2203 static inline void dump_syscall(CPUState *env)
2204 {
2205 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
2206 " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
2207 " nip=" TARGET_FMT_lx "\n",
2208 ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
2209 ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
2210 ppc_dump_gpr(env, 6), env->nip);
2211 }
2212
2213 /* Note that this function should be greatly optimized
2214 * when called with a constant excp, from ppc_hw_interrupt
2215 */
2216 static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
2217 {
2218 target_ulong msr, new_msr, vector;
2219 int srr0, srr1, asrr0, asrr1;
2220 int lpes0, lpes1, lev;
2221
2222 if (0) {
2223 /* XXX: find a suitable condition to enable the hypervisor mode */
2224 lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
2225 lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
2226 } else {
2227 /* Those values ensure we won't enter the hypervisor mode */
2228 lpes0 = 0;
2229 lpes1 = 1;
2230 }
2231
2232 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
2233 " => %08x (%02x)\n", env->nip, excp, env->error_code);
2234
2235 /* new srr1 value excluding must-be-zero bits */
2236 msr = env->msr & ~0x783f0000ULL;
2237
2238 /* new interrupt handler msr */
2239 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
2240
2241 /* target registers */
2242 srr0 = SPR_SRR0;
2243 srr1 = SPR_SRR1;
2244 asrr0 = -1;
2245 asrr1 = -1;
2246
2247 switch (excp) {
2248 case POWERPC_EXCP_NONE:
2249 /* Should never happen */
2250 return;
2251 case POWERPC_EXCP_CRITICAL: /* Critical input */
2252 switch (excp_model) {
2253 case POWERPC_EXCP_40x:
2254 srr0 = SPR_40x_SRR2;
2255 srr1 = SPR_40x_SRR3;
2256 break;
2257 case POWERPC_EXCP_BOOKE:
2258 srr0 = SPR_BOOKE_CSRR0;
2259 srr1 = SPR_BOOKE_CSRR1;
2260 break;
2261 case POWERPC_EXCP_G2:
2262 break;
2263 default:
2264 goto excp_invalid;
2265 }
2266 goto store_next;
2267 case POWERPC_EXCP_MCHECK: /* Machine check exception */
2268 if (msr_me == 0) {
2269 /* Machine check exception is not enabled.
2270 * Enter checkstop state.
2271 */
2272 if (qemu_log_enabled()) {
2273 qemu_log("Machine check while not allowed. "
2274 "Entering checkstop state\n");
2275 } else {
2276 fprintf(stderr, "Machine check while not allowed. "
2277 "Entering checkstop state\n");
2278 }
2279 env->halted = 1;
2280 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2281 }
2282 if (0) {
2283 /* XXX: find a suitable condition to enable the hypervisor mode */
2284 new_msr |= (target_ulong)MSR_HVB;
2285 }
2286
2287 /* machine check exceptions don't have ME set */
2288 new_msr &= ~((target_ulong)1 << MSR_ME);
2289
2290 /* XXX: should also have something loaded in DAR / DSISR */
2291 switch (excp_model) {
2292 case POWERPC_EXCP_40x:
2293 srr0 = SPR_40x_SRR2;
2294 srr1 = SPR_40x_SRR3;
2295 break;
2296 case POWERPC_EXCP_BOOKE:
2297 srr0 = SPR_BOOKE_MCSRR0;
2298 srr1 = SPR_BOOKE_MCSRR1;
2299 asrr0 = SPR_BOOKE_CSRR0;
2300 asrr1 = SPR_BOOKE_CSRR1;
2301 break;
2302 default:
2303 break;
2304 }
2305 goto store_next;
2306 case POWERPC_EXCP_DSI: /* Data storage exception */
2307 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
2308 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
2309 if (lpes1 == 0)
2310 new_msr |= (target_ulong)MSR_HVB;
2311 goto store_next;
2312 case POWERPC_EXCP_ISI: /* Instruction storage exception */
2313 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
2314 "\n", msr, env->nip);
2315 if (lpes1 == 0)
2316 new_msr |= (target_ulong)MSR_HVB;
2317 msr |= env->error_code;
2318 goto store_next;
2319 case POWERPC_EXCP_EXTERNAL: /* External input */
2320 if (lpes0 == 1)
2321 new_msr |= (target_ulong)MSR_HVB;
2322 goto store_next;
2323 case POWERPC_EXCP_ALIGN: /* Alignment exception */
2324 if (lpes1 == 0)
2325 new_msr |= (target_ulong)MSR_HVB;
2326 /* XXX: this is false */
2327 /* Get rS/rD and rA from faulting opcode */
2328 env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
2329 goto store_current;
2330 case POWERPC_EXCP_PROGRAM: /* Program exception */
2331 switch (env->error_code & ~0xF) {
2332 case POWERPC_EXCP_FP:
2333 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
2334 LOG_EXCP("Ignore floating point exception\n");
2335 env->exception_index = POWERPC_EXCP_NONE;
2336 env->error_code = 0;
2337 return;
2338 }
2339 if (lpes1 == 0)
2340 new_msr |= (target_ulong)MSR_HVB;
2341 msr |= 0x00100000;
2342 if (msr_fe0 == msr_fe1)
2343 goto store_next;
2344 msr |= 0x00010000;
2345 break;
2346 case POWERPC_EXCP_INVAL:
2347 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
2348 if (lpes1 == 0)
2349 new_msr |= (target_ulong)MSR_HVB;
2350 msr |= 0x00080000;
2351 break;
2352 case POWERPC_EXCP_PRIV:
2353 if (lpes1 == 0)
2354 new_msr |= (target_ulong)MSR_HVB;
2355 msr |= 0x00040000;
2356 break;
2357 case POWERPC_EXCP_TRAP:
2358 if (lpes1 == 0)
2359 new_msr |= (target_ulong)MSR_HVB;
2360 msr |= 0x00020000;
2361 break;
2362 default:
2363 /* Should never occur */
2364 cpu_abort(env, "Invalid program exception %d. Aborting\n",
2365 env->error_code);
2366 break;
2367 }
2368 goto store_current;
2369 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
2370 if (lpes1 == 0)
2371 new_msr |= (target_ulong)MSR_HVB;
2372 goto store_current;
2373 case POWERPC_EXCP_SYSCALL: /* System call exception */
2374 dump_syscall(env);
2375 lev = env->error_code;
2376 if ((lev == 1) && cpu_ppc_hypercall) {
2377 cpu_ppc_hypercall(env);
2378 return;
2379 }
2380 if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2381 new_msr |= (target_ulong)MSR_HVB;
2382 goto store_next;
2383 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
2384 goto store_current;
2385 case POWERPC_EXCP_DECR: /* Decrementer exception */
2386 if (lpes1 == 0)
2387 new_msr |= (target_ulong)MSR_HVB;
2388 goto store_next;
2389 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
2390 /* FIT on 4xx */
2391 LOG_EXCP("FIT exception\n");
2392 goto store_next;
2393 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
2394 LOG_EXCP("WDT exception\n");
2395 switch (excp_model) {
2396 case POWERPC_EXCP_BOOKE:
2397 srr0 = SPR_BOOKE_CSRR0;
2398 srr1 = SPR_BOOKE_CSRR1;
2399 break;
2400 default:
2401 break;
2402 }
2403 goto store_next;
2404 case POWERPC_EXCP_DTLB: /* Data TLB error */
2405 goto store_next;
2406 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
2407 goto store_next;
2408 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
2409 switch (excp_model) {
2410 case POWERPC_EXCP_BOOKE:
2411 srr0 = SPR_BOOKE_DSRR0;
2412 srr1 = SPR_BOOKE_DSRR1;
2413 asrr0 = SPR_BOOKE_CSRR0;
2414 asrr1 = SPR_BOOKE_CSRR1;
2415 break;
2416 default:
2417 break;
2418 }
2419 /* XXX: TODO */
2420 cpu_abort(env, "Debug exception is not implemented yet !\n");
2421 goto store_next;
2422 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
2423 goto store_current;
2424 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
2425 /* XXX: TODO */
2426 cpu_abort(env, "Embedded floating point data exception "
2427 "is not implemented yet !\n");
2428 goto store_next;
2429 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
2430 /* XXX: TODO */
2431 cpu_abort(env, "Embedded floating point round exception "
2432 "is not implemented yet !\n");
2433 goto store_next;
2434 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
2435 /* XXX: TODO */
2436 cpu_abort(env,
2437 "Performance counter exception is not implemented yet !\n");
2438 goto store_next;
2439 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
2440 /* XXX: TODO */
2441 cpu_abort(env,
2442 "Embedded doorbell interrupt is not implemented yet !\n");
2443 goto store_next;
2444 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
2445 switch (excp_model) {
2446 case POWERPC_EXCP_BOOKE:
2447 srr0 = SPR_BOOKE_CSRR0;
2448 srr1 = SPR_BOOKE_CSRR1;
2449 break;
2450 default:
2451 break;
2452 }
2453 /* XXX: TODO */
2454 cpu_abort(env, "Embedded doorbell critical interrupt "
2455 "is not implemented yet !\n");
2456 goto store_next;
2457 case POWERPC_EXCP_RESET: /* System reset exception */
2458 if (msr_pow) {
2459 /* indicate that we resumed from power save mode */
2460 msr |= 0x10000;
2461 } else {
2462 new_msr &= ~((target_ulong)1 << MSR_ME);
2463 }
2464
2465 if (0) {
2466 /* XXX: find a suitable condition to enable the hypervisor mode */
2467 new_msr |= (target_ulong)MSR_HVB;
2468 }
2469 goto store_next;
2470 case POWERPC_EXCP_DSEG: /* Data segment exception */
2471 if (lpes1 == 0)
2472 new_msr |= (target_ulong)MSR_HVB;
2473 goto store_next;
2474 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
2475 if (lpes1 == 0)
2476 new_msr |= (target_ulong)MSR_HVB;
2477 goto store_next;
2478 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
2479 srr0 = SPR_HSRR0;
2480 srr1 = SPR_HSRR1;
2481 new_msr |= (target_ulong)MSR_HVB;
2482 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2483 goto store_next;
2484 case POWERPC_EXCP_TRACE: /* Trace exception */
2485 if (lpes1 == 0)
2486 new_msr |= (target_ulong)MSR_HVB;
2487 goto store_next;
2488 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
2489 srr0 = SPR_HSRR0;
2490 srr1 = SPR_HSRR1;
2491 new_msr |= (target_ulong)MSR_HVB;
2492 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2493 goto store_next;
2494 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
2495 srr0 = SPR_HSRR0;
2496 srr1 = SPR_HSRR1;
2497 new_msr |= (target_ulong)MSR_HVB;
2498 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2499 goto store_next;
2500 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
2501 srr0 = SPR_HSRR0;
2502 srr1 = SPR_HSRR1;
2503 new_msr |= (target_ulong)MSR_HVB;
2504 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2505 goto store_next;
2506 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
2507 srr0 = SPR_HSRR0;
2508 srr1 = SPR_HSRR1;
2509 new_msr |= (target_ulong)MSR_HVB;
2510 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2511 goto store_next;
2512 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
2513 if (lpes1 == 0)
2514 new_msr |= (target_ulong)MSR_HVB;
2515 goto store_current;
2516 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
2517 LOG_EXCP("PIT exception\n");
2518 goto store_next;
2519 case POWERPC_EXCP_IO: /* IO error exception */
2520 /* XXX: TODO */
2521 cpu_abort(env, "601 IO error exception is not implemented yet !\n");
2522 goto store_next;
2523 case POWERPC_EXCP_RUNM: /* Run mode exception */
2524 /* XXX: TODO */
2525 cpu_abort(env, "601 run mode exception is not implemented yet !\n");
2526 goto store_next;
2527 case POWERPC_EXCP_EMUL: /* Emulation trap exception */
2528 /* XXX: TODO */
2529 cpu_abort(env, "602 emulation trap exception "
2530 "is not implemented yet !\n");
2531 goto store_next;
2532 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
2533 if (lpes1 == 0) /* XXX: check this */
2534 new_msr |= (target_ulong)MSR_HVB;
2535 switch (excp_model) {
2536 case POWERPC_EXCP_602:
2537 case POWERPC_EXCP_603:
2538 case POWERPC_EXCP_603E:
2539 case POWERPC_EXCP_G2:
2540 goto tlb_miss_tgpr;
2541 case POWERPC_EXCP_7x5:
2542 goto tlb_miss;
2543 case POWERPC_EXCP_74xx:
2544 goto tlb_miss_74xx;
2545 default:
2546 cpu_abort(env, "Invalid instruction TLB miss exception\n");
2547 break;
2548 }
2549 break;
2550 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
2551 if (lpes1 == 0) /* XXX: check this */
2552 new_msr |= (target_ulong)MSR_HVB;
2553 switch (excp_model) {
2554 case POWERPC_EXCP_602:
2555 case POWERPC_EXCP_603:
2556 case POWERPC_EXCP_603E:
2557 case POWERPC_EXCP_G2:
2558 goto tlb_miss_tgpr;
2559 case POWERPC_EXCP_7x5:
2560 goto tlb_miss;
2561 case POWERPC_EXCP_74xx:
2562 goto tlb_miss_74xx;
2563 default:
2564 cpu_abort(env, "Invalid data load TLB miss exception\n");
2565 break;
2566 }
2567 break;
2568 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
2569 if (lpes1 == 0) /* XXX: check this */
2570 new_msr |= (target_ulong)MSR_HVB;
2571 switch (excp_model) {
2572 case POWERPC_EXCP_602:
2573 case POWERPC_EXCP_603:
2574 case POWERPC_EXCP_603E:
2575 case POWERPC_EXCP_G2:
2576 tlb_miss_tgpr:
2577 /* Swap temporary saved registers with GPRs */
2578 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
2579 new_msr |= (target_ulong)1 << MSR_TGPR;
2580 hreg_swap_gpr_tgpr(env);
2581 }
2582 goto tlb_miss;
2583 case POWERPC_EXCP_7x5:
2584 tlb_miss:
2585 #if defined (DEBUG_SOFTWARE_TLB)
2586 if (qemu_log_enabled()) {
2587 const char *es;
2588 target_ulong *miss, *cmp;
2589 int en;
2590 if (excp == POWERPC_EXCP_IFTLB) {
2591 es = "I";
2592 en = 'I';
2593 miss = &env->spr[SPR_IMISS];
2594 cmp = &env->spr[SPR_ICMP];
2595 } else {
2596 if (excp == POWERPC_EXCP_DLTLB)
2597 es = "DL";
2598 else
2599 es = "DS";
2600 en = 'D';
2601 miss = &env->spr[SPR_DMISS];
2602 cmp = &env->spr[SPR_DCMP];
2603 }
2604 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2605 TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
2606 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2607 env->spr[SPR_HASH1], env->spr[SPR_HASH2],
2608 env->error_code);
2609 }
2610 #endif
2611 msr |= env->crf[0] << 28;
2612 msr |= env->error_code; /* key, D/I, S/L bits */
2613 /* Set way using a LRU mechanism */
2614 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2615 break;
2616 case POWERPC_EXCP_74xx:
2617 tlb_miss_74xx:
2618 #if defined (DEBUG_SOFTWARE_TLB)
2619 if (qemu_log_enabled()) {
2620 const char *es;
2621 target_ulong *miss, *cmp;
2622 int en;
2623 if (excp == POWERPC_EXCP_IFTLB) {
2624 es = "I";
2625 en = 'I';
2626 miss = &env->spr[SPR_TLBMISS];
2627 cmp = &env->spr[SPR_PTEHI];
2628 } else {
2629 if (excp == POWERPC_EXCP_DLTLB)
2630 es = "DL";
2631 else
2632 es = "DS";
2633 en = 'D';
2634 miss = &env->spr[SPR_TLBMISS];
2635 cmp = &env->spr[SPR_PTEHI];
2636 }
2637 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2638 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2639 env->error_code);
2640 }
2641 #endif
2642 msr |= env->error_code; /* key bit */
2643 break;
2644 default:
2645 cpu_abort(env, "Invalid data store TLB miss exception\n");
2646 break;
2647 }
2648 goto store_next;
2649 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
2650 /* XXX: TODO */
2651 cpu_abort(env, "Floating point assist exception "
2652 "is not implemented yet !\n");
2653 goto store_next;
2654 case POWERPC_EXCP_DABR: /* Data address breakpoint */
2655 /* XXX: TODO */
2656 cpu_abort(env, "DABR exception is not implemented yet !\n");
2657 goto store_next;
2658 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
2659 /* XXX: TODO */
2660 cpu_abort(env, "IABR exception is not implemented yet !\n");
2661 goto store_next;
2662 case POWERPC_EXCP_SMI: /* System management interrupt */
2663 /* XXX: TODO */
2664 cpu_abort(env, "SMI exception is not implemented yet !\n");
2665 goto store_next;
2666 case POWERPC_EXCP_THERM: /* Thermal interrupt */
2667 /* XXX: TODO */
2668 cpu_abort(env, "Thermal management exception "
2669 "is not implemented yet !\n");
2670 goto store_next;
2671 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
2672 if (lpes1 == 0)
2673 new_msr |= (target_ulong)MSR_HVB;
2674 /* XXX: TODO */
2675 cpu_abort(env,
2676 "Performance counter exception is not implemented yet !\n");
2677 goto store_next;
2678 case POWERPC_EXCP_VPUA: /* Vector assist exception */
2679 /* XXX: TODO */
2680 cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2681 goto store_next;
2682 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
2683 /* XXX: TODO */
2684 cpu_abort(env,
2685 "970 soft-patch exception is not implemented yet !\n");
2686 goto store_next;
2687 case POWERPC_EXCP_MAINT: /* Maintenance exception */
2688 /* XXX: TODO */
2689 cpu_abort(env,
2690 "970 maintenance exception is not implemented yet !\n");
2691 goto store_next;
2692 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */
2693 /* XXX: TODO */
2694 cpu_abort(env, "Maskable external exception "
2695 "is not implemented yet !\n");
2696 goto store_next;
2697 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */
2698 /* XXX: TODO */
2699 cpu_abort(env, "Non maskable external exception "
2700 "is not implemented yet !\n");
2701 goto store_next;
2702 default:
2703 excp_invalid:
2704 cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
2705 break;
2706 store_current:
2707 /* save current instruction location */
2708 env->spr[srr0] = env->nip - 4;
2709 break;
2710 store_next:
2711 /* save next instruction location */
2712 env->spr[srr0] = env->nip;
2713 break;
2714 }
2715 /* Save MSR */
2716 env->spr[srr1] = msr;
2717 /* If any alternate SRR register are defined, duplicate saved values */
2718 if (asrr0 != -1)
2719 env->spr[asrr0] = env->spr[srr0];
2720 if (asrr1 != -1)
2721 env->spr[asrr1] = env->spr[srr1];
2722 /* If we disactivated any translation, flush TLBs */
2723 if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
2724 tlb_flush(env, 1);
2725
2726 if (msr_ile) {
2727 new_msr |= (target_ulong)1 << MSR_LE;
2728 }
2729
2730 /* Jump to handler */
2731 vector = env->excp_vectors[excp];
2732 if (vector == (target_ulong)-1ULL) {
2733 cpu_abort(env, "Raised an exception without defined vector %d\n",
2734 excp);
2735 }
2736 vector |= env->excp_prefix;
2737 #if defined(TARGET_PPC64)
2738 if (excp_model == POWERPC_EXCP_BOOKE) {
2739 if (!msr_icm) {
2740 vector = (uint32_t)vector;
2741 } else {
2742 new_msr |= (target_ulong)1 << MSR_CM;
2743 }
2744 } else {
2745 if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
2746 vector = (uint32_t)vector;
2747 } else {
2748 new_msr |= (target_ulong)1 << MSR_SF;
2749 }
2750 }
2751 #endif
2752 /* XXX: we don't use hreg_store_msr here as already have treated
2753 * any special case that could occur. Just store MSR and update hflags
2754 */
2755 env->msr = new_msr & env->msr_mask;
2756 hreg_compute_hflags(env);
2757 env->nip = vector;
2758 /* Reset exception state */
2759 env->exception_index = POWERPC_EXCP_NONE;
2760 env->error_code = 0;
2761
2762 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
2763 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
2764 /* XXX: The BookE changes address space when switching modes,
2765 we should probably implement that as different MMU indexes,
2766 but for the moment we do it the slow way and flush all. */
2767 tlb_flush(env, 1);
2768 }
2769 }
2770
2771 void do_interrupt (CPUState *env)
2772 {
2773 powerpc_excp(env, env->excp_model, env->exception_index);
2774 }
2775
2776 void ppc_hw_interrupt (CPUPPCState *env)
2777 {
2778 int hdice;
2779
2780 #if 0
2781 qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
2782 __func__, env, env->pending_interrupts,
2783 env->interrupt_request, (int)msr_me, (int)msr_ee);
2784 #endif
2785 /* External reset */
2786 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2787 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2788 powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
2789 return;
2790 }
2791 /* Machine check exception */
2792 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2793 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2794 powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
2795 return;
2796 }
2797 #if 0 /* TODO */
2798 /* External debug exception */
2799 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2800 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2801 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
2802 return;
2803 }
2804 #endif
2805 if (0) {
2806 /* XXX: find a suitable condition to enable the hypervisor mode */
2807 hdice = env->spr[SPR_LPCR] & 1;
2808 } else {
2809 hdice = 0;
2810 }
2811 if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
2812 /* Hypervisor decrementer exception */
2813 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2814 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2815 powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
2816 return;
2817 }
2818 }
2819 if (msr_ce != 0) {
2820 /* External critical interrupt */
2821 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2822 /* Taking a critical external interrupt does not clear the external
2823 * critical interrupt status
2824 */
2825 #if 0
2826 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
2827 #endif
2828 powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
2829 return;
2830 }
2831 }
2832 if (msr_ee != 0) {
2833 /* Watchdog timer on embedded PowerPC */
2834 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2835 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2836 powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
2837 return;
2838 }
2839 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2840 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2841 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
2842 return;
2843 }
2844 /* Fixed interval timer on embedded PowerPC */
2845 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2846 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2847 powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
2848 return;
2849 }
2850 /* Programmable interval timer on embedded PowerPC */
2851 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2852 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2853 powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
2854 return;
2855 }
2856 /* Decrementer exception */
2857 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2858 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2859 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
2860 return;
2861 }
2862 /* External interrupt */
2863 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2864 /* Taking an external interrupt does not clear the external
2865 * interrupt status
2866 */
2867 #if 0
2868 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2869 #endif
2870 powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
2871 return;
2872 }
2873 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2874 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2875 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
2876 return;
2877 }
2878 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2879 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2880 powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
2881 return;
2882 }
2883 /* Thermal interrupt */
2884 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2885 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2886 powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
2887 return;
2888 }
2889 }
2890 }
2891 #endif /* !CONFIG_USER_ONLY */
2892
2893 void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2894 {
2895 qemu_log("Return from exception at " TARGET_FMT_lx " with flags "
2896 TARGET_FMT_lx "\n", RA, msr);
2897 }
2898
2899 void cpu_reset(CPUPPCState *env)
2900 {
2901 target_ulong msr;
2902
2903 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
2904 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
2905 log_cpu_state(env, 0);
2906 }
2907
2908 msr = (target_ulong)0;
2909 if (0) {
2910 /* XXX: find a suitable condition to enable the hypervisor mode */
2911 msr |= (target_ulong)MSR_HVB;
2912 }
2913 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
2914 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
2915 msr |= (target_ulong)1 << MSR_EP;
2916 #if defined (DO_SINGLE_STEP) && 0
2917 /* Single step trace mode */
2918 msr |= (target_ulong)1 << MSR_SE;
2919 msr |= (target_ulong)1 << MSR_BE;
2920 #endif
2921 #if defined(CONFIG_USER_ONLY)
2922 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
2923 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
2924 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
2925 msr |= (target_ulong)1 << MSR_PR;
2926 #else
2927 env->excp_prefix = env->hreset_excp_prefix;
2928 env->nip = env->hreset_vector | env->excp_prefix;
2929 if (env->mmu_model != POWERPC_MMU_REAL)
2930 ppc_tlb_invalidate_all(env);
2931 #endif
2932 env->msr = msr & env->msr_mask;
2933 #if defined(TARGET_PPC64)
2934 if (env->mmu_model & POWERPC_MMU_64)
2935 env->msr |= (1ULL << MSR_SF);
2936 #endif
2937 hreg_compute_hflags(env);
2938 env->reserve_addr = (target_ulong)-1ULL;
2939 /* Be sure no exception or interrupt is pending */
2940 env->pending_interrupts = 0;
2941 env->exception_index = POWERPC_EXCP_NONE;
2942 env->error_code = 0;
2943 /* Flush all TLBs */
2944 tlb_flush(env, 1);
2945 }
2946
2947 CPUPPCState *cpu_ppc_init (const char *cpu_model)
2948 {
2949 CPUPPCState *env;
2950 const ppc_def_t *def;
2951
2952 def = cpu_ppc_find_by_name(cpu_model);
2953 if (!def)
2954 return NULL;
2955
2956 env = qemu_mallocz(sizeof(CPUPPCState));
2957 cpu_exec_init(env);
2958 ppc_translate_init();
2959 env->cpu_model_str = cpu_model;
2960 cpu_ppc_register_internal(env, def);
2961
2962 qemu_init_vcpu(env);
2963
2964 return env;
2965 }
2966
2967 void cpu_ppc_close (CPUPPCState *env)
2968 {
2969 /* Should also remove all opcode tables... */
2970 qemu_free(env);
2971 }