Statistics
| Branch: | Revision:

root / target-ppc / helper.c @ 2bd9543c

History | View | Annotate | Download (104.6 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

    
25
#include "cpu.h"
26
#include "helper_regs.h"
27
#include "qemu-common.h"
28
#include "kvm.h"
29

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

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

    
46

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

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

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

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

    
71
/*****************************************************************************/
72
/* PowerPC Hypercall emulation */
73

    
74
void (*cpu_ppc_hypercall)(CPUState *);
75

    
76
/*****************************************************************************/
77
/* PowerPC MMU emulation */
78

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

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

    
99
    return 1;
100
}
101

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

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

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

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

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

    
133
static inline int pp_check(int key, int pp, int nx)
134
{
135
    int access;
136

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

    
170
    return access;
171
}
172

    
173
static inline int check_prot(int prot, int rw, int access_type)
174
{
175
    int ret;
176

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

    
194
    return ret;
195
}
196

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

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

    
255
    return ret;
256
}
257

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

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

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

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

    
294
    return store;
295
}
296

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

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

    
311
    return nr;
312
}
313

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

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

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

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

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

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

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

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

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

    
439
    return ret;
440
}
441

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

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

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

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

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

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

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

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

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

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

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

    
679
    return ret;
680
}
681

    
682
static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
683
                           int type, int target_page_bits)
684
{
685
#if defined(TARGET_PPC64)
686
    if (env->mmu_model & POWERPC_MMU_64)
687
        return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
688
#endif
689

    
690
    return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
691
}
692

    
693
#if defined(TARGET_PPC64)
694
static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
695
{
696
    uint64_t esid_256M, esid_1T;
697
    int n;
698

    
699
    LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
700

    
701
    esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
702
    esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
703

    
704
    for (n = 0; n < env->slb_nr; n++) {
705
        ppc_slb_t *slb = &env->slb[n];
706

    
707
        LOG_SLB("%s: slot %d %016" PRIx64 " %016"
708
                    PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
709
        /* We check for 1T matches on all MMUs here - if the MMU
710
         * doesn't have 1T segment support, we will have prevented 1T
711
         * entries from being inserted in the slbmte code. */
712
        if (((slb->esid == esid_256M) &&
713
             ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
714
            || ((slb->esid == esid_1T) &&
715
                ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) {
716
            return slb;
717
        }
718
    }
719

    
720
    return NULL;
721
}
722

    
723
void ppc_slb_invalidate_all (CPUPPCState *env)
724
{
725
    int n, do_invalidate;
726

    
727
    do_invalidate = 0;
728
    /* XXX: Warning: slbia never invalidates the first segment */
729
    for (n = 1; n < env->slb_nr; n++) {
730
        ppc_slb_t *slb = &env->slb[n];
731

    
732
        if (slb->esid & SLB_ESID_V) {
733
            slb->esid &= ~SLB_ESID_V;
734
            /* XXX: given the fact that segment size is 256 MB or 1TB,
735
             *      and we still don't have a tlb_flush_mask(env, n, mask)
736
             *      in Qemu, we just invalidate all TLBs
737
             */
738
            do_invalidate = 1;
739
        }
740
    }
741
    if (do_invalidate)
742
        tlb_flush(env, 1);
743
}
744

    
745
void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
746
{
747
    ppc_slb_t *slb;
748

    
749
    slb = slb_lookup(env, T0);
750
    if (!slb) {
751
        return;
752
    }
753

    
754
    if (slb->esid & SLB_ESID_V) {
755
        slb->esid &= ~SLB_ESID_V;
756

    
757
        /* XXX: given the fact that segment size is 256 MB or 1TB,
758
         *      and we still don't have a tlb_flush_mask(env, n, mask)
759
         *      in Qemu, we just invalidate all TLBs
760
         */
761
        tlb_flush(env, 1);
762
    }
763
}
764

    
765
int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
766
{
767
    int slot = rb & 0xfff;
768
    ppc_slb_t *slb = &env->slb[slot];
769

    
770
    if (rb & (0x1000 - env->slb_nr)) {
771
        return -1; /* Reserved bits set or slot too high */
772
    }
773
    if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
774
        return -1; /* Bad segment size */
775
    }
776
    if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
777
        return -1; /* 1T segment on MMU that doesn't support it */
778
    }
779

    
780
    /* Mask out the slot number as we store the entry */
781
    slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
782
    slb->vsid = rs;
783

    
784
    LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
785
            " %016" PRIx64 "\n", __func__, slot, rb, rs,
786
            slb->esid, slb->vsid);
787

    
788
    return 0;
789
}
790

    
791
int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
792
{
793
    int slot = rb & 0xfff;
794
    ppc_slb_t *slb = &env->slb[slot];
795

    
796
    if (slot >= env->slb_nr) {
797
        return -1;
798
    }
799

    
800
    *rt = slb->esid;
801
    return 0;
802
}
803

    
804
int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
805
{
806
    int slot = rb & 0xfff;
807
    ppc_slb_t *slb = &env->slb[slot];
808

    
809
    if (slot >= env->slb_nr) {
810
        return -1;
811
    }
812

    
813
    *rt = slb->vsid;
814
    return 0;
815
}
816
#endif /* defined(TARGET_PPC64) */
817

    
818
/* Perform segment based translation */
819
static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
820
                              target_ulong eaddr, int rw, int type)
821
{
822
    target_phys_addr_t hash;
823
    target_ulong vsid;
824
    int ds, pr, target_page_bits;
825
    int ret, ret2;
826

    
827
    pr = msr_pr;
828
    ctx->eaddr = eaddr;
829
#if defined(TARGET_PPC64)
830
    if (env->mmu_model & POWERPC_MMU_64) {
831
        ppc_slb_t *slb;
832
        target_ulong pageaddr;
833
        int segment_bits;
834

    
835
        LOG_MMU("Check SLBs\n");
836
        slb = slb_lookup(env, eaddr);
837
        if (!slb) {
838
            return -5;
839
        }
840

    
841
        if (slb->vsid & SLB_VSID_B) {
842
            vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
843
            segment_bits = 40;
844
        } else {
845
            vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
846
            segment_bits = 28;
847
        }
848

    
849
        target_page_bits = (slb->vsid & SLB_VSID_L)
850
            ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
851
        ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
852
                      : (slb->vsid & SLB_VSID_KS));
853
        ds = 0;
854
        ctx->nx = !!(slb->vsid & SLB_VSID_N);
855

    
856
        pageaddr = eaddr & ((1ULL << segment_bits)
857
                            - (1ULL << target_page_bits));
858
        if (slb->vsid & SLB_VSID_B) {
859
            hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits);
860
        } else {
861
            hash = vsid ^ (pageaddr >> target_page_bits);
862
        }
863
        /* Only 5 bits of the page index are used in the AVPN */
864
        ctx->ptem = (slb->vsid & SLB_VSID_PTEM) |
865
            ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
866
    } else
867
#endif /* defined(TARGET_PPC64) */
868
    {
869
        target_ulong sr, pgidx;
870

    
871
        sr = env->sr[eaddr >> 28];
872
        ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
873
                    ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
874
        ds = sr & 0x80000000 ? 1 : 0;
875
        ctx->nx = sr & 0x10000000 ? 1 : 0;
876
        vsid = sr & 0x00FFFFFF;
877
        target_page_bits = TARGET_PAGE_BITS;
878
        LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
879
                TARGET_FMT_lx " lr=" TARGET_FMT_lx
880
                " ir=%d dr=%d pr=%d %d t=%d\n",
881
                eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
882
                (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
883
        pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
884
        hash = vsid ^ pgidx;
885
        ctx->ptem = (vsid << 7) | (pgidx >> 10);
886
    }
887
    LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
888
            ctx->key, ds, ctx->nx, vsid);
889
    ret = -1;
890
    if (!ds) {
891
        /* Check if instruction fetch is allowed, if needed */
892
        if (type != ACCESS_CODE || ctx->nx == 0) {
893
            /* Page address translation */
894
            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
895
                    " hash " TARGET_FMT_plx "\n",
896
                    env->htab_base, env->htab_mask, hash);
897
            ctx->hash[0] = hash;
898
            ctx->hash[1] = ~hash;
899

    
900
            /* Initialize real address with an invalid value */
901
            ctx->raddr = (target_phys_addr_t)-1ULL;
902
            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
903
                         env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
904
                /* Software TLB search */
905
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
906
            } else {
907
                LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
908
                        " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
909
                        " hash=" TARGET_FMT_plx "\n",
910
                        env->htab_base, env->htab_mask, vsid, ctx->ptem,
911
                        ctx->hash[0]);
912
                /* Primary table lookup */
913
                ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
914
                if (ret < 0) {
915
                    /* Secondary table lookup */
916
                    if (eaddr != 0xEFFFFFFF)
917
                        LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
918
                                " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
919
                                " hash=" TARGET_FMT_plx "\n", env->htab_base,
920
                                env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
921
                    ret2 = find_pte(env, ctx, 1, rw, type,
922
                                    target_page_bits);
923
                    if (ret2 != -1)
924
                        ret = ret2;
925
                }
926
            }
927
#if defined (DUMP_PAGE_TABLES)
928
            if (qemu_log_enabled()) {
929
                target_phys_addr_t curaddr;
930
                uint32_t a0, a1, a2, a3;
931
                qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
932
                         "\n", sdr, mask + 0x80);
933
                for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
934
                     curaddr += 16) {
935
                    a0 = ldl_phys(curaddr);
936
                    a1 = ldl_phys(curaddr + 4);
937
                    a2 = ldl_phys(curaddr + 8);
938
                    a3 = ldl_phys(curaddr + 12);
939
                    if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
940
                        qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
941
                                 curaddr, a0, a1, a2, a3);
942
                    }
943
                }
944
            }
945
#endif
946
        } else {
947
            LOG_MMU("No access allowed\n");
948
            ret = -3;
949
        }
950
    } else {
951
        target_ulong sr;
952
        LOG_MMU("direct store...\n");
953
        /* Direct-store segment : absolutely *BUGGY* for now */
954

    
955
        /* Direct-store implies a 32-bit MMU.
956
         * Check the Segment Register's bus unit ID (BUID).
957
         */
958
        sr = env->sr[eaddr >> 28];
959
        if ((sr & 0x1FF00000) >> 20 == 0x07f) {
960
            /* Memory-forced I/O controller interface access */
961
            /* If T=1 and BUID=x'07F', the 601 performs a memory access
962
             * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
963
             */
964
            ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
965
            ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
966
            return 0;
967
        }
968

    
969
        switch (type) {
970
        case ACCESS_INT:
971
            /* Integer load/store : only access allowed */
972
            break;
973
        case ACCESS_CODE:
974
            /* No code fetch is allowed in direct-store areas */
975
            return -4;
976
        case ACCESS_FLOAT:
977
            /* Floating point load/store */
978
            return -4;
979
        case ACCESS_RES:
980
            /* lwarx, ldarx or srwcx. */
981
            return -4;
982
        case ACCESS_CACHE:
983
            /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
984
            /* Should make the instruction do no-op.
985
             * As it already do no-op, it's quite easy :-)
986
             */
987
            ctx->raddr = eaddr;
988
            return 0;
989
        case ACCESS_EXT:
990
            /* eciwx or ecowx */
991
            return -4;
992
        default:
993
            qemu_log("ERROR: instruction should not need "
994
                        "address translation\n");
995
            return -4;
996
        }
997
        if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
998
            ctx->raddr = eaddr;
999
            ret = 2;
1000
        } else {
1001
            ret = -2;
1002
        }
