Statistics
| Branch: | Revision:

root / target-ppc / helper.c @ 256cebe5

History | View | Annotate | Download (90.1 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
/* PowerPC Hypercall emulation */
75

    
76
void (*cpu_ppc_hypercall)(CPUState *);
77

    
78
/*****************************************************************************/
79
/* PowerPC MMU emulation */
80

    
81
#if defined(CONFIG_USER_ONLY)
82
int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
83
                              int mmu_idx, int is_softmmu)
84
{
85
    int exception, error_code;
86

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

    
101
    return 1;
102
}
103

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

    
111
static inline void pte_invalidate(target_ulong *pte0)
112
{
113
    *pte0 &= ~0x80000000;
114
}
115

    
116
#if defined(TARGET_PPC64)
117
static inline int pte64_is_valid(target_ulong pte0)
118
{
119
    return pte0 & 0x0000000000000001ULL ? 1 : 0;
120
}
121

    
122
static inline void pte64_invalidate(target_ulong *pte0)
123
{
124
    *pte0 &= ~0x0000000000000001ULL;
125
}
126
#endif
127

    
128
#define PTE_PTEM_MASK 0x7FFFFFBF
129
#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
130
#if defined(TARGET_PPC64)
131
#define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
132
#define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
133
#endif
134

    
135
static inline int pp_check(int key, int pp, int nx)
136
{
137
    int access;
138

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

    
172
    return access;
173
}
174

    
175
static inline int check_prot(int prot, int rw, int access_type)
176
{
177
    int ret;
178

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

    
196
    return ret;
197
}
198

    
199
static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
200
                             target_ulong pte1, int h, int rw, int type)
201
{
202
    target_ulong ptem, mmask;
203
    int access, ret, pteh, ptev, pp;
204

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

    
257
    return ret;
258
}
259

    
260
static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
261
                              target_ulong pte1, int h, int rw, int type)
262
{
263
    return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
264
}
265

    
266
#if defined(TARGET_PPC64)
267
static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
268
                              target_ulong pte1, int h, int rw, int type)
269
{
270
    return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
271
}
272
#endif
273

    
274
static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
275
                                   int ret, int rw)
276
{
277
    int store = 0;
278

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

    
296
    return store;
297
}
298

    
299
/* Software driven TLB helpers */
300
static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
301
                                    int is_code)
302
{
303
    int nr;
304

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

    
313
    return nr;
314
}
315

    
316
static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
317
{
318
    ppc6xx_tlb_t *tlb;
319
    int nr, max;
320

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

    
333
static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env,
334
                                                target_ulong eaddr,
335
                                                int is_code, int match_epn)
336
{
337
#if !defined(FLUSH_ALL_TLBS)
338
    ppc6xx_tlb_t *tlb;
339
    int way, nr;
340

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

    
358
static inline void ppc6xx_tlb_invalidate_virt(CPUState *env,
359
                                              target_ulong eaddr, int is_code)
360
{
361
    __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
362
}
363

    
364
void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
365
                       target_ulong pte0, target_ulong pte1)
366
{
367
    ppc6xx_tlb_t *tlb;
368
    int nr;
369

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

    
383
static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
384
                                   target_ulong eaddr, int rw, int access_type)
385
{
386
    ppc6xx_tlb_t *tlb;
387
    int nr, best, way;
388
    int ret;
389

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

    
441
    return ret;
442
}
443

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

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

    
470
static inline void bat_601_size_prot(CPUState *env, target_ulong *blp,
471
                                     int *validp, int *protp,
472
                                     target_ulong *BATu, target_ulong *BATl)
473
{
474
    target_ulong bl;
475
    int key, pp, valid, prot;
476

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

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

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

    
570
static inline target_phys_addr_t get_pteg_offset(CPUState *env,
571
                                                 target_phys_addr_t hash,
572
                                                 int pte_size)
573
{
574
    return (hash * pte_size * 8) & env->htab_mask;
575
}
576

    
577
/* PTE table lookup */
578
static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
579
                            int rw, int type, int target_page_bits)
