Statistics
| Branch: | Revision:

root / target-ppc / helper.c @ 81762d6d

History | View | Annotate | Download (90.3 kB)

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
#include <signal.h>
25

    
26
#include "cpu.h"
27
#include "exec-all.h"
28
#include "helper_regs.h"
29
#include "qemu-common.h"
30
#include "kvm.h"
31

    
32
//#define DEBUG_MMU
33
//#define DEBUG_BATS
34
//#define DEBUG_SLB
35
//#define DEBUG_SOFTWARE_TLB
36
//#define DUMP_PAGE_TABLES
37
//#define DEBUG_EXCEPTIONS
38
//#define FLUSH_ALL_TLBS
39

    
40
#ifdef DEBUG_MMU
41
#  define LOG_MMU(...) qemu_log(__VA_ARGS__)
42
#  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
43
#else
44
#  define LOG_MMU(...) do { } while (0)
45
#  define LOG_MMU_STATE(...) do { } while (0)
46
#endif
47

    
48

    
49
#ifdef DEBUG_SOFTWARE_TLB
50
#  define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
51
#else
52
#  define LOG_SWTLB(...) do { } while (0)
53
#endif
54

    
55
#ifdef DEBUG_BATS
56
#  define LOG_BATS(...) qemu_log(__VA_ARGS__)
57
#else
58
#  define LOG_BATS(...) do { } while (0)
59
#endif
60

    
61
#ifdef DEBUG_SLB
62
#  define LOG_SLB(...) qemu_log(__VA_ARGS__)
63
#else
64
#  define LOG_SLB(...) do { } while (0)
65
#endif
66

    
67
#ifdef DEBUG_EXCEPTIONS
68
#  define LOG_EXCP(...) qemu_log(__VA_ARGS__)
69
#else
70
#  define LOG_EXCP(...) do { } while (0)
71
#endif
72

    
73

    
74
/*****************************************************************************/
75
/* PowerPC MMU emulation */
76

    
77
#if defined(CONFIG_USER_ONLY)
78
int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
79
                              int mmu_idx, int is_softmmu)
80
{
81
    int exception, error_code;
82

    
83
    if (rw == 2) {
84
        exception = POWERPC_EXCP_ISI;
85
        error_code = 0x40000000;
86
    } else {
87
        exception = POWERPC_EXCP_DSI;
88
        error_code = 0x40000000;
89
        if (rw)
90
            error_code |= 0x02000000;
91
        env->spr[SPR_DAR] = address;
92
        env->spr[SPR_DSISR] = error_code;
93
    }
94
    env->exception_index = exception;
95
    env->error_code = error_code;
96

    
97
    return 1;
98
}
99

    
100
#else
101
/* Common routines used by software and hardware TLBs emulation */
102
static inline int pte_is_valid(target_ulong pte0)
103
{
104
    return pte0 & 0x80000000 ? 1 : 0;
105
}
106

    
107
static inline void pte_invalidate(target_ulong *pte0)
108
{
109
    *pte0 &= ~0x80000000;
110
}
111

    
112
#if defined(TARGET_PPC64)
113
static inline int pte64_is_valid(target_ulong pte0)
114
{
115
    return pte0 & 0x0000000000000001ULL ? 1 : 0;
116
}
117

    
118
static inline void pte64_invalidate(target_ulong *pte0)
119
{
120
    *pte0 &= ~0x0000000000000001ULL;
121
}
122
#endif
123

    
124
#define PTE_PTEM_MASK 0x7FFFFFBF
125
#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
126
#if defined(TARGET_PPC64)
127
#define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
128
#define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
129
#endif
130

    
131
static inline int pp_check(int key, int pp, int nx)
132
{
133
    int access;
134

    
135
    /* Compute access rights */
136
    /* When pp is 3/7, the result is undefined. Set it to noaccess */
137
    access = 0;
138
    if (key == 0) {
139
        switch (pp) {
140
        case 0x0:
141
        case 0x1:
142
        case 0x2:
143
            access |= PAGE_WRITE;
144
            /* No break here */
145
        case 0x3:
146
        case 0x6:
147
            access |= PAGE_READ;
148
            break;
149
        }
150
    } else {
151
        switch (pp) {
152
        case 0x0:
153
        case 0x6:
154
            access = 0;
155
            break;
156
        case 0x1:
157
        case 0x3:
158
            access = PAGE_READ;
159
            break;
160
        case 0x2:
161
            access = PAGE_READ | PAGE_WRITE;
162
            break;
163
        }
164
    }
165
    if (nx == 0)
166
        access |= PAGE_EXEC;
167

    
168
    return access;
169
}
170

    
171
static inline int check_prot(int prot, int rw, int access_type)
172
{
173
    int ret;
174

    
175
    if (access_type == ACCESS_CODE) {
176
        if (prot & PAGE_EXEC)
177
            ret = 0;
178
        else
179
            ret = -2;
180
    } else if (rw) {
181
        if (prot & PAGE_WRITE)
182
            ret = 0;
183
        else
184
            ret = -2;
185
    } else {
186
        if (prot & PAGE_READ)
187
            ret = 0;
188
        else
189
            ret = -2;
190
    }
191

    
192
    return ret;
193
}
194

    
195
static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
196
                             target_ulong pte1, int h, int rw, int type)
197
{
198
    target_ulong ptem, mmask;
199
    int access, ret, pteh, ptev, pp;
200

    
201
    ret = -1;
202
    /* Check validity and table match */
203
#if defined(TARGET_PPC64)
204
    if (is_64b) {
205
        ptev = pte64_is_valid(pte0);
206
        pteh = (pte0 >> 1) & 1;
207
    } else
208
#endif
209
    {
210
        ptev = pte_is_valid(pte0);
211
        pteh = (pte0 >> 6) & 1;
212
    }
213
    if (ptev && h == pteh) {
214
        /* Check vsid & api */
215
#if defined(TARGET_PPC64)
216
        if (is_64b) {
217
            ptem = pte0 & PTE64_PTEM_MASK;
218
            mmask = PTE64_CHECK_MASK;
219
            pp = (pte1 & 0x00000003) | ((pte1 >> 61) & 0x00000004);
220
            ctx->nx  = (pte1 >> 2) & 1; /* No execute bit */
221
            ctx->nx |= (pte1 >> 3) & 1; /* Guarded bit    */
222
        } else
223
#endif
224
        {
225
            ptem = pte0 & PTE_PTEM_MASK;
226
            mmask = PTE_CHECK_MASK;
227
            pp = pte1 & 0x00000003;
228
        }
229
        if (ptem == ctx->ptem) {
230
            if (ctx->raddr != (target_phys_addr_t)-1ULL) {
231
                /* all matches should have equal RPN, WIMG & PP */
232
                if ((ctx->raddr & mmask) != (pte1 & mmask)) {
233
                    qemu_log("Bad RPN/WIMG/PP\n");
234
                    return -3;
235
                }
236
            }
237
            /* Compute access rights */
238
            access = pp_check(ctx->key, pp, ctx->nx);
239
            /* Keep the matching PTE informations */
240
            ctx->raddr = pte1;
241
            ctx->prot = access;
242
            ret = check_prot(ctx->prot, rw, type);
243
            if (ret == 0) {
244
                /* Access granted */
245
                LOG_MMU("PTE access granted !\n");
246
            } else {
247
                /* Access right violation */
248
                LOG_MMU("PTE access rejected\n");
249
            }
250
        }
251
    }
252

    
253
    return ret;
254
}
255

    
256
static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
257
                              target_ulong pte1, int h, int rw, int type)
258
{
259
    return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
260
}
261

    
262
#if defined(TARGET_PPC64)
263
static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
264
                              target_ulong pte1, int h, int rw, int type)
265
{
266
    return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
267
}
268
#endif
269

    
270
static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
271
                                   int ret, int rw)
272
{
273
    int store = 0;
274

    
275
    /* Update page flags */
276
    if (!(*pte1p & 0x00000100)) {
277
        /* Update accessed flag */
278
        *pte1p |= 0x00000100;
279
        store = 1;
280
    }
281
    if (!(*pte1p & 0x00000080)) {
282
        if (rw == 1 && ret == 0) {
283
            /* Update changed flag */
284
            *pte1p |= 0x00000080;
285
            store = 1;
286
        } else {
287
            /* Force page fault for first write access */
288
            ctx->prot &= ~PAGE_WRITE;
289
        }
290
    }
291

    
292
    return store;
293
}
294

    
295
/* Software driven TLB helpers */
296
static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
297
                                    int is_code)
298
{
299
    int nr;
300

    
301
    /* Select TLB num in a way from address */
302
    nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
303
    /* Select TLB way */
304
    nr += env->tlb_per_way * way;
305
    /* 6xx have separate TLBs for instructions and data */
306
    if (is_code && env->id_tlbs == 1)
307
        nr += env->nb_tlb;
308

    
309
    return nr;
310
}
311

    
312
static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
313
{
314
    ppc6xx_tlb_t *tlb;
315
    int nr, max;
316

    
317
    //LOG_SWTLB("Invalidate all TLBs\n");
318
    /* Invalidate all defined software TLB */
319
    max = env->nb_tlb;
320
    if (env->id_tlbs == 1)
321
        max *= 2;
322
    for (nr = 0; nr < max; nr++) {
323
        tlb = &env->tlb[nr].tlb6;
324
        pte_invalidate(&tlb->pte0);
325
    }
326
    tlb_flush(env, 1);
327
}
328

    
329
static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env,
330
                                                target_ulong eaddr,
331
                                                int is_code, int match_epn)
332
{
333
#if !defined(FLUSH_ALL_TLBS)
334
    ppc6xx_tlb_t *tlb;
335
    int way, nr;
336

    
337
    /* Invalidate ITLB + DTLB, all ways */
338
    for (way = 0; way < env->nb_ways; way++) {
339
        nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
340
        tlb = &env->tlb[nr].tlb6;
341
        if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
342
            LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr,
343
                      env->nb_tlb, eaddr);
344
            pte_invalidate(&tlb->pte0);
345
            tlb_flush_page(env, tlb->EPN);
346
        }
347
    }
348
#else
349
    /* XXX: PowerPC specification say this is valid as well */
350
    ppc6xx_tlb_invalidate_all(env);
351
#endif
352
}
353

    
354
static inline void ppc6xx_tlb_invalidate_virt(CPUState *env,
355
                                              target_ulong eaddr, int is_code)
356
{
357
    __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
358
}
359

    
360
void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
361
                       target_ulong pte0, target_ulong pte1)
362
{
363
    ppc6xx_tlb_t *tlb;
364
    int nr;
365

    
366
    nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
367
    tlb = &env->tlb[nr].tlb6;
368
    LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
369
              " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
370
    /* Invalidate any pending reference in Qemu for this virtual address */
371
    __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
372
    tlb->pte0 = pte0;
373
    tlb->pte1 = pte1;
374
    tlb->EPN = EPN;
375
    /* Store last way for LRU mechanism */
376
    env->last_way = way;
377
}
378

    
379
static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
380
                                   target_ulong eaddr, int rw, int access_type)
381
{
382
    ppc6xx_tlb_t *tlb;
383
    int nr, best, way;
384
    int ret;
385

    
386
    best = -1;
387
    ret = -1; /* No TLB found */
388
    for (way = 0; way < env->nb_ways; way++) {
389
        nr = ppc6xx_tlb_getnum(env, eaddr, way,
390
                               access_type == ACCESS_CODE ? 1 : 0);
391
        tlb = &env->tlb[nr].tlb6;
392
        /* This test "emulates" the PTE index match for hardware TLBs */
393
        if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
394
            LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx
395
                      "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb,
396
                      pte_is_valid(tlb->pte0) ? "valid" : "inval",
397
                      tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
398
            continue;
399
        }
400
        LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " "
401
                  TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb,
402
                  pte_is_valid(tlb->pte0) ? "valid" : "inval",
403
                  tlb->EPN, eaddr, tlb->pte1,
404
                  rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
405
        switch (pte32_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
406
        case -3:
407
            /* TLB inconsistency */
408
            return -1;
409
        case -2:
410
            /* Access violation */
411
            ret = -2;
412
            best = nr;
413
            break;
414
        case -1:
415
        default:
416
            /* No match */
417
            break;
418
        case 0:
419
            /* access granted */
420
            /* XXX: we should go on looping to check all TLBs consistency
421
             *      but we can speed-up the whole thing as the
422
             *      result would be undefined if TLBs are not consistent.
423
             */
424
            ret = 0;
425
            best = nr;
426
            goto done;
427
        }
428
    }