1003
    }
1004

    
1005
    return ret;
1006
}
1007

    
1008
/* Generic TLB check function for embedded PowerPC implementations */
1009
int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
1010
                     target_phys_addr_t *raddrp,
1011
                     target_ulong address, uint32_t pid, int ext,
1012
                     int i)
1013
{
1014
    target_ulong mask;
1015

    
1016
    /* Check valid flag */
1017
    if (!(tlb->prot & PAGE_VALID)) {
1018
        return -1;
1019
    }
1020
    mask = ~(tlb->size - 1);
1021
    LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx
1022
              " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN,
1023
              mask, (uint32_t)tlb->PID, tlb->prot);
1024
    /* Check PID */
1025
    if (tlb->PID != 0 && tlb->PID != pid)
1026
        return -1;
1027
    /* Check effective address */
1028
    if ((address & mask) != tlb->EPN)
1029
        return -1;
1030
    *raddrp = (tlb->RPN & mask) | (address & ~mask);
1031
#if (TARGET_PHYS_ADDR_BITS >= 36)
1032
    if (ext) {
1033
        /* Extend the physical address to 36 bits */
1034
        *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
1035
    }
1036
#endif
1037

    
1038
    return 0;
1039
}
1040

    
1041
/* Generic TLB search function for PowerPC embedded implementations */
1042
int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
1043
{
1044
    ppcemb_tlb_t *tlb;
1045
    target_phys_addr_t raddr;
1046
    int i, ret;
1047

    
1048
    /* Default return value is no match */
1049
    ret = -1;
1050
    for (i = 0; i < env->nb_tlb; i++) {
1051
        tlb = &env->tlb.tlbe[i];
1052
        if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
1053
            ret = i;
1054
            break;
1055
        }
1056
    }
1057

    
1058
    return ret;
1059
}
1060

    
1061
/* Helpers specific to PowerPC 40x implementations */
1062
static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
1063
{
1064
    ppcemb_tlb_t *tlb;
1065
    int i;
1066

    
1067
    for (i = 0; i < env->nb_tlb; i++) {
1068
        tlb = &env->tlb.tlbe[i];
1069
        tlb->prot &= ~PAGE_VALID;
1070
    }
1071
    tlb_flush(env, 1);
1072
}
1073

    
1074
static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
1075
                                              target_ulong eaddr, uint32_t pid)
1076
{
1077
#if !defined(FLUSH_ALL_TLBS)
1078
    ppcemb_tlb_t *tlb;
1079
    target_phys_addr_t raddr;
1080
    target_ulong page, end;
1081
    int i;
1082

    
1083
    for (i = 0; i < env->nb_tlb; i++) {
1084
        tlb = &env->tlb.tlbe[i];
1085
        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
1086
            end = tlb->EPN + tlb->size;
1087
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
1088
                tlb_flush_page(env, page);
1089
            tlb->prot &= ~PAGE_VALID;
1090
            break;
1091
        }
1092
    }
1093
#else
1094
    ppc4xx_tlb_invalidate_all(env);
1095
#endif
1096
}
1097

    
1098
static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1099
                                 target_ulong address, int rw, int access_type)
1100
{
1101
    ppcemb_tlb_t *tlb;
1102
    target_phys_addr_t raddr;
1103
    int i, ret, zsel, zpr, pr;
1104

    
1105
    ret = -1;
1106
    raddr = (target_phys_addr_t)-1ULL;
1107
    pr = msr_pr;
1108
    for (i = 0; i < env->nb_tlb; i++) {
1109
        tlb = &env->tlb.tlbe[i];
1110
        if (ppcemb_tlb_check(env, tlb, &raddr, address,
1111
                             env->spr[SPR_40x_PID], 0, i) < 0)
1112
            continue;
1113
        zsel = (tlb->attr >> 4) & 0xF;
1114
        zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
1115
        LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1116
                    __func__, i, zsel, zpr, rw, tlb->attr);
1117
        /* Check execute enable bit */
1118
        switch (zpr) {
1119
        case 0x2:
1120
            if (pr != 0)
1121
                goto check_perms;
1122
            /* No break here */
1123
        case 0x3:
1124
            /* All accesses granted */
1125
            ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1126
            ret = 0;
1127
            break;
1128
        case 0x0:
1129
            if (pr != 0) {
1130
                /* Raise Zone protection fault.  */
1131
                env->spr[SPR_40x_ESR] = 1 << 22;
1132
                ctx->prot = 0;
1133
                ret = -2;
1134
                break;
1135
            }
1136
            /* No break here */
1137
        case 0x1:
1138
        check_perms:
1139
            /* Check from TLB entry */
1140
            ctx->prot = tlb->prot;
1141
            ret = check_prot(ctx->prot, rw, access_type);
1142
            if (ret == -2)
1143
                env->spr[SPR_40x_ESR] = 0;
1144
            break;
1145
        }
1146
        if (ret >= 0) {
1147
            ctx->raddr = raddr;
1148
            LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1149
                      " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1150
                      ret);
1151
            return 0;
1152
        }
1153
    }
1154
    LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1155
              " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1156

    
1157
    return ret;
1158
}
1159

    
1160
void store_40x_sler (CPUPPCState *env, uint32_t val)
1161
{
1162
    /* XXX: TO BE FIXED */
1163
    if (val != 0x00000000) {
1164
        cpu_abort(env, "Little-endian regions are not supported by now\n");
1165
    }
1166
    env->spr[SPR_405_SLER] = val;
1167
}
1168

    
1169
static inline int mmubooke_check_tlb (CPUState *env, ppcemb_tlb_t *tlb,
1170
                                      target_phys_addr_t *raddr, int *prot,
1171
                                      target_ulong address, int rw,
1172
                                      int access_type, int i)
1173
{
1174
    int ret, _prot;
1175

    
1176
    if (ppcemb_tlb_check(env, tlb, raddr, address,
1177
                         env->spr[SPR_BOOKE_PID],
1178
                         !env->nb_pids, i) >= 0) {
1179
        goto found_tlb;
1180
    }
1181

    
1182
    if (env->spr[SPR_BOOKE_PID1] &&
1183
        ppcemb_tlb_check(env, tlb, raddr, address,
1184
                         env->spr[SPR_BOOKE_PID1], 0, i) >= 0) {
1185
        goto found_tlb;
1186
    }
1187

    
1188
    if (env->spr[SPR_BOOKE_PID2] &&
1189
        ppcemb_tlb_check(env, tlb, raddr, address,
1190
                         env->spr[SPR_BOOKE_PID2], 0, i) >= 0) {
1191
        goto found_tlb;
1192
    }
1193

    
1194
    LOG_SWTLB("%s: TLB entry not found\n", __func__);
1195
    return -1;
1196

    
1197
found_tlb:
1198

    
1199
    if (msr_pr != 0) {
1200
        _prot = tlb->prot & 0xF;
1201
    } else {
1202
        _prot = (tlb->prot >> 4) & 0xF;
1203
    }
1204

    
1205
    /* Check the address space */
1206
    if (access_type == ACCESS_CODE) {
1207
        if (msr_ir != (tlb->attr & 1)) {
1208
            LOG_SWTLB("%s: AS doesn't match\n", __func__);
1209
            return -1;
1210
        }
1211

    
1212
        *prot = _prot;
1213
        if (_prot & PAGE_EXEC) {
1214
            LOG_SWTLB("%s: good TLB!\n", __func__);
1215
            return 0;
1216
        }
1217

    
1218
        LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot);
1219
        ret = -3;
1220
    } else {
1221
        if (msr_dr != (tlb->attr & 1)) {
1222
            LOG_SWTLB("%s: AS doesn't match\n", __func__);
1223
            return -1;
1224
        }
1225

    
1226
        *prot = _prot;
1227
        if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) {
1228
            LOG_SWTLB("%s: found TLB!\n", __func__);
1229
            return 0;
1230
        }
1231

    
1232
        LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot);
1233
        ret = -2;
1234
    }
1235

    
1236
    return ret;
1237
}
1238

    
1239
static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1240
                                          target_ulong address, int rw,
1241
                                          int access_type)
1242
{
1243
    ppcemb_tlb_t *tlb;
1244
    target_phys_addr_t raddr;
1245
    int i, ret;
1246

    
1247
    ret = -1;
1248
    raddr = (target_phys_addr_t)-1ULL;
1249
    for (i = 0; i < env->nb_tlb; i++) {
1250
        tlb = &env->tlb.tlbe[i];
1251
        ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw,
1252
                                 access_type, i);
1253
        if (!ret) {
1254
            break;
1255
        }
1256
    }
1257

    
1258
    if (ret >= 0) {
1259
        ctx->raddr = raddr;
1260
        LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1261
                  " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1262
                  ret);
1263
    } else {
1264
        LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1265
                  " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1266
    }
1267

    
1268
    return ret;
1269
}
1270

    
1271
void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot)
1272
{
1273
    int tlb_size;
1274
    int i, j;
1275
    ppcmas_tlb_t *tlb = env->tlb.tlbm;
1276

    
1277
    for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1278
        if (flags & (1 << i)) {
1279
            tlb_size = booke206_tlb_size(env, i);
1280
            for (j = 0; j < tlb_size; j++) {
1281
                if (!check_iprot || !(tlb[j].mas1 & MAS1_IPROT)) {
1282
                    tlb[j].mas1 &= ~MAS1_VALID;
1283
                }
1284
            }
1285
        }
1286
        tlb += booke206_tlb_size(env, i);
1287
    }
1288

    
1289
    tlb_flush(env, 1);
1290
}
1291

    
1292
target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb)
1293
{
1294
    uint32_t tlbncfg;
1295
    int tlbn = booke206_tlbm_to_tlbn(env, tlb);
1296
    int tlbm_size;
1297

    
1298
    tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
1299

    
1300
    if (tlbncfg & TLBnCFG_AVAIL) {
1301
        tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
1302
    } else {
1303
        tlbm_size = (tlbncfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
1304
        tlbm_size <<= 1;
1305
    }
1306

    
1307
    return 1024ULL << tlbm_size;
1308
}
1309

    
1310
/* TLB check function for MAS based SoftTLBs */
1311
int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb,
1312
                     target_phys_addr_t *raddrp,
1313
                     target_ulong address, uint32_t pid)
1314
{
1315
    target_ulong mask;
1316
    uint32_t tlb_pid;
1317

    
1318
    /* Check valid flag */
1319
    if (!(tlb->mas1 & MAS1_VALID)) {
1320
        return -1;
1321
    }
1322

    
1323
    mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
1324
    LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%"
1325
              PRIx64 " mask=0x" TARGET_FMT_lx " MAS7_3=0x%" PRIx64 " MAS8=%x\n",
1326
              __func__, address, pid, tlb->mas1, tlb->mas2, mask, tlb->mas7_3,
1327
              tlb->mas8);
1328

    
1329
    /* Check PID */
1330
    tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
1331
    if (tlb_pid != 0 && tlb_pid != pid) {
1332
        return -1;
1333
    }
1334

    
1335
    /* Check effective address */