580
{
581
    target_phys_addr_t pteg_off;
582
    target_ulong pte0, pte1;
583
    int i, good = -1;
584
    int ret, r;
585

    
586
    ret = -1; /* No entry found */
587
    pteg_off = get_pteg_offset(env, ctx->hash[h],
588
                               is_64b ? HASH_PTE_SIZE_64 : HASH_PTE_SIZE_32);
589
    for (i = 0; i < 8; i++) {
590
#if defined(TARGET_PPC64)
591
        if (is_64b) {
592
            pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
593
            pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
594

    
595
            /* We have a TLB that saves 4K pages, so let's
596
             * split a huge page to 4k chunks */
597
            if (target_page_bits != TARGET_PAGE_BITS)
598
                pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
599
                        & TARGET_PAGE_MASK;
600

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

    
661
    return ret;
662
}
663

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

    
672
    return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
673
}
674

    
675
#if defined(TARGET_PPC64)
676
static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
677
{
678
    uint64_t esid;
679
    int n;
680

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

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

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

    
688
        LOG_SLB("%s: slot %d %016" PRIx64 " %016"
689
                    PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
690
        if (slb->esid == esid) {
691
            return slb;
692
        }
693
    }
694

    
695
    return NULL;
696
}
697

    
698
void ppc_slb_invalidate_all (CPUPPCState *env)
699
{
700
    int n, do_invalidate;
701

    
702
    do_invalidate = 0;
703
    /* XXX: Warning: slbia never invalidates the first segment */
704
    for (n = 1; n < env->slb_nr; n++) {
705
        ppc_slb_t *slb = &env->slb[n];
706

    
707
        if (slb->esid & SLB_ESID_V) {
708
            slb->esid &= ~SLB_ESID_V;
709
            /* XXX: given the fact that segment size is 256 MB or 1TB,
710
             *      and we still don't have a tlb_flush_mask(env, n, mask)
711
             *      in Qemu, we just invalidate all TLBs
712
             */
713
            do_invalidate = 1;
714
        }
715
    }
716
    if (do_invalidate)
717
        tlb_flush(env, 1);
718
}
719

    
720
void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
721
{
722
    ppc_slb_t *slb;
723

    
724
    slb = slb_lookup(env, T0);
725
    if (!slb) {
726
        return;
727
    }
728

    
729
    if (slb->esid & SLB_ESID_V) {
730
        slb->esid &= ~SLB_ESID_V;
731

    
732
        /* XXX: given the fact that segment size is 256 MB or 1TB,
733
         *      and we still don't have a tlb_flush_mask(env, n, mask)
734
         *      in Qemu, we just invalidate all TLBs
735
         */
736
        tlb_flush(env, 1);
737
    }
738
}
739

    
740
int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
741
{
742
    int slot = rb & 0xfff;
743
    uint64_t esid = rb & ~0xfff;
744
    ppc_slb_t *slb = &env->slb[slot];
745

    
746
    if (slot >= env->slb_nr) {
747
        return -1;
748
    }
749

    
750
    slb->esid = esid;
751
    slb->vsid = rs;
752

    
753
    LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
754
            " %016" PRIx64 "\n", __func__, slot, rb, rs,
755
            slb->esid, slb->vsid);
756

    
757
    return 0;
758
}
759

    
760
int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
761
{
762
    int slot = rb & 0xfff;
763
    ppc_slb_t *slb = &env->slb[slot];
764

    
765
    if (slot >= env->slb_nr) {
766
        return -1;
767
    }
768

    
769
    *rt = slb->esid;
770
    return 0;
771
}
772

    
773
int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
774
{
775
    int slot = rb & 0xfff;
776
    ppc_slb_t *slb = &env->slb[slot];
777

    
778
    if (slot >= env->slb_nr) {
779
        return -1;
780
    }
781

    
782
    *rt = slb->vsid;
783
    return 0;
784
}
785
#endif /* defined(TARGET_PPC64) */
786

    
787
/* Perform segment based translation */
788
static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
789
                              target_ulong eaddr, int rw, int type)