429
    if (best != -1) {
430
    done:
431
        LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n",
432
                  ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
433
        /* Update page flags */
434
        pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);
435
    }
436

    
437
    return ret;
438
}
439

    
440
/* Perform BAT hit & translation */
441
static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp,
442
                                 int *protp, target_ulong *BATu,
443
                                 target_ulong *BATl)
444
{
445
    target_ulong bl;
446
    int pp, valid, prot;
447

    
448
    bl = (*BATu & 0x00001FFC) << 15;
449
    valid = 0;
450
    prot = 0;
451
    if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
452
        ((msr_pr != 0) && (*BATu & 0x00000001))) {
453
        valid = 1;
454
        pp = *BATl & 0x00000003;
455
        if (pp != 0) {
456
            prot = PAGE_READ | PAGE_EXEC;
457
            if (pp == 0x2)
458
                prot |= PAGE_WRITE;
459
        }
460
    }
461
    *blp = bl;
462
    *validp = valid;
463
    *protp = prot;
464
}
465

    
466
static inline void bat_601_size_prot(CPUState *env, target_ulong *blp,
467
                                     int *validp, int *protp,
468
                                     target_ulong *BATu, target_ulong *BATl)
469
{
470
    target_ulong bl;
471
    int key, pp, valid, prot;
472

    
473
    bl = (*BATl & 0x0000003F) << 17;
474
    LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n",
475
             (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
476
    prot = 0;
477
    valid = (*BATl >> 6) & 1;
478
    if (valid) {
479
        pp = *BATu & 0x00000003;
480
        if (msr_pr == 0)
481
            key = (*BATu >> 3) & 1;
482
        else
483
            key = (*BATu >> 2) & 1;
484
        prot = pp_check(key, pp, 0);
485
    }
486
    *blp = bl;
487
    *validp = valid;
488
    *protp = prot;
489
}
490

    
491
static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
492
                          int rw, int type)
493
{
494
    target_ulong *BATlt, *BATut, *BATu, *BATl;
495
    target_ulong BEPIl, BEPIu, bl;
496
    int i, valid, prot;
497
    int ret = -1;
498

    
499
    LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
500
             type == ACCESS_CODE ? 'I' : 'D', virtual);
501
    switch (type) {
502
    case ACCESS_CODE:
503
        BATlt = env->IBAT[1];
504
        BATut = env->IBAT[0];
505
        break;
506
    default:
507
        BATlt = env->DBAT[1];
508
        BATut = env->DBAT[0];
509
        break;
510
    }
511
    for (i = 0; i < env->nb_BATs; i++) {
512
        BATu = &BATut[i];
513
        BATl = &BATlt[i];
514
        BEPIu = *BATu & 0xF0000000;
515
        BEPIl = *BATu & 0x0FFE0000;
516
        if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
517
            bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
518
        } else {
519
            bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
520
        }
521
        LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
522
                 " BATl " TARGET_FMT_lx "\n", __func__,
523
                 type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
524
        if ((virtual & 0xF0000000) == BEPIu &&
525
            ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
526
            /* BAT matches */
527
            if (valid != 0) {
528
                /* Get physical address */
529
                ctx->raddr = (*BATl & 0xF0000000) |
530
                    ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
531
                    (virtual & 0x0001F000);
532
                /* Compute access rights */
533
                ctx->prot = prot;
534
                ret = check_prot(ctx->prot, rw, type);
535
                if (ret == 0)
536
                    LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",
537
                             i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
538
                             ctx->prot & PAGE_WRITE ? 'W' : '-');
539
                break;
540
            }
541
        }
542
    }
543
    if (ret < 0) {
544
#if defined(DEBUG_BATS)
545
        if (qemu_log_enabled()) {
546
            LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual);
547
            for (i = 0; i < 4; i++) {
548
                BATu = &BATut[i];
549
                BATl = &BATlt[i];
550
                BEPIu = *BATu & 0xF0000000;
551
                BEPIl = *BATu & 0x0FFE0000;
552
                bl = (*BATu & 0x00001FFC) << 15;
553
                LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
554
                         " BATl " TARGET_FMT_lx " \n\t" TARGET_FMT_lx " "
555
                         TARGET_FMT_lx " " TARGET_FMT_lx "\n",
556
                         __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
557
                         *BATu, *BATl, BEPIu, BEPIl, bl);
558
            }
559
        }
560
#endif
561
    }
562
    /* No hit */
563
    return ret;
564
}
565

    
566
/* PTE table lookup */
567
static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw,
568
                            int type, int target_page_bits)
569
{
570
    target_ulong base, pte0, pte1;
571
    int i, good = -1;
572
    int ret, r;
573

    
574
    ret = -1; /* No entry found */
575
    base = ctx->pg_addr[h];
576
    for (i = 0; i < 8; i++) {
577
#if defined(TARGET_PPC64)
578
        if (is_64b) {
579
            pte0 = ldq_phys(base + (i * 16));
580
            pte1 = ldq_phys(base + (i * 16) + 8);
581

    
582
            /* We have a TLB that saves 4K pages, so let's
583
             * split a huge page to 4k chunks */
584
            if (target_page_bits != TARGET_PAGE_BITS)
585
                pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
586
                        & TARGET_PAGE_MASK;
587

    
588
            r = pte64_check(ctx, pte0, pte1, h, rw, type);
589
            LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
590
                    TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
591
                    base + (i * 16), pte0, pte1, (int)(pte0 & 1), h,
592
                    (int)((pte0 >> 1) & 1), ctx->ptem);
593
        } else
594
#endif
595
        {
596
            pte0 = ldl_phys(base + (i * 8));
597
            pte1 =  ldl_phys(base + (i * 8) + 4);
598
            r = pte32_check(ctx, pte0, pte1, h, rw, type);
599
            LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
600
                    TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
601
                    base + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,
602
                    (int)((pte0 >> 6) & 1), ctx->ptem);
603
        }
604
        switch (r) {
605
        case -3:
606
            /* PTE inconsistency */
607
            return -1;
608
        case -2:
609
            /* Access violation */
610
            ret = -2;
611
            good = i;
612
            break;
613
        case -1:
614
        default:
615
            /* No PTE match */
616
            break;
617
        case 0:
618
            /* access granted */
619
            /* XXX: we should go on looping to check all PTEs consistency
620
             *      but if we can speed-up the whole thing as the
621
             *      result would be undefined if PTEs are not consistent.
622
             */
623
            ret = 0;
624
            good = i;
625
            goto done;
626
        }
627
    }
628
    if (good != -1) {
629
    done:
630
        LOG_MMU("found PTE at addr " TARGET_FMT_lx " prot=%01x ret=%d\n",
631
                ctx->raddr, ctx->prot, ret);
632
        /* Update page flags */
633
        pte1 = ctx->raddr;
634
        if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
635
#if defined(TARGET_PPC64)
636
            if (is_64b) {
637
                stq_phys_notdirty(base + (good * 16) + 8, pte1);
638
            } else
639
#endif
640
            {
641
                stl_phys_notdirty(base + (good * 8) + 4, pte1);
642
            }
643
        }
644
    }
645

    
646
    return ret;
647
}
648

    
649
static inline int find_pte32(mmu_ctx_t *ctx, int h, int rw, int type,
650
                             int target_page_bits)
651
{
652
    return _find_pte(ctx, 0, h, rw, type, target_page_bits);
653
}
654

    
655
#if defined(TARGET_PPC64)
656
static inline int find_pte64(mmu_ctx_t *ctx, int h, int rw, int type,
657
                             int target_page_bits)
658
{
659
    return _find_pte(ctx, 1, h, rw, type, target_page_bits);
660
}
661
#endif
662

    
663
static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
664
                           int type, int target_page_bits)
665
{
666
#if defined(TARGET_PPC64)
667
    if (env->mmu_model & POWERPC_MMU_64)
668
        return find_pte64(ctx, h, rw, type, target_page_bits);
669
#endif
670

    
671
    return find_pte32(ctx, h, rw, type, target_page_bits);
672
}
673

    
674
#if defined(TARGET_PPC64)
675
static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr,
676
                             target_ulong *vsid, target_ulong *page_mask,
677
                             int *attr, int *target_page_bits)
678
{
679
    uint64_t esid;
680
    int n;
681

    
682
    LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
683

    
684
    esid = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
685

    
686
    for (n = 0; n < env->slb_nr; n++) {
687
        ppc_slb_t *slb = &env->slb[n];
688

    
689
        LOG_SLB("%s: slot %d %016" PRIx64 " %016"
690
                    PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
691
        if (slb->esid == esid) {
692
            *vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
693
            *page_mask = ~SEGMENT_MASK_256M;
694
            *attr = slb->vsid & SLB_VSID_ATTR;
695
            if (target_page_bits) {
696
                *target_page_bits = (slb->vsid & SLB_VSID_L)
697
                    ? TARGET_PAGE_BITS_16M
698
                    : TARGET_PAGE_BITS;
699
            }
700
            return n;
701
        }
702
    }
703

    
704
    return -5;
705
}
706

    
707
void ppc_slb_invalidate_all (CPUPPCState *env)
708
{
709
    int n, do_invalidate;
710

    
711
    do_invalidate = 0;
712
    /* XXX: Warning: slbia never invalidates the first segment */
713
    for (n = 1; n < env->slb_nr; n++) {
714
        ppc_slb_t *slb = &env->slb[n];
715

    
716
        if (slb->esid & SLB_ESID_V) {
717
            slb->esid &= ~SLB_ESID_V;
718
            /* XXX: given the fact that segment size is 256 MB or 1TB,
719
             *      and we still don't have a tlb_flush_mask(env, n, mask)
720
             *      in Qemu, we just invalidate all TLBs
721
             */
722
            do_invalidate = 1;
723
        }
724
    }
725
    if (do_invalidate)
726
        tlb_flush(env, 1);
727
}
728

    
729
void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
730
{
731
    target_ulong vsid, page_mask;
732
    int attr;
733
    int n;
734
    ppc_slb_t *slb;
735

    
736
    n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL);
737
    if (n < 0) {
738
        return;
739
    }
740

    
741
    slb = &env->slb[n];
742

    
743
    if (slb->esid & SLB_ESID_V) {
744
        slb->esid &= ~SLB_ESID_V;
745

    
746
        /* XXX: given the fact that segment size is 256 MB or 1TB,
747
         *      and we still don't have a tlb_flush_mask(env, n, mask)
748
         *      in Qemu, we just invalidate all TLBs
749
         */
750
        tlb_flush(env, 1);
751
    }
752
}
753

    
754
int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
755
{
756
    int slot = rb & 0xfff;
757
    uint64_t esid = rb & ~0xfff;
758
    ppc_slb_t *slb = &env->slb[slot];
759

    
760
    if (slot >= env->slb_nr) {
761
        return -1;
762
    }
763

    
764
    slb->esid = esid;
765
    slb->vsid = rs;
766

    
767
    LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
768
            " %016" PRIx64 "\n", __func__, slot, rb, rs,
769
            slb->esid, slb->vsid);
770

    
771
    return 0;