1336
    if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
1337
        return -1;
1338
    }
1339
    *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
1340

    
1341
    return 0;
1342
}
1343

    
1344
static int mmubooke206_check_tlb(CPUState *env, ppcmas_tlb_t *tlb,
1345
                                 target_phys_addr_t *raddr, int *prot,
1346
                                 target_ulong address, int rw,
1347
                                 int access_type)
1348
{
1349
    int ret;
1350
    int _prot = 0;
1351

    
1352
    if (ppcmas_tlb_check(env, tlb, raddr, address,
1353
                         env->spr[SPR_BOOKE_PID]) >= 0) {
1354
        goto found_tlb;
1355
    }
1356

    
1357
    if (env->spr[SPR_BOOKE_PID1] &&
1358
        ppcmas_tlb_check(env, tlb, raddr, address,
1359
                         env->spr[SPR_BOOKE_PID1]) >= 0) {
1360
        goto found_tlb;
1361
    }
1362

    
1363
    if (env->spr[SPR_BOOKE_PID2] &&
1364
        ppcmas_tlb_check(env, tlb, raddr, address,
1365
                         env->spr[SPR_BOOKE_PID2]) >= 0) {
1366
        goto found_tlb;
1367
    }
1368

    
1369
    LOG_SWTLB("%s: TLB entry not found\n", __func__);
1370
    return -1;
1371

    
1372
found_tlb:
1373

    
1374
    if (msr_pr != 0) {
1375
        if (tlb->mas7_3 & MAS3_UR) {
1376
            _prot |= PAGE_READ;
1377
        }
1378
        if (tlb->mas7_3 & MAS3_UW) {
1379
            _prot |= PAGE_WRITE;
1380
        }
1381
        if (tlb->mas7_3 & MAS3_UX) {
1382
            _prot |= PAGE_EXEC;
1383
        }
1384
    } else {
1385
        if (tlb->mas7_3 & MAS3_SR) {
1386
            _prot |= PAGE_READ;
1387
        }
1388
        if (tlb->mas7_3 & MAS3_SW) {
1389
            _prot |= PAGE_WRITE;
1390
        }
1391
        if (tlb->mas7_3 & MAS3_SX) {
1392
            _prot |= PAGE_EXEC;
1393
        }
1394
    }
1395

    
1396
    /* Check the address space and permissions */
1397
    if (access_type == ACCESS_CODE) {
1398
        if (msr_ir != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
1399
            LOG_SWTLB("%s: AS doesn't match\n", __func__);
1400
            return -1;
1401
        }
1402

    
1403
        *prot = _prot;
1404
        if (_prot & PAGE_EXEC) {
1405
            LOG_SWTLB("%s: good TLB!\n", __func__);
1406
            return 0;
1407
        }
1408

    
1409
        LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot);
1410
        ret = -3;
1411
    } else {
1412
        if (msr_dr != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
1413
            LOG_SWTLB("%s: AS doesn't match\n", __func__);
1414
            return -1;
1415
        }
1416

    
1417
        *prot = _prot;
1418
        if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) {
1419
            LOG_SWTLB("%s: found TLB!\n", __func__);
1420
            return 0;
1421
        }
1422

    
1423
        LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot);
1424
        ret = -2;
1425
    }
1426

    
1427
    return ret;
1428
}
1429

    
1430
static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
1431
                                            target_ulong address, int rw,
1432
                                            int access_type)
1433
{
1434
    ppcmas_tlb_t *tlb;
1435
    target_phys_addr_t raddr;
1436
    int i, j, ret;
1437

    
1438
    ret = -1;
1439
    raddr = (target_phys_addr_t)-1ULL;
1440

    
1441
    for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1442
        int ways = booke206_tlb_ways(env, i);
1443

    
1444
        for (j = 0; j < ways; j++) {
1445
            tlb = booke206_get_tlbm(env, i, address, j);
1446
            ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
1447
                                        rw, access_type);
1448
            if (ret != -1) {
1449
                goto found_tlb;
1450
            }
1451
        }
1452
    }
1453

    
1454
found_tlb:
1455

    
1456
    if (ret >= 0) {
1457
        ctx->raddr = raddr;
1458
        LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1459
                  " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1460
                  ret);
1461
    } else {
1462
        LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1463
                  " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1464
    }
1465

    
1466
    return ret;
1467
}
1468

    
1469
static const char *book3e_tsize_to_str[32] = {
1470
    "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
1471
    "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
1472
    "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
1473
    "1T", "2T"
1474
};
1475

    
1476
static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf,
1477
                                     CPUState *env, int tlbn, int offset,
1478
                                     int tlbsize)
1479
{
1480
    ppcmas_tlb_t *entry;
1481
    int i;
1482

    
1483
    cpu_fprintf(f, "\nTLB%d:\n", tlbn);
1484
    cpu_fprintf(f, "Effective          Physical           Size TID   TS SRWX URWX WIMGE U0123\n");
1485

    
1486
    entry = &env->tlb.tlbm[offset];
1487
    for (i = 0; i < tlbsize; i++, entry++) {
1488
        target_phys_addr_t ea, pa, size;
1489
        int tsize;
1490

    
1491
        if (!(entry->mas1 & MAS1_VALID)) {
1492
            continue;
1493
        }
1494

    
1495
        tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
1496
        size = 1024ULL << tsize;
1497
        ea = entry->mas2 & ~(size - 1);
1498
        pa = entry->mas7_3 & ~(size - 1);
1499

    
1500
        cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u  S%c%c%c U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
1501
                    (uint64_t)ea, (uint64_t)pa,
1502
                    book3e_tsize_to_str[tsize],
1503
                    (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
1504
                    (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
1505
                    entry->mas7_3 & MAS3_SR ? 'R' : '-',
1506
                    entry->mas7_3 & MAS3_SW ? 'W' : '-',
1507
                    entry->mas7_3 & MAS3_SX ? 'X' : '-',
1508
                    entry->mas7_3 & MAS3_UR ? 'R' : '-',
1509
                    entry->mas7_3 & MAS3_UW ? 'W' : '-',
1510
                    entry->mas7_3 & MAS3_UX ? 'X' : '-',
1511
                    entry->mas2 & MAS2_W ? 'W' : '-',
1512
                    entry->mas2 & MAS2_I ? 'I' : '-',
1513
                    entry->mas2 & MAS2_M ? 'M' : '-',
1514
                    entry->mas2 & MAS2_G ? 'G' : '-',
1515
                    entry->mas2 & MAS2_E ? 'E' : '-',
1516
                    entry->mas7_3 & MAS3_U0 ? '0' : '-',
1517
                    entry->mas7_3 & MAS3_U1 ? '1' : '-',
1518
                    entry->mas7_3 & MAS3_U2 ? '2' : '-',
1519
                    entry->mas7_3 & MAS3_U3 ? '3' : '-');
1520
    }
1521
}
1522

    
1523
static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
1524
                                 CPUState *env)
1525
{
1526
    int offset = 0;
1527
    int i;
1528

    
1529
    if (kvm_enabled() && !env->kvm_sw_tlb) {
1530
        cpu_fprintf(f, "Cannot access KVM TLB\n");
1531
        return;
1532
    }
1533

    
1534
    for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1535
        int size = booke206_tlb_size(env, i);
1536

    
1537
        if (size == 0) {
1538
            continue;
1539
        }
1540

    
1541
        mmubooke206_dump_one_tlb(f, cpu_fprintf, env, i, offset, size);
1542
        offset += size;
1543
    }
1544
}
1545

    
1546
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
1547
{
1548
    switch (env->mmu_model) {
1549
    case POWERPC_MMU_BOOKE206:
1550
        mmubooke206_dump_mmu(f, cpu_fprintf, env);
1551
        break;
1552
    default:
1553
        cpu_fprintf(f, "%s: unimplemented\n", __func__);
1554
    }
1555
}
1556

    
1557
static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
1558
                                 target_ulong eaddr, int rw)
1559
{
1560
    int in_plb, ret;
1561

    
1562
    ctx->raddr = eaddr;
1563
    ctx->prot = PAGE_READ | PAGE_EXEC;
1564
    ret = 0;
1565
    switch (env->mmu_model) {
1566
    case POWERPC_MMU_32B:
1567
    case POWERPC_MMU_601:
1568
    case POWERPC_MMU_SOFT_6xx:
1569
    case POWERPC_MMU_SOFT_74xx:
1570
    case POWERPC_MMU_SOFT_4xx:
1571
    case POWERPC_MMU_REAL:
1572
    case POWERPC_MMU_BOOKE:
1573
        ctx->prot |= PAGE_WRITE;
1574
        break;
1575
#if defined(TARGET_PPC64)
1576
    case POWERPC_MMU_620:
1577
    case POWERPC_MMU_64B:
1578
    case POWERPC_MMU_2_06:
1579
        /* Real address are 60 bits long */
1580
        ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1581
        ctx->prot |= PAGE_WRITE;
1582
        break;
1583
#endif
1584
    case POWERPC_MMU_SOFT_4xx_Z:
1585
        if (unlikely(msr_pe != 0)) {
1586
            /* 403 family add some particular protections,
1587
             * using PBL/PBU registers for accesses with no translation.
1588
             */
1589
            in_plb =
1590
                /* Check PLB validity */
1591
                (env->pb[0] < env->pb[1] &&
1592
                 /* and address in plb area */
1593
                 eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
1594
                (env->pb[2] < env->pb[3] &&
1595
                 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
1596
            if (in_plb ^ msr_px) {
1597
                /* Access in protected area */
1598
                if (rw == 1) {
1599
                    /* Access is not allowed */
1600
                    ret = -2;
1601
                }
1602
            } else {
1603
                /* Read-write access is allowed */
1604
                ctx->prot |= PAGE_WRITE;
1605
            }
1606
        }
1607
        break;
1608
    case POWERPC_MMU_MPC8xx:
1609
        /* XXX: TODO */
1610
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1611
        break;
1612
    case POWERPC_MMU_BOOKE206:
1613
        cpu_abort(env, "BookE 2.06 MMU doesn't have physical real mode\n");
1614
        break;
1615
    default:
1616
        cpu_abort(env, "Unknown or invalid MMU model\n");
1617
        return -1;
1618
    }
1619

    
1620
    return ret;
1621
}
1622

    
1623
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1624
                          int rw, int access_type)
1625
{
1626
    int ret;
1627

    
1628
#if 0
1629
    qemu_log("%s\n", __func__);
1630
#endif
1631
    if ((access_type == ACCESS_CODE && msr_ir == 0) ||
1632
        (access_type != ACCESS_CODE && msr_dr == 0)) {
1633
        if (env->mmu_model == POWERPC_MMU_BOOKE) {
1634
            /* The BookE MMU always performs address translation. The
1635
               IS and DS bits only affect the address space.  */
1636
            ret = mmubooke_get_physical_address(env, ctx, eaddr,
1637
                                                rw, access_type);
1638
        } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
1639
            ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
1640
                                                   access_type);
1641
        } else {
1642
            /* No address translation.  */
1643
            ret = check_physical(env, ctx, eaddr, rw);
1644
        }
1645
    } else {
1646
        ret = -1;
1647
        switch (env->mmu_model) {
1648
        case POWERPC_MMU_32B:
1649
        case POWERPC_MMU_601:
1650
        case POWERPC_MMU_SOFT_6xx:
1651
        case POWERPC_MMU_SOFT_74xx:
1652
            /* Try to find a BAT */
1653
            if (env->nb_BATs != 0)
1654
                ret = get_bat(env, ctx, eaddr, rw, access_type);
1655
#if defined(TARGET_PPC64)
1656
        case POWERPC_MMU_620:
1657
        case POWERPC_MMU_64B:
1658
        case POWERPC_MMU_2_06:
1659
#endif
1660
            if (ret < 0) {
1661
                /* We didn't match any BAT entry or don't have BATs */
1662
                ret = get_segment(env, ctx, eaddr, rw, access_type);
1663
            }
1664
            break;
1665
        case POWERPC_MMU_SOFT_4xx:
1666
        case POWERPC_MMU_SOFT_4xx_Z:
1667
            ret = mmu40x_get_physical_address(env, ctx, eaddr,
1668
                                              rw, access_type);
1669
            break;
1670
        case POWERPC_MMU_BOOKE:
1671
            ret = mmubooke_get_physical_address(env, ctx, eaddr,
1672
                                                rw, access_type);
1673
            break;
1674
        case POWERPC_MMU_BOOKE206:
1675
            ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
1676
                                               access_type);
1677
            break;
1678
        case POWERPC_MMU_MPC8xx:
1679
            /* XXX: TODO */
1680
            cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1681
            break;
1682
        case POWERPC_MMU_REAL:
1683
            cpu_abort(env, "PowerPC in real mode do not do any translation\n");
1684
            return -1;
1685
        default:
1686
            cpu_abort(env, "Unknown or invalid MMU model\n");
1687
            return -1;
1688
        }