790
{
791
    target_phys_addr_t hash;
792
    target_ulong vsid;
793
    int ds, pr, target_page_bits;
794
    int ret, ret2;
795

    
796
    pr = msr_pr;
797
    ctx->eaddr = eaddr;
798
#if defined(TARGET_PPC64)
799
    if (env->mmu_model & POWERPC_MMU_64) {
800
        ppc_slb_t *slb;
801
        target_ulong pageaddr;
802

    
803
        LOG_MMU("Check SLBs\n");
804
        slb = slb_lookup(env, eaddr);
805
        if (!slb) {
806
            return -5;
807
        }
808

    
809
        vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
810
        target_page_bits = (slb->vsid & SLB_VSID_L)
811
            ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
812
        ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
813
                      : (slb->vsid & SLB_VSID_KS));
814
        ds = 0;
815
        ctx->nx = !!(slb->vsid & SLB_VSID_N);
816

    
817
        pageaddr = eaddr & ((1ULL << 28) - (1ULL << target_page_bits));
818
        /* XXX: this is false for 1 TB segments */
819
        hash = vsid ^ (pageaddr >> target_page_bits);
820
        /* Only 5 bits of the page index are used in the AVPN */
821
        ctx->ptem = (slb->vsid & SLB_VSID_PTEM) | ((pageaddr >> 16) & 0x0F80);
822
    } else
823
#endif /* defined(TARGET_PPC64) */
824
    {
825
        target_ulong sr, pgidx;
826

    
827
        sr = env->sr[eaddr >> 28];
828
        ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
829
                    ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
830
        ds = sr & 0x80000000 ? 1 : 0;
831
        ctx->nx = sr & 0x10000000 ? 1 : 0;
832
        vsid = sr & 0x00FFFFFF;
833
        target_page_bits = TARGET_PAGE_BITS;
834
        LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
835
                TARGET_FMT_lx " lr=" TARGET_FMT_lx
836
                " ir=%d dr=%d pr=%d %d t=%d\n",
837
                eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
838
                (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
839
        pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
840
        hash = vsid ^ pgidx;
841
        ctx->ptem = (vsid << 7) | (pgidx >> 10);
842
    }
843
    LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
844
            ctx->key, ds, ctx->nx, vsid);
845
    ret = -1;
846
    if (!ds) {
847
        /* Check if instruction fetch is allowed, if needed */
848
        if (type != ACCESS_CODE || ctx->nx == 0) {
849
            /* Page address translation */
850
            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
851
                    " hash " TARGET_FMT_plx "\n",
852
                    env->htab_base, env->htab_mask, hash);
853
            ctx->hash[0] = hash;
854
            ctx->hash[1] = ~hash;
855

    
856
            /* Initialize real address with an invalid value */
857
            ctx->raddr = (target_phys_addr_t)-1ULL;
858
            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
859
                         env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
860
                /* Software TLB search */
861
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
862
            } else {
863
                LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
864
                        " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
865
                        " hash=" TARGET_FMT_plx "\n",
866
                        env->htab_base, env->htab_mask, vsid, ctx->ptem,
867
                        ctx->hash[0]);
868
                /* Primary table lookup */
869
                ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
870
                if (ret < 0) {
871
                    /* Secondary table lookup */
872
                    if (eaddr != 0xEFFFFFFF)
873
                        LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
874
                                " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
875
                                " hash=" TARGET_FMT_plx " pg_addr="
876
                                TARGET_FMT_plx "\n", env->htab_base,
877
                                env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
878
                    ret2 = find_pte(env, ctx, 1, rw, type,
879
                                    target_page_bits);
880
                    if (ret2 != -1)
881
                        ret = ret2;
882
                }
883
            }
884
#if defined (DUMP_PAGE_TABLES)
885
            if (qemu_log_enabled()) {
886
                target_phys_addr_t curaddr;
887
                uint32_t a0, a1, a2, a3;
888
                qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
889
                         "\n", sdr, mask + 0x80);