772
}
773
#endif /* defined(TARGET_PPC64) */
774

    
775
/* Perform segment based translation */
776
static inline target_phys_addr_t get_pgaddr(target_phys_addr_t sdr1,
777
                                            int sdr_sh,
778
                                            target_phys_addr_t hash,
779
                                            target_phys_addr_t mask)
780
{
781
    return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask);
782
}
783

    
784
static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
785
                              target_ulong eaddr, int rw, int type)
786
{
787
    target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
788
    target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
789
    int ds, vsid_sh, sdr_sh, pr, target_page_bits;
790
    int ret, ret2;
791

    
792
    pr = msr_pr;
793
#if defined(TARGET_PPC64)
794
    if (env->mmu_model & POWERPC_MMU_64) {
795
        int attr;
796

    
797
        LOG_MMU("Check SLBs\n");
798
        ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr,
799
                         &target_page_bits);
800
        if (ret < 0)
801
            return ret;
802
        ctx->key = !!(pr ? (attr & SLB_VSID_KP) : (attr & SLB_VSID_KS));
803
        ds = 0;
804
        ctx->nx = !!(attr & SLB_VSID_N);
805
        ctx->eaddr = eaddr;
806
        vsid_mask = 0x00003FFFFFFFFF80ULL;
807
        vsid_sh = 7;
808
        sdr_sh = 18;
809
        sdr_mask = 0x3FF80;
810
    } else
811
#endif /* defined(TARGET_PPC64) */
812
    {
813
        sr = env->sr[eaddr >> 28];
814
        page_mask = 0x0FFFFFFF;
815
        ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
816
                    ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
817
        ds = sr & 0x80000000 ? 1 : 0;
818
        ctx->nx = sr & 0x10000000 ? 1 : 0;
819
        vsid = sr & 0x00FFFFFF;
820
        vsid_mask = 0x01FFFFC0;
821
        vsid_sh = 6;
822
        sdr_sh = 16;
823
        sdr_mask = 0xFFC0;
824
        target_page_bits = TARGET_PAGE_BITS;
825
        LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
826
                TARGET_FMT_lx " lr=" TARGET_FMT_lx
827
                " ir=%d dr=%d pr=%d %d t=%d\n",
828
                eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
829
                (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
830
    }
831
    LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
832
            ctx->key, ds, ctx->nx, vsid);
833
    ret = -1;
834
    if (!ds) {
835
        /* Check if instruction fetch is allowed, if needed */
836
        if (type != ACCESS_CODE || ctx->nx == 0) {
837
            /* Page address translation */
838
            /* Primary table address */
839
            sdr = env->sdr1;
840
            pgidx = (eaddr & page_mask) >> target_page_bits;
841
#if defined(TARGET_PPC64)
842
            if (env->mmu_model & POWERPC_MMU_64) {
843
                htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
844
                /* XXX: this is false for 1 TB segments */
845
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
846
            } else
847
#endif
848
            {
849
                htab_mask = sdr & 0x000001FF;
850
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
851
            }
852
            mask = (htab_mask << sdr_sh) | sdr_mask;
853
            LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx
854
                    " mask " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
855
                    sdr, sdr_sh, hash, mask, page_mask);
856
            ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
857
            /* Secondary table address */
858
            hash = (~hash) & vsid_mask;
859
            LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx
860
                    " mask " TARGET_FMT_plx "\n", sdr, sdr_sh, hash, mask);
861
            ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
862
#if defined(TARGET_PPC64)
863
            if (env->mmu_model & POWERPC_MMU_64) {
864
                /* Only 5 bits of the page index are used in the AVPN */
865
                if (target_page_bits > 23) {
866
                    ctx->ptem = (vsid << 12) |
867
                                ((pgidx << (target_page_bits - 16)) & 0xF80);
868
                } else {
869
                    ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
870
                }
871
            } else
872
#endif
873
            {
874
                ctx->ptem = (vsid << 7) | (pgidx >> 10);
875
            }
876
            /* Initialize real address with an invalid value */
877
            ctx->raddr = (target_phys_addr_t)-1ULL;
878
            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
879
                         env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
880
                /* Software TLB search */
881
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
882
            } else {
883
                LOG_MMU("0 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " "
884
                        "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx
885
                        " pg_addr=" TARGET_FMT_plx "\n",
886
                        sdr, vsid, pgidx, hash, ctx->pg_addr[0]);
887
                /* Primary table lookup */
888
                ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
889
                if (ret < 0) {
890
                    /* Secondary table lookup */
891
                    if (eaddr != 0xEFFFFFFF)
892
                        LOG_MMU("1 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " "
893
                                "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx
894
                                " pg_addr=" TARGET_FMT_plx "\n", sdr, vsid,
895
                                pgidx, hash, ctx->pg_addr[1]);
896
                    ret2 = find_pte(env, ctx, 1, rw, type,
897
                                    target_page_bits);
898
                    if (ret2 != -1)
899
                        ret = ret2;
900
                }
901
            }
902
#if defined (DUMP_PAGE_TABLES)
903
            if (qemu_log_enabled()) {
904
                target_phys_addr_t curaddr;
905
                uint32_t a0, a1, a2, a3;
906
                qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
907
                         "\n", sdr, mask + 0x80);
908
                for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
909
                     curaddr += 16) {
910
                    a0 = ldl_phys(curaddr);
911
                    a1 = ldl_phys(curaddr + 4);
912
                    a2 = ldl_phys(curaddr + 8);
913
                    a3 = ldl_phys(curaddr + 12);
914
                    if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
915
                        qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
916
                                 curaddr, a0, a1, a2, a3);
917
                    }
918
                }
919
            }
920
#endif
921
        } else {
922
            LOG_MMU("No access allowed\n");
923
            ret = -3;
924
        }
925
    } else {
926
        LOG_MMU("direct store...\n");
927
        /* Direct-store segment : absolutely *BUGGY* for now */
928
        switch (type) {
929
        case ACCESS_INT:
930
            /* Integer load/store : only access allowed */
931
            break;
932
        case ACCESS_CODE:
933
            /* No code fetch is allowed in direct-store areas */
934
            return -4;
935
        case ACCESS_FLOAT:
936
            /* Floating point load/store */
937
            return -4;
938
        case ACCESS_RES:
939
            /* lwarx, ldarx or srwcx. */
940
            return -4;
941
        case ACCESS_CACHE:
942
            /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
943
            /* Should make the instruction do no-op.
944
             * As it already do no-op, it's quite easy :-)
945
             */
946
            ctx->raddr = eaddr;
947
            return 0;
948
        case ACCESS_EXT:
949
            /* eciwx or ecowx */
950
            return -4;
951
        default:
952
            qemu_log("ERROR: instruction should not need "
953
                        "address translation\n");
954
            return -4;
955
        }
956
        if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
957
            ctx->raddr = eaddr;
958
            ret = 2;
959
        } else {
960
            ret = -2;
961
        }
962
    }
963

    
964
    return ret;
965
}
966

    
967
/* Generic TLB check function for embedded PowerPC implementations */
968
static inline int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
969
                                   target_phys_addr_t *raddrp,
970
                                   target_ulong address, uint32_t pid, int ext,
971
                                   int i)
972
{
973
    target_ulong mask;
974

    
975
    /* Check valid flag */
976
    if (!(tlb->prot & PAGE_VALID)) {
977
        return -1;
978
    }
979
    mask = ~(tlb->size - 1);
980
    LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx
981
              " " TARGET_FMT_lx " %u\n", __func__, i, address, pid, tlb->EPN,
982
              mask, (uint32_t)tlb->PID);
983
    /* Check PID */
984
    if (tlb->PID != 0 && tlb->PID != pid)
985
        return -1;
986
    /* Check effective address */
987
    if ((address & mask) != tlb->EPN)
988
        return -1;
989
    *raddrp = (tlb->RPN & mask) | (address & ~mask);
990
#if (TARGET_PHYS_ADDR_BITS >= 36)
991
    if (ext) {
992
        /* Extend the physical address to 36 bits */
993
        *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
994
    }
995
#endif
996

    
997
    return 0;
998
}
999

    
1000
/* Generic TLB search function for PowerPC embedded implementations */
1001
int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
1002
{
1003
    ppcemb_tlb_t *tlb;
1004
    target_phys_addr_t raddr;
1005
    int i, ret;
1006

    
1007
    /* Default return value is no match */
1008
    ret = -1;
1009
    for (i = 0; i < env->nb_tlb; i++) {
1010
        tlb = &env->tlb[i].tlbe;
1011
        if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
1012
            ret = i;
1013
            break;
1014
        }
1015
    }
1016

    
1017
    return ret;
1018
}
1019

    
1020
/* Helpers specific to PowerPC 40x implementations */
1021
static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
1022
{
1023
    ppcemb_tlb_t *tlb;
1024
    int i;
1025

    
1026
    for (i = 0; i < env->nb_tlb; i++) {
1027
        tlb = &env->tlb[i].tlbe;
1028
        tlb->prot &= ~PAGE_VALID;
1029
    }
1030
    tlb_flush(env, 1);
1031
}
1032

    
1033
static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
1034
                                              target_ulong eaddr, uint32_t pid)
1035
{
1036
#if !defined(FLUSH_ALL_TLBS)
1037
    ppcemb_tlb_t *tlb;
1038
    target_phys_addr_t raddr;
1039
    target_ulong page, end;
1040
    int i;
1041

    
1042
    for (i = 0; i < env->nb_tlb; i++) {
1043
        tlb = &env->tlb[i].tlbe;
1044
        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
1045
            end = tlb->EPN + tlb->size;
1046
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
1047
                tlb_flush_page(env, page);
1048
            tlb->prot &= ~PAGE_VALID;
1049
            break;
1050
        }
1051
    }
1052
#else
1053
    ppc4xx_tlb_invalidate_all(env);
1054
#endif
1055
}
1056

    
1057
static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1058
                                 target_ulong address, int rw, int access_type)
1059
{
1060
    ppcemb_tlb_t *tlb;
1061
    target_phys_addr_t raddr;
1062
    int i, ret, zsel, zpr, pr;
1063

    
1064
    ret = -1;
1065
    raddr = (target_phys_addr_t)-1ULL;
1066
    pr = msr_pr;
1067
    for (i = 0; i < env->nb_tlb; i++) {
1068
        tlb = &env->tlb[i].tlbe;
1069
        if (ppcemb_tlb_check(env, tlb, &raddr, address,
1070
                             env->spr[SPR_40x_PID], 0, i) < 0)
1071
            continue;
1072
        zsel = (tlb->attr >> 4) & 0xF;
1073
        zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
1074
        LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1075
                    __func__, i, zsel, zpr, rw, tlb->attr);
1076
        /* Check execute enable bit */
1077
        switch (zpr) {
1078
        case 0x2:
1079
            if (pr != 0)
1080
                goto check_perms;
1081
            /* No break here */
1082
        case 0x3:
1083
            /* All accesses granted */
1084
            ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1085
            ret = 0;
1086
            break;
1087
        case 0x0:
1088
            if (pr != 0) {
1089
                /* Raise Zone protection fault.  */
1090
                env->spr[SPR_40x_ESR] = 1 << 22;
1091
                ctx->prot = 0;
1092
                ret = -2;
1093
                break;
1094
            }
1095
            /* No break here */
1096
        case 0x1:
1097
        check_perms:
1098
            /* Check from TLB entry */
1099
            ctx->prot = tlb->prot;
1100
            ret = check_prot(ctx->prot, rw, access_type);
1101
            if (ret == -2)
1102
                env->spr[SPR_40x_ESR] = 0;
1103
            break;
1104
        }
1105
        if (ret >= 0) {
1106
            ctx->raddr = raddr;
1107
            LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1108
                      " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1109
                      ret);
1110
            return 0;
1111
        }
1112
    }
1113
    LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1114
              " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1115

    
1116
    return ret;