1689
    }
1690
#if 0
1691
    qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n",
1692
             __func__, eaddr, ret, ctx->raddr);
1693
#endif
1694

    
1695
    return ret;
1696
}
1697

    
1698
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1699
{
1700
    mmu_ctx_t ctx;
1701

    
1702
    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1703
        return -1;
1704

    
1705
    return ctx.raddr & TARGET_PAGE_MASK;
1706
}
1707

    
1708
static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address,
1709
                                     int rw)
1710
{
1711
    env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1712
    env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1713
    env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1714
    env->spr[SPR_BOOKE_MAS3] = 0;
1715
    env->spr[SPR_BOOKE_MAS6] = 0;
1716
    env->spr[SPR_BOOKE_MAS7] = 0;
1717

    
1718
    /* AS */
1719
    if (((rw == 2) && msr_ir) || ((rw != 2) && msr_dr)) {
1720
        env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1721
        env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1722
    }
1723

    
1724
    env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1725
    env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1726

    
1727
    switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1728
    case MAS4_TIDSELD_PID0:
1729
        env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID] << MAS1_TID_SHIFT;
1730
        break;
1731
    case MAS4_TIDSELD_PID1:
1732
        env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID1] << MAS1_TID_SHIFT;
1733
        break;
1734
    case MAS4_TIDSELD_PID2:
1735
        env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID2] << MAS1_TID_SHIFT;
1736
        break;
1737
    }
1738

    
1739
    env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1740

    
1741
    /* next victim logic */
1742
    env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1743
    env->last_way++;
1744
    env->last_way &= booke206_tlb_ways(env, 0) - 1;
1745
    env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1746
}
1747

    
1748
/* Perform address translation */
1749
int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1750
                              int mmu_idx)
1751
{
1752
    mmu_ctx_t ctx;
1753
    int access_type;
1754
    int ret = 0;
1755

    
1756
    if (rw == 2) {
1757
        /* code access */
1758
        rw = 0;
1759
        access_type = ACCESS_CODE;
1760
    } else {
1761
        /* data access */
1762
        access_type = env->access_type;
1763
    }
1764
    ret = get_physical_address(env, &ctx, address, rw, access_type);
1765
    if (ret == 0) {
1766
        tlb_set_page(env, address & TARGET_PAGE_MASK,
1767
                     ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1768
                     mmu_idx, TARGET_PAGE_SIZE);
1769
        ret = 0;
1770
    } else if (ret < 0) {
1771
        LOG_MMU_STATE(env);
1772
        if (access_type == ACCESS_CODE) {
1773
            switch (ret) {
1774
            case -1:
1775
                /* No matches in page tables or TLB */
1776
                switch (env->mmu_model) {
1777
                case POWERPC_MMU_SOFT_6xx:
1778
                    env->exception_index = POWERPC_EXCP_IFTLB;
1779
                    env->error_code = 1 << 18;
1780
                    env->spr[SPR_IMISS] = address;
1781
                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1782
                    goto tlb_miss;
1783
                case POWERPC_MMU_SOFT_74xx:
1784
                    env->exception_index = POWERPC_EXCP_IFTLB;
1785
                    goto tlb_miss_74xx;
1786
                case POWERPC_MMU_SOFT_4xx:
1787
                case POWERPC_MMU_SOFT_4xx_Z:
1788
                    env->exception_index = POWERPC_EXCP_ITLB;
1789
                    env->error_code = 0;
1790
                    env->spr[SPR_40x_DEAR] = address;
1791
                    env->spr[SPR_40x_ESR] = 0x00000000;
1792
                    break;
1793
                case POWERPC_MMU_32B:
1794
                case POWERPC_MMU_601:
1795
#if defined(TARGET_PPC64)
1796
                case POWERPC_MMU_620:
1797
                case POWERPC_MMU_64B:
1798
                case POWERPC_MMU_2_06:
1799
#endif
1800
                    env->exception_index = POWERPC_EXCP_ISI;
1801
                    env->error_code = 0x40000000;
1802
                    break;
1803
                case POWERPC_MMU_BOOKE206:
1804
                    booke206_update_mas_tlb_miss(env, address, rw);
1805
                    /* fall through */
1806
                case POWERPC_MMU_BOOKE:
1807
                    env->exception_index = POWERPC_EXCP_ITLB;
1808
                    env->error_code = 0;
1809
                    env->spr[SPR_BOOKE_DEAR] = address;
1810
                    return -1;
1811
                case POWERPC_MMU_MPC8xx:
1812
                    /* XXX: TODO */
1813
                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1814
                    break;
1815
                case POWERPC_MMU_REAL:
1816
                    cpu_abort(env, "PowerPC in real mode should never raise "
1817
                              "any MMU exceptions\n");
1818
                    return -1;
1819
                default:
1820
                    cpu_abort(env, "Unknown or invalid MMU model\n");
1821
                    return -1;
1822
                }
1823
                break;
1824
            case -2:
1825
                /* Access rights violation */
1826
                env->exception_index = POWERPC_EXCP_ISI;
1827
                env->error_code = 0x08000000;
1828
                break;
1829
            case -3:
1830
                /* No execute protection violation */
1831
                if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1832
                    (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1833
                    env->spr[SPR_BOOKE_ESR] = 0x00000000;
1834
                }
1835
                env->exception_index = POWERPC_EXCP_ISI;
1836
                env->error_code = 0x10000000;
1837
                break;
1838
            case -4:
1839
                /* Direct store exception */
1840
                /* No code fetch is allowed in direct-store areas */
1841
                env->exception_index = POWERPC_EXCP_ISI;
1842
                env->error_code = 0x10000000;
1843
                break;
1844
#if defined(TARGET_PPC64)
1845
            case -5:
1846
                /* No match in segment table */
1847
                if (env->mmu_model == POWERPC_MMU_620) {
1848
                    env->exception_index = POWERPC_EXCP_ISI;
1849
                    /* XXX: this might be incorrect */
1850
                    env->error_code = 0x40000000;
1851
                } else {
1852
                    env->exception_index = POWERPC_EXCP_ISEG;
1853
                    env->error_code = 0;
1854
                }
1855
                break;
1856
#endif
1857
            }
1858
        } else {
1859
            switch (ret) {
1860
            case -1:
1861
                /* No matches in page tables or TLB */
1862
                switch (env->mmu_model) {
1863
                case POWERPC_MMU_SOFT_6xx:
1864
                    if (rw == 1) {
1865
                        env->exception_index = POWERPC_EXCP_DSTLB;
1866
                        env->error_code = 1 << 16;
1867
                    } else {
1868
                        env->exception_index = POWERPC_EXCP_DLTLB;
1869
                        env->error_code = 0;
1870
                    }
1871
                    env->spr[SPR_DMISS] = address;
1872
                    env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1873
                tlb_miss:
1874
                    env->error_code |= ctx.key << 19;
1875
                    env->spr[SPR_HASH1] = env->htab_base +
1876
                        get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32);
1877
                    env->spr[SPR_HASH2] = env->htab_base +
1878
                        get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32);
1879
                    break;
1880
                case POWERPC_MMU_SOFT_74xx:
1881
                    if (rw == 1) {
1882
                        env->exception_index = POWERPC_EXCP_DSTLB;
1883
                    } else {
1884
                        env->exception_index = POWERPC_EXCP_DLTLB;
1885
                    }
1886
                tlb_miss_74xx:
1887
                    /* Implement LRU algorithm */
1888
                    env->error_code = ctx.key << 19;
1889
                    env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
1890
                        ((env->last_way + 1) & (env->nb_ways - 1));
1891
                    env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1892
                    break;
1893
                case POWERPC_MMU_SOFT_4xx:
1894
                case POWERPC_MMU_SOFT_4xx_Z:
1895
                    env->exception_index = POWERPC_EXCP_DTLB;
1896
                    env->error_code = 0;
1897
                    env->spr[SPR_40x_DEAR] = address;
1898
                    if (rw)
1899
                        env->spr[SPR_40x_ESR] = 0x00800000;
1900
                    else
1901
                        env->spr[SPR_40x_ESR] = 0x00000000;
1902
                    break;
1903
                case POWERPC_MMU_32B:
1904
                case POWERPC_MMU_601:
1905
#if defined(TARGET_PPC64)
1906
                case POWERPC_MMU_620:
1907
                case POWERPC_MMU_64B:
1908
                case POWERPC_MMU_2_06:
1909
#endif
1910
                    env->exception_index = POWERPC_EXCP_DSI;
1911
                    env->error_code = 0;
1912
                    env->spr[SPR_DAR] = address;
1913
                    if (rw == 1)
1914
                        env->spr[SPR_DSISR] = 0x42000000;
1915
                    else
1916
                        env->spr[SPR_DSISR] = 0x40000000;
1917
                    break;
1918
                case POWERPC_MMU_MPC8xx:
1919
                    /* XXX: TODO */
1920
                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1921
                    break;
1922
                case POWERPC_MMU_BOOKE206:
1923
                    booke206_update_mas_tlb_miss(env, address, rw);
1924
                    /* fall through */
1925
                case POWERPC_MMU_BOOKE:
1926
                    env->exception_index = POWERPC_EXCP_DTLB;
1927
                    env->error_code = 0;
1928
                    env->spr[SPR_BOOKE_DEAR] = address;
1929
                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
1930
                    return -1;
1931
                case POWERPC_MMU_REAL:
1932
                    cpu_abort(env, "PowerPC in real mode should never raise "
1933
                              "any MMU exceptions\n");
1934
                    return -1;
1935
                default:
1936
                    cpu_abort(env, "Unknown or invalid MMU model\n");
1937
                    return -1;
1938
                }
1939
                break;
1940
            case -2:
1941
                /* Access rights violation */
1942
                env->exception_index = POWERPC_EXCP_DSI;
1943
                env->error_code = 0;
1944
                if (env->mmu_model == POWERPC_MMU_SOFT_4xx
1945
                    || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
1946
                    env->spr[SPR_40x_DEAR] = address;
1947
                    if (rw) {
1948
                        env->spr[SPR_40x_ESR] |= 0x00800000;
1949
                    }
1950
                } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1951
                           (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1952
                    env->spr[SPR_BOOKE_DEAR] = address;
1953
                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
1954
                } else {
1955
                    env->spr[SPR_DAR] = address;
1956
                    if (rw == 1) {
1957
                        env->spr[SPR_DSISR] = 0x0A000000;
1958
                    } else {
1959
                        env->spr[SPR_DSISR] = 0x08000000;
1960
                    }
1961
                }
1962
                break;
1963
            case -4:
1964
                /* Direct store exception */
1965
                switch (access_type) {
1966
                case ACCESS_FLOAT:
1967
                    /* Floating point load/store */
1968
                    env->exception_index = POWERPC_EXCP_ALIGN;
1969
                    env->error_code = POWERPC_EXCP_ALIGN_FP;
1970
                    env->spr[SPR_DAR] = address;
1971
                    break;
1972
                case ACCESS_RES:
1973
                    /* lwarx, ldarx or stwcx. */
1974
                    env->exception_index = POWERPC_EXCP_DSI;
1975
                    env->error_code = 0;
1976
                    env->spr[SPR_DAR] = address;
1977
                    if (rw == 1)
1978
                        env->spr[SPR_DSISR] = 0x06000000;
1979
                    else
1980
                        env->spr[SPR_DSISR] = 0x04000000;
1981
                    break;
1982
                case ACCESS_EXT:
1983
                    /* eciwx or ecowx */
1984
                    env->exception_index = POWERPC_EXCP_DSI;
1985
                    env->error_code = 0;
1986
                    env->spr[SPR_DAR] = address;
1987
                    if (rw == 1)
1988
                        env->spr[SPR_DSISR] = 0x06100000;
1989
                    else
1990
                        env->spr[SPR_DSISR] = 0x04100000;
1991
                    break;
1992
                default:
1993
                    printf("DSI: invalid exception (%d)\n", ret);
1994
                    env->exception_index = POWERPC_EXCP_PROGRAM;
1995
                    env->error_code =
1996
                        POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1997
                    env->spr[SPR_DAR] = address;
1998
                    break;
1999
                }
2000
                break;
2001
#if defined(TARGET_PPC64)
2002
            case -5:
2003
                /* No match in segment table */
2004
                if (env->mmu_model == POWERPC_MMU_620) {
2005
                    env->exception_index = POWERPC_EXCP_DSI;
2006
                    env->error_code = 0;
2007
                    env->spr[SPR_DAR] = address;
2008
                    /* XXX: this might be incorrect */
2009
                    if (rw == 1)
2010
                        env->spr[SPR_DSISR] = 0x42000000;
2011
                    else
2012
                        env->spr[SPR_DSISR] = 0x40000000;
2013
                } else {
2014
                    env->exception_index = POWERPC_EXCP_DSEG;
2015
                    env->error_code = 0;
2016
                    env->spr[SPR_DAR] = address;
2017
                }
2018
                break;
2019
#endif
2020
            }
2021
        }