890
                for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
891
                     curaddr += 16) {
892
                    a0 = ldl_phys(curaddr);
893
                    a1 = ldl_phys(curaddr + 4);
894
                    a2 = ldl_phys(curaddr + 8);
895
                    a3 = ldl_phys(curaddr + 12);
896
                    if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
897
                        qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
898
                                 curaddr, a0, a1, a2, a3);
899
                    }
900
                }
901
            }
902
#endif
903
        } else {
904
            LOG_MMU("No access allowed\n");
905
            ret = -3;
906
        }
907
    } else {
908
        LOG_MMU("direct store...\n");
909
        /* Direct-store segment : absolutely *BUGGY* for now */
910
        switch (type) {
911
        case ACCESS_INT:
912
            /* Integer load/store : only access allowed */
913
            break;
914
        case ACCESS_CODE:
915
            /* No code fetch is allowed in direct-store areas */
916
            return -4;
917
        case ACCESS_FLOAT:
918
            /* Floating point load/store */
919
            return -4;
920
        case ACCESS_RES:
921
            /* lwarx, ldarx or srwcx. */
922
            return -4;
923
        case ACCESS_CACHE:
924
            /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
925
            /* Should make the instruction do no-op.
926
             * As it already do no-op, it's quite easy :-)
927
             */
928
            ctx->raddr = eaddr;
929
            return 0;
930
        case ACCESS_EXT:
931
            /* eciwx or ecowx */
932
            return -4;
933
        default:
934
            qemu_log("ERROR: instruction should not need "
935
                        "address translation\n");
936
            return -4;
937
        }
938
        if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
939
            ctx->raddr = eaddr;
940
            ret = 2;
941
        } else {
942
            ret = -2;
943
        }
944
    }
945

    
946
    return ret;
947
}
948

    
949
/* Generic TLB check function for embedded PowerPC implementations */
950
static inline int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
951
                                   target_phys_addr_t *raddrp,
952
                                   target_ulong address, uint32_t pid, int ext,
953
                                   int i)
954
{
955
    target_ulong mask;
956

    
957
    /* Check valid flag */
958
    if (!(tlb->prot & PAGE_VALID)) {
959
        return -1;
960
    }
961
    mask = ~(tlb->size - 1);
962
    LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx
963
              " " TARGET_FMT_lx " %u\n", __func__, i, address, pid, tlb->EPN,
964
              mask, (uint32_t)tlb->PID);
965
    /* Check PID */
966
    if (tlb->PID != 0 && tlb->PID != pid)
967
        return -1;
968
    /* Check effective address */
969
    if ((address & mask) != tlb->EPN)
970
        return -1;
971
    *raddrp = (tlb->RPN & mask) | (address & ~mask);
972
#if (TARGET_PHYS_ADDR_BITS >= 36)
973
    if (ext) {
974
        /* Extend the physical address to 36 bits */
975
        *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
976
    }
977
#endif
978

    
979
    return 0;
980
}
981

    
982
/* Generic TLB search function for PowerPC embedded implementations */
983
int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
984
{
985
    ppcemb_tlb_t *tlb;
986
    target_phys_addr_t raddr;
987
    int i, ret;
988

    
989
    /* Default return value is no match */
990
    ret = -1;
991
    for (i = 0; i < env->nb_tlb; i++) {
992
        tlb = &env->tlb[i].tlbe;
993
        if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
994
            ret = i;
995
            break;
996
        }
997
    }
998

    
999
    return ret;
1000
}
1001

    
1002
/* Helpers specific to PowerPC 40x implementations */
1003
static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
1004
{
1005
    ppcemb_tlb_t *tlb;
1006
    int i;
1007

    
1008
    for (i = 0; i < env->nb_tlb; i++) {
1009
        tlb = &env->tlb[i].tlbe;
1010
        tlb->prot &= ~PAGE_VALID;
1011
    }
1012
    tlb_flush(env, 1);
1013
}
1014

    
1015
static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
1016
                                              target_ulong eaddr, uint32_t pid)