1117
}
1118

    
1119
void store_40x_sler (CPUPPCState *env, uint32_t val)
1120
{
1121
    /* XXX: TO BE FIXED */
1122
    if (val != 0x00000000) {
1123
        cpu_abort(env, "Little-endian regions are not supported by now\n");
1124
    }
1125
    env->spr[SPR_405_SLER] = val;
1126
}
1127

    
1128
static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1129
                                          target_ulong address, int rw,
1130
                                          int access_type)
1131
{
1132
    ppcemb_tlb_t *tlb;
1133
    target_phys_addr_t raddr;
1134
    int i, prot, ret;
1135

    
1136
    ret = -1;
1137
    raddr = (target_phys_addr_t)-1ULL;
1138
    for (i = 0; i < env->nb_tlb; i++) {
1139
        tlb = &env->tlb[i].tlbe;
1140
        if (ppcemb_tlb_check(env, tlb, &raddr, address,
1141
                             env->spr[SPR_BOOKE_PID], 1, i) < 0)
1142
            continue;
1143
        if (msr_pr != 0)
1144
            prot = tlb->prot & 0xF;
1145
        else
1146
            prot = (tlb->prot >> 4) & 0xF;
1147
        /* Check the address space */
1148
        if (access_type == ACCESS_CODE) {
1149
            if (msr_ir != (tlb->attr & 1))
1150
                continue;
1151
            ctx->prot = prot;
1152
            if (prot & PAGE_EXEC) {
1153
                ret = 0;
1154
                break;
1155
            }
1156
            ret = -3;
1157
        } else {
1158
            if (msr_dr != (tlb->attr & 1))
1159
                continue;
1160
            ctx->prot = prot;
1161
            if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) {
1162
                ret = 0;
1163
                break;
1164
            }
1165
            ret = -2;
1166
        }
1167
    }
1168
    if (ret >= 0)
1169
        ctx->raddr = raddr;
1170

    
1171
    return ret;
1172
}
1173

    
1174
static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
1175
                                 target_ulong eaddr, int rw)
1176
{
1177
    int in_plb, ret;
1178

    
1179
    ctx->raddr = eaddr;
1180
    ctx->prot = PAGE_READ | PAGE_EXEC;
1181
    ret = 0;
1182
    switch (env->mmu_model) {
1183
    case POWERPC_MMU_32B:
1184
    case POWERPC_MMU_601:
1185
    case POWERPC_MMU_SOFT_6xx:
1186
    case POWERPC_MMU_SOFT_74xx:
1187
    case POWERPC_MMU_SOFT_4xx:
1188
    case POWERPC_MMU_REAL:
1189
    case POWERPC_MMU_BOOKE:
1190
        ctx->prot |= PAGE_WRITE;
1191
        break;
1192
#if defined(TARGET_PPC64)
1193
    case POWERPC_MMU_620:
1194
    case POWERPC_MMU_64B:
1195
        /* Real address are 60 bits long */
1196
        ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1197
        ctx->prot |= PAGE_WRITE;
1198
        break;
1199
#endif
1200
    case POWERPC_MMU_SOFT_4xx_Z:
1201
        if (unlikely(msr_pe != 0)) {
1202
            /* 403 family add some particular protections,
1203
             * using PBL/PBU registers for accesses with no translation.
1204
             */
1205
            in_plb =
1206
                /* Check PLB validity */
1207
                (env->pb[0] < env->pb[1] &&
1208
                 /* and address in plb area */
1209
                 eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
1210
                (env->pb[2] < env->pb[3] &&
1211
                 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
1212
            if (in_plb ^ msr_px) {
1213
                /* Access in protected area */
1214
                if (rw == 1) {
1215
                    /* Access is not allowed */
1216
                    ret = -2;
1217
                }
1218
            } else {
1219
                /* Read-write access is allowed */
1220
                ctx->prot |= PAGE_WRITE;
1221
            }
1222
        }
1223
        break;
1224
    case POWERPC_MMU_MPC8xx:
1225
        /* XXX: TODO */
1226
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1227
        break;
1228
    case POWERPC_MMU_BOOKE_FSL:
1229
        /* XXX: TODO */
1230
        cpu_abort(env, "BookE FSL MMU model not implemented\n");
1231
        break;
1232
    default:
1233
        cpu_abort(env, "Unknown or invalid MMU model\n");
1234
        return -1;
1235
    }
1236

    
1237
    return ret;
1238
}
1239

    
1240
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1241
                          int rw, int access_type)
1242
{
1243
    int ret;
1244

    
1245
#if 0
1246
    qemu_log("%s\n", __func__);
1247
#endif
1248
    if ((access_type == ACCESS_CODE && msr_ir == 0) ||
1249
        (access_type != ACCESS_CODE && msr_dr == 0)) {
1250
        if (env->mmu_model == POWERPC_MMU_BOOKE) {
1251
            /* The BookE MMU always performs address translation. The
1252
               IS and DS bits only affect the address space.  */
1253
            ret = mmubooke_get_physical_address(env, ctx, eaddr,
1254
                                                rw, access_type);
1255
        } else {
1256
            /* No address translation.  */
1257
            ret = check_physical(env, ctx, eaddr, rw);
1258
        }
1259
    } else {
1260
        ret = -1;
1261
        switch (env->mmu_model) {
1262
        case POWERPC_MMU_32B:
1263
        case POWERPC_MMU_601:
1264
        case POWERPC_MMU_SOFT_6xx:
1265
        case POWERPC_MMU_SOFT_74xx:
1266
            /* Try to find a BAT */
1267
            if (env->nb_BATs != 0)
1268
                ret = get_bat(env, ctx, eaddr, rw, access_type);
1269
#if defined(TARGET_PPC64)
1270
        case POWERPC_MMU_620:
1271
        case POWERPC_MMU_64B:
1272
#endif
1273
            if (ret < 0) {
1274
                /* We didn't match any BAT entry or don't have BATs */
1275
                ret = get_segment(env, ctx, eaddr, rw, access_type);
1276
            }
1277
            break;
1278
        case POWERPC_MMU_SOFT_4xx:
1279
        case POWERPC_MMU_SOFT_4xx_Z:
1280
            ret = mmu40x_get_physical_address(env, ctx, eaddr,
1281
                                              rw, access_type);
1282
            break;
1283
        case POWERPC_MMU_BOOKE:
1284
            ret = mmubooke_get_physical_address(env, ctx, eaddr,
1285
                                                rw, access_type);
1286
            break;
1287
        case POWERPC_MMU_MPC8xx:
1288
            /* XXX: TODO */
1289
            cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1290
            break;
1291
        case POWERPC_MMU_BOOKE_FSL:
1292
            /* XXX: TODO */
1293
            cpu_abort(env, "BookE FSL MMU model not implemented\n");
1294
            return -1;
1295
        case POWERPC_MMU_REAL:
1296
            cpu_abort(env, "PowerPC in real mode do not do any translation\n");
1297
            return -1;
1298
        default:
1299
            cpu_abort(env, "Unknown or invalid MMU model\n");
1300
            return -1;
1301
        }
1302
    }
1303
#if 0
1304
    qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n",
1305
             __func__, eaddr, ret, ctx->raddr);
1306
#endif
1307

    
1308
    return ret;
1309
}
1310

    
1311
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1312
{
1313
    mmu_ctx_t ctx;
1314

    
1315
    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1316
        return -1;
1317

    
1318
    return ctx.raddr & TARGET_PAGE_MASK;
1319
}
1320

    
1321
/* Perform address translation */
1322
int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1323
                              int mmu_idx, int is_softmmu)