2022
#if 0
2023
        printf("%s: set exception to %d %02x\n", __func__,
2024
               env->exception, env->error_code);
2025
#endif
2026
        ret = 1;
2027
    }
2028

    
2029
    return ret;
2030
}
2031

    
2032
/*****************************************************************************/
2033
/* BATs management */
2034
#if !defined(FLUSH_ALL_TLBS)
2035
static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
2036
                                     target_ulong mask)
2037
{
2038
    target_ulong base, end, page;
2039

    
2040
    base = BATu & ~0x0001FFFF;
2041
    end = base + mask + 0x00020000;
2042
    LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
2043
             TARGET_FMT_lx ")\n", base, end, mask);
2044
    for (page = base; page != end; page += TARGET_PAGE_SIZE)
2045
        tlb_flush_page(env, page);
2046
    LOG_BATS("Flush done\n");
2047
}
2048
#endif
2049

    
2050
static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
2051
                                  target_ulong value)
2052
{
2053
    LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID,
2054
             nr, ul == 0 ? 'u' : 'l', value, env->nip);
2055
}
2056

    
2057
void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
2058
{
2059
    target_ulong mask;
2060

    
2061
    dump_store_bat(env, 'I', 0, nr, value);
2062
    if (env->IBAT[0][nr] != value) {
2063
        mask = (value << 15) & 0x0FFE0000UL;
2064
#if !defined(FLUSH_ALL_TLBS)
2065
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
2066
#endif
2067
        /* When storing valid upper BAT, mask BEPI and BRPN
2068
         * and invalidate all TLBs covered by this BAT
2069
         */
2070
        mask = (value << 15) & 0x0FFE0000UL;
2071
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
2072
            (value & ~0x0001FFFFUL & ~mask);
2073
        env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
2074
            (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
2075
#if !defined(FLUSH_ALL_TLBS)
2076
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
2077
#else
2078
        tlb_flush(env, 1);
2079
#endif
2080
    }
2081
}
2082

    
2083
void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
2084
{
2085
    dump_store_bat(env, 'I', 1, nr, value);
2086
    env->IBAT[1][nr] = value;
2087
}
2088

    
2089
void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
2090
{
2091
    target_ulong mask;
2092

    
2093
    dump_store_bat(env, 'D', 0, nr, value);
2094
    if (env->DBAT[0][nr] != value) {
2095
        /* When storing valid upper BAT, mask BEPI and BRPN
2096
         * and invalidate all TLBs covered by this BAT
2097
         */
2098
        mask = (value << 15) & 0x0FFE0000UL;
2099
#if !defined(FLUSH_ALL_TLBS)
2100
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
2101
#endif
2102
        mask = (value << 15) & 0x0FFE0000UL;
2103
        env->DBAT[0][nr] = (value & 0x00001FFFUL) |
2104
            (value & ~0x0001FFFFUL & ~mask);
2105
        env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
2106
            (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
2107
#if !defined(FLUSH_ALL_TLBS)
2108
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
2109
#else
2110
        tlb_flush(env, 1);
2111
#endif
2112
    }
2113
}
2114

    
2115
void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
2116
{
2117
    dump_store_bat(env, 'D', 1, nr, value);
2118
    env->DBAT[1][nr] = value;
2119
}
2120

    
2121
void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
2122
{
2123
    target_ulong mask;
2124
#if defined(FLUSH_ALL_TLBS)
2125
    int do_inval;
2126
#endif
2127

    
2128
    dump_store_bat(env, 'I', 0, nr, value);
2129
    if (env->IBAT[0][nr] != value) {
2130
#if defined(FLUSH_ALL_TLBS)
2131
        do_inval = 0;
2132
#endif
2133
        mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
2134
        if (env->IBAT[1][nr] & 0x40) {
2135
            /* Invalidate BAT only if it is valid */
2136
#if !defined(FLUSH_ALL_TLBS)
2137
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
2138
#else
2139
            do_inval = 1;
2140
#endif
2141
        }
2142
        /* When storing valid upper BAT, mask BEPI and BRPN
2143
         * and invalidate all TLBs covered by this BAT
2144
         */
2145
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
2146
            (value & ~0x0001FFFFUL & ~mask);
2147
        env->DBAT[0][nr] = env->IBAT[0][nr];
2148
        if (env->IBAT[1][nr] & 0x40) {
2149
#if !defined(FLUSH_ALL_TLBS)
2150
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
2151
#else
2152
            do_inval = 1;
2153
#endif
2154
        }
2155
#if defined(FLUSH_ALL_TLBS)
2156
        if (do_inval)
2157
            tlb_flush(env, 1);
2158
#endif
2159
    }
2160
}
2161

    
2162
void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
2163
{
2164
    target_ulong mask;
2165
#if defined(FLUSH_ALL_TLBS)
2166
    int do_inval;
2167
#endif
2168

    
2169
    dump_store_bat(env, 'I', 1, nr, value);
2170
    if (env->IBAT[1][nr] != value) {
2171
#if defined(FLUSH_ALL_TLBS)
2172
        do_inval = 0;
2173
#endif
2174
        if (env->IBAT[1][nr] & 0x40) {
2175
#if !defined(FLUSH_ALL_TLBS)
2176
            mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
2177
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
2178
#else
2179
            do_inval = 1;
2180
#endif
2181
        }
2182
        if (value & 0x40) {
2183
#if !defined(FLUSH_ALL_TLBS)
2184
            mask = (value << 17) & 0x0FFE0000UL;
2185
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
2186
#else
2187
            do_inval = 1;
2188
#endif
2189
        }
2190
        env->IBAT[1][nr] = value;
2191
        env->DBAT[1][nr] = value;
2192
#if defined(FLUSH_ALL_TLBS)
2193
        if (do_inval)
2194
            tlb_flush(env, 1);
2195
#endif
2196
    }
2197
}
2198

    
2199
/*****************************************************************************/
2200
/* TLB management */
2201
void ppc_tlb_invalidate_all (CPUPPCState *env)
2202
{
2203
    switch (env->mmu_model) {
2204
    case POWERPC_MMU_SOFT_6xx:
2205
    case POWERPC_MMU_SOFT_74xx:
2206
        ppc6xx_tlb_invalidate_all(env);
2207
        break;
2208
    case POWERPC_MMU_SOFT_4xx:
2209
    case POWERPC_MMU_SOFT_4xx_Z:
2210
        ppc4xx_tlb_invalidate_all(env);
2211
        break;
2212
    case POWERPC_MMU_REAL:
2213
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
2214
        break;
2215
    case POWERPC_MMU_MPC8xx:
2216
        /* XXX: TODO */
2217
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
2218
        break;
2219
    case POWERPC_MMU_BOOKE:
2220
        tlb_flush(env, 1);
2221
        break;
2222
    case POWERPC_MMU_BOOKE206:
2223
        booke206_flush_tlb(env, -1, 0);
2224
        break;
2225
    case POWERPC_MMU_32B:
2226
    case POWERPC_MMU_601:
2227
#if defined(TARGET_PPC64)
2228
    case POWERPC_MMU_620:
2229
    case POWERPC_MMU_64B:
2230
    case POWERPC_MMU_2_06:
2231
#endif /* defined(TARGET_PPC64) */
2232
        tlb_flush(env, 1);
2233
        break;
2234
    default:
2235
        /* XXX: TODO */
2236
        cpu_abort(env, "Unknown MMU model\n");
2237
        break;
2238
    }
2239
}
2240

    
2241
void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
2242
{
2243
#if !defined(FLUSH_ALL_TLBS)
2244
    addr &= TARGET_PAGE_MASK;
2245
    switch (env->mmu_model) {
2246
    case POWERPC_MMU_SOFT_6xx:
2247
    case POWERPC_MMU_SOFT_74xx:
2248
        ppc6xx_tlb_invalidate_virt(env, addr, 0);
2249
        if (env->id_tlbs == 1)
2250
            ppc6xx_tlb_invalidate_virt(env, addr, 1);
2251
        break;
2252
    case POWERPC_MMU_SOFT_4xx:
2253
    case POWERPC_MMU_SOFT_4xx_Z:
2254
        ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
2255
        break;
2256
    case POWERPC_MMU_REAL:
2257
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
2258
        break;
2259
    case POWERPC_MMU_MPC8xx:
2260
        /* XXX: TODO */
2261
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
2262
        break;
2263
    case POWERPC_MMU_BOOKE:
2264
        /* XXX: TODO */
2265
        cpu_abort(env, "BookE MMU model is not implemented\n");
2266
        break;
2267
    case POWERPC_MMU_BOOKE206:
2268
        /* XXX: TODO */
2269
        cpu_abort(env, "BookE 2.06 MMU model is not implemented\n");
2270
        break;
2271
    case POWERPC_MMU_32B:
2272
    case POWERPC_MMU_601:
2273
        /* tlbie invalidate TLBs for all segments */
2274
        addr &= ~((target_ulong)-1ULL << 28);
2275
        /* XXX: this case should be optimized,
2276
         * giving a mask to tlb_flush_page
2277
         */
2278
        tlb_flush_page(env, addr | (0x0 << 28));
2279
        tlb_flush_page(env, addr | (0x1 << 28));
2280
        tlb_flush_page(env, addr | (0x2 << 28));
2281
        tlb_flush_page(env, addr | (0x3 << 28));
2282
        tlb_flush_page(env, addr | (0x4 << 28));
2283
        tlb_flush_page(env, addr | (0x5 << 28));
2284
        tlb_flush_page(env, addr | (0x6 << 28));
2285
        tlb_flush_page(env, addr | (0x7 << 28));
2286
        tlb_flush_page(env, addr | (0x8 << 28));
2287
        tlb_flush_page(env, addr | (0x9 << 28));
2288
        tlb_flush_page(env, addr | (0xA << 28));
2289
        tlb_flush_page(env, addr | (0xB << 28));
2290
        tlb_flush_page(env, addr | (0xC << 28));
2291
        tlb_flush_page(env, addr | (0xD << 28));
2292
        tlb_flush_page(env, addr | (0xE << 28));
2293
        tlb_flush_page(env, addr | (0xF << 28));
2294
        break;
2295
#if defined(TARGET_PPC64)
2296
    case POWERPC_MMU_620:
2297
    case POWERPC_MMU_64B:
2298
    case POWERPC_MMU_2_06:
2299
        /* tlbie invalidate TLBs for all segments */
2300
        /* XXX: given the fact that there are too many segments to invalidate,
2301
         *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2302
         *      we just invalidate all TLBs
2303
         */
2304
        tlb_flush(env, 1);
2305
        break;
2306
#endif /* defined(TARGET_PPC64) */
2307
    default:
2308
        /* XXX: TODO */
2309
        cpu_abort(env, "Unknown MMU model\n");
2310
        break;
2311
    }
2312
#else
2313
    ppc_tlb_invalidate_all(env);
2314
#endif
2315
}
2316

    
2317
/*****************************************************************************/
2318
/* Special registers manipulation */
2319
#if defined(TARGET_PPC64)
2320
void ppc_store_asr (CPUPPCState *env, target_ulong value)
2321
{
2322
    if (env->asr != value) {
2323
        env->asr = value;
2324
        tlb_flush(env, 1);
2325
    }
2326
}
2327
#endif
2328

    
2329
void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
2330
{
2331
    LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
2332
    if (env->spr[SPR_SDR1] != value) {
2333
        env->spr[SPR_SDR1] = value;
2334
#if defined(TARGET_PPC64)
2335
        if (env->mmu_model & POWERPC_MMU_64) {
2336
            target_ulong htabsize = value & SDR_64_HTABSIZE;
2337

    
2338
            if (htabsize > 28) {
2339
                fprintf(stderr, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2340
                        " stored in SDR1\n", htabsize);
2341
                htabsize = 28;
2342
            }
2343
            env->htab_mask = (1ULL << (htabsize + 18)) - 1;
2344
            env->htab_base = value & SDR_64_HTABORG;
2345
        } else
2346
#endif /* defined(TARGET_PPC64) */
2347
        {
2348
            /* FIXME: Should check for valid HTABMASK values */
2349
            env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
2350
            env->htab_base = value & SDR_32_HTABORG;
2351
        }
2352
        tlb_flush(env, 1);
2353
    }
2354
}
2355

    
2356
#if defined(TARGET_PPC64)
2357
target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
2358
{
2359
    // XXX
2360
    return 0;
2361
}
2362
#endif
2363

    
2364
void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
2365
{
2366
    LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
2367
            srnum, value, env->sr[srnum]);
2368
#if defined(TARGET_PPC64)
2369
    if (env->mmu_model & POWERPC_MMU_64) {
2370
        uint64_t rb = 0, rs = 0;
2371

    
2372
        /* ESID = srnum */
2373
        rb |= ((uint32_t)srnum & 0xf) << 28;
2374
        /* Set the valid bit */
2375
        rb |= 1 << 27;
2376
        /* Index = ESID */
2377
        rb |= (uint32_t)srnum;
2378

    
2379
        /* VSID = VSID */
2380
        rs |= (value & 0xfffffff) << 12;
2381
        /* flags = flags */
2382
        rs |= ((value >> 27) & 0xf) << 8;
2383

    
2384
        ppc_store_slb(env, rb, rs);
2385
    } else
2386
#endif
2387
    if (env->sr[srnum] != value) {
2388
        env->sr[srnum] = value;
2389
/* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2390
   flusing the whole TLB. */
2391
#if !defined(FLUSH_ALL_TLBS) && 0
2392
        {
2393
            target_ulong page, end;
2394
            /* Invalidate 256 MB of virtual memory */
2395
            page = (16 << 20) * srnum;
2396
            end = page + (16 << 20);
2397
            for (; page != end; page += TARGET_PAGE_SIZE)
2398
                tlb_flush_page(env, page);
2399
        }
2400
#else
2401
        tlb_flush(env, 1);
2402
#endif
2403
    }
2404
}
2405
#endif /* !defined (CONFIG_USER_ONLY) */
2406

    
2407
/* GDBstub can read and write MSR... */
2408
void ppc_store_msr (CPUPPCState *env, target_ulong value)
2409
{
2410
    hreg_store_msr(env, value, 0);
2411
}
2412

    
2413
/*****************************************************************************/
2414
/* Exception processing */
2415
#if defined (CONFIG_USER_ONLY)
2416
void do_interrupt (CPUState *env)
2417
{
2418
    env->exception_index = POWERPC_EXCP_NONE;
2419
    env->error_code = 0;
2420
}
2421

    
2422
void ppc_hw_interrupt (CPUState *env)
2423
{
2424
    env->exception_index = POWERPC_EXCP_NONE;
2425
    env->error_code = 0;
2426
}
2427
#else /* defined (CONFIG_USER_ONLY) */
2428
static inline void dump_syscall(CPUState *env)
2429
{
2430
    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
2431
                  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
2432
                  " nip=" TARGET_FMT_lx "\n",
2433
                  ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
2434
                  ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
2435
                  ppc_dump_gpr(env, 6), env->nip);
2436
}
2437

    
2438
/* Note that this function should be greatly optimized
2439
 * when called with a constant excp, from ppc_hw_interrupt
2440
 */