1017
{
1018
#if !defined(FLUSH_ALL_TLBS)
1019
    ppcemb_tlb_t *tlb;
1020
    target_phys_addr_t raddr;
1021
    target_ulong page, end;
1022
    int i;
1023

    
1024
    for (i = 0; i < env->nb_tlb; i++) {
1025
        tlb = &env->tlb[i].tlbe;
1026
        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
1027
            end = tlb->EPN + tlb->size;
1028
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
1029
                tlb_flush_page(env, page);
1030
            tlb->prot &= ~PAGE_VALID;
1031
            break;
1032
        }
1033
    }
1034
#else
1035
    ppc4xx_tlb_invalidate_all(env);
1036
#endif
1037
}
1038

    
1039
static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1040
                                 target_ulong address, int rw, int access_type)
1041
{
1042
    ppcemb_tlb_t *tlb;
1043
    target_phys_addr_t raddr;
1044
    int i, ret, zsel, zpr, pr;
1045

    
1046
    ret = -1;
1047
    raddr = (target_phys_addr_t)-1ULL;
1048
    pr = msr_pr;
1049
    for (i = 0; i < env->nb_tlb; i++) {
1050
        tlb = &env->tlb[i].tlbe;
1051
        if (ppcemb_tlb_check(env, tlb, &raddr, address,
1052
                             env->spr[SPR_40x_PID], 0, i) < 0)
1053
            continue;
1054
        zsel = (tlb->attr >> 4) & 0xF;
1055
        zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
1056
        LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1057
                    __func__, i, zsel, zpr, rw, tlb->attr);
1058
        /* Check execute enable bit */
1059
        switch (zpr) {
1060
        case 0x2:
1061
            if (pr != 0)
1062
                goto check_perms;
1063
            /* No break here */
1064
        case 0x3:
1065
            /* All accesses granted */
1066
            ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1067
            ret = 0;
1068
            break;
1069
        case 0x0:
1070
            if (pr != 0) {
1071
                /* Raise Zone protection fault.  */
1072
                env->spr[SPR_40x_ESR] = 1 << 22;
1073
                ctx->prot = 0;
1074
                ret = -2;
1075
                break;
1076
            }
1077
            /* No break here */
1078
        case 0x1:
1079
        check_perms:
1080
            /* Check from TLB entry */
1081
            ctx->prot = tlb->prot;
1082
            ret = check_prot(ctx->prot, rw, access_type);
1083
            if (ret == -2)
1084
                env->spr[SPR_40x_ESR] = 0;
1085
            break;
1086
        }
1087
        if (ret >= 0) {
1088
            ctx->raddr = raddr;
1089
            LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1090
                      " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1091
                      ret);
1092
            return 0;
1093
        }
1094
    }
1095
    LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1096
              " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1097

    
1098
    return ret;
1099
}
1100

    
1101
void store_40x_sler (CPUPPCState *env, uint32_t val)
1102
{
1103
    /* XXX: TO BE FIXED */
1104
    if (val != 0x00000000) {
1105
        cpu_abort(env, "Little-endian regions are not supported by now\n");
1106
    }
1107
    env->spr[SPR_405_SLER] = val;
1108
}
1109

    
1110
static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1111
                                          target_ulong address, int rw,
1112
                                          int access_type)