1324
{
1325
    mmu_ctx_t ctx;
1326
    int access_type;
1327
    int ret = 0;
1328

    
1329
    if (rw == 2) {
1330
        /* code access */
1331
        rw = 0;
1332
        access_type = ACCESS_CODE;
1333
    } else {
1334
        /* data access */
1335
        access_type = env->access_type;
1336
    }
1337
    ret = get_physical_address(env, &ctx, address, rw, access_type);
1338
    if (ret == 0) {
1339
        tlb_set_page(env, address & TARGET_PAGE_MASK,
1340
                     ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1341
                     mmu_idx, TARGET_PAGE_SIZE);
1342
        ret = 0;
1343
    } else if (ret < 0) {
1344
        LOG_MMU_STATE(env);
1345
        if (access_type == ACCESS_CODE) {
1346
            switch (ret) {
1347
            case -1:
1348
                /* No matches in page tables or TLB */
1349
                switch (env->mmu_model) {
1350
                case POWERPC_MMU_SOFT_6xx:
1351
                    env->exception_index = POWERPC_EXCP_IFTLB;
1352
                    env->error_code = 1 << 18;
1353
                    env->spr[SPR_IMISS] = address;
1354
                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1355
                    goto tlb_miss;
1356
                case POWERPC_MMU_SOFT_74xx:
1357
                    env->exception_index = POWERPC_EXCP_IFTLB;
1358
                    goto tlb_miss_74xx;
1359
                case POWERPC_MMU_SOFT_4xx:
1360
                case POWERPC_MMU_SOFT_4xx_Z:
1361
                    env->exception_index = POWERPC_EXCP_ITLB;
1362
                    env->error_code = 0;
1363
                    env->spr[SPR_40x_DEAR] = address;
1364
                    env->spr[SPR_40x_ESR] = 0x00000000;
1365
                    break;
1366
                case POWERPC_MMU_32B:
1367
                case POWERPC_MMU_601:
1368
#if defined(TARGET_PPC64)
1369
                case POWERPC_MMU_620:
1370
                case POWERPC_MMU_64B:
1371
#endif
1372
                    env->exception_index = POWERPC_EXCP_ISI;
1373
                    env->error_code = 0x40000000;
1374
                    break;
1375
                case POWERPC_MMU_BOOKE:
1376
                    env->exception_index = POWERPC_EXCP_ITLB;
1377
                    env->error_code = 0;
1378
                    env->spr[SPR_BOOKE_DEAR] = address;
1379
                    return -1;
1380
                case POWERPC_MMU_BOOKE_FSL:
1381
                    /* XXX: TODO */
1382
                    cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1383
                    return -1;
1384
                case POWERPC_MMU_MPC8xx:
1385
                    /* XXX: TODO */
1386
                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1387
                    break;
1388
                case POWERPC_MMU_REAL:
1389
                    cpu_abort(env, "PowerPC in real mode should never raise "
1390
                              "any MMU exceptions\n");
1391
                    return -1;
1392
                default:
1393
                    cpu_abort(env, "Unknown or invalid MMU model\n");
1394
                    return -1;
1395
                }
1396
                break;
1397
            case -2:
1398
                /* Access rights violation */
1399
                env->exception_index = POWERPC_EXCP_ISI;
1400
                env->error_code = 0x08000000;
1401
                break;
1402
            case -3:
1403
                /* No execute protection violation */
1404
                if (env->mmu_model == POWERPC_MMU_BOOKE) {
1405
                    env->spr[SPR_BOOKE_ESR] = 0x00000000;
1406
                }
1407
                env->exception_index = POWERPC_EXCP_ISI;
1408
                env->error_code = 0x10000000;
1409
                break;
1410
            case -4:
1411
                /* Direct store exception */
1412
                /* No code fetch is allowed in direct-store areas */
1413
                env->exception_index = POWERPC_EXCP_ISI;
1414
                env->error_code = 0x10000000;
1415
                break;
1416
#if defined(TARGET_PPC64)
1417
            case -5:
1418
                /* No match in segment table */
1419
                if (env->mmu_model == POWERPC_MMU_620) {
1420
                    env->exception_index = POWERPC_EXCP_ISI;
1421
                    /* XXX: this might be incorrect */
1422
                    env->error_code = 0x40000000;
1423
                } else {
1424
                    env->exception_index = POWERPC_EXCP_ISEG;
1425
                    env->error_code = 0;
1426
                }
1427
                break;
1428
#endif
1429
            }
1430
        } else {
1431
            switch (ret) {
1432
            case -1:
1433
                /* No matches in page tables or TLB */
1434
                switch (env->mmu_model) {
1435
                case POWERPC_MMU_SOFT_6xx:
1436
                    if (rw == 1) {
1437
                        env->exception_index = POWERPC_EXCP_DSTLB;
1438
                        env->error_code = 1 << 16;
1439
                    } else {
1440
                        env->exception_index = POWERPC_EXCP_DLTLB;
1441
                        env->error_code = 0;
1442
                    }
1443
                    env->spr[SPR_DMISS] = address;
1444
                    env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1445
                tlb_miss:
1446
                    env->error_code |= ctx.key << 19;
1447
                    env->spr[SPR_HASH1] = ctx.pg_addr[0];
1448
                    env->spr[SPR_HASH2] = ctx.pg_addr[1];
1449
                    break;
1450
                case POWERPC_MMU_SOFT_74xx:
1451
                    if (rw == 1) {
1452
                        env->exception_index = POWERPC_EXCP_DSTLB;
1453
                    } else {
1454
                        env->exception_index = POWERPC_EXCP_DLTLB;
1455
                    }
1456
                tlb_miss_74xx:
1457
                    /* Implement LRU algorithm */
1458
                    env->error_code = ctx.key << 19;
1459
                    env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
1460
                        ((env->last_way + 1) & (env->nb_ways - 1));
1461
                    env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1462
                    break;
1463
                case POWERPC_MMU_SOFT_4xx:
1464
                case POWERPC_MMU_SOFT_4xx_Z:
1465
                    env->exception_index = POWERPC_EXCP_DTLB;
1466
                    env->error_code = 0;
1467
                    env->spr[SPR_40x_DEAR] = address;
1468
                    if (rw)
1469
                        env->spr[SPR_40x_ESR] = 0x00800000;
1470
                    else
1471
                        env->spr[SPR_40x_ESR] = 0x00000000;
1472
                    break;
1473
                case POWERPC_MMU_32B:
1474
                case POWERPC_MMU_601:
1475
#if defined(TARGET_PPC64)
1476
                case POWERPC_MMU_620:
1477
                case POWERPC_MMU_64B:
1478
#endif
1479
                    env->exception_index = POWERPC_EXCP_DSI;
1480
                    env->error_code = 0;
1481
                    env->spr[SPR_DAR] = address;
1482
                    if (rw == 1)
1483
                        env->spr[SPR_DSISR] = 0x42000000;
1484
                    else
1485
                        env->spr[SPR_DSISR] = 0x40000000;
1486
                    break;
1487
                case POWERPC_MMU_MPC8xx:
1488
                    /* XXX: TODO */
1489
                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1490
                    break;
1491
                case POWERPC_MMU_BOOKE:
1492
                    env->exception_index = POWERPC_EXCP_DTLB;
1493
                    env->error_code = 0;
1494
                    env->spr[SPR_BOOKE_DEAR] = address;
1495
                    env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
1496
                    return -1;
1497
                case POWERPC_MMU_BOOKE_FSL:
1498
                    /* XXX: TODO */
1499
                    cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1500
                    return -1;
1501
                case POWERPC_MMU_REAL:
1502
                    cpu_abort(env, "PowerPC in real mode should never raise "
1503
                              "any MMU exceptions\n");
1504
                    return -1;
1505
                default:
1506
                    cpu_abort(env, "Unknown or invalid MMU model\n");
1507
                    return -1;
1508
                }
1509
                break;
1510
            case -2:
1511
                /* Access rights violation */
1512
                env->exception_index = POWERPC_EXCP_DSI;
1513
                env->error_code = 0;
1514
                if (env->mmu_model == POWERPC_MMU_SOFT_4xx
1515
                    || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
1516
                    env->spr[SPR_40x_DEAR] = address;
1517
                    if (rw) {
1518
                        env->spr[SPR_40x_ESR] |= 0x00800000;
1519
                    }
1520
                } else if (env->mmu_model == POWERPC_MMU_BOOKE) {
1521
                    env->spr[SPR_BOOKE_DEAR] = address;
1522
                    env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
1523
                } else {
1524
                    env->spr[SPR_DAR] = address;
1525
                    if (rw == 1) {
1526
                        env->spr[SPR_DSISR] = 0x0A000000;
1527
                    } else {
1528
                        env->spr[SPR_DSISR] = 0x08000000;
1529
                    }
1530
                }
1531
                break;
1532
            case -4:
1533
                /* Direct store exception */
1534
                switch (access_type) {
1535
                case ACCESS_FLOAT:
1536
                    /* Floating point load/store */
1537
                    env->exception_index = POWERPC_EXCP_ALIGN;
1538
                    env->error_code = POWERPC_EXCP_ALIGN_FP;
1539
                    env->spr[SPR_DAR] = address;
1540
                    break;
1541
                case ACCESS_RES:
1542
                    /* lwarx, ldarx or stwcx. */
1543
                    env->exception_index = POWERPC_EXCP_DSI;
1544
                    env->error_code = 0;
1545
                    env->spr[SPR_DAR] = address;
1546
                    if (rw == 1)
1547
                        env->spr[SPR_DSISR] = 0x06000000;
1548
                    else
1549
                        env->spr[SPR_DSISR] = 0x04000000;
1550
                    break;
1551
                case ACCESS_EXT:
1552
                    /* eciwx or ecowx */
1553
                    env->exception_index = POWERPC_EXCP_DSI;
1554
                    env->error_code = 0;
1555
                    env->spr[SPR_DAR] = address;
1556
                    if (rw == 1)
1557
                        env->spr[SPR_DSISR] = 0x06100000;
1558
                    else
1559
                        env->spr[SPR_DSISR] = 0x04100000;
1560
                    break;
1561
                default:
1562
                    printf("DSI: invalid exception (%d)\n", ret);
1563
                    env->exception_index = POWERPC_EXCP_PROGRAM;
1564
                    env->error_code =
1565
                        POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1566
                    env->spr[SPR_DAR] = address;
1567
                    break;
1568
                }
1569
                break;
1570
#if defined(TARGET_PPC64)
1571
            case -5:
1572
                /* No match in segment table */
1573
                if (env->mmu_model == POWERPC_MMU_620) {
1574
                    env->exception_index = POWERPC_EXCP_DSI;
1575
                    env->error_code = 0;
1576
                    env->spr[SPR_DAR] = address;
1577
                    /* XXX: this might be incorrect */
1578
                    if (rw == 1)
1579
                        env->spr[SPR_DSISR] = 0x42000000;
1580
                    else
1581
                        env->spr[SPR_DSISR] = 0x40000000;
1582
                } else {
1583
                    env->exception_index = POWERPC_EXCP_DSEG;
1584
                    env->error_code = 0;
1585
                    env->spr[SPR_DAR] = address;
1586
                }
1587
                break;
1588
#endif
1589
            }
1590
        }
1591
#if 0
1592
        printf("%s: set exception to %d %02x\n", __func__,
1593
               env->exception, env->error_code);
1594
#endif
1595
        ret = 1;
1596
    }
1597

    
1598
    return ret;
1599
}
1600

    
1601
/*****************************************************************************/
1602
/* BATs management */
1603
#if !defined(FLUSH_ALL_TLBS)
1604
static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
1605
                                     target_ulong mask)
1606
{
1607
    target_ulong base, end, page;
1608

    
1609
    base = BATu & ~0x0001FFFF;
1610
    end = base + mask + 0x00020000;
1611
    LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
1612
             TARGET_FMT_lx ")\n", base, end, mask);
1613
    for (page = base; page != end; page += TARGET_PAGE_SIZE)
1614
        tlb_flush_page(env, page);
1615
    LOG_BATS("Flush done\n");
1616
}
1617
#endif
1618

    
1619
static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
1620
                                  target_ulong value)
1621
{
1622
    LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID,
1623
             nr, ul == 0 ? 'u' : 'l', value, env->nip);