2441
static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
2442
{
2443
    target_ulong msr, new_msr, vector;
2444
    int srr0, srr1, asrr0, asrr1;
2445
    int lpes0, lpes1, lev;
2446

    
2447
    if (0) {
2448
        /* XXX: find a suitable condition to enable the hypervisor mode */
2449
        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
2450
        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
2451
    } else {
2452
        /* Those values ensure we won't enter the hypervisor mode */
2453
        lpes0 = 0;
2454
        lpes1 = 1;
2455
    }
2456

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

    
2460
    /* new srr1 value excluding must-be-zero bits */
2461
    msr = env->msr & ~0x783f0000ULL;
2462

    
2463
    /* new interrupt handler msr */
2464
    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
2465

    
2466
    /* target registers */
2467
    srr0 = SPR_SRR0;
2468
    srr1 = SPR_SRR1;
2469
    asrr0 = -1;
2470
    asrr1 = -1;
2471

    
2472
    switch (excp) {
2473
    case POWERPC_EXCP_NONE:
2474
        /* Should never happen */
2475
        return;
2476
    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
2477
        switch (excp_model) {
2478
        case POWERPC_EXCP_40x:
2479
            srr0 = SPR_40x_SRR2;
2480
            srr1 = SPR_40x_SRR3;
2481
            break;
2482
        case POWERPC_EXCP_BOOKE:
2483
            srr0 = SPR_BOOKE_CSRR0;
2484
            srr1 = SPR_BOOKE_CSRR1;
2485
            break;
2486
        case POWERPC_EXCP_G2:
2487
            break;
2488
        default:
2489
            goto excp_invalid;
2490
        }
2491
        goto store_next;
2492
    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
2493
        if (msr_me == 0) {
2494
            /* Machine check exception is not enabled.
2495
             * Enter checkstop state.
2496
             */
2497
            if (qemu_log_enabled()) {
2498
                qemu_log("Machine check while not allowed. "
2499
                        "Entering checkstop state\n");
2500
            } else {
2501
                fprintf(stderr, "Machine check while not allowed. "
2502
                        "Entering checkstop state\n");
2503
            }
2504
            env->halted = 1;
2505
            env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2506
        }
2507
        if (0) {
2508
            /* XXX: find a suitable condition to enable the hypervisor mode */
2509
            new_msr |= (target_ulong)MSR_HVB;
2510
        }
2511

    
2512
        /* machine check exceptions don't have ME set */
2513
        new_msr &= ~((target_ulong)1 << MSR_ME);
2514

    
2515
        /* XXX: should also have something loaded in DAR / DSISR */
2516
        switch (excp_model) {
2517
        case POWERPC_EXCP_40x:
2518
            srr0 = SPR_40x_SRR2;
2519
            srr1 = SPR_40x_SRR3;
2520
            break;
2521
        case POWERPC_EXCP_BOOKE:
2522
            srr0 = SPR_BOOKE_MCSRR0;
2523
            srr1 = SPR_BOOKE_MCSRR1;
2524
            asrr0 = SPR_BOOKE_CSRR0;
2525
            asrr1 = SPR_BOOKE_CSRR1;
2526
            break;
2527
        default:
2528
            break;
2529
        }
2530
        goto store_next;
2531
    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
2532
        LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
2533
                 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
2534
        if (lpes1 == 0)
2535
            new_msr |= (target_ulong)MSR_HVB;
2536
        goto store_next;
2537
    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
2538
        LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
2539
                 "\n", msr, env->nip);
2540
        if (lpes1 == 0)
2541
            new_msr |= (target_ulong)MSR_HVB;
2542
        msr |= env->error_code;
2543
        goto store_next;
2544
    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
2545
        if (lpes0 == 1)
2546
            new_msr |= (target_ulong)MSR_HVB;
2547
        goto store_next;
2548
    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
2549
        if (lpes1 == 0)
2550
            new_msr |= (target_ulong)MSR_HVB;
2551
        /* XXX: this is false */
2552
        /* Get rS/rD and rA from faulting opcode */
2553
        env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
2554
        goto store_current;
2555
    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
2556
        switch (env->error_code & ~0xF) {
2557
        case POWERPC_EXCP_FP:
2558
            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
2559
                LOG_EXCP("Ignore floating point exception\n");
2560
                env->exception_index = POWERPC_EXCP_NONE;
2561
                env->error_code = 0;
2562
                return;
2563
            }
2564
            if (lpes1 == 0)
2565
                new_msr |= (target_ulong)MSR_HVB;
2566
            msr |= 0x00100000;
2567
            if (msr_fe0 == msr_fe1)
2568
                goto store_next;
2569
            msr |= 0x00010000;
2570
            break;
2571
        case POWERPC_EXCP_INVAL:
2572
            LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
2573
            if (lpes1 == 0)
2574
                new_msr |= (target_ulong)MSR_HVB;
2575
            msr |= 0x00080000;
2576
            env->spr[SPR_BOOKE_ESR] = ESR_PIL;
2577
            break;
2578
        case POWERPC_EXCP_PRIV:
2579
            if (lpes1 == 0)
2580
                new_msr |= (target_ulong)MSR_HVB;
2581
            msr |= 0x00040000;
2582
            env->spr[SPR_BOOKE_ESR] = ESR_PPR;
2583
            break;
2584
        case POWERPC_EXCP_TRAP:
2585
            if (lpes1 == 0)
2586
                new_msr |= (target_ulong)MSR_HVB;
2587
            msr |= 0x00020000;
2588
            env->spr[SPR_BOOKE_ESR] = ESR_PTR;
2589
            break;
2590
        default:
2591
            /* Should never occur */
2592
            cpu_abort(env, "Invalid program exception %d. Aborting\n",
2593
                      env->error_code);
2594
            break;
2595
        }