1113
{
1114
    ppcemb_tlb_t *tlb;
1115
    target_phys_addr_t raddr;
1116
    int i, prot, ret;
1117

    
1118
    ret = -1;
1119
    raddr = (target_phys_addr_t)-1ULL;
1120
    for (i = 0; i < env->nb_tlb; i++) {
1121
        tlb = &env->tlb[i].tlbe;
1122
        if (ppcemb_tlb_check(env, tlb, &raddr, address,
1123
                             env->spr[SPR_BOOKE_PID], 1, i) < 0)
1124
            continue;
1125
        if (msr_pr != 0)
1126
            prot = tlb->prot & 0xF;
1127
        else
1128
            prot = (tlb->prot >> 4) & 0xF;
1129
        /* Check the address space */
1130
        if (access_type == ACCESS_CODE) {
1131
            if (msr_ir != (tlb->attr & 1))
1132
                continue;
1133
            ctx->prot = prot;
1134
            if (prot & PAGE_EXEC) {
1135
                ret = 0;
1136
                break;
1137
            }
1138
            ret = -3;
1139
        } else {
1140
            if (msr_dr != (tlb->attr & 1))
1141
                continue;
1142
            ctx->prot = prot;
1143
            if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) {
1144
                ret = 0;
1145
                break;
1146
            }
1147
            ret = -2;
1148
        }
1149
    }
1150
    if (ret >= 0)
1151
        ctx->raddr = raddr;
1152

    
1153
    return ret;
1154
}
1155

    
1156
static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
1157
                                 target_ulong eaddr, int rw)
1158
{
1159
    int in_plb, ret;
1160

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

    
1219
    return ret;
1220
}
1221

    
1222
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1223
                          int rw, int access_type)
1224
{
1225
    int ret;
1226

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

    
1290
    return ret;
1291
}
1292

    
1293
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1294
{
1295
    mmu_ctx_t ctx;
1296

    
1297
    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1298
        return -1;
1299

    
1300
    return ctx.raddr & TARGET_PAGE_MASK;
1301
}
1302

    
1303
/* Perform address translation */
1304
int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1305
                              int mmu_idx, int is_softmmu)
1306
{
1307
    mmu_ctx_t ctx;
1308
    int access_type;
1309
    int ret = 0;
1310

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

    
1582
    return ret;
1583
}
1584

    
1585
/*****************************************************************************/
1586
/* BATs management */
1587
#if !defined(FLUSH_ALL_TLBS)
1588
static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
1589
                                     target_ulong mask)
1590
{
1591
    target_ulong base, end, page;
1592

    
1593
    base = BATu & ~0x0001FFFF;
1594
    end = base + mask + 0x00020000;
1595
    LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
1596
             TARGET_FMT_lx ")\n", base, end, mask);
1597
    for (page = base; page != end; page += TARGET_PAGE_SIZE)
1598
        tlb_flush_page(env, page);
1599
    LOG_BATS("Flush done\n");
1600
}
1601
#endif
1602

    
1603
static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
1604
                                  target_ulong value)
1605
{
1606
    LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID,
1607
             nr, ul == 0 ? 'u' : 'l', value, env->nip);