1624
}
1625

    
1626
void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1627
{
1628
    target_ulong mask;
1629

    
1630
    dump_store_bat(env, 'I', 0, nr, value);
1631
    if (env->IBAT[0][nr] != value) {
1632
        mask = (value << 15) & 0x0FFE0000UL;
1633
#if !defined(FLUSH_ALL_TLBS)
1634
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1635
#endif
1636
        /* When storing valid upper BAT, mask BEPI and BRPN
1637
         * and invalidate all TLBs covered by this BAT
1638
         */
1639
        mask = (value << 15) & 0x0FFE0000UL;
1640
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1641
            (value & ~0x0001FFFFUL & ~mask);
1642
        env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1643
            (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1644
#if !defined(FLUSH_ALL_TLBS)
1645
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1646
#else
1647
        tlb_flush(env, 1);
1648
#endif
1649
    }
1650
}
1651

    
1652
void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1653
{
1654
    dump_store_bat(env, 'I', 1, nr, value);
1655
    env->IBAT[1][nr] = value;
1656
}
1657

    
1658
void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1659
{
1660
    target_ulong mask;
1661

    
1662
    dump_store_bat(env, 'D', 0, nr, value);
1663
    if (env->DBAT[0][nr] != value) {
1664
        /* When storing valid upper BAT, mask BEPI and BRPN
1665
         * and invalidate all TLBs covered by this BAT
1666
         */
1667
        mask = (value << 15) & 0x0FFE0000UL;
1668
#if !defined(FLUSH_ALL_TLBS)
1669
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1670
#endif
1671
        mask = (value << 15) & 0x0FFE0000UL;
1672
        env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1673
            (value & ~0x0001FFFFUL & ~mask);
1674
        env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1675
            (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1676
#if !defined(FLUSH_ALL_TLBS)
1677
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1678
#else
1679
        tlb_flush(env, 1);
1680
#endif
1681
    }
1682
}
1683

    
1684
void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1685
{
1686
    dump_store_bat(env, 'D', 1, nr, value);
1687
    env->DBAT[1][nr] = value;
1688
}
1689

    
1690
void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
1691
{
1692
    target_ulong mask;
1693
#if defined(FLUSH_ALL_TLBS)
1694
    int do_inval;
1695
#endif
1696

    
1697
    dump_store_bat(env, 'I', 0, nr, value);
1698
    if (env->IBAT[0][nr] != value) {
1699
#if defined(FLUSH_ALL_TLBS)
1700
        do_inval = 0;
1701
#endif
1702
        mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1703
        if (env->IBAT[1][nr] & 0x40) {
1704
            /* Invalidate BAT only if it is valid */
1705
#if !defined(FLUSH_ALL_TLBS)
1706
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1707
#else
1708
            do_inval = 1;
1709
#endif
1710
        }
1711
        /* When storing valid upper BAT, mask BEPI and BRPN
1712
         * and invalidate all TLBs covered by this BAT
1713
         */
1714
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1715
            (value & ~0x0001FFFFUL & ~mask);
1716
        env->DBAT[0][nr] = env->IBAT[0][nr];
1717
        if (env->IBAT[1][nr] & 0x40) {
1718
#if !defined(FLUSH_ALL_TLBS)
1719
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1720
#else
1721
            do_inval = 1;
1722
#endif
1723
        }
1724
#if defined(FLUSH_ALL_TLBS)
1725
        if (do_inval)
1726
            tlb_flush(env, 1);
1727
#endif
1728
    }
1729
}
1730

    
1731
void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
1732
{
1733
    target_ulong mask;
1734
#if defined(FLUSH_ALL_TLBS)
1735
    int do_inval;
1736
#endif
1737

    
1738
    dump_store_bat(env, 'I', 1, nr, value);
1739
    if (env->IBAT[1][nr] != value) {
1740
#if defined(FLUSH_ALL_TLBS)
1741
        do_inval = 0;
1742
#endif
1743
        if (env->IBAT[1][nr] & 0x40) {
1744
#if !defined(FLUSH_ALL_TLBS)
1745
            mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1746
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1747
#else
1748
            do_inval = 1;
1749
#endif
1750
        }
1751
        if (value & 0x40) {
1752
#if !defined(FLUSH_ALL_TLBS)
1753
            mask = (value << 17) & 0x0FFE0000UL;
1754
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1755
#else
1756
            do_inval = 1;
1757
#endif
1758
        }
1759
        env->IBAT[1][nr] = value;
1760
        env->DBAT[1][nr] = value;
1761
#if defined(FLUSH_ALL_TLBS)
1762
        if (do_inval)
1763
            tlb_flush(env, 1);
1764
#endif
1765
    }
1766
}
1767

    
1768
/*****************************************************************************/
1769
/* TLB management */
1770
void ppc_tlb_invalidate_all (CPUPPCState *env)
1771
{
1772
    switch (env->mmu_model) {
1773
    case POWERPC_MMU_SOFT_6xx:
1774
    case POWERPC_MMU_SOFT_74xx:
1775
        ppc6xx_tlb_invalidate_all(env);
1776
        break;
1777
    case POWERPC_MMU_SOFT_4xx:
1778
    case POWERPC_MMU_SOFT_4xx_Z:
1779
        ppc4xx_tlb_invalidate_all(env);
1780
        break;
1781
    case POWERPC_MMU_REAL:
1782
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1783
        break;
1784
    case POWERPC_MMU_MPC8xx:
1785
        /* XXX: TODO */
1786
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1787
        break;
1788
    case POWERPC_MMU_BOOKE:
1789
        tlb_flush(env, 1);
1790
        break;
1791
    case POWERPC_MMU_BOOKE_FSL:
1792
        /* XXX: TODO */
1793
        if (!kvm_enabled())
1794
            cpu_abort(env, "BookE MMU model is not implemented\n");
1795
        break;
1796
    case POWERPC_MMU_32B:
1797
    case POWERPC_MMU_601:
1798
#if defined(TARGET_PPC64)
1799
    case POWERPC_MMU_620:
1800
    case POWERPC_MMU_64B:
1801
#endif /* defined(TARGET_PPC64) */
1802
        tlb_flush(env, 1);
1803
        break;
1804
    default:
1805
        /* XXX: TODO */
1806
        cpu_abort(env, "Unknown MMU model\n");
1807
        break;
1808
    }
1809
}
1810

    
1811
void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
1812
{
1813
#if !defined(FLUSH_ALL_TLBS)
1814
    addr &= TARGET_PAGE_MASK;
1815
    switch (env->mmu_model) {
1816
    case POWERPC_MMU_SOFT_6xx:
1817
    case POWERPC_MMU_SOFT_74xx:
1818
        ppc6xx_tlb_invalidate_virt(env, addr, 0);
1819
        if (env->id_tlbs == 1)
1820
            ppc6xx_tlb_invalidate_virt(env, addr, 1);
1821
        break;
1822
    case POWERPC_MMU_SOFT_4xx:
1823
    case POWERPC_MMU_SOFT_4xx_Z:
1824
        ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
1825
        break;
1826
    case POWERPC_MMU_REAL:
1827
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1828
        break;
1829
    case POWERPC_MMU_MPC8xx:
1830
        /* XXX: TODO */
1831
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1832
        break;
1833
    case POWERPC_MMU_BOOKE:
1834
        /* XXX: TODO */
1835
        cpu_abort(env, "BookE MMU model is not implemented\n");
1836
        break;
1837
    case POWERPC_MMU_BOOKE_FSL:
1838
        /* XXX: TODO */
1839
        cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1840
        break;
1841
    case POWERPC_MMU_32B:
1842
    case POWERPC_MMU_601:
1843
        /* tlbie invalidate TLBs for all segments */
1844
        addr &= ~((target_ulong)-1ULL << 28);
1845
        /* XXX: this case should be optimized,
1846
         * giving a mask to tlb_flush_page
1847
         */
1848
        tlb_flush_page(env, addr | (0x0 << 28));
1849
        tlb_flush_page(env, addr | (0x1 << 28));
1850
        tlb_flush_page(env, addr | (0x2 << 28));
1851
        tlb_flush_page(env, addr | (0x3 << 28));
1852
        tlb_flush_page(env, addr | (0x4 << 28));
1853
        tlb_flush_page(env, addr | (0x5 << 28));
1854
        tlb_flush_page(env, addr | (0x6 << 28));
1855
        tlb_flush_page(env, addr | (0x7 << 28));
1856
        tlb_flush_page(env, addr | (0x8 << 28));
1857
        tlb_flush_page(env, addr | (0x9 << 28));
1858
        tlb_flush_page(env, addr | (0xA << 28));
1859
        tlb_flush_page(env, addr | (0xB << 28));
1860
        tlb_flush_page(env, addr | (0xC << 28));
1861
        tlb_flush_page(env, addr | (0xD << 28));
1862
        tlb_flush_page(env, addr | (0xE << 28));
1863
        tlb_flush_page(env, addr | (0xF << 28));
1864
        break;
1865
#if defined(TARGET_PPC64)
1866
    case POWERPC_MMU_620:
1867
    case POWERPC_MMU_64B:
1868
        /* tlbie invalidate TLBs for all segments */
1869
        /* XXX: given the fact that there are too many segments to invalidate,
1870
         *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
1871
         *      we just invalidate all TLBs
1872
         */
1873
        tlb_flush(env, 1);
1874
        break;
1875
#endif /* defined(TARGET_PPC64) */
1876
    default:
1877
        /* XXX: TODO */
1878
        cpu_abort(env, "Unknown MMU model\n");
1879
        break;
1880
    }
1881
#else
1882
    ppc_tlb_invalidate_all(env);
1883
#endif
1884
}
1885

    
1886
/*****************************************************************************/
1887
/* Special registers manipulation */
1888
#if defined(TARGET_PPC64)
1889
void ppc_store_asr (CPUPPCState *env, target_ulong value)
1890
{
1891
    if (env->asr != value) {
1892
        env->asr = value;
1893
        tlb_flush(env, 1);
1894
    }
1895
}
1896
#endif
1897

    
1898
void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
1899
{
1900
    LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
1901
    if (env->sdr1 != value) {
1902
        /* XXX: for PowerPC 64, should check that the HTABSIZE value
1903
         *      is <= 28
1904
         */
1905
        env->sdr1 = value;
1906
        tlb_flush(env, 1);
1907
    }
1908
}
1909

    
1910
#if defined(TARGET_PPC64)
1911
target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
1912
{
1913
    // XXX
1914
    return 0;
1915
}
1916
#endif
1917

    
1918
void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1919
{
1920
    LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
1921
            srnum, value, env->sr[srnum]);
1922
#if defined(TARGET_PPC64)
1923
    if (env->mmu_model & POWERPC_MMU_64) {
1924
        uint64_t rb = 0, rs = 0;
1925

    
1926
        /* ESID = srnum */
1927
        rb |= ((uint32_t)srnum & 0xf) << 28;
1928
        /* Set the valid bit */
1929
        rb |= 1 << 27;
1930
        /* Index = ESID */
1931
        rb |= (uint32_t)srnum;
1932

    
1933
        /* VSID = VSID */
1934
        rs |= (value & 0xfffffff) << 12;
1935
        /* flags = flags */
1936
        rs |= ((value >> 27) & 0xf) << 9;
1937

    
1938
        ppc_store_slb(env, rb, rs);
1939
    } else
1940
#endif
1941
    if (env->sr[srnum] != value) {
1942
        env->sr[srnum] = value;
1943
/* Invalidating 256MB of virtual memory in 4kB pages is way longer than
1944
   flusing the whole TLB. */
1945
#if !defined(FLUSH_ALL_TLBS) && 0
1946
        {
1947
            target_ulong page, end;
1948
            /* Invalidate 256 MB of virtual memory */
1949
            page = (16 << 20) * srnum;
1950
            end = page + (16 << 20);
1951
            for (; page != end; page += TARGET_PAGE_SIZE)
1952
                tlb_flush_page(env, page);
1953
        }
1954
#else
1955
        tlb_flush(env, 1);
1956
#endif
1957
    }
1958
}
1959
#endif /* !defined (CONFIG_USER_ONLY) */
1960

    
1961
/* GDBstub can read and write MSR... */
1962
void ppc_store_msr (CPUPPCState *env, target_ulong value)
1963
{
1964
    hreg_store_msr(env, value, 0);
1965
}
1966

    
1967
/*****************************************************************************/
1968
/* Exception processing */
1969
#if defined (CONFIG_USER_ONLY)
1970
void do_interrupt (CPUState *env)
1971
{
1972
    env->exception_index = POWERPC_EXCP_NONE;
1973
    env->error_code = 0;
1974
}
1975

    
1976
void ppc_hw_interrupt (CPUState *env)
1977
{
1978
    env->exception_index = POWERPC_EXCP_NONE;
1979
    env->error_code = 0;
1980
}
1981
#else /* defined (CONFIG_USER_ONLY) */
1982
static inline void dump_syscall(CPUState *env)
1983
{
1984
    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
1985
                  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
1986
                  " nip=" TARGET_FMT_lx "\n",
1987
                  ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
1988
                  ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
1989
                  ppc_dump_gpr(env, 6), env->nip);
1990
}
1991

    
1992
/* Note that this function should be greatly optimized
1993
 * when called with a constant excp, from ppc_hw_interrupt
1994
 */
1995
static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
1996
{
1997
    target_ulong msr, new_msr, vector;
1998
    int srr0, srr1, asrr0, asrr1;
1999
    int lpes0, lpes1, lev;
2000

    
2001
    if (0) {
2002
        /* XXX: find a suitable condition to enable the hypervisor mode */
2003
        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
2004
        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
2005
    } else {
2006
        /* Those values ensure we won't enter the hypervisor mode */
2007
        lpes0 = 0;
2008
        lpes1 = 1;
2009
    }
2010

    
2011
    qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
2012
                  " => %08x (%02x)\n", env->nip, excp, env->error_code);
2013

    
2014
    /* new srr1 value excluding must-be-zero bits */
2015
    msr = env->msr & ~0x783f0000ULL;
2016

    
2017
    /* new interrupt handler msr */
2018
    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
2019

    
2020
    /* target registers */
2021
    srr0 = SPR_SRR0;
2022
    srr1 = SPR_SRR1;
2023
    asrr0 = -1;
2024
    asrr1 = -1;
2025

    
2026
    switch (excp) {
2027
    case POWERPC_EXCP_NONE:
2028
        /* Should never happen */
2029
        return;
2030
    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
2031
        switch (excp_model) {
2032
        case POWERPC_EXCP_40x:
2033
            srr0 = SPR_40x_SRR2;
2034
            srr1 = SPR_40x_SRR3;
2035
            break;
2036
        case POWERPC_EXCP_BOOKE:
2037
            srr0 = SPR_BOOKE_CSRR0;
2038
            srr1 = SPR_BOOKE_CSRR1;
2039
            break;
2040
        case POWERPC_EXCP_G2:
2041
            break;
2042
        default:
2043
            goto excp_invalid;
2044
        }
2045
        goto store_next;
2046
    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
2047
        if (msr_me == 0) {
2048
            /* Machine check exception is not enabled.
2049
             * Enter checkstop state.
2050
             */
2051
            if (qemu_log_enabled()) {
2052
                qemu_log("Machine check while not allowed. "
2053
                        "Entering checkstop state\n");
2054
            } else {
2055
                fprintf(stderr, "Machine check while not allowed. "
2056
                        "Entering checkstop state\n");
2057
            }
2058
            env->halted = 1;
2059
            env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2060
        }
2061
        if (0) {
2062
            /* XXX: find a suitable condition to enable the hypervisor mode */
2063
            new_msr |= (target_ulong)MSR_HVB;
2064
        }
2065

    
2066
        /* machine check exceptions don't have ME set */
2067
        new_msr &= ~((target_ulong)1 << MSR_ME);
2068

    
2069
        /* XXX: should also have something loaded in DAR / DSISR */
2070
        switch (excp_model) {
2071
        case POWERPC_EXCP_40x:
2072
            srr0 = SPR_40x_SRR2;
2073
            srr1 = SPR_40x_SRR3;
2074
            break;
2075
        case POWERPC_EXCP_BOOKE:
2076
            srr0 = SPR_BOOKE_MCSRR0;
2077
            srr1 = SPR_BOOKE_MCSRR1;
2078
            asrr0 = SPR_BOOKE_CSRR0;
2079
            asrr1 = SPR_BOOKE_CSRR1;
2080
            break;
2081
        default:
2082
            break;
2083
        }
2084
        goto store_next;
2085
    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
2086
        LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
2087
                 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
2088
        if (lpes1 == 0)
2089
            new_msr |= (target_ulong)MSR_HVB;
2090
        goto store_next;
2091
    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
2092
        LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
2093
                 "\n", msr, env->nip);