2596
        goto store_current;
2597
    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
2598
        if (lpes1 == 0)
2599
            new_msr |= (target_ulong)MSR_HVB;
2600
        goto store_current;
2601
    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
2602
        dump_syscall(env);
2603
        lev = env->error_code;
2604
        if ((lev == 1) && cpu_ppc_hypercall) {
2605
            cpu_ppc_hypercall(env);
2606
            return;
2607
        }
2608
        if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2609
            new_msr |= (target_ulong)MSR_HVB;
2610
        goto store_next;
2611
    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
2612
        goto store_current;
2613
    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
2614
        if (lpes1 == 0)
2615
            new_msr |= (target_ulong)MSR_HVB;
2616
        goto store_next;
2617
    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
2618
        /* FIT on 4xx */
2619
        LOG_EXCP("FIT exception\n");
2620
        goto store_next;
2621
    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
2622
        LOG_EXCP("WDT exception\n");
2623
        switch (excp_model) {
2624
        case POWERPC_EXCP_BOOKE:
2625
            srr0 = SPR_BOOKE_CSRR0;
2626
            srr1 = SPR_BOOKE_CSRR1;
2627
            break;
2628
        default:
2629
            break;
2630
        }
2631
        goto store_next;
2632
    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
2633
        goto store_next;
2634
    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
2635
        goto store_next;
2636
    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
2637
        switch (excp_model) {
2638
        case POWERPC_EXCP_BOOKE:
2639
            srr0 = SPR_BOOKE_DSRR0;
2640
            srr1 = SPR_BOOKE_DSRR1;
2641
            asrr0 = SPR_BOOKE_CSRR0;
2642
            asrr1 = SPR_BOOKE_CSRR1;
2643
            break;
2644
        default:
2645
            break;
2646
        }
2647
        /* XXX: TODO */
2648
        cpu_abort(env, "Debug exception is not implemented yet !\n");
2649
        goto store_next;
2650
    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
2651
        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
2652
        goto store_current;
2653
    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
2654
        /* XXX: TODO */
2655
        cpu_abort(env, "Embedded floating point data exception "
2656
                  "is not implemented yet !\n");
2657
        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
2658
        goto store_next;
2659
    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
2660
        /* XXX: TODO */
2661
        cpu_abort(env, "Embedded floating point round exception "
2662
                  "is not implemented yet !\n");
2663
        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
2664
        goto store_next;
2665
    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
2666
        /* XXX: TODO */
2667
        cpu_abort(env,
2668
                  "Performance counter exception is not implemented yet !\n");
2669
        goto store_next;
2670
    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
2671
        /* XXX: TODO */
2672
        cpu_abort(env,
2673
                  "Embedded doorbell interrupt is not implemented yet !\n");
2674
        goto store_next;
2675
    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
2676
        switch (excp_model) {
2677
        case POWERPC_EXCP_BOOKE:
2678
            srr0 = SPR_BOOKE_CSRR0;
2679
            srr1 = SPR_BOOKE_CSRR1;
2680
            break;
2681
        default:
2682
            break;
2683
        }
2684
        /* XXX: TODO */
2685
        cpu_abort(env, "Embedded doorbell critical interrupt "
2686
                  "is not implemented yet !\n");
2687
        goto store_next;
2688
    case POWERPC_EXCP_RESET:     /* System reset exception                   */
2689
        if (msr_pow) {
2690
            /* indicate that we resumed from power save mode */
2691
            msr |= 0x10000;
2692
        } else {
2693
            new_msr &= ~((target_ulong)1 << MSR_ME);
2694
        }
2695

    
2696
        if (0) {
2697
            /* XXX: find a suitable condition to enable the hypervisor mode */
2698
            new_msr |= (target_ulong)MSR_HVB;
2699
        }
2700
        goto store_next;
2701
    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
2702
        if (lpes1 == 0)
2703
            new_msr |= (target_ulong)MSR_HVB;
2704
        goto store_next;
2705
    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
2706
        if (lpes1 == 0)
2707
            new_msr |= (target_ulong)MSR_HVB;
2708
        goto store_next;
2709
    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
2710
        srr0 = SPR_HSRR0;
2711
        srr1 = SPR_HSRR1;
2712
        new_msr |= (target_ulong)MSR_HVB;
2713
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2714
        goto store_next;
2715
    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
2716
        if (lpes1 == 0)
2717
            new_msr |= (target_ulong)MSR_HVB;
2718
        goto store_next;
2719
    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
2720
        srr0 = SPR_HSRR0;
2721
        srr1 = SPR_HSRR1;
2722
        new_msr |= (target_ulong)MSR_HVB;
2723
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2724
        goto store_next;
2725
    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
2726
        srr0 = SPR_HSRR0;
2727
        srr1 = SPR_HSRR1;
2728
        new_msr |= (target_ulong)MSR_HVB;
2729
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2730
        goto store_next;
2731
    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
2732
        srr0 = SPR_HSRR0;
2733
        srr1 = SPR_HSRR1;
2734
        new_msr |= (target_ulong)MSR_HVB;
2735
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2736
        goto store_next;
2737
    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
2738
        srr0 = SPR_HSRR0;
2739
        srr1 = SPR_HSRR1;
2740
        new_msr |= (target_ulong)MSR_HVB;
2741
        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2742
        goto store_next;
2743
    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
2744
        if (lpes1 == 0)
2745
            new_msr |= (target_ulong)MSR_HVB;
2746
        goto store_current;
2747
    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
2748
        LOG_EXCP("PIT exception\n");
2749
        goto store_next;
2750
    case POWERPC_EXCP_IO:        /* IO error exception                       */
2751
        /* XXX: TODO */
2752
        cpu_abort(env, "601 IO error exception is not implemented yet !\n");
2753
        goto store_next;
2754
    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
2755
        /* XXX: TODO */
2756
        cpu_abort(env, "601 run mode exception is not implemented yet !\n");
2757
        goto store_next;
2758
    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
2759
        /* XXX: TODO */
2760
        cpu_abort(env, "602 emulation trap exception "
2761
                  "is not implemented yet !\n");
2762
        goto store_next;
2763
    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
2764
        if (lpes1 == 0) /* XXX: check this */
2765
            new_msr |= (target_ulong)MSR_HVB;
2766
        switch (excp_model) {
2767
        case POWERPC_EXCP_602:
2768
        case POWERPC_EXCP_603:
2769
        case POWERPC_EXCP_603E:
2770
        case POWERPC_EXCP_G2:
2771
            goto tlb_miss_tgpr;
2772
        case POWERPC_EXCP_7x5:
2773
            goto tlb_miss;
2774
        case POWERPC_EXCP_74xx:
2775
            goto tlb_miss_74xx;
2776
        default:
2777
            cpu_abort(env, "Invalid instruction TLB miss exception\n");
2778
            break;
2779
        }
2780
        break;
2781
    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
2782
        if (lpes1 == 0) /* XXX: check this */
2783
            new_msr |= (target_ulong)MSR_HVB;
2784
        switch (excp_model) {
2785
        case POWERPC_EXCP_602:
2786
        case POWERPC_EXCP_603:
2787
        case POWERPC_EXCP_603E:
2788
        case POWERPC_EXCP_G2:
2789
            goto tlb_miss_tgpr;
2790
        case POWERPC_EXCP_7x5:
2791
            goto tlb_miss;
2792
        case POWERPC_EXCP_74xx:
2793
            goto tlb_miss_74xx;
2794
        default:
2795
            cpu_abort(env, "Invalid data load TLB miss exception\n");
2796
            break;
2797
        }
2798
        break;
2799
    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
2800
        if (lpes1 == 0) /* XXX: check this */
2801
            new_msr |= (target_ulong)MSR_HVB;
2802
        switch (excp_model) {
2803
        case POWERPC_EXCP_602:
2804
        case POWERPC_EXCP_603:
2805
        case POWERPC_EXCP_603E:
2806
        case POWERPC_EXCP_G2:
2807
        tlb_miss_tgpr:
2808
            /* Swap temporary saved registers with GPRs */
2809
            if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
2810
                new_msr |= (target_ulong)1 << MSR_TGPR;
2811
                hreg_swap_gpr_tgpr(env);
2812
            }
2813
            goto tlb_miss;
2814
        case POWERPC_EXCP_7x5:
2815
        tlb_miss:
2816
#if defined (DEBUG_SOFTWARE_TLB)
2817
            if (qemu_log_enabled()) {
2818
                const char *es;
2819
                target_ulong *miss, *cmp;
2820
                int en;
2821
                if (excp == POWERPC_EXCP_IFTLB) {
2822
                    es = "I";
2823
                    en = 'I';
2824
                    miss = &env->spr[SPR_IMISS];
2825
                    cmp = &env->spr[SPR_ICMP];
2826
                } else {
2827
                    if (excp == POWERPC_EXCP_DLTLB)
2828
                        es = "DL";
2829
                    else
2830
                        es = "DS";
2831
                    en = 'D';
2832
                    miss = &env->spr[SPR_DMISS];
2833
                    cmp = &env->spr[SPR_DCMP];
2834
                }
2835
                qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2836
                         TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
2837
                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2838
                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],
2839
                         env->error_code);
2840
            }
2841
#endif
2842
            msr |= env->crf[0] << 28;
2843
            msr |= env->error_code; /* key, D/I, S/L bits */
2844
            /* Set way using a LRU mechanism */
2845
            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2846
            break;
2847
        case POWERPC_EXCP_74xx:
2848
        tlb_miss_74xx:
2849
#if defined (DEBUG_SOFTWARE_TLB)
2850
            if (qemu_log_enabled()) {
2851
                const char *es;
2852
                target_ulong *miss, *cmp;
2853
                int en;
2854
                if (excp == POWERPC_EXCP_IFTLB) {
2855
                    es = "I";
2856
                    en = 'I';
2857
                    miss = &env->spr[SPR_TLBMISS];
2858
                    cmp = &env->spr[SPR_PTEHI];
2859
                } else {
2860
                    if (excp == POWERPC_EXCP_DLTLB)
2861
                        es = "DL";
2862
                    else
2863
                        es = "DS";
2864
                    en = 'D';
2865
                    miss = &env->spr[SPR_TLBMISS];
2866
                    cmp = &env->spr[SPR_PTEHI];
2867
                }
2868
                qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2869
                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2870
                         env->error_code);
2871
            }
2872
#endif
2873
            msr |= env->error_code; /* key bit */
2874
            break;
2875
        default:
2876
            cpu_abort(env, "Invalid data store TLB miss exception\n");
2877
            break;
2878
        }
2879
        goto store_next;
2880
    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
2881
        /* XXX: TODO */
2882
        cpu_abort(env, "Floating point assist exception "
2883
                  "is not implemented yet !\n");
2884
        goto store_next;
2885
    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
2886
        /* XXX: TODO */
2887
        cpu_abort(env, "DABR exception is not implemented yet !\n");
2888
        goto store_next;
2889
    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
2890
        /* XXX: TODO */
2891
        cpu_abort(env, "IABR exception is not implemented yet !\n");
2892
        goto store_next;
2893
    case POWERPC_EXCP_SMI:       /* System management interrupt              */
2894
        /* XXX: TODO */
2895
        cpu_abort(env, "SMI exception is not implemented yet !\n");
2896
        goto store_next;
2897
    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
2898
        /* XXX: TODO */
2899
        cpu_abort(env, "Thermal management exception "
2900
                  "is not implemented yet !\n");
2901
        goto store_next;
2902
    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
2903
        if (lpes1 == 0)
2904
            new_msr |= (target_ulong)MSR_HVB;
2905
        /* XXX: TODO */
2906
        cpu_abort(env,
2907
                  "Performance counter exception is not implemented yet !\n");
2908
        goto store_next;
2909
    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
2910
        /* XXX: TODO */
2911
        cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2912
        goto store_next;
2913
    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
2914
        /* XXX: TODO */
2915
        cpu_abort(env,
2916
                  "970 soft-patch exception is not implemented yet !\n");
2917
        goto store_next;
2918
    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
2919
        /* XXX: TODO */
2920
        cpu_abort(env,
2921
                  "970 maintenance exception is not implemented yet !\n");
2922
        goto store_next;
2923
    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
2924
        /* XXX: TODO */
2925
        cpu_abort(env, "Maskable external exception "
2926
                  "is not implemented yet !\n");
2927
        goto store_next;
2928
    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
2929
        /* XXX: TODO */
2930
        cpu_abort(env, "Non maskable external exception "
2931
                  "is not implemented yet !\n");
2932
        goto store_next;
2933
    default:
2934
    excp_invalid:
2935
        cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
2936
        break;
2937
    store_current:
2938
        /* save current instruction location */
2939
        env->spr[srr0] = env->nip - 4;
2940
        break;
2941
    store_next:
2942
        /* save next instruction location */
2943
        env->spr[srr0] = env->nip;
2944
        break;
2945
    }
2946
    /* Save MSR */
2947
    env->spr[srr1] = msr;
2948
    /* If any alternate SRR register are defined, duplicate saved values */
2949
    if (asrr0 != -1)
2950
        env->spr[asrr0] = env->spr[srr0];
2951
    if (asrr1 != -1)
2952
        env->spr[asrr1] = env->spr[srr1];
2953
    /* If we disactivated any translation, flush TLBs */
2954
    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
2955
        tlb_flush(env, 1);
2956

    
2957
    if (msr_ile) {
2958
        new_msr |= (target_ulong)1 << MSR_LE;
2959
    }
2960

    
2961
    /* Jump to handler */
2962
    vector = env->excp_vectors[excp];
2963
    if (vector == (target_ulong)-1ULL) {
2964
        cpu_abort(env, "Raised an exception without defined vector %d\n",
2965
                  excp);
2966
    }
2967
    vector |= env->excp_prefix;
2968
#if defined(TARGET_PPC64)
2969
    if (excp_model == POWERPC_EXCP_BOOKE) {
2970
        if (!msr_icm) {
2971
            vector = (uint32_t)vector;
2972
        } else {
2973
            new_msr |= (target_ulong)1 << MSR_CM;
2974
        }
2975
    } else {
2976
        if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
2977
            vector = (uint32_t)vector;
2978
        } else {
2979
            new_msr |= (target_ulong)1 << MSR_SF;
2980
        }
2981
    }
2982
#endif
2983
    /* XXX: we don't use hreg_store_msr here as already have treated
2984
     *      any special case that could occur. Just store MSR and update hflags
2985
     */
2986
    env->msr = new_msr & env->msr_mask;
2987
    hreg_compute_hflags(env);
2988
    env->nip = vector;
2989
    /* Reset exception state */
2990
    env->exception_index = POWERPC_EXCP_NONE;
2991
    env->error_code = 0;
2992

    
2993
    if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
2994
        (env->mmu_model == POWERPC_MMU_BOOKE206)) {
2995
        /* XXX: The BookE changes address space when switching modes,
2996
                we should probably implement that as different MMU indexes,
2997
                but for the moment we do it the slow way and flush all.  */
2998
        tlb_flush(env, 1);
2999
    }
3000
}
3001

    
3002
void do_interrupt (CPUState *env)
3003
{
3004
    powerpc_excp(env, env->excp_model, env->exception_index);
3005
}
3006

    
3007
void ppc_hw_interrupt (CPUPPCState *env)
3008
{
3009
    int hdice;
3010

    
3011
#if 0
3012
    qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
3013
                __func__, env, env->pending_interrupts,
3014
                env->interrupt_request, (int)msr_me, (int)msr_ee);
3015
#endif
3016
    /* External reset */
3017
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
3018
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
3019
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
3020
        return;
3021
    }
3022
    /* Machine check exception */
3023
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
3024
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
3025
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
3026
        return;
3027
    }
3028
#if 0 /* TODO */
3029
    /* External debug exception */
3030
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
3031
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
3032
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
3033
        return;
3034
    }
3035
#endif
3036
    if (0) {
3037
        /* XXX: find a suitable condition to enable the hypervisor mode */
3038
        hdice = env->spr[SPR_LPCR] & 1;
3039
    } else {
3040
        hdice = 0;
3041
    }
3042
    if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
3043
        /* Hypervisor decrementer exception */
3044
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
3045
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
3046
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
3047
            return;
3048
        }
3049
    }
3050
    if (msr_ce != 0) {
3051
        /* External critical interrupt */
3052
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
3053
            /* Taking a critical external interrupt does not clear the external
3054
             * critical interrupt status
3055
             */
3056
#if 0
3057
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
3058
#endif
3059
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
3060
            return;
3061
        }
3062
    }
3063
    if (msr_ee != 0) {
3064
        /* Watchdog timer on embedded PowerPC */
3065
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
3066
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
3067
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
3068
            return;
3069
        }
3070
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
3071
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
3072
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
3073
            return;
3074
        }
3075
        /* Fixed interval timer on embedded PowerPC */
3076
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
3077
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
3078
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
3079
            return;
3080
        }
3081
        /* Programmable interval timer on embedded PowerPC */
3082
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
3083
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
3084
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
3085
            return;
3086
        }
3087
        /* Decrementer exception */
3088
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
3089
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
3090
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
3091
            return;
3092
        }
3093
        /* External interrupt */
3094
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
3095
            /* Taking an external interrupt does not clear the external
3096
             * interrupt status
3097
             */
3098
#if 0
3099
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
3100
#endif
3101
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
3102
            return;
3103
        }
3104
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
3105
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
3106
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
3107
            return;
3108
        }
3109
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
3110
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
3111
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
3112
            return;
3113
        }
3114
        /* Thermal interrupt */
3115
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
3116
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
3117
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
3118
            return;
3119
        }
3120
    }
3121
}
3122
#endif /* !CONFIG_USER_ONLY */
3123

    
3124
void cpu_dump_rfi (target_ulong RA, target_ulong msr)
3125
{
3126
    qemu_log("Return from exception at " TARGET_FMT_lx " with flags "
3127
             TARGET_FMT_lx "\n", RA, msr);
3128
}
3129

    
3130
void cpu_reset(CPUPPCState *env)
3131
{
3132
    target_ulong msr;
3133

    
3134
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
3135
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
3136
        log_cpu_state(env, 0);
3137
    }
3138

    
3139
    msr = (target_ulong)0;
3140
    if (0) {
3141
        /* XXX: find a suitable condition to enable the hypervisor mode */
3142
        msr |= (target_ulong)MSR_HVB;
3143
    }
3144
    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
3145
    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
3146
    msr |= (target_ulong)1 << MSR_EP;
3147
#if defined (DO_SINGLE_STEP) && 0
3148
    /* Single step trace mode */
3149
    msr |= (target_ulong)1 << MSR_SE;
3150
    msr |= (target_ulong)1 << MSR_BE;
3151
#endif
3152
#if defined(CONFIG_USER_ONLY)
3153
    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
3154
    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
3155
    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
3156
    msr |= (target_ulong)1 << MSR_PR;
3157
#else
3158
    env->excp_prefix = env->hreset_excp_prefix;
3159
    env->nip = env->hreset_vector | env->excp_prefix;
3160
    if (env->mmu_model != POWERPC_MMU_REAL)
3161
        ppc_tlb_invalidate_all(env);
3162
#endif
3163
    env->msr = msr & env->msr_mask;
3164
#if defined(TARGET_PPC64)
3165
    if (env->mmu_model & POWERPC_MMU_64)
3166
        env->msr |= (1ULL << MSR_SF);
3167
#endif
3168
    hreg_compute_hflags(env);
3169
    env->reserve_addr = (target_ulong)-1ULL;
3170
    /* Be sure no exception or interrupt is pending */
3171
    env->pending_interrupts = 0;
3172
    env->exception_index = POWERPC_EXCP_NONE;
3173
    env->error_code = 0;
3174
    /* Flush all TLBs */
3175
    tlb_flush(env, 1);
3176
}
3177

    
3178
CPUPPCState *cpu_ppc_init (const char *cpu_model)
3179
{
3180
    CPUPPCState *env;
3181
    const ppc_def_t *def;
3182

    
3183
    def = cpu_ppc_find_by_name(cpu_model);
3184
    if (!def)
3185
        return NULL;
3186

    
3187
    env = g_malloc0(sizeof(CPUPPCState));
3188
    cpu_exec_init(env);
3189
    if (tcg_enabled()) {
3190
        ppc_translate_init();
3191
    }
3192
    env->cpu_model_str = cpu_model;
3193
    cpu_ppc_register_internal(env, def);
3194

    
3195
    qemu_init_vcpu(env);
3196

    
3197
    return env;
3198
}
3199

    
3200
void cpu_ppc_close (CPUPPCState *env)
3201
{
3202
    /* Should also remove all opcode tables... */
3203
    g_free(env);
3204
}