1608
}
1609

    
1610
void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1611
{
1612
    target_ulong mask;
1613

    
1614
    dump_store_bat(env, 'I', 0, nr, value);
1615
    if (env->IBAT[0][nr] != value) {
1616
        mask = (value << 15) & 0x0FFE0000UL;
1617
#if !defined(FLUSH_ALL_TLBS)
1618
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1619
#endif
1620
        /* When storing valid upper BAT, mask BEPI and BRPN
1621
         * and invalidate all TLBs covered by this BAT
1622
         */
1623
        mask = (value << 15) & 0x0FFE0000UL;
1624
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1625
            (value & ~0x0001FFFFUL & ~mask);
1626
        env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1627
            (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1628
#if !defined(FLUSH_ALL_TLBS)
1629
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1630
#else
1631
        tlb_flush(env, 1);
1632
#endif
1633
    }
1634
}
1635

    
1636
void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1637
{
1638
    dump_store_bat(env, 'I', 1, nr, value);
1639
    env->IBAT[1][nr] = value;
1640
}
1641

    
1642
void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1643
{
1644
    target_ulong mask;
1645

    
1646
    dump_store_bat(env, 'D', 0, nr, value);
1647
    if (env->DBAT[0][nr] != value) {
1648
        /* When storing valid upper BAT, mask BEPI and BRPN
1649
         * and invalidate all TLBs covered by this BAT
1650
         */
1651
        mask = (value << 15) & 0x0FFE0000UL;
1652
#if !defined(FLUSH_ALL_TLBS)
1653
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1654
#endif
1655
        mask = (value << 15) & 0x0FFE0000UL;
1656
        env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1657
            (value & ~0x0001FFFFUL & ~mask);
1658
        env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1659
            (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1660
#if !defined(FLUSH_ALL_TLBS)
1661
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1662
#else
1663
        tlb_flush(env, 1);
1664
#endif
1665
    }
1666
}
1667

    
1668
void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1669
{
1670
    dump_store_bat(env, 'D', 1, nr, value);
1671
    env->DBAT[1][nr] = value;
1672
}
1673

    
1674
void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
1675
{
1676
    target_ulong mask;
1677
#if defined(FLUSH_ALL_TLBS)
1678
    int do_inval;
1679
#endif
1680

    
1681
    dump_store_bat(env, 'I', 0, nr, value);
1682
    if (env->IBAT[0][nr] != value) {
1683
#if defined(FLUSH_ALL_TLBS)
1684
        do_inval = 0;
1685
#endif
1686
        mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1687
        if (env->IBAT[1][nr] & 0x40) {
1688
            /* Invalidate BAT only if it is valid */
1689
#if !defined(FLUSH_ALL_TLBS)
1690
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1691
#else
1692
            do_inval = 1;
1693
#endif
1694
        }
1695
        /* When storing valid upper BAT, mask BEPI and BRPN
1696
         * and invalidate all TLBs covered by this BAT
1697
         */
1698
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1699
            (value & ~0x0001FFFFUL & ~mask);
1700
        env->DBAT[0][nr] = env->IBAT[0][nr];
1701
        if (env->IBAT[1][nr] & 0x40) {
1702
#if !defined(FLUSH_ALL_TLBS)
1703
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1704
#else
1705
            do_inval = 1;
1706
#endif
1707
        }
1708
#if defined(FLUSH_ALL_TLBS)
1709
        if (do_inval)
1710
            tlb_flush(env, 1);
1711
#endif
1712
    }
1713
}
1714

    
1715
void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
1716
{
1717
    target_ulong mask;
1718
#if defined(FLUSH_ALL_TLBS)
1719
    int do_inval;
1720
#endif
1721

    
1722
    dump_store_bat(env, 'I', 1, nr, value);
1723
    if (env->IBAT[1][nr] != value) {
1724
#if defined(FLUSH_ALL_TLBS)
1725
        do_inval = 0;
1726
#endif
1727
        if (env->IBAT[1][nr] & 0x40) {
1728
#if !defined(FLUSH_ALL_TLBS)
1729
            mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1730
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1731
#else
1732
            do_inval = 1;
1733
#endif
1734
        }
1735
        if (value & 0x40) {
1736
#if !defined(FLUSH_ALL_TLBS)
1737
            mask = (value << 17) & 0x0FFE0000UL;
1738
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1739
#else
1740
            do_inval = 1;
1741
#endif
1742
        }
1743
        env->IBAT[1][nr] = value;
1744
        env->DBAT[1][nr] = value;
1745
#if defined(FLUSH_ALL_TLBS)
1746
        if (do_inval)
1747
            tlb_flush(env, 1);
1748
#endif
1749
    }
1750
}
1751

    
1752
/*****************************************************************************/
1753
/* TLB management */
1754
void ppc_tlb_invalidate_all (CPUPPCState *env)
1755
{
1756
    switch (env->mmu_model) {
1757
    case POWERPC_MMU_SOFT_6xx:
1758
    case POWERPC_MMU_SOFT_74xx:
1759
        ppc6xx_tlb_invalidate_all(env);
1760
        break;
1761
    case POWERPC_MMU_SOFT_4xx:
1762
    case POWERPC_MMU_SOFT_4xx_Z:
1763
        ppc4xx_tlb_invalidate_all(env);
1764
        break;
1765
    case POWERPC_MMU_REAL:
1766
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1767
        break;
1768
    case POWERPC_MMU_MPC8xx:
1769
        /* XXX: TODO */
1770
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1771
        break;
1772
    case POWERPC_MMU_BOOKE:
1773
        tlb_flush(env, 1);
1774
        break;
1775
    case POWERPC_MMU_BOOKE_FSL:
1776
        /* XXX: TODO */
1777
        if (!kvm_enabled())
1778
            cpu_abort(env, "BookE MMU model is not implemented\n");
1779
        break;
1780
    case POWERPC_MMU_32B:
1781
    case POWERPC_MMU_601:
1782
#if defined(TARGET_PPC64)
1783
    case POWERPC_MMU_620:
1784
    case POWERPC_MMU_64B:
1785
#endif /* defined(TARGET_PPC64) */
1786
        tlb_flush(env, 1);
1787
        break;
1788
    default:
1789
        /* XXX: TODO */
1790
        cpu_abort(env, "Unknown MMU model\n");
1791
        break;
1792
    }
1793
}
1794

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

    
1870
/*****************************************************************************/
1871
/* Special registers manipulation */
1872
#if defined(TARGET_PPC64)
1873
void ppc_store_asr (CPUPPCState *env, target_ulong value)
1874
{
1875
    if (env->asr != value) {
1876
        env->asr = value;
1877
        tlb_flush(env, 1);
1878
    }
1879
}
1880
#endif
1881

    
1882
void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
1883
{
1884
    LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
1885
    if (env->spr[SPR_SDR1] != value) {
1886
        env->spr[SPR_SDR1] = value;
1887
#if defined(TARGET_PPC64)
1888
        if (env->mmu_model & POWERPC_MMU_64) {
1889
            target_ulong htabsize = value & SDR_64_HTABSIZE;
1890

    
1891
            if (htabsize > 28) {
1892
                fprintf(stderr, "Invalid HTABSIZE 0x" TARGET_FMT_lx
1893
                        " stored in SDR1\n", htabsize);
1894
                htabsize = 28;
1895
            }
1896
            env->htab_mask = (1ULL << (htabsize + 18)) - 1;
1897
            env->htab_base = value & SDR_64_HTABORG;
1898
        } else
1899
#endif /* defined(TARGET_PPC64) */
1900
        {
1901
            /* FIXME: Should check for valid HTABMASK values */
1902
            env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
1903
            env->htab_base = value & SDR_32_HTABORG;
1904
        }
1905
        tlb_flush(env, 1);
1906
    }
1907
}
1908

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2504
    if (msr_ile) {
2505
        new_msr |= (target_ulong)1 << MSR_LE;
2506
    }
2507

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

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

    
2548
void do_interrupt (CPUState *env)
2549
{
2550
    powerpc_excp(env, env->excp_model, env->exception_index);
2551
}
2552

    
2553
void ppc_hw_interrupt (CPUPPCState *env)
2554
{
2555
    int hdice;
2556

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

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

    
2676
void cpu_reset(CPUPPCState *env)
2677
{
2678
    target_ulong msr;
2679

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

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

    
2724
CPUPPCState *cpu_ppc_init (const char *cpu_model)
2725
{
2726
    CPUPPCState *env;
2727
    const ppc_def_t *def;
2728

    
2729
    def = cpu_ppc_find_by_name(cpu_model);
2730
    if (!def)
2731
        return NULL;
2732

    
2733
    env = qemu_mallocz(sizeof(CPUPPCState));
2734
    cpu_exec_init(env);
2735
    ppc_translate_init();
2736
    env->cpu_model_str = cpu_model;
2737
    cpu_ppc_register_internal(env, def);
2738

    
2739
    qemu_init_vcpu(env);
2740

    
2741
    return env;
2742
}
2743

    
2744
void cpu_ppc_close (CPUPPCState *env)
2745
{
2746
    /* Should also remove all opcode tables... */
2747
    qemu_free(env);
2748
}