2094
        if (lpes1 == 0)
2095
            new_msr |= (target_ulong)MSR_HVB;
2096
        msr |= env->error_code;
2097
        goto store_next;
2098
    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
2099
        if (lpes0 == 1)
2100
            new_msr |= (target_ulong)MSR_HVB;
2101
        goto store_next;
2102
    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
2103
        if (lpes1 == 0)
2104
            new_msr |= (target_ulong)MSR_HVB;
2105
        /* XXX: this is false */
2106
        /* Get rS/rD and rA from faulting opcode */
2107
        env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
2108
        goto store_current;
2109
    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
2110
        switch (env->error_code & ~0xF) {
2111
        case POWERPC_EXCP_FP:
2112
            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
2113
                LOG_EXCP("Ignore floating point exception\n");
2114
                env->exception_index = POWERPC_EXCP_NONE;
2115
                env->error_code = 0;
2116
                return;
2117
            }
2118
            if (lpes1 == 0)
2119
                new_msr |= (target_ulong)MSR_HVB;
2120
            msr |= 0x00100000;
2121
            if (msr_fe0 == msr_fe1)
2122
                goto store_next;
2123
            msr |= 0x00010000;
2124
            break;
2125
        case POWERPC_EXCP_INVAL:
2126
            LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
2127
            if (lpes1 == 0)
2128
                new_msr |= (target_ulong)MSR_HVB;
2129
            msr |= 0x00080000;
2130
            break;
2131
        case POWERPC_EXCP_PRIV:
2132
            if (lpes1 == 0)
2133
                new_msr |= (target_ulong)MSR_HVB;
2134
            msr |= 0x00040000;
2135
            break;
2136
        case POWERPC_EXCP_TRAP:
2137
            if (lpes1 == 0)
2138
                new_msr |= (target_ulong)MSR_HVB;
2139
            msr |= 0x00020000;
2140
            break;
2141
        default:
2142
            /* Should never occur */
2143
            cpu_abort(env, "Invalid program exception %d. Aborting\n",
2144
                      env->error_code);
2145
            break;
2146
        }
2147
        goto store_current;
2148
    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
2149
        if (lpes1 == 0)
2150
            new_msr |= (target_ulong)MSR_HVB;
2151
        goto store_current;
2152
    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
2153
        dump_syscall(env);
2154
        lev = env->error_code;
2155
        if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2156
            new_msr |= (target_ulong)MSR_HVB;
2157
        goto store_next;
2158
    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
2159
        goto store_current;
2160
    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
2161
        if (lpes1 == 0)
2162
            new_msr |= (target_ulong)MSR_HVB;
2163
        goto store_next;
2164
    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
2165
        /* FIT on 4xx */
2166
        LOG_EXCP("FIT exception\n");
2167
        goto store_next;
2168
    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
2169
        LOG_EXCP("WDT exception\n");
2170
        switch (excp_model) {
2171
        case POWERPC_EXCP_BOOKE:
2172
            srr0 = SPR_BOOKE_CSRR0;
2173
            srr1 = SPR_BOOKE_CSRR1;
2174
            break;
2175
        default:
2176
            break;
2177
        }
2178
        goto store_next;
2179
    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
2180
        goto store_next;
2181
    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
2182
        goto store_next;
2183
    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
2184
        switch (excp_model) {
2185
        case POWERPC_EXCP_BOOKE:
2186
            srr0 = SPR_BOOKE_DSRR0;
2187
            srr1 = SPR_BOOKE_DSRR1;
2188
            asrr0 = SPR_BOOKE_CSRR0;
2189
            asrr1 = SPR_BOOKE_CSRR1;
2190
            break;
2191
        default:
2192
            break;
2193
        }
2194
        /* XXX: TODO */
2195
        cpu_abort(env, "Debug exception is not implemented yet !\n");
2196
        goto store_next;
2197
    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
2198
        goto store_current;
2199
    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
2200
        /* XXX: TODO */
2201
        cpu_abort(env, "Embedded floating point data exception "
2202
                  "is not implemented yet !\n");
2203
        goto store_next;
2204
    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
2205
        /* XXX: TODO */
2206
        cpu_abort(env, "Embedded floating point round exception "
2207
                  "is not implemented yet !\n");
2208
        goto store_next;
2209
    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
2210
        /* XXX: TODO */
2211
        cpu_abort(env,
2212
                  "Performance counter exception is not implemented yet !\n");
2213
        goto store_next;
2214
    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
2215
        /* XXX: TODO */
2216
        cpu_abort(env,
2217
                  "Embedded doorbell interrupt is not implemented yet !\n");
2218
        goto store_next;
2219
    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
2220
        switch (excp_model) {
2221
        case POWERPC_EXCP_BOOKE:
2222
            srr0 = SPR_BOOKE_CSRR0;
2223
            srr1 = SPR_BOOKE_CSRR1;
2224
            break;
2225
        default:
2226
            break;
2227
        }
2228
        /* XXX: TODO */
2229
        cpu_abort(env, "Embedded doorbell critical interrupt "
2230
                  "is not implemented yet !\n");
2231
        goto store_next;
2232
    case POWERPC_EXCP_RESET:     /* System reset exception                   */
2233
        if (msr_pow) {
2234
            /* indicate that we resumed from power save mode */
2235
            msr |= 0x10000;
2236
        } else {
2237
            new_msr &= ~((target_ulong)1 << MSR_ME);
2238
        }
2239

    
2240
        if (0) {
2241
            /* XXX: find a suitable condition to enable the hypervisor mode */
2242
            new_msr |= (target_ulong)MSR_HVB;
2243
        }
2244
        goto store_next;
2245
    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
2246
        if (lpes1 == 0)
2247
            new_msr |= (target_ulong)MSR_HVB;
2248
        goto store_next;
2249
    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
2250
        if (lpes1 == 0)
2251
            new_msr |= (target_ulong)MSR_HVB;
2252
        goto store_next;
2253
    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
2254
        srr0 = SPR_HSRR0;
2255
        srr1 = SPR_HSRR1;
2256
        new_msr |= (target_ulong)MSR_HVB;
2257
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2258
        goto store_next;
2259
    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
2260
        if (lpes1 == 0)
2261
            new_msr |= (target_ulong)MSR_HVB;
2262
        goto store_next;
2263
    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
2264
        srr0 = SPR_HSRR0;
2265
        srr1 = SPR_HSRR1;
2266
        new_msr |= (target_ulong)MSR_HVB;
2267
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2268
        goto store_next;
2269
    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
2270
        srr0 = SPR_HSRR0;
2271
        srr1 = SPR_HSRR1;
2272
        new_msr |= (target_ulong)MSR_HVB;
2273
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2274
        goto store_next;
2275
    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
2276
        srr0 = SPR_HSRR0;
2277
        srr1 = SPR_HSRR1;
2278
        new_msr |= (target_ulong)MSR_HVB;
2279
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2280
        goto store_next;
2281
    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
2282
        srr0 = SPR_HSRR0;
2283
        srr1 = SPR_HSRR1;
2284
        new_msr |= (target_ulong)MSR_HVB;
2285
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2286
        goto store_next;
2287
    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
2288
        if (lpes1 == 0)
2289
            new_msr |= (target_ulong)MSR_HVB;
2290
        goto store_current;
2291
    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
2292
        LOG_EXCP("PIT exception\n");
2293
        goto store_next;
2294
    case POWERPC_EXCP_IO:        /* IO error exception                       */
2295
        /* XXX: TODO */
2296
        cpu_abort(env, "601 IO error exception is not implemented yet !\n");
2297
        goto store_next;
2298
    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
2299
        /* XXX: TODO */
2300
        cpu_abort(env, "601 run mode exception is not implemented yet !\n");
2301
        goto store_next;
2302
    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
2303
        /* XXX: TODO */
2304
        cpu_abort(env, "602 emulation trap exception "
2305
                  "is not implemented yet !\n");
2306
        goto store_next;
2307
    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
2308
        if (lpes1 == 0) /* XXX: check this */
2309
            new_msr |= (target_ulong)MSR_HVB;
2310
        switch (excp_model) {
2311
        case POWERPC_EXCP_602:
2312
        case POWERPC_EXCP_603:
2313
        case POWERPC_EXCP_603E:
2314
        case POWERPC_EXCP_G2:
2315
            goto tlb_miss_tgpr;
2316
        case POWERPC_EXCP_7x5:
2317
            goto tlb_miss;
2318
        case POWERPC_EXCP_74xx:
2319
            goto tlb_miss_74xx;
2320
        default:
2321
            cpu_abort(env, "Invalid instruction TLB miss exception\n");
2322
            break;
2323
        }
2324
        break;
2325
    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
2326
        if (lpes1 == 0) /* XXX: check this */
2327
            new_msr |= (target_ulong)MSR_HVB;
2328
        switch (excp_model) {
2329
        case POWERPC_EXCP_602:
2330
        case POWERPC_EXCP_603:
2331
        case POWERPC_EXCP_603E:
2332
        case POWERPC_EXCP_G2:
2333
            goto tlb_miss_tgpr;
2334
        case POWERPC_EXCP_7x5:
2335
            goto tlb_miss;
2336
        case POWERPC_EXCP_74xx:
2337
            goto tlb_miss_74xx;
2338
        default:
2339
            cpu_abort(env, "Invalid data load TLB miss exception\n");
2340
            break;
2341
        }
2342
        break;
2343
    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
2344
        if (lpes1 == 0) /* XXX: check this */
2345
            new_msr |= (target_ulong)MSR_HVB;
2346
        switch (excp_model) {
2347
        case POWERPC_EXCP_602:
2348
        case POWERPC_EXCP_603:
2349
        case POWERPC_EXCP_603E:
2350
        case POWERPC_EXCP_G2:
2351
        tlb_miss_tgpr:
2352
            /* Swap temporary saved registers with GPRs */
2353
            if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
2354
                new_msr |= (target_ulong)1 << MSR_TGPR;
2355
                hreg_swap_gpr_tgpr(env);
2356
            }
2357
            goto tlb_miss;
2358
        case POWERPC_EXCP_7x5:
2359
        tlb_miss:
2360
#if defined (DEBUG_SOFTWARE_TLB)
2361
            if (qemu_log_enabled()) {
2362
                const char *es;
2363
                target_ulong *miss, *cmp;
2364
                int en;
2365
                if (excp == POWERPC_EXCP_IFTLB) {
2366
                    es = "I";
2367
                    en = 'I';
2368
                    miss = &env->spr[SPR_IMISS];
2369
                    cmp = &env->spr[SPR_ICMP];
2370
                } else {
2371
                    if (excp == POWERPC_EXCP_DLTLB)
2372
                        es = "DL";
2373
                    else
2374
                        es = "DS";
2375
                    en = 'D';
2376
                    miss = &env->spr[SPR_DMISS];
2377
                    cmp = &env->spr[SPR_DCMP];
2378
                }
2379
                qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2380
                         TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
2381
                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2382
                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],
2383
                         env->error_code);
2384
            }
2385
#endif
2386
            msr |= env->crf[0] << 28;
2387
            msr |= env->error_code; /* key, D/I, S/L bits */
2388
            /* Set way using a LRU mechanism */
2389
            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2390
            break;
2391
        case POWERPC_EXCP_74xx:
2392
        tlb_miss_74xx:
2393
#if defined (DEBUG_SOFTWARE_TLB)
2394
            if (qemu_log_enabled()) {
2395
                const char *es;
2396
                target_ulong *miss, *cmp;
2397
                int en;
2398
                if (excp == POWERPC_EXCP_IFTLB) {
2399
                    es = "I";
2400
                    en = 'I';
2401
                    miss = &env->spr[SPR_TLBMISS];
2402
                    cmp = &env->spr[SPR_PTEHI];
2403
                } else {
2404
                    if (excp == POWERPC_EXCP_DLTLB)
2405
                        es = "DL";
2406
                    else
2407
                        es = "DS";
2408
                    en = 'D';
2409
                    miss = &env->spr[SPR_TLBMISS];
2410
                    cmp = &env->spr[SPR_PTEHI];
2411
                }
2412
                qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2413
                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2414
                         env->error_code);
2415
            }
2416
#endif
2417
            msr |= env->error_code; /* key bit */
2418
            break;
2419
        default:
2420
            cpu_abort(env, "Invalid data store TLB miss exception\n");
2421
            break;
2422
        }
2423
        goto store_next;
2424
    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
2425
        /* XXX: TODO */
2426
        cpu_abort(env, "Floating point assist exception "
2427
                  "is not implemented yet !\n");
2428
        goto store_next;
2429
    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
2430
        /* XXX: TODO */
2431
        cpu_abort(env, "DABR exception is not implemented yet !\n");
2432
        goto store_next;
2433
    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
2434
        /* XXX: TODO */
2435
        cpu_abort(env, "IABR exception is not implemented yet !\n");
2436
        goto store_next;
2437
    case POWERPC_EXCP_SMI:       /* System management interrupt              */
2438
        /* XXX: TODO */
2439
        cpu_abort(env, "SMI exception is not implemented yet !\n");
2440
        goto store_next;
2441
    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
2442
        /* XXX: TODO */
2443
        cpu_abort(env, "Thermal management exception "
2444
                  "is not implemented yet !\n");
2445
        goto store_next;
2446
    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
2447
        if (lpes1 == 0)
2448
            new_msr |= (target_ulong)MSR_HVB;
2449
        /* XXX: TODO */
2450
        cpu_abort(env,
2451
                  "Performance counter exception is not implemented yet !\n");
2452
        goto store_next;
2453
    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
2454
        /* XXX: TODO */
2455
        cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2456
        goto store_next;
2457
    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
2458
        /* XXX: TODO */
2459
        cpu_abort(env,
2460
                  "970 soft-patch exception is not implemented yet !\n");
2461
        goto store_next;
2462
    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
2463
        /* XXX: TODO */
2464
        cpu_abort(env,
2465
                  "970 maintenance exception is not implemented yet !\n");
2466
        goto store_next;
2467
    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
2468
        /* XXX: TODO */
2469
        cpu_abort(env, "Maskable external exception "
2470
                  "is not implemented yet !\n");
2471
        goto store_next;
2472
    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
2473
        /* XXX: TODO */
2474
        cpu_abort(env, "Non maskable external exception "
2475
                  "is not implemented yet !\n");
2476
        goto store_next;
2477
    default:
2478
    excp_invalid:
2479
        cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
2480
        break;
2481
    store_current:
2482
        /* save current instruction location */
2483
        env->spr[srr0] = env->nip - 4;
2484
        break;
2485
    store_next:
2486
        /* save next instruction location */
2487
        env->spr[srr0] = env->nip;
2488
        break;
2489
    }
2490
    /* Save MSR */
2491
    env->spr[srr1] = msr;
2492
    /* If any alternate SRR register are defined, duplicate saved values */
2493
    if (asrr0 != -1)
2494
        env->spr[asrr0] = env->spr[srr0];
2495
    if (asrr1 != -1)
2496
        env->spr[asrr1] = env->spr[srr1];
2497
    /* If we disactivated any translation, flush TLBs */
2498
    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
2499
        tlb_flush(env, 1);
2500

    
2501
    if (msr_ile) {
2502
        new_msr |= (target_ulong)1 << MSR_LE;
2503
    }
2504

    
2505
    /* Jump to handler */
2506
    vector = env->excp_vectors[excp];
2507
    if (vector == (target_ulong)-1ULL) {
2508
        cpu_abort(env, "Raised an exception without defined vector %d\n",
2509
                  excp);
2510
    }
2511
    vector |= env->excp_prefix;
2512
#if defined(TARGET_PPC64)
2513
    if (excp_model == POWERPC_EXCP_BOOKE) {
2514
        if (!msr_icm) {
2515
            vector = (uint32_t)vector;
2516
        } else {
2517
            new_msr |= (target_ulong)1 << MSR_CM;
2518
        }
2519
    } else {
2520
        if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
2521
            vector = (uint32_t)vector;
2522
        } else {
2523
            new_msr |= (target_ulong)1 << MSR_SF;
2524
        }
2525
    }
2526
#endif
2527
    /* XXX: we don't use hreg_store_msr here as already have treated
2528
     *      any special case that could occur. Just store MSR and update hflags
2529
     */
2530
    env->msr = new_msr & env->msr_mask;
2531
    hreg_compute_hflags(env);
2532
    env->nip = vector;
2533
    /* Reset exception state */
2534
    env->exception_index = POWERPC_EXCP_NONE;
2535
    env->error_code = 0;
2536

    
2537
    if (env->mmu_model == POWERPC_MMU_BOOKE) {
2538
        /* XXX: The BookE changes address space when switching modes,
2539
                we should probably implement that as different MMU indexes,
2540
                but for the moment we do it the slow way and flush all.  */
2541
        tlb_flush(env, 1);
2542
    }
2543
}
2544

    
2545
void do_interrupt (CPUState *env)
2546
{
2547
    powerpc_excp(env, env->excp_model, env->exception_index);
2548
}
2549

    
2550
void ppc_hw_interrupt (CPUPPCState *env)
2551
{
2552
    int hdice;
2553

    
2554
#if 0
2555
    qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
2556
                __func__, env, env->pending_interrupts,
2557
                env->interrupt_request, (int)msr_me, (int)msr_ee);
2558
#endif
2559
    /* External reset */
2560
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2561
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2562
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
2563
        return;
2564
    }
2565
    /* Machine check exception */
2566
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2567
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2568
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
2569
        return;
2570
    }
2571
#if 0 /* TODO */
2572
    /* External debug exception */
2573
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2574
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2575
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
2576
        return;
2577
    }
2578
#endif
2579
    if (0) {
2580
        /* XXX: find a suitable condition to enable the hypervisor mode */
2581
        hdice = env->spr[SPR_LPCR] & 1;
2582
    } else {
2583
        hdice = 0;
2584
    }
2585
    if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
2586
        /* Hypervisor decrementer exception */
2587
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2588
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2589
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
2590
            return;
2591
        }
2592
    }
2593
    if (msr_ce != 0) {
2594
        /* External critical interrupt */
2595
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2596
            /* Taking a critical external interrupt does not clear the external
2597
             * critical interrupt status
2598
             */
2599
#if 0
2600
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
2601
#endif
2602
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
2603
            return;
2604
        }
2605
    }
2606
    if (msr_ee != 0) {
2607
        /* Watchdog timer on embedded PowerPC */
2608
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2609
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2610
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
2611
            return;
2612
        }
2613
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2614
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2615
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
2616
            return;
2617
        }
2618
        /* Fixed interval timer on embedded PowerPC */
2619
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2620
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2621
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
2622
            return;
2623
        }
2624
        /* Programmable interval timer on embedded PowerPC */
2625
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2626
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2627
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
2628
            return;
2629
        }
2630
        /* Decrementer exception */
2631
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2632
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2633
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
2634
            return;
2635
        }
2636
        /* External interrupt */
2637
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2638
            /* Taking an external interrupt does not clear the external
2639
             * interrupt status
2640
             */
2641
#if 0
2642
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2643
#endif
2644
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
2645
            return;
2646
        }
2647
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2648
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2649
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
2650
            return;
2651
        }
2652
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2653
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2654
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
2655
            return;
2656
        }
2657
        /* Thermal interrupt */
2658
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2659
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2660
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
2661
            return;
2662
        }
2663
    }
2664
}
2665
#endif /* !CONFIG_USER_ONLY */
2666

    
2667
void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2668
{
2669
    qemu_log("Return from exception at " TARGET_FMT_lx " with flags "
2670
             TARGET_FMT_lx "\n", RA, msr);
2671
}
2672

    
2673
void cpu_reset(CPUPPCState *env)
2674
{
2675
    target_ulong msr;
2676

    
2677
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
2678
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
2679
        log_cpu_state(env, 0);
2680
    }
2681

    
2682
    msr = (target_ulong)0;
2683
    if (0) {
2684
        /* XXX: find a suitable condition to enable the hypervisor mode */
2685
        msr |= (target_ulong)MSR_HVB;
2686
    }
2687
    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
2688
    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
2689
    msr |= (target_ulong)1 << MSR_EP;
2690
#if defined (DO_SINGLE_STEP) && 0
2691
    /* Single step trace mode */
2692
    msr |= (target_ulong)1 << MSR_SE;
2693
    msr |= (target_ulong)1 << MSR_BE;
2694
#endif
2695
#if defined(CONFIG_USER_ONLY)
2696
    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
2697
    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
2698
    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
2699
    msr |= (target_ulong)1 << MSR_PR;
2700
#else
2701
    env->excp_prefix = env->hreset_excp_prefix;
2702
    env->nip = env->hreset_vector | env->excp_prefix;
2703
    if (env->mmu_model != POWERPC_MMU_REAL)
2704
        ppc_tlb_invalidate_all(env);
2705
#endif
2706
    env->msr = msr & env->msr_mask;
2707
#if defined(TARGET_PPC64)
2708
    if (env->mmu_model & POWERPC_MMU_64)
2709
        env->msr |= (1ULL << MSR_SF);
2710
#endif
2711
    hreg_compute_hflags(env);
2712
    env->reserve_addr = (target_ulong)-1ULL;
2713
    /* Be sure no exception or interrupt is pending */
2714
    env->pending_interrupts = 0;
2715
    env->exception_index = POWERPC_EXCP_NONE;
2716
    env->error_code = 0;
2717
    /* Flush all TLBs */
2718
    tlb_flush(env, 1);
2719
}
2720

    
2721
CPUPPCState *cpu_ppc_init (const char *cpu_model)
2722
{
2723
    CPUPPCState *env;
2724
    const ppc_def_t *def;
2725

    
2726
    def = cpu_ppc_find_by_name(cpu_model);
2727
    if (!def)
2728
        return NULL;
2729

    
2730
    env = qemu_mallocz(sizeof(CPUPPCState));
2731
    cpu_exec_init(env);
2732
    ppc_translate_init();
2733
    env->cpu_model_str = cpu_model;
2734
    cpu_ppc_register_internal(env, def);
2735

    
2736
    qemu_init_vcpu(env);
2737

    
2738
    return env;
2739
}
2740

    
2741
void cpu_ppc_close (CPUPPCState *env)
2742
{
2743
    /* Should also remove all opcode tables... */
2744
    qemu_free(env);
2745
}