Statistics
| Branch: | Revision:

root / target-ppc / helper.c @ 6ce0ca12

History | View | Annotate | Download (93.8 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, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <signal.h>
26
#include <assert.h>
27

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

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

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

    
50

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

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

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

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

    
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, int is_softmmu)
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
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
103
{
104
    return addr;
105
}
106

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

    
114
static always_inline void pte_invalidate (target_ulong *pte0)
115
{
116
    *pte0 &= ~0x80000000;
117
}
118

    
119
#if defined(TARGET_PPC64)
120
static always_inline int pte64_is_valid (target_ulong pte0)
121
{
122
    return pte0 & 0x0000000000000001ULL ? 1 : 0;
123
}
124

    
125
static always_inline void pte64_invalidate (target_ulong *pte0)
126
{
127
    *pte0 &= ~0x0000000000000001ULL;
128
}
129
#endif
130

    
131
#define PTE_PTEM_MASK 0x7FFFFFBF
132
#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
133
#if defined(TARGET_PPC64)
134
#define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
135
#define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
136
#endif
137

    
138
static always_inline int pp_check (int key, int pp, int nx)
139
{
140
    int access;
141

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

    
175
    return access;
176
}
177

    
178
static always_inline int check_prot (int prot, int rw, int access_type)
179
{
180
    int ret;
181

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

    
199
    return ret;
200
}
201

    
202
static always_inline int _pte_check (mmu_ctx_t *ctx, int is_64b,
203
                                     target_ulong pte0, target_ulong pte1,
204
                                     int h, int rw, int type)
205
{
206
    target_ulong ptem, mmask;
207
    int access, ret, pteh, ptev, pp;
208

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

    
262
    return ret;
263
}
264

    
265
static always_inline int pte32_check (mmu_ctx_t *ctx,
266
                                      target_ulong pte0, target_ulong pte1,
267
                                      int h, int rw, int type)
268
{
269
    return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
270
}
271

    
272
#if defined(TARGET_PPC64)
273
static always_inline int pte64_check (mmu_ctx_t *ctx,
274
                                      target_ulong pte0, target_ulong pte1,
275
                                      int h, int rw, int type)
276
{
277
    return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
278
}
279
#endif
280

    
281
static always_inline int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
282
                                           int ret, int rw)
283
{
284
    int store = 0;
285

    
286
    /* Update page flags */
287
    if (!(*pte1p & 0x00000100)) {
288
        /* Update accessed flag */
289
        *pte1p |= 0x00000100;
290
        store = 1;
291
    }
292
    if (!(*pte1p & 0x00000080)) {
293
        if (rw == 1 && ret == 0) {
294
            /* Update changed flag */
295
            *pte1p |= 0x00000080;
296
            store = 1;
297
        } else {
298
            /* Force page fault for first write access */
299
            ctx->prot &= ~PAGE_WRITE;
300
        }
301
    }
302

    
303
    return store;
304
}
305

    
306
/* Software driven TLB helpers */
307
static always_inline int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
308
                                            int way, int is_code)
309
{
310
    int nr;
311

    
312
    /* Select TLB num in a way from address */
313
    nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
314
    /* Select TLB way */
315
    nr += env->tlb_per_way * way;
316
    /* 6xx have separate TLBs for instructions and data */
317
    if (is_code && env->id_tlbs == 1)
318
        nr += env->nb_tlb;
319

    
320
    return nr;
321
}
322

    
323
static always_inline void ppc6xx_tlb_invalidate_all (CPUState *env)
324
{
325
    ppc6xx_tlb_t *tlb;
326
    int nr, max;
327

    
328
    //LOG_SWTLB("Invalidate all TLBs\n");
329
    /* Invalidate all defined software TLB */
330
    max = env->nb_tlb;
331
    if (env->id_tlbs == 1)
332
        max *= 2;
333
    for (nr = 0; nr < max; nr++) {
334
        tlb = &env->tlb[nr].tlb6;
335
        pte_invalidate(&tlb->pte0);
336
    }
337
    tlb_flush(env, 1);
338
}
339

    
340
static always_inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
341
                                                        target_ulong eaddr,
342
                                                        int is_code,
343
                                                        int match_epn)
344
{
345
#if !defined(FLUSH_ALL_TLBS)
346
    ppc6xx_tlb_t *tlb;
347
    int way, nr;
348

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

    
366
static always_inline void ppc6xx_tlb_invalidate_virt (CPUState *env,
367
                                                      target_ulong eaddr,
368
                                                      int is_code)
369
{
370
    __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
371
}
372

    
373
void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
374
                       target_ulong pte0, target_ulong pte1)
375
{
376
    ppc6xx_tlb_t *tlb;
377
    int nr;
378

    
379
    nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
380
    tlb = &env->tlb[nr].tlb6;
381
    LOG_SWTLB("Set TLB %d/%d EPN " ADDRX " PTE0 " ADDRX
382
                " PTE1 " ADDRX "\n", nr, env->nb_tlb, EPN, pte0, pte1);
383
    /* Invalidate any pending reference in Qemu for this virtual address */
384
    __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
385
    tlb->pte0 = pte0;
386
    tlb->pte1 = pte1;
387
    tlb->EPN = EPN;
388
    /* Store last way for LRU mechanism */
389
    env->last_way = way;
390
}
391

    
392
static always_inline int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
393
                                           target_ulong eaddr, int rw,
394
                                           int access_type)
395
{
396
    ppc6xx_tlb_t *tlb;
397
    int nr, best, way;
398
    int ret;
399

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

    
453
    return ret;
454
}
455

    
456
/* Perform BAT hit & translation */
457
static always_inline void bat_size_prot (CPUState *env, target_ulong *blp,
458
                                         int *validp, int *protp,
459
                                         target_ulong *BATu, target_ulong *BATl)
460
{
461
    target_ulong bl;
462
    int pp, valid, prot;
463

    
464
    bl = (*BATu & 0x00001FFC) << 15;
465
    valid = 0;
466
    prot = 0;
467
    if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
468
        ((msr_pr != 0) && (*BATu & 0x00000001))) {
469
        valid = 1;
470
        pp = *BATl & 0x00000003;
471
        if (pp != 0) {
472
            prot = PAGE_READ | PAGE_EXEC;
473
            if (pp == 0x2)
474
                prot |= PAGE_WRITE;
475
        }
476
    }
477
    *blp = bl;
478
    *validp = valid;
479
    *protp = prot;
480
}
481

    
482
static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp,
483
                                             int *validp, int *protp,
484
                                             target_ulong *BATu,
485
                                             target_ulong *BATl)
486
{
487
    target_ulong bl;
488
    int key, pp, valid, prot;
489

    
490
    bl = (*BATl & 0x0000003F) << 17;
491
    LOG_BATS("b %02x ==> bl " ADDRX " msk " ADDRX "\n",
492
                (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
493
    prot = 0;
494
    valid = (*BATl >> 6) & 1;
495
    if (valid) {
496
        pp = *BATu & 0x00000003;
497
        if (msr_pr == 0)
498
            key = (*BATu >> 3) & 1;
499
        else
500
            key = (*BATu >> 2) & 1;
501
        prot = pp_check(key, pp, 0);
502
    }
503
    *blp = bl;
504
    *validp = valid;
505
    *protp = prot;
506
}
507

    
508
static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
509
                                  target_ulong virtual, int rw, int type)
510
{
511
    target_ulong *BATlt, *BATut, *BATu, *BATl;
512
    target_ulong base, BEPIl, BEPIu, bl;
513
    int i, valid, prot;
514
    int ret = -1;
515

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

    
583
/* PTE table lookup */
584
static always_inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h,
585
                                    int rw, int type,
586
                                    int target_page_bits)
587
{
588
    target_ulong base, pte0, pte1;
589
    int i, good = -1;
590
    int ret, r;
591

    
592
    ret = -1; /* No entry found */
593
    base = ctx->pg_addr[h];
594
    for (i = 0; i < 8; i++) {
595
#if defined(TARGET_PPC64)
596
        if (is_64b) {
597
            pte0 = ldq_phys(base + (i * 16));
598
            pte1 = ldq_phys(base + (i * 16) + 8);
599

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

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

    
666
    return ret;
667
}
668

    
669
static always_inline int find_pte32 (mmu_ctx_t *ctx, int h, int rw,
670
                                     int type, int target_page_bits)
671
{
672
    return _find_pte(ctx, 0, h, rw, type, target_page_bits);
673
}
674

    
675
#if defined(TARGET_PPC64)
676
static always_inline int find_pte64 (mmu_ctx_t *ctx, int h, int rw,
677
                                     int type, int target_page_bits)
678
{
679
    return _find_pte(ctx, 1, h, rw, type, target_page_bits);
680
}
681
#endif
682

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

    
692
    return find_pte32(ctx, h, rw, type, target_page_bits);
693
}
694

    
695
#if defined(TARGET_PPC64)
696
static always_inline int slb_is_valid (uint64_t slb64)
697
{
698
    return slb64 & 0x0000000008000000ULL ? 1 : 0;
699
}
700

    
701
static always_inline void slb_invalidate (uint64_t *slb64)
702
{
703
    *slb64 &= ~0x0000000008000000ULL;
704
}
705

    
706
static always_inline int slb_lookup (CPUPPCState *env, target_ulong eaddr,
707
                                     target_ulong *vsid,
708
                                     target_ulong *page_mask, int *attr,
709
                                     int *target_page_bits)
710
{
711
    target_phys_addr_t sr_base;
712
    target_ulong mask;
713
    uint64_t tmp64;
714
    uint32_t tmp;
715
    int n, ret;
716

    
717
    ret = -5;
718
    sr_base = env->spr[SPR_ASR];
719
    LOG_SLB("%s: eaddr " ADDRX " base " PADDRX "\n",
720
                __func__, eaddr, sr_base);
721
    mask = 0x0000000000000000ULL; /* Avoid gcc warning */
722
    for (n = 0; n < env->slb_nr; n++) {
723
        tmp64 = ldq_phys(sr_base);
724
        tmp = ldl_phys(sr_base + 8);
725
        LOG_SLB("%s: seg %d " PADDRX " %016" PRIx64 " %08"
726
                    PRIx32 "\n", __func__, n, sr_base, tmp64, tmp);
727
        if (slb_is_valid(tmp64)) {
728
            /* SLB entry is valid */
729
            if (tmp & 0x8) {
730
                /* 1 TB Segment */
731
                mask = 0xFFFF000000000000ULL;
732
                if (target_page_bits)
733
                    *target_page_bits = 24; // XXX 16M pages?
734
            } else {
735
                /* 256MB Segment */
736
                mask = 0xFFFFFFFFF0000000ULL;
737
                if (target_page_bits)
738
                    *target_page_bits = TARGET_PAGE_BITS;
739
            }
740
            if ((eaddr & mask) == (tmp64 & mask)) {
741
                /* SLB match */
742
                *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;
743
                *page_mask = ~mask;
744
                *attr = tmp & 0xFF;
745
                ret = n;
746
                break;
747
            }
748
        }
749
        sr_base += 12;
750
    }
751

    
752
    return ret;
753
}
754

    
755
void ppc_slb_invalidate_all (CPUPPCState *env)
756
{
757
    target_phys_addr_t sr_base;
758
    uint64_t tmp64;
759
    int n, do_invalidate;
760

    
761
    do_invalidate = 0;
762
    sr_base = env->spr[SPR_ASR];
763
    /* XXX: Warning: slbia never invalidates the first segment */
764
    for (n = 1; n < env->slb_nr; n++) {
765
        tmp64 = ldq_phys(sr_base);
766
        if (slb_is_valid(tmp64)) {
767
            slb_invalidate(&tmp64);
768
            stq_phys(sr_base, tmp64);
769
            /* XXX: given the fact that segment size is 256 MB or 1TB,
770
             *      and we still don't have a tlb_flush_mask(env, n, mask)
771
             *      in Qemu, we just invalidate all TLBs
772
             */
773
            do_invalidate = 1;
774
        }
775
        sr_base += 12;
776
    }
777
    if (do_invalidate)
778
        tlb_flush(env, 1);
779
}
780

    
781
void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
782
{
783
    target_phys_addr_t sr_base;
784
    target_ulong vsid, page_mask;
785
    uint64_t tmp64;
786
    int attr;
787
    int n;
788

    
789
    n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL);
790
    if (n >= 0) {
791
        sr_base = env->spr[SPR_ASR];
792
        sr_base += 12 * n;
793
        tmp64 = ldq_phys(sr_base);
794
        if (slb_is_valid(tmp64)) {
795
            slb_invalidate(&tmp64);
796
            stq_phys(sr_base, tmp64);
797
            /* XXX: given the fact that segment size is 256 MB or 1TB,
798
             *      and we still don't have a tlb_flush_mask(env, n, mask)
799
             *      in Qemu, we just invalidate all TLBs
800
             */
801
            tlb_flush(env, 1);
802
        }
803
    }
804
}
805

    
806
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
807
{
808
    target_phys_addr_t sr_base;
809
    target_ulong rt;
810
    uint64_t tmp64;
811
    uint32_t tmp;
812

    
813
    sr_base = env->spr[SPR_ASR];
814
    sr_base += 12 * slb_nr;
815
    tmp64 = ldq_phys(sr_base);
816
    tmp = ldl_phys(sr_base + 8);
817
    if (tmp64 & 0x0000000008000000ULL) {
818
        /* SLB entry is valid */
819
        /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */
820
        rt = tmp >> 8;             /* 65:88 => 40:63 */
821
        rt |= (tmp64 & 0x7) << 24; /* 62:64 => 37:39 */
822
        /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */
823
        rt |= ((tmp >> 4) & 0xF) << 27;
824
    } else {
825
        rt = 0;
826
    }
827
    LOG_SLB("%s: " PADDRX " %016" PRIx64 " %08" PRIx32 " => %d "
828
                ADDRX "\n", __func__, sr_base, tmp64, tmp, slb_nr, rt);
829

    
830
    return rt;
831
}
832

    
833
void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
834
{
835
    target_phys_addr_t sr_base;
836
    uint64_t tmp64;
837
    uint32_t tmp;
838

    
839
    uint64_t vsid;
840
    uint64_t esid;
841
    int flags, valid, slb_nr;
842

    
843
    vsid = rs >> 12;
844
    flags = ((rs >> 8) & 0xf);
845

    
846
    esid = rb >> 28;
847
    valid = (rb & (1 << 27));
848
    slb_nr = rb & 0xfff;
849

    
850
    tmp64 = (esid << 28) | valid | (vsid >> 24);
851
    tmp = (vsid << 8) | (flags << 3);
852

    
853
    /* Write SLB entry to memory */
854
    sr_base = env->spr[SPR_ASR];
855
    sr_base += 12 * slb_nr;
856

    
857
    LOG_SLB("%s: %d " ADDRX " - " ADDRX " => " PADDRX " %016" PRIx64
858
                " %08" PRIx32 "\n", __func__,
859
                slb_nr, rb, rs, sr_base, tmp64, tmp);
860

    
861
    stq_phys(sr_base, tmp64);
862
    stl_phys(sr_base + 8, tmp);
863
}
864
#endif /* defined(TARGET_PPC64) */
865

    
866
/* Perform segment based translation */
867
static always_inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
868
                                                    int sdr_sh,
869
                                                    target_phys_addr_t hash,
870
                                                    target_phys_addr_t mask)
871
{
872
    return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask);
873
}
874

    
875
static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
876
                                      target_ulong eaddr, int rw, int type)
877
{
878
    target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
879
    target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
880
#if defined(TARGET_PPC64)
881
    int attr;
882
#endif
883
    int ds, vsid_sh, sdr_sh, pr, target_page_bits;
884
    int ret, ret2;
885

    
886
    pr = msr_pr;
887
#if defined(TARGET_PPC64)
888
    if (env->mmu_model & POWERPC_MMU_64) {
889
        LOG_MMU("Check SLBs\n");
890
        ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr,
891
                         &target_page_bits);
892
        if (ret < 0)
893
            return ret;
894
        ctx->key = ((attr & 0x40) && (pr != 0)) ||
895
            ((attr & 0x80) && (pr == 0)) ? 1 : 0;
896
        ds = 0;
897
        ctx->nx = attr & 0x10 ? 1 : 0;
898
        ctx->eaddr = eaddr;
899
        vsid_mask = 0x00003FFFFFFFFF80ULL;
900
        vsid_sh = 7;
901
        sdr_sh = 18;
902
        sdr_mask = 0x3FF80;
903
    } else
904
#endif /* defined(TARGET_PPC64) */
905
    {
906
        sr = env->sr[eaddr >> 28];
907
        page_mask = 0x0FFFFFFF;
908
        ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
909
                    ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
910
        ds = sr & 0x80000000 ? 1 : 0;
911
        ctx->nx = sr & 0x10000000 ? 1 : 0;
912
        vsid = sr & 0x00FFFFFF;
913
        vsid_mask = 0x01FFFFC0;
914
        vsid_sh = 6;
915
        sdr_sh = 16;
916
        sdr_mask = 0xFFC0;
917
        target_page_bits = TARGET_PAGE_BITS;
918
        LOG_MMU("Check segment v=" ADDRX " %d " ADDRX
919
                    " nip=" ADDRX " lr=" ADDRX " ir=%d dr=%d pr=%d %d t=%d\n",
920
                    eaddr, (int)(eaddr >> 28), sr, env->nip,
921
                    env->lr, (int)msr_ir, (int)msr_dr, pr != 0 ? 1 : 0,
922
                    rw, type);
923
    }
924
    LOG_MMU("pte segment: key=%d ds %d nx %d vsid " ADDRX "\n",
925
                ctx->key, ds, ctx->nx, vsid);
926
    ret = -1;
927
    if (!ds) {
928
        /* Check if instruction fetch is allowed, if needed */
929
        if (type != ACCESS_CODE || ctx->nx == 0) {
930
            /* Page address translation */
931
            /* Primary table address */
932
            sdr = env->sdr1;
933
            pgidx = (eaddr & page_mask) >> target_page_bits;
934
#if defined(TARGET_PPC64)
935
            if (env->mmu_model & POWERPC_MMU_64) {
936
                htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
937
                /* XXX: this is false for 1 TB segments */
938
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
939
            } else
940
#endif
941
            {
942
                htab_mask = sdr & 0x000001FF;
943
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
944
            }
945
            mask = (htab_mask << sdr_sh) | sdr_mask;
946
            LOG_MMU("sdr " PADDRX " sh %d hash " PADDRX
947
                        " mask " PADDRX " " ADDRX "\n",
948
                        sdr, sdr_sh, hash, mask, page_mask);
949
            ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
950
            /* Secondary table address */
951
            hash = (~hash) & vsid_mask;
952
            LOG_MMU("sdr " PADDRX " sh %d hash " PADDRX
953
                        " mask " PADDRX "\n",
954
                        sdr, sdr_sh, hash, mask);
955
            ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
956
#if defined(TARGET_PPC64)
957
            if (env->mmu_model & POWERPC_MMU_64) {
958
                /* Only 5 bits of the page index are used in the AVPN */
959
                if (target_page_bits > 23) {
960
                    ctx->ptem = (vsid << 12) |
961
                                ((pgidx << (target_page_bits - 16)) & 0xF80);
962
                } else {
963
                    ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
964
                }
965
            } else
966
#endif
967
            {
968
                ctx->ptem = (vsid << 7) | (pgidx >> 10);
969
            }
970
            /* Initialize real address with an invalid value */
971
            ctx->raddr = (target_phys_addr_t)-1ULL;
972
            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
973
                         env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
974
                /* Software TLB search */
975
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
976
            } else {
977
                LOG_MMU("0 sdr1=" PADDRX " vsid=" ADDRX " "
978
                            "api=" ADDRX " hash=" PADDRX
979
                            " pg_addr=" PADDRX "\n",
980
                            sdr, vsid, pgidx, hash, ctx->pg_addr[0]);
981
                /* Primary table lookup */
982
                ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
983
                if (ret < 0) {
984
                    /* Secondary table lookup */
985
                    if (eaddr != 0xEFFFFFFF)
986
                        LOG_MMU("1 sdr1=" PADDRX " vsid=" ADDRX " "
987
                                "api=" ADDRX " hash=" PADDRX
988
                                " pg_addr=" PADDRX "\n",
989
                                sdr, vsid, pgidx, hash, ctx->pg_addr[1]);
990
                    ret2 = find_pte(env, ctx, 1, rw, type,
991
                                    target_page_bits);
992
                    if (ret2 != -1)
993
                        ret = ret2;
994
                }
995
            }
996
#if defined (DUMP_PAGE_TABLES)
997
            if (qemu_log_enabled()) {
998
                target_phys_addr_t curaddr;
999
                uint32_t a0, a1, a2, a3;
1000
                qemu_log("Page table: " PADDRX " len " PADDRX "\n",
1001
                          sdr, mask + 0x80);
1002
                for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
1003
                     curaddr += 16) {
1004
                    a0 = ldl_phys(curaddr);
1005
                    a1 = ldl_phys(curaddr + 4);
1006
                    a2 = ldl_phys(curaddr + 8);
1007
                    a3 = ldl_phys(curaddr + 12);
1008
                    if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
1009
                        qemu_log(PADDRX ": %08x %08x %08x %08x\n",
1010
                                  curaddr, a0, a1, a2, a3);
1011
                    }
1012
                }
1013
            }
1014
#endif
1015
        } else {
1016
            LOG_MMU("No access allowed\n");
1017
            ret = -3;
1018
        }
1019
    } else {
1020
        LOG_MMU("direct store...\n");
1021
        /* Direct-store segment : absolutely *BUGGY* for now */
1022
        switch (type) {
1023
        case ACCESS_INT:
1024
            /* Integer load/store : only access allowed */
1025
            break;
1026
        case ACCESS_CODE:
1027
            /* No code fetch is allowed in direct-store areas */
1028
            return -4;
1029
        case ACCESS_FLOAT:
1030
            /* Floating point load/store */
1031
            return -4;
1032
        case ACCESS_RES:
1033
            /* lwarx, ldarx or srwcx. */
1034
            return -4;
1035
        case ACCESS_CACHE:
1036
            /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
1037
            /* Should make the instruction do no-op.
1038
             * As it already do no-op, it's quite easy :-)
1039
             */
1040
            ctx->raddr = eaddr;
1041
            return 0;
1042
        case ACCESS_EXT:
1043
            /* eciwx or ecowx */
1044
            return -4;
1045
        default:
1046
            qemu_log("ERROR: instruction should not need "
1047
                        "address translation\n");
1048
            return -4;
1049
        }
1050
        if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
1051
            ctx->raddr = eaddr;
1052
            ret = 2;
1053
        } else {
1054
            ret = -2;
1055
        }
1056
    }
1057

    
1058
    return ret;
1059
}
1060

    
1061
/* Generic TLB check function for embedded PowerPC implementations */
1062
static always_inline int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
1063
                                           target_phys_addr_t *raddrp,
1064
                                           target_ulong address,
1065
                                           uint32_t pid, int ext, int i)
1066
{
1067
    target_ulong mask;
1068

    
1069
    /* Check valid flag */
1070
    if (!(tlb->prot & PAGE_VALID)) {
1071
        qemu_log("%s: TLB %d not valid\n", __func__, i);
1072
        return -1;
1073
    }
1074
    mask = ~(tlb->size - 1);
1075
    LOG_SWTLB("%s: TLB %d address " ADDRX " PID %u <=> " ADDRX
1076
                " " ADDRX " %u\n",
1077
                __func__, i, address, pid, tlb->EPN, mask, (uint32_t)tlb->PID);
1078
    /* Check PID */
1079
    if (tlb->PID != 0 && tlb->PID != pid)
1080
        return -1;
1081
    /* Check effective address */
1082
    if ((address & mask) != tlb->EPN)
1083
        return -1;
1084
    *raddrp = (tlb->RPN & mask) | (address & ~mask);
1085
#if (TARGET_PHYS_ADDR_BITS >= 36)
1086
    if (ext) {
1087
        /* Extend the physical address to 36 bits */
1088
        *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
1089
    }
1090
#endif
1091

    
1092
    return 0;
1093
}
1094

    
1095
/* Generic TLB search function for PowerPC embedded implementations */
1096
int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
1097
{
1098
    ppcemb_tlb_t *tlb;
1099
    target_phys_addr_t raddr;
1100
    int i, ret;
1101

    
1102
    /* Default return value is no match */
1103
    ret = -1;
1104
    for (i = 0; i < env->nb_tlb; i++) {
1105
        tlb = &env->tlb[i].tlbe;
1106
        if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
1107
            ret = i;
1108
            break;
1109
        }
1110
    }
1111

    
1112
    return ret;
1113
}
1114

    
1115
/* Helpers specific to PowerPC 40x implementations */
1116
static always_inline void ppc4xx_tlb_invalidate_all (CPUState *env)
1117
{
1118
    ppcemb_tlb_t *tlb;
1119
    int i;
1120

    
1121
    for (i = 0; i < env->nb_tlb; i++) {
1122
        tlb = &env->tlb[i].tlbe;
1123
        tlb->prot &= ~PAGE_VALID;
1124
    }
1125
    tlb_flush(env, 1);
1126
}
1127

    
1128
static always_inline void ppc4xx_tlb_invalidate_virt (CPUState *env,
1129
                                                      target_ulong eaddr,
1130
                                                      uint32_t pid)
1131
{
1132
#if !defined(FLUSH_ALL_TLBS)
1133
    ppcemb_tlb_t *tlb;
1134
    target_phys_addr_t raddr;
1135
    target_ulong page, end;
1136
    int i;
1137

    
1138
    for (i = 0; i < env->nb_tlb; i++) {
1139
        tlb = &env->tlb[i].tlbe;
1140
        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
1141
            end = tlb->EPN + tlb->size;
1142
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
1143
                tlb_flush_page(env, page);
1144
            tlb->prot &= ~PAGE_VALID;
1145
            break;
1146
        }
1147
    }
1148
#else
1149
    ppc4xx_tlb_invalidate_all(env);
1150
#endif
1151
}
1152

    
1153
static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1154
                                 target_ulong address, int rw, int access_type)
1155
{
1156
    ppcemb_tlb_t *tlb;
1157
    target_phys_addr_t raddr;
1158
    int i, ret, zsel, zpr, pr;
1159

    
1160
    ret = -1;
1161
    raddr = (target_phys_addr_t)-1ULL;
1162
    pr = msr_pr;
1163
    for (i = 0; i < env->nb_tlb; i++) {
1164
        tlb = &env->tlb[i].tlbe;
1165
        if (ppcemb_tlb_check(env, tlb, &raddr, address,
1166
                             env->spr[SPR_40x_PID], 0, i) < 0)
1167
            continue;
1168
        zsel = (tlb->attr >> 4) & 0xF;
1169
        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
1170
        LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1171
                    __func__, i, zsel, zpr, rw, tlb->attr);
1172
        /* Check execute enable bit */
1173
        switch (zpr) {
1174
        case 0x2:
1175
            if (pr != 0)
1176
                goto check_perms;
1177
            /* No break here */
1178
        case 0x3:
1179
            /* All accesses granted */
1180
            ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1181
            ret = 0;
1182
            break;
1183
        case 0x0:
1184
            if (pr != 0) {
1185
                ctx->prot = 0;
1186
                ret = -2;
1187
                break;
1188
            }
1189
            /* No break here */
1190
        case 0x1:
1191
        check_perms:
1192
            /* Check from TLB entry */
1193
            /* XXX: there is a problem here or in the TLB fill code... */
1194
            ctx->prot = tlb->prot;
1195
            ctx->prot |= PAGE_EXEC;
1196
            ret = check_prot(ctx->prot, rw, access_type);
1197
            break;
1198
        }
1199
        if (ret >= 0) {
1200
            ctx->raddr = raddr;
1201
            LOG_SWTLB("%s: access granted " ADDRX " => " PADDRX
1202
                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1203
                        ret);
1204
            return 0;
1205
        }
1206
    }
1207
    LOG_SWTLB("%s: access refused " ADDRX " => " PADDRX
1208
                " %d %d\n", __func__, address, raddr, ctx->prot,
1209
                ret);
1210

    
1211
    return ret;
1212
}
1213

    
1214
void store_40x_sler (CPUPPCState *env, uint32_t val)
1215
{
1216
    /* XXX: TO BE FIXED */
1217
    if (val != 0x00000000) {
1218
        cpu_abort(env, "Little-endian regions are not supported by now\n");
1219
    }
1220
    env->spr[SPR_405_SLER] = val;
1221
}
1222

    
1223
static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1224
                                          target_ulong address, int rw,
1225
                                          int access_type)
1226
{
1227
    ppcemb_tlb_t *tlb;
1228
    target_phys_addr_t raddr;
1229
    int i, prot, ret;
1230

    
1231
    ret = -1;
1232
    raddr = (target_phys_addr_t)-1ULL;
1233
    for (i = 0; i < env->nb_tlb; i++) {
1234
        tlb = &env->tlb[i].tlbe;
1235
        if (ppcemb_tlb_check(env, tlb, &raddr, address,
1236
                             env->spr[SPR_BOOKE_PID], 1, i) < 0)
1237
            continue;
1238
        if (msr_pr != 0)
1239
            prot = tlb->prot & 0xF;
1240
        else
1241
            prot = (tlb->prot >> 4) & 0xF;
1242
        /* Check the address space */
1243
        if (access_type == ACCESS_CODE) {
1244
            if (msr_ir != (tlb->attr & 1))
1245
                continue;
1246
            ctx->prot = prot;
1247
            if (prot & PAGE_EXEC) {
1248
                ret = 0;
1249
                break;
1250
            }
1251
            ret = -3;
1252
        } else {
1253
            if (msr_dr != (tlb->attr & 1))
1254
                continue;
1255
            ctx->prot = prot;
1256
            if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) {
1257
                ret = 0;
1258
                break;
1259
            }
1260
            ret = -2;
1261
        }
1262
    }
1263
    if (ret >= 0)
1264
        ctx->raddr = raddr;
1265

    
1266
    return ret;
1267
}
1268

    
1269
static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
1270
                                         target_ulong eaddr, int rw)
1271
{
1272
    int in_plb, ret;
1273

    
1274
    ctx->raddr = eaddr;
1275
    ctx->prot = PAGE_READ | PAGE_EXEC;
1276
    ret = 0;
1277
    switch (env->mmu_model) {
1278
    case POWERPC_MMU_32B:
1279
    case POWERPC_MMU_601:
1280
    case POWERPC_MMU_SOFT_6xx:
1281
    case POWERPC_MMU_SOFT_74xx:
1282
    case POWERPC_MMU_SOFT_4xx:
1283
    case POWERPC_MMU_REAL:
1284
    case POWERPC_MMU_BOOKE:
1285
        ctx->prot |= PAGE_WRITE;
1286
        break;
1287
#if defined(TARGET_PPC64)
1288
    case POWERPC_MMU_620:
1289
    case POWERPC_MMU_64B:
1290
        /* Real address are 60 bits long */
1291
        ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1292
        ctx->prot |= PAGE_WRITE;
1293
        break;
1294
#endif
1295
    case POWERPC_MMU_SOFT_4xx_Z:
1296
        if (unlikely(msr_pe != 0)) {
1297
            /* 403 family add some particular protections,
1298
             * using PBL/PBU registers for accesses with no translation.
1299
             */
1300
            in_plb =
1301
                /* Check PLB validity */
1302
                (env->pb[0] < env->pb[1] &&
1303
                 /* and address in plb area */
1304
                 eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
1305
                (env->pb[2] < env->pb[3] &&
1306
                 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
1307
            if (in_plb ^ msr_px) {
1308
                /* Access in protected area */
1309
                if (rw == 1) {
1310
                    /* Access is not allowed */
1311
                    ret = -2;
1312
                }
1313
            } else {
1314
                /* Read-write access is allowed */
1315
                ctx->prot |= PAGE_WRITE;
1316
            }
1317
        }
1318
        break;
1319
    case POWERPC_MMU_MPC8xx:
1320
        /* XXX: TODO */
1321
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1322
        break;
1323
    case POWERPC_MMU_BOOKE_FSL:
1324
        /* XXX: TODO */
1325
        cpu_abort(env, "BookE FSL MMU model not implemented\n");
1326
        break;
1327
    default:
1328
        cpu_abort(env, "Unknown or invalid MMU model\n");
1329
        return -1;
1330
    }
1331

    
1332
    return ret;
1333
}
1334

    
1335
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1336
                          int rw, int access_type)
1337
{
1338
    int ret;
1339

    
1340
#if 0
1341
    qemu_log("%s\n", __func__);
1342
#endif
1343
    if ((access_type == ACCESS_CODE && msr_ir == 0) ||
1344
        (access_type != ACCESS_CODE && msr_dr == 0)) {
1345
        /* No address translation */
1346
        ret = check_physical(env, ctx, eaddr, rw);
1347
    } else {
1348
        ret = -1;
1349
        switch (env->mmu_model) {
1350
        case POWERPC_MMU_32B:
1351
        case POWERPC_MMU_601:
1352
        case POWERPC_MMU_SOFT_6xx:
1353
        case POWERPC_MMU_SOFT_74xx:
1354
#if defined(TARGET_PPC64)
1355
        case POWERPC_MMU_620:
1356
        case POWERPC_MMU_64B:
1357
#endif
1358
            /* Try to find a BAT */
1359
            if (env->nb_BATs != 0)
1360
                ret = get_bat(env, ctx, eaddr, rw, access_type);
1361
            if (ret < 0) {
1362
                /* We didn't match any BAT entry or don't have BATs */
1363
                ret = get_segment(env, ctx, eaddr, rw, access_type);
1364
            }
1365
            break;
1366
        case POWERPC_MMU_SOFT_4xx:
1367
        case POWERPC_MMU_SOFT_4xx_Z:
1368
            ret = mmu40x_get_physical_address(env, ctx, eaddr,
1369
                                              rw, access_type);
1370
            break;
1371
        case POWERPC_MMU_BOOKE:
1372
            ret = mmubooke_get_physical_address(env, ctx, eaddr,
1373
                                                rw, access_type);
1374
            break;
1375
        case POWERPC_MMU_MPC8xx:
1376
            /* XXX: TODO */
1377
            cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1378
            break;
1379
        case POWERPC_MMU_BOOKE_FSL:
1380
            /* XXX: TODO */
1381
            cpu_abort(env, "BookE FSL MMU model not implemented\n");
1382
            return -1;
1383
        case POWERPC_MMU_REAL:
1384
            cpu_abort(env, "PowerPC in real mode do not do any translation\n");
1385
            return -1;
1386
        default:
1387
            cpu_abort(env, "Unknown or invalid MMU model\n");
1388
            return -1;
1389
        }
1390
    }
1391
#if 0
1392
    qemu_log("%s address " ADDRX " => %d " PADDRX "\n",
1393
                __func__, eaddr, ret, ctx->raddr);
1394
#endif
1395

    
1396
    return ret;
1397
}
1398

    
1399
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1400
{
1401
    mmu_ctx_t ctx;
1402

    
1403
    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1404
        return -1;
1405

    
1406
    return ctx.raddr & TARGET_PAGE_MASK;
1407
}
1408

    
1409
/* Perform address translation */
1410
int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1411
                              int mmu_idx, int is_softmmu)
1412
{
1413
    mmu_ctx_t ctx;
1414
    int access_type;
1415
    int ret = 0;
1416

    
1417
    if (rw == 2) {
1418
        /* code access */
1419
        rw = 0;
1420
        access_type = ACCESS_CODE;
1421
    } else {
1422
        /* data access */
1423
        access_type = env->access_type;
1424
    }
1425
    ret = get_physical_address(env, &ctx, address, rw, access_type);
1426
    if (ret == 0) {
1427
        ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
1428
                                ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1429
                                mmu_idx, is_softmmu);
1430
    } else if (ret < 0) {
1431
        LOG_MMU_STATE(env);
1432
        if (access_type == ACCESS_CODE) {
1433
            switch (ret) {
1434
            case -1:
1435
                /* No matches in page tables or TLB */
1436
                switch (env->mmu_model) {
1437
                case POWERPC_MMU_SOFT_6xx:
1438
                    env->exception_index = POWERPC_EXCP_IFTLB;
1439
                    env->error_code = 1 << 18;
1440
                    env->spr[SPR_IMISS] = address;
1441
                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1442
                    goto tlb_miss;
1443
                case POWERPC_MMU_SOFT_74xx:
1444
                    env->exception_index = POWERPC_EXCP_IFTLB;
1445
                    goto tlb_miss_74xx;
1446
                case POWERPC_MMU_SOFT_4xx:
1447
                case POWERPC_MMU_SOFT_4xx_Z:
1448
                    env->exception_index = POWERPC_EXCP_ITLB;
1449
                    env->error_code = 0;
1450
                    env->spr[SPR_40x_DEAR] = address;
1451
                    env->spr[SPR_40x_ESR] = 0x00000000;
1452
                    break;
1453
                case POWERPC_MMU_32B:
1454
                case POWERPC_MMU_601:
1455
#if defined(TARGET_PPC64)
1456
                case POWERPC_MMU_620:
1457
                case POWERPC_MMU_64B:
1458
#endif
1459
                    env->exception_index = POWERPC_EXCP_ISI;
1460
                    env->error_code = 0x40000000;
1461
                    break;
1462
                case POWERPC_MMU_BOOKE:
1463
                    /* XXX: TODO */
1464
                    cpu_abort(env, "BookE MMU model is not implemented\n");
1465
                    return -1;
1466
                case POWERPC_MMU_BOOKE_FSL:
1467
                    /* XXX: TODO */
1468
                    cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1469
                    return -1;
1470
                case POWERPC_MMU_MPC8xx:
1471
                    /* XXX: TODO */
1472
                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1473
                    break;
1474
                case POWERPC_MMU_REAL:
1475
                    cpu_abort(env, "PowerPC in real mode should never raise "
1476
                              "any MMU exceptions\n");
1477
                    return -1;
1478
                default:
1479
                    cpu_abort(env, "Unknown or invalid MMU model\n");
1480
                    return -1;
1481
                }
1482
                break;
1483
            case -2:
1484
                /* Access rights violation */
1485
                env->exception_index = POWERPC_EXCP_ISI;
1486
                env->error_code = 0x08000000;
1487
                break;
1488
            case -3:
1489
                /* No execute protection violation */
1490
                env->exception_index = POWERPC_EXCP_ISI;
1491
                env->error_code = 0x10000000;
1492
                break;
1493
            case -4:
1494
                /* Direct store exception */
1495
                /* No code fetch is allowed in direct-store areas */
1496
                env->exception_index = POWERPC_EXCP_ISI;
1497
                env->error_code = 0x10000000;
1498
                break;
1499
#if defined(TARGET_PPC64)
1500
            case -5:
1501
                /* No match in segment table */
1502
                if (env->mmu_model == POWERPC_MMU_620) {
1503
                    env->exception_index = POWERPC_EXCP_ISI;
1504
                    /* XXX: this might be incorrect */
1505
                    env->error_code = 0x40000000;
1506
                } else {
1507
                    env->exception_index = POWERPC_EXCP_ISEG;
1508
                    env->error_code = 0;
1509
                }
1510
                break;
1511
#endif
1512
            }
1513
        } else {
1514
            switch (ret) {
1515
            case -1:
1516
                /* No matches in page tables or TLB */
1517
                switch (env->mmu_model) {
1518
                case POWERPC_MMU_SOFT_6xx:
1519
                    if (rw == 1) {
1520
                        env->exception_index = POWERPC_EXCP_DSTLB;
1521
                        env->error_code = 1 << 16;
1522
                    } else {
1523
                        env->exception_index = POWERPC_EXCP_DLTLB;
1524
                        env->error_code = 0;
1525
                    }
1526
                    env->spr[SPR_DMISS] = address;
1527
                    env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1528
                tlb_miss:
1529
                    env->error_code |= ctx.key << 19;
1530
                    env->spr[SPR_HASH1] = ctx.pg_addr[0];
1531
                    env->spr[SPR_HASH2] = ctx.pg_addr[1];
1532
                    break;
1533
                case POWERPC_MMU_SOFT_74xx:
1534
                    if (rw == 1) {
1535
                        env->exception_index = POWERPC_EXCP_DSTLB;
1536
                    } else {
1537
                        env->exception_index = POWERPC_EXCP_DLTLB;
1538
                    }
1539
                tlb_miss_74xx:
1540
                    /* Implement LRU algorithm */
1541
                    env->error_code = ctx.key << 19;
1542
                    env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
1543
                        ((env->last_way + 1) & (env->nb_ways - 1));
1544
                    env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1545
                    break;
1546
                case POWERPC_MMU_SOFT_4xx:
1547
                case POWERPC_MMU_SOFT_4xx_Z:
1548
                    env->exception_index = POWERPC_EXCP_DTLB;
1549
                    env->error_code = 0;
1550
                    env->spr[SPR_40x_DEAR] = address;
1551
                    if (rw)
1552
                        env->spr[SPR_40x_ESR] = 0x00800000;
1553
                    else
1554
                        env->spr[SPR_40x_ESR] = 0x00000000;
1555
                    break;
1556
                case POWERPC_MMU_32B:
1557
                case POWERPC_MMU_601:
1558
#if defined(TARGET_PPC64)
1559
                case POWERPC_MMU_620:
1560
                case POWERPC_MMU_64B:
1561
#endif
1562
                    env->exception_index = POWERPC_EXCP_DSI;
1563
                    env->error_code = 0;
1564
                    env->spr[SPR_DAR] = address;
1565
                    if (rw == 1)
1566
                        env->spr[SPR_DSISR] = 0x42000000;
1567
                    else
1568
                        env->spr[SPR_DSISR] = 0x40000000;
1569
                    break;
1570
                case POWERPC_MMU_MPC8xx:
1571
                    /* XXX: TODO */
1572
                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1573
                    break;
1574
                case POWERPC_MMU_BOOKE:
1575
                    /* XXX: TODO */
1576
                    cpu_abort(env, "BookE MMU model is not implemented\n");
1577
                    return -1;
1578
                case POWERPC_MMU_BOOKE_FSL:
1579
                    /* XXX: TODO */
1580
                    cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1581
                    return -1;
1582
                case POWERPC_MMU_REAL:
1583
                    cpu_abort(env, "PowerPC in real mode should never raise "
1584
                              "any MMU exceptions\n");
1585
                    return -1;
1586
                default:
1587
                    cpu_abort(env, "Unknown or invalid MMU model\n");
1588
                    return -1;
1589
                }
1590
                break;
1591
            case -2:
1592
                /* Access rights violation */
1593
                env->exception_index = POWERPC_EXCP_DSI;
1594
                env->error_code = 0;
1595
                env->spr[SPR_DAR] = address;
1596
                if (rw == 1)
1597
                    env->spr[SPR_DSISR] = 0x0A000000;
1598
                else
1599
                    env->spr[SPR_DSISR] = 0x08000000;
1600
                break;
1601
            case -4:
1602
                /* Direct store exception */
1603
                switch (access_type) {
1604
                case ACCESS_FLOAT:
1605
                    /* Floating point load/store */
1606
                    env->exception_index = POWERPC_EXCP_ALIGN;
1607
                    env->error_code = POWERPC_EXCP_ALIGN_FP;
1608
                    env->spr[SPR_DAR] = address;
1609
                    break;
1610
                case ACCESS_RES:
1611
                    /* lwarx, ldarx or stwcx. */
1612
                    env->exception_index = POWERPC_EXCP_DSI;
1613
                    env->error_code = 0;
1614
                    env->spr[SPR_DAR] = address;
1615
                    if (rw == 1)
1616
                        env->spr[SPR_DSISR] = 0x06000000;
1617
                    else
1618
                        env->spr[SPR_DSISR] = 0x04000000;
1619
                    break;
1620
                case ACCESS_EXT:
1621
                    /* eciwx or ecowx */
1622
                    env->exception_index = POWERPC_EXCP_DSI;
1623
                    env->error_code = 0;
1624
                    env->spr[SPR_DAR] = address;
1625
                    if (rw == 1)
1626
                        env->spr[SPR_DSISR] = 0x06100000;
1627
                    else
1628
                        env->spr[SPR_DSISR] = 0x04100000;
1629
                    break;
1630
                default:
1631
                    printf("DSI: invalid exception (%d)\n", ret);
1632
                    env->exception_index = POWERPC_EXCP_PROGRAM;
1633
                    env->error_code =
1634
                        POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1635
                    env->spr[SPR_DAR] = address;
1636
                    break;
1637
                }
1638
                break;
1639
#if defined(TARGET_PPC64)
1640
            case -5:
1641
                /* No match in segment table */
1642
                if (env->mmu_model == POWERPC_MMU_620) {
1643
                    env->exception_index = POWERPC_EXCP_DSI;
1644
                    env->error_code = 0;
1645
                    env->spr[SPR_DAR] = address;
1646
                    /* XXX: this might be incorrect */
1647
                    if (rw == 1)
1648
                        env->spr[SPR_DSISR] = 0x42000000;
1649
                    else
1650
                        env->spr[SPR_DSISR] = 0x40000000;
1651
                } else {
1652
                    env->exception_index = POWERPC_EXCP_DSEG;
1653
                    env->error_code = 0;
1654
                    env->spr[SPR_DAR] = address;
1655
                }
1656
                break;
1657
#endif
1658
            }
1659
        }
1660
#if 0
1661
        printf("%s: set exception to %d %02x\n", __func__,
1662
               env->exception, env->error_code);
1663
#endif
1664
        ret = 1;
1665
    }
1666

    
1667
    return ret;
1668
}
1669

    
1670
/*****************************************************************************/
1671
/* BATs management */
1672
#if !defined(FLUSH_ALL_TLBS)
1673
static always_inline void do_invalidate_BAT (CPUPPCState *env,
1674
                                             target_ulong BATu,
1675
                                             target_ulong mask)
1676
{
1677
    target_ulong base, end, page;
1678

    
1679
    base = BATu & ~0x0001FFFF;
1680
    end = base + mask + 0x00020000;
1681
    LOG_BATS("Flush BAT from " ADDRX " to " ADDRX " (" ADDRX ")\n",
1682
                base, end, mask);
1683
    for (page = base; page != end; page += TARGET_PAGE_SIZE)
1684
        tlb_flush_page(env, page);
1685
    LOG_BATS("Flush done\n");
1686
}
1687
#endif
1688

    
1689
static always_inline void dump_store_bat (CPUPPCState *env, char ID,
1690
                                          int ul, int nr, target_ulong value)
1691
{
1692
    LOG_BATS("Set %cBAT%d%c to " ADDRX " (" ADDRX ")\n",
1693
                ID, nr, ul == 0 ? 'u' : 'l', value, env->nip);
1694
}
1695

    
1696
void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1697
{
1698
    target_ulong mask;
1699

    
1700
    dump_store_bat(env, 'I', 0, nr, value);
1701
    if (env->IBAT[0][nr] != value) {
1702
        mask = (value << 15) & 0x0FFE0000UL;
1703
#if !defined(FLUSH_ALL_TLBS)
1704
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1705
#endif
1706
        /* When storing valid upper BAT, mask BEPI and BRPN
1707
         * and invalidate all TLBs covered by this BAT
1708
         */
1709
        mask = (value << 15) & 0x0FFE0000UL;
1710
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1711
            (value & ~0x0001FFFFUL & ~mask);
1712
        env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1713
            (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1714
#if !defined(FLUSH_ALL_TLBS)
1715
        do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1716
#else
1717
        tlb_flush(env, 1);
1718
#endif
1719
    }
1720
}
1721

    
1722
void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1723
{
1724
    dump_store_bat(env, 'I', 1, nr, value);
1725
    env->IBAT[1][nr] = value;
1726
}
1727

    
1728
void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1729
{
1730
    target_ulong mask;
1731

    
1732
    dump_store_bat(env, 'D', 0, nr, value);
1733
    if (env->DBAT[0][nr] != value) {
1734
        /* When storing valid upper BAT, mask BEPI and BRPN
1735
         * and invalidate all TLBs covered by this BAT
1736
         */
1737
        mask = (value << 15) & 0x0FFE0000UL;
1738
#if !defined(FLUSH_ALL_TLBS)
1739
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1740
#endif
1741
        mask = (value << 15) & 0x0FFE0000UL;
1742
        env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1743
            (value & ~0x0001FFFFUL & ~mask);
1744
        env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1745
            (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1746
#if !defined(FLUSH_ALL_TLBS)
1747
        do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1748
#else
1749
        tlb_flush(env, 1);
1750
#endif
1751
    }
1752
}
1753

    
1754
void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1755
{
1756
    dump_store_bat(env, 'D', 1, nr, value);
1757
    env->DBAT[1][nr] = value;
1758
}
1759

    
1760
void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
1761
{
1762
    target_ulong mask;
1763
    int do_inval;
1764

    
1765
    dump_store_bat(env, 'I', 0, nr, value);
1766
    if (env->IBAT[0][nr] != value) {
1767
        do_inval = 0;
1768
        mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1769
        if (env->IBAT[1][nr] & 0x40) {
1770
            /* Invalidate BAT only if it is valid */
1771
#if !defined(FLUSH_ALL_TLBS)
1772
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1773
#else
1774
            do_inval = 1;
1775
#endif
1776
        }
1777
        /* When storing valid upper BAT, mask BEPI and BRPN
1778
         * and invalidate all TLBs covered by this BAT
1779
         */
1780
        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1781
            (value & ~0x0001FFFFUL & ~mask);
1782
        env->DBAT[0][nr] = env->IBAT[0][nr];
1783
        if (env->IBAT[1][nr] & 0x40) {
1784
#if !defined(FLUSH_ALL_TLBS)
1785
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1786
#else
1787
            do_inval = 1;
1788
#endif
1789
        }
1790
#if defined(FLUSH_ALL_TLBS)
1791
        if (do_inval)
1792
            tlb_flush(env, 1);
1793
#endif
1794
    }
1795
}
1796

    
1797
void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
1798
{
1799
    target_ulong mask;
1800
    int do_inval;
1801

    
1802
    dump_store_bat(env, 'I', 1, nr, value);
1803
    if (env->IBAT[1][nr] != value) {
1804
        do_inval = 0;
1805
        if (env->IBAT[1][nr] & 0x40) {
1806
#if !defined(FLUSH_ALL_TLBS)
1807
            mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1808
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1809
#else
1810
            do_inval = 1;
1811
#endif
1812
        }
1813
        if (value & 0x40) {
1814
#if !defined(FLUSH_ALL_TLBS)
1815
            mask = (value << 17) & 0x0FFE0000UL;
1816
            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1817
#else
1818
            do_inval = 1;
1819
#endif
1820
        }
1821
        env->IBAT[1][nr] = value;
1822
        env->DBAT[1][nr] = value;
1823
#if defined(FLUSH_ALL_TLBS)
1824
        if (do_inval)
1825
            tlb_flush(env, 1);
1826
#endif
1827
    }
1828
}
1829

    
1830
/*****************************************************************************/
1831
/* TLB management */
1832
void ppc_tlb_invalidate_all (CPUPPCState *env)
1833
{
1834
    switch (env->mmu_model) {
1835
    case POWERPC_MMU_SOFT_6xx:
1836
    case POWERPC_MMU_SOFT_74xx:
1837
        ppc6xx_tlb_invalidate_all(env);
1838
        break;
1839
    case POWERPC_MMU_SOFT_4xx:
1840
    case POWERPC_MMU_SOFT_4xx_Z:
1841
        ppc4xx_tlb_invalidate_all(env);
1842
        break;
1843
    case POWERPC_MMU_REAL:
1844
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1845
        break;
1846
    case POWERPC_MMU_MPC8xx:
1847
        /* XXX: TODO */
1848
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1849
        break;
1850
    case POWERPC_MMU_BOOKE:
1851
        /* XXX: TODO */
1852
        cpu_abort(env, "BookE MMU model is not implemented\n");
1853
        break;
1854
    case POWERPC_MMU_BOOKE_FSL:
1855
        /* XXX: TODO */
1856
        if (!kvm_enabled())
1857
            cpu_abort(env, "BookE MMU model is not implemented\n");
1858
        break;
1859
    case POWERPC_MMU_32B:
1860
    case POWERPC_MMU_601:
1861
#if defined(TARGET_PPC64)
1862
    case POWERPC_MMU_620:
1863
    case POWERPC_MMU_64B:
1864
#endif /* defined(TARGET_PPC64) */
1865
        tlb_flush(env, 1);
1866
        break;
1867
    default:
1868
        /* XXX: TODO */
1869
        cpu_abort(env, "Unknown MMU model\n");
1870
        break;
1871
    }
1872
}
1873

    
1874
void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
1875
{
1876
#if !defined(FLUSH_ALL_TLBS)
1877
    addr &= TARGET_PAGE_MASK;
1878
    switch (env->mmu_model) {
1879
    case POWERPC_MMU_SOFT_6xx:
1880
    case POWERPC_MMU_SOFT_74xx:
1881
        ppc6xx_tlb_invalidate_virt(env, addr, 0);
1882
        if (env->id_tlbs == 1)
1883
            ppc6xx_tlb_invalidate_virt(env, addr, 1);
1884
        break;
1885
    case POWERPC_MMU_SOFT_4xx:
1886
    case POWERPC_MMU_SOFT_4xx_Z:
1887
        ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
1888
        break;
1889
    case POWERPC_MMU_REAL:
1890
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1891
        break;
1892
    case POWERPC_MMU_MPC8xx:
1893
        /* XXX: TODO */
1894
        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1895
        break;
1896
    case POWERPC_MMU_BOOKE:
1897
        /* XXX: TODO */
1898
        cpu_abort(env, "BookE MMU model is not implemented\n");
1899
        break;
1900
    case POWERPC_MMU_BOOKE_FSL:
1901
        /* XXX: TODO */
1902
        cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1903
        break;
1904
    case POWERPC_MMU_32B:
1905
    case POWERPC_MMU_601:
1906
        /* tlbie invalidate TLBs for all segments */
1907
        addr &= ~((target_ulong)-1ULL << 28);
1908
        /* XXX: this case should be optimized,
1909
         * giving a mask to tlb_flush_page
1910
         */
1911
        tlb_flush_page(env, addr | (0x0 << 28));
1912
        tlb_flush_page(env, addr | (0x1 << 28));
1913
        tlb_flush_page(env, addr | (0x2 << 28));
1914
        tlb_flush_page(env, addr | (0x3 << 28));
1915
        tlb_flush_page(env, addr | (0x4 << 28));
1916
        tlb_flush_page(env, addr | (0x5 << 28));
1917
        tlb_flush_page(env, addr | (0x6 << 28));
1918
        tlb_flush_page(env, addr | (0x7 << 28));
1919
        tlb_flush_page(env, addr | (0x8 << 28));
1920
        tlb_flush_page(env, addr | (0x9 << 28));
1921
        tlb_flush_page(env, addr | (0xA << 28));
1922
        tlb_flush_page(env, addr | (0xB << 28));
1923
        tlb_flush_page(env, addr | (0xC << 28));
1924
        tlb_flush_page(env, addr | (0xD << 28));
1925
        tlb_flush_page(env, addr | (0xE << 28));
1926
        tlb_flush_page(env, addr | (0xF << 28));
1927
        break;
1928
#if defined(TARGET_PPC64)
1929
    case POWERPC_MMU_620:
1930
    case POWERPC_MMU_64B:
1931
        /* tlbie invalidate TLBs for all segments */
1932
        /* XXX: given the fact that there are too many segments to invalidate,
1933
         *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
1934
         *      we just invalidate all TLBs
1935
         */
1936
        tlb_flush(env, 1);
1937
        break;
1938
#endif /* defined(TARGET_PPC64) */
1939
    default:
1940
        /* XXX: TODO */
1941
        cpu_abort(env, "Unknown MMU model\n");
1942
        break;
1943
    }
1944
#else
1945
    ppc_tlb_invalidate_all(env);
1946
#endif
1947
}
1948

    
1949
/*****************************************************************************/
1950
/* Special registers manipulation */
1951
#if defined(TARGET_PPC64)
1952
void ppc_store_asr (CPUPPCState *env, target_ulong value)
1953
{
1954
    if (env->asr != value) {
1955
        env->asr = value;
1956
        tlb_flush(env, 1);
1957
    }
1958
}
1959
#endif
1960

    
1961
void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
1962
{
1963
    LOG_MMU("%s: " ADDRX "\n", __func__, value);
1964
    if (env->sdr1 != value) {
1965
        /* XXX: for PowerPC 64, should check that the HTABSIZE value
1966
         *      is <= 28
1967
         */
1968
        env->sdr1 = value;
1969
        tlb_flush(env, 1);
1970
    }
1971
}
1972

    
1973
#if defined(TARGET_PPC64)
1974
target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
1975
{
1976
    // XXX
1977
    return 0;
1978
}
1979
#endif
1980

    
1981
void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1982
{
1983
    LOG_MMU("%s: reg=%d " ADDRX " " ADDRX "\n",
1984
                __func__, srnum, value, env->sr[srnum]);
1985
#if defined(TARGET_PPC64)
1986
    if (env->mmu_model & POWERPC_MMU_64) {
1987
        uint64_t rb = 0, rs = 0;
1988

    
1989
        /* ESID = srnum */
1990
        rb |= ((uint32_t)srnum & 0xf) << 28;
1991
        /* Set the valid bit */
1992
        rb |= 1 << 27;
1993
        /* Index = ESID */
1994
        rb |= (uint32_t)srnum;
1995

    
1996
        /* VSID = VSID */
1997
        rs |= (value & 0xfffffff) << 12;
1998
        /* flags = flags */
1999
        rs |= ((value >> 27) & 0xf) << 9;
2000

    
2001
        ppc_store_slb(env, rb, rs);
2002
    } else
2003
#endif
2004
    if (env->sr[srnum] != value) {
2005
        env->sr[srnum] = value;
2006
#if !defined(FLUSH_ALL_TLBS) && 0
2007
        {
2008
            target_ulong page, end;
2009
            /* Invalidate 256 MB of virtual memory */
2010
            page = (16 << 20) * srnum;
2011
            end = page + (16 << 20);
2012
            for (; page != end; page += TARGET_PAGE_SIZE)
2013
                tlb_flush_page(env, page);
2014
        }
2015
#else
2016
        tlb_flush(env, 1);
2017
#endif
2018
    }
2019
}
2020
#endif /* !defined (CONFIG_USER_ONLY) */
2021

    
2022
/* GDBstub can read and write MSR... */
2023
void ppc_store_msr (CPUPPCState *env, target_ulong value)
2024
{
2025
    hreg_store_msr(env, value, 0);
2026
}
2027

    
2028
/*****************************************************************************/
2029
/* Exception processing */
2030
#if defined (CONFIG_USER_ONLY)
2031
void do_interrupt (CPUState *env)
2032
{
2033
    env->exception_index = POWERPC_EXCP_NONE;
2034
    env->error_code = 0;
2035
}
2036

    
2037
void ppc_hw_interrupt (CPUState *env)
2038
{
2039
    env->exception_index = POWERPC_EXCP_NONE;
2040
    env->error_code = 0;
2041
}
2042
#else /* defined (CONFIG_USER_ONLY) */
2043
static always_inline void dump_syscall (CPUState *env)
2044
{
2045
    qemu_log_mask(CPU_LOG_INT, "syscall r0=" REGX " r3=" REGX " r4=" REGX
2046
            " r5=" REGX " r6=" REGX " nip=" ADDRX "\n",
2047
            ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
2048
            ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), env->nip);
2049
}
2050

    
2051
/* Note that this function should be greatly optimized
2052
 * when called with a constant excp, from ppc_hw_interrupt
2053
 */
2054
static always_inline void powerpc_excp (CPUState *env,
2055
                                        int excp_model, int excp)
2056
{
2057
    target_ulong msr, new_msr, vector;
2058
    int srr0, srr1, asrr0, asrr1;
2059
    int lpes0, lpes1, lev;
2060

    
2061
    if (0) {
2062
        /* XXX: find a suitable condition to enable the hypervisor mode */
2063
        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
2064
        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
2065
    } else {
2066
        /* Those values ensure we won't enter the hypervisor mode */
2067
        lpes0 = 0;
2068
        lpes1 = 1;
2069
    }
2070

    
2071
    qemu_log_mask(CPU_LOG_INT, "Raise exception at " ADDRX " => %08x (%02x)\n",
2072
                 env->nip, excp, env->error_code);
2073
    msr = env->msr;
2074
    new_msr = msr;
2075
    srr0 = SPR_SRR0;
2076
    srr1 = SPR_SRR1;
2077
    asrr0 = -1;
2078
    asrr1 = -1;
2079
    msr &= ~((target_ulong)0x783F0000);
2080
    switch (excp) {
2081
    case POWERPC_EXCP_NONE:
2082
        /* Should never happen */
2083
        return;
2084
    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
2085
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2086
        switch (excp_model) {
2087
        case POWERPC_EXCP_40x:
2088
            srr0 = SPR_40x_SRR2;
2089
            srr1 = SPR_40x_SRR3;
2090
            break;
2091
        case POWERPC_EXCP_BOOKE:
2092
            srr0 = SPR_BOOKE_CSRR0;
2093
            srr1 = SPR_BOOKE_CSRR1;
2094
            break;
2095
        case POWERPC_EXCP_G2:
2096
            break;
2097
        default:
2098
            goto excp_invalid;
2099
        }
2100
        goto store_next;
2101
    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
2102
        if (msr_me == 0) {
2103
            /* Machine check exception is not enabled.
2104
             * Enter checkstop state.
2105
             */
2106
            if (qemu_log_enabled()) {
2107
                qemu_log("Machine check while not allowed. "
2108
                        "Entering checkstop state\n");
2109
            } else {
2110
                fprintf(stderr, "Machine check while not allowed. "
2111
                        "Entering checkstop state\n");
2112
            }
2113
            env->halted = 1;
2114
            env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2115
        }
2116
        new_msr &= ~((target_ulong)1 << MSR_RI);
2117
        new_msr &= ~((target_ulong)1 << MSR_ME);
2118
        if (0) {
2119
            /* XXX: find a suitable condition to enable the hypervisor mode */
2120
            new_msr |= (target_ulong)MSR_HVB;
2121
        }
2122
        /* XXX: should also have something loaded in DAR / DSISR */
2123
        switch (excp_model) {
2124
        case POWERPC_EXCP_40x:
2125
            srr0 = SPR_40x_SRR2;
2126
            srr1 = SPR_40x_SRR3;
2127
            break;
2128
        case POWERPC_EXCP_BOOKE:
2129
            srr0 = SPR_BOOKE_MCSRR0;
2130
            srr1 = SPR_BOOKE_MCSRR1;
2131
            asrr0 = SPR_BOOKE_CSRR0;
2132
            asrr1 = SPR_BOOKE_CSRR1;
2133
            break;
2134
        default:
2135
            break;
2136
        }
2137
        goto store_next;
2138
    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
2139
        LOG_EXCP("DSI exception: DSISR=" ADDRX" DAR=" ADDRX "\n",
2140
                    env->spr[SPR_DSISR], env->spr[SPR_DAR]);
2141
        new_msr &= ~((target_ulong)1 << MSR_RI);
2142
        if (lpes1 == 0)
2143
            new_msr |= (target_ulong)MSR_HVB;
2144
        goto store_next;
2145
    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
2146
        LOG_EXCP("ISI exception: msr=" ADDRX ", nip=" ADDRX "\n",
2147
                    msr, env->nip);
2148
        new_msr &= ~((target_ulong)1 << MSR_RI);
2149
        if (lpes1 == 0)
2150
            new_msr |= (target_ulong)MSR_HVB;
2151
        msr |= env->error_code;
2152
        goto store_next;
2153
    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
2154
        new_msr &= ~((target_ulong)1 << MSR_RI);
2155
        if (lpes0 == 1)
2156
            new_msr |= (target_ulong)MSR_HVB;
2157
        goto store_next;
2158
    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
2159
        new_msr &= ~((target_ulong)1 << MSR_RI);
2160
        if (lpes1 == 0)
2161
            new_msr |= (target_ulong)MSR_HVB;
2162
        /* XXX: this is false */
2163
        /* Get rS/rD and rA from faulting opcode */
2164
        env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
2165
        goto store_current;
2166
    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
2167
        switch (env->error_code & ~0xF) {
2168
        case POWERPC_EXCP_FP:
2169
            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
2170
                LOG_EXCP("Ignore floating point exception\n");
2171
                env->exception_index = POWERPC_EXCP_NONE;
2172
                env->error_code = 0;
2173
                return;
2174
            }
2175
            new_msr &= ~((target_ulong)1 << MSR_RI);
2176
            if (lpes1 == 0)
2177
                new_msr |= (target_ulong)MSR_HVB;
2178
            msr |= 0x00100000;
2179
            if (msr_fe0 == msr_fe1)
2180
                goto store_next;
2181
            msr |= 0x00010000;
2182
            break;
2183
        case POWERPC_EXCP_INVAL:
2184
            LOG_EXCP("Invalid instruction at " ADDRX "\n",
2185
                        env->nip);
2186
            new_msr &= ~((target_ulong)1 << MSR_RI);
2187
            if (lpes1 == 0)
2188
                new_msr |= (target_ulong)MSR_HVB;
2189
            msr |= 0x00080000;
2190
            break;
2191
        case POWERPC_EXCP_PRIV:
2192
            new_msr &= ~((target_ulong)1 << MSR_RI);
2193
            if (lpes1 == 0)
2194
                new_msr |= (target_ulong)MSR_HVB;
2195
            msr |= 0x00040000;
2196
            break;
2197
        case POWERPC_EXCP_TRAP:
2198
            new_msr &= ~((target_ulong)1 << MSR_RI);
2199
            if (lpes1 == 0)
2200
                new_msr |= (target_ulong)MSR_HVB;
2201
            msr |= 0x00020000;
2202
            break;
2203
        default:
2204
            /* Should never occur */
2205
            cpu_abort(env, "Invalid program exception %d. Aborting\n",
2206
                      env->error_code);
2207
            break;
2208
        }
2209
        goto store_current;
2210
    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
2211
        new_msr &= ~((target_ulong)1 << MSR_RI);
2212
        if (lpes1 == 0)
2213
            new_msr |= (target_ulong)MSR_HVB;
2214
        goto store_current;
2215
    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
2216
        /* NOTE: this is a temporary hack to support graphics OSI
2217
           calls from the MOL driver */
2218
        /* XXX: To be removed */
2219
        if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
2220
            env->osi_call) {
2221
            if (env->osi_call(env) != 0) {
2222
                env->exception_index = POWERPC_EXCP_NONE;
2223
                env->error_code = 0;
2224
                return;
2225
            }
2226
        }
2227
        dump_syscall(env);
2228
        new_msr &= ~((target_ulong)1 << MSR_RI);
2229
        lev = env->error_code;
2230
        if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2231
            new_msr |= (target_ulong)MSR_HVB;
2232
        goto store_next;
2233
    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
2234
        new_msr &= ~((target_ulong)1 << MSR_RI);
2235
        goto store_current;
2236
    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
2237
        new_msr &= ~((target_ulong)1 << MSR_RI);
2238
        if (lpes1 == 0)
2239
            new_msr |= (target_ulong)MSR_HVB;
2240
        goto store_next;
2241
    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
2242
        /* FIT on 4xx */
2243
        LOG_EXCP("FIT exception\n");
2244
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2245
        goto store_next;
2246
    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
2247
        LOG_EXCP("WDT exception\n");
2248
        switch (excp_model) {
2249
        case POWERPC_EXCP_BOOKE:
2250
            srr0 = SPR_BOOKE_CSRR0;
2251
            srr1 = SPR_BOOKE_CSRR1;
2252
            break;
2253
        default:
2254
            break;
2255
        }
2256
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2257
        goto store_next;
2258
    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
2259
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2260
        goto store_next;
2261
    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
2262
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2263
        goto store_next;
2264
    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
2265
        switch (excp_model) {
2266
        case POWERPC_EXCP_BOOKE:
2267
            srr0 = SPR_BOOKE_DSRR0;
2268
            srr1 = SPR_BOOKE_DSRR1;
2269
            asrr0 = SPR_BOOKE_CSRR0;
2270
            asrr1 = SPR_BOOKE_CSRR1;
2271
            break;
2272
        default:
2273
            break;
2274
        }
2275
        /* XXX: TODO */
2276
        cpu_abort(env, "Debug exception is not implemented yet !\n");
2277
        goto store_next;
2278
    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
2279
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2280
        goto store_current;
2281
    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
2282
        /* XXX: TODO */
2283
        cpu_abort(env, "Embedded floating point data exception "
2284
                  "is not implemented yet !\n");
2285
        goto store_next;
2286
    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
2287
        /* XXX: TODO */
2288
        cpu_abort(env, "Embedded floating point round exception "
2289
                  "is not implemented yet !\n");
2290
        goto store_next;
2291
    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
2292
        new_msr &= ~((target_ulong)1 << MSR_RI);
2293
        /* XXX: TODO */
2294
        cpu_abort(env,
2295
                  "Performance counter exception is not implemented yet !\n");
2296
        goto store_next;
2297
    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
2298
        /* XXX: TODO */
2299
        cpu_abort(env,
2300
                  "Embedded doorbell interrupt is not implemented yet !\n");
2301
        goto store_next;
2302
    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
2303
        switch (excp_model) {
2304
        case POWERPC_EXCP_BOOKE:
2305
            srr0 = SPR_BOOKE_CSRR0;
2306
            srr1 = SPR_BOOKE_CSRR1;
2307
            break;
2308
        default:
2309
            break;
2310
        }
2311
        /* XXX: TODO */
2312
        cpu_abort(env, "Embedded doorbell critical interrupt "
2313
                  "is not implemented yet !\n");
2314
        goto store_next;
2315
    case POWERPC_EXCP_RESET:     /* System reset exception                   */
2316
        new_msr &= ~((target_ulong)1 << MSR_RI);
2317
        if (0) {
2318
            /* XXX: find a suitable condition to enable the hypervisor mode */
2319
            new_msr |= (target_ulong)MSR_HVB;
2320
        }
2321
        goto store_next;
2322
    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
2323
        new_msr &= ~((target_ulong)1 << MSR_RI);
2324
        if (lpes1 == 0)
2325
            new_msr |= (target_ulong)MSR_HVB;
2326
        goto store_next;
2327
    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
2328
        new_msr &= ~((target_ulong)1 << MSR_RI);
2329
        if (lpes1 == 0)
2330
            new_msr |= (target_ulong)MSR_HVB;
2331
        goto store_next;
2332
    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
2333
        srr0 = SPR_HSRR0;
2334
        srr1 = SPR_HSRR1;
2335
        new_msr |= (target_ulong)MSR_HVB;
2336
        goto store_next;
2337
    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
2338
        new_msr &= ~((target_ulong)1 << MSR_RI);
2339
        if (lpes1 == 0)
2340
            new_msr |= (target_ulong)MSR_HVB;
2341
        goto store_next;
2342
    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
2343
        srr0 = SPR_HSRR0;
2344
        srr1 = SPR_HSRR1;
2345
        new_msr |= (target_ulong)MSR_HVB;
2346
        goto store_next;
2347
    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
2348
        srr0 = SPR_HSRR0;
2349
        srr1 = SPR_HSRR1;
2350
        new_msr |= (target_ulong)MSR_HVB;
2351
        goto store_next;
2352
    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
2353
        srr0 = SPR_HSRR0;
2354
        srr1 = SPR_HSRR1;
2355
        new_msr |= (target_ulong)MSR_HVB;
2356
        goto store_next;
2357
    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
2358
        srr0 = SPR_HSRR0;
2359
        srr1 = SPR_HSRR1;
2360
        new_msr |= (target_ulong)MSR_HVB;
2361
        goto store_next;
2362
    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
2363
        new_msr &= ~((target_ulong)1 << MSR_RI);
2364
        if (lpes1 == 0)
2365
            new_msr |= (target_ulong)MSR_HVB;
2366
        goto store_current;
2367
    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
2368
        LOG_EXCP("PIT exception\n");
2369
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2370
        goto store_next;
2371
    case POWERPC_EXCP_IO:        /* IO error exception                       */
2372
        /* XXX: TODO */
2373
        cpu_abort(env, "601 IO error exception is not implemented yet !\n");
2374
        goto store_next;
2375
    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
2376
        /* XXX: TODO */
2377
        cpu_abort(env, "601 run mode exception is not implemented yet !\n");
2378
        goto store_next;
2379
    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
2380
        /* XXX: TODO */
2381
        cpu_abort(env, "602 emulation trap exception "
2382
                  "is not implemented yet !\n");
2383
        goto store_next;
2384
    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
2385
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2386
        if (lpes1 == 0) /* XXX: check this */
2387
            new_msr |= (target_ulong)MSR_HVB;
2388
        switch (excp_model) {
2389
        case POWERPC_EXCP_602:
2390
        case POWERPC_EXCP_603:
2391
        case POWERPC_EXCP_603E:
2392
        case POWERPC_EXCP_G2:
2393
            goto tlb_miss_tgpr;
2394
        case POWERPC_EXCP_7x5:
2395
            goto tlb_miss;
2396
        case POWERPC_EXCP_74xx:
2397
            goto tlb_miss_74xx;
2398
        default:
2399
            cpu_abort(env, "Invalid instruction TLB miss exception\n");
2400
            break;
2401
        }
2402
        break;
2403
    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
2404
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2405
        if (lpes1 == 0) /* XXX: check this */
2406
            new_msr |= (target_ulong)MSR_HVB;
2407
        switch (excp_model) {
2408
        case POWERPC_EXCP_602:
2409
        case POWERPC_EXCP_603:
2410
        case POWERPC_EXCP_603E:
2411
        case POWERPC_EXCP_G2:
2412
            goto tlb_miss_tgpr;
2413
        case POWERPC_EXCP_7x5:
2414
            goto tlb_miss;
2415
        case POWERPC_EXCP_74xx:
2416
            goto tlb_miss_74xx;
2417
        default:
2418
            cpu_abort(env, "Invalid data load TLB miss exception\n");
2419
            break;
2420
        }
2421
        break;
2422
    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
2423
        new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2424
        if (lpes1 == 0) /* XXX: check this */
2425
            new_msr |= (target_ulong)MSR_HVB;
2426
        switch (excp_model) {
2427
        case POWERPC_EXCP_602:
2428
        case POWERPC_EXCP_603:
2429
        case POWERPC_EXCP_603E:
2430
        case POWERPC_EXCP_G2:
2431
        tlb_miss_tgpr:
2432
            /* Swap temporary saved registers with GPRs */
2433
            if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
2434
                new_msr |= (target_ulong)1 << MSR_TGPR;
2435
                hreg_swap_gpr_tgpr(env);
2436
            }
2437
            goto tlb_miss;
2438
        case POWERPC_EXCP_7x5:
2439
        tlb_miss:
2440
#if defined (DEBUG_SOFTWARE_TLB)
2441
            if (qemu_log_enabled()) {
2442
                const unsigned char *es;
2443
                target_ulong *miss, *cmp;
2444
                int en;
2445
                if (excp == POWERPC_EXCP_IFTLB) {
2446
                    es = "I";
2447
                    en = 'I';
2448
                    miss = &env->spr[SPR_IMISS];
2449
                    cmp = &env->spr[SPR_ICMP];
2450
                } else {
2451
                    if (excp == POWERPC_EXCP_DLTLB)
2452
                        es = "DL";
2453
                    else
2454
                        es = "DS";
2455
                    en = 'D';
2456
                    miss = &env->spr[SPR_DMISS];
2457
                    cmp = &env->spr[SPR_DCMP];
2458
                }
2459
                qemu_log("6xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
2460
                        " H1 " ADDRX " H2 " ADDRX " %08x\n",
2461
                        es, en, *miss, en, *cmp,
2462
                        env->spr[SPR_HASH1], env->spr[SPR_HASH2],
2463
                        env->error_code);
2464
            }
2465
#endif
2466
            msr |= env->crf[0] << 28;
2467
            msr |= env->error_code; /* key, D/I, S/L bits */
2468
            /* Set way using a LRU mechanism */
2469
            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2470
            break;
2471
        case POWERPC_EXCP_74xx:
2472
        tlb_miss_74xx:
2473
#if defined (DEBUG_SOFTWARE_TLB)
2474
            if (qemu_log_enabled()) {
2475
                const unsigned char *es;
2476
                target_ulong *miss, *cmp;
2477
                int en;
2478
                if (excp == POWERPC_EXCP_IFTLB) {
2479
                    es = "I";
2480
                    en = 'I';
2481
                    miss = &env->spr[SPR_TLBMISS];
2482
                    cmp = &env->spr[SPR_PTEHI];
2483
                } else {
2484
                    if (excp == POWERPC_EXCP_DLTLB)
2485
                        es = "DL";
2486
                    else
2487
                        es = "DS";
2488
                    en = 'D';
2489
                    miss = &env->spr[SPR_TLBMISS];
2490
                    cmp = &env->spr[SPR_PTEHI];
2491
                }
2492
                qemu_log("74xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
2493
                        " %08x\n",
2494
                        es, en, *miss, en, *cmp, env->error_code);
2495
            }
2496
#endif
2497
            msr |= env->error_code; /* key bit */
2498
            break;
2499
        default:
2500
            cpu_abort(env, "Invalid data store TLB miss exception\n");
2501
            break;
2502
        }
2503
        goto store_next;
2504
    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
2505
        /* XXX: TODO */
2506
        cpu_abort(env, "Floating point assist exception "
2507
                  "is not implemented yet !\n");
2508
        goto store_next;
2509
    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
2510
        /* XXX: TODO */
2511
        cpu_abort(env, "DABR exception is not implemented yet !\n");
2512
        goto store_next;
2513
    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
2514
        /* XXX: TODO */
2515
        cpu_abort(env, "IABR exception is not implemented yet !\n");
2516
        goto store_next;
2517
    case POWERPC_EXCP_SMI:       /* System management interrupt              */
2518
        /* XXX: TODO */
2519
        cpu_abort(env, "SMI exception is not implemented yet !\n");
2520
        goto store_next;
2521
    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
2522
        /* XXX: TODO */
2523
        cpu_abort(env, "Thermal management exception "
2524
                  "is not implemented yet !\n");
2525
        goto store_next;
2526
    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
2527
        new_msr &= ~((target_ulong)1 << MSR_RI);
2528
        if (lpes1 == 0)
2529
            new_msr |= (target_ulong)MSR_HVB;
2530
        /* XXX: TODO */
2531
        cpu_abort(env,
2532
                  "Performance counter exception is not implemented yet !\n");
2533
        goto store_next;
2534
    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
2535
        /* XXX: TODO */
2536
        cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2537
        goto store_next;
2538
    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
2539
        /* XXX: TODO */
2540
        cpu_abort(env,
2541
                  "970 soft-patch exception is not implemented yet !\n");
2542
        goto store_next;
2543
    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
2544
        /* XXX: TODO */
2545
        cpu_abort(env,
2546
                  "970 maintenance exception is not implemented yet !\n");
2547
        goto store_next;
2548
    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
2549
        /* XXX: TODO */
2550
        cpu_abort(env, "Maskable external exception "
2551
                  "is not implemented yet !\n");
2552
        goto store_next;
2553
    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
2554
        /* XXX: TODO */
2555
        cpu_abort(env, "Non maskable external exception "
2556
                  "is not implemented yet !\n");
2557
        goto store_next;
2558
    default:
2559
    excp_invalid:
2560
        cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
2561
        break;
2562
    store_current:
2563
        /* save current instruction location */
2564
        env->spr[srr0] = env->nip - 4;
2565
        break;
2566
    store_next:
2567
        /* save next instruction location */
2568
        env->spr[srr0] = env->nip;
2569
        break;
2570
    }
2571
    /* Save MSR */
2572
    env->spr[srr1] = msr;
2573
    /* If any alternate SRR register are defined, duplicate saved values */
2574
    if (asrr0 != -1)
2575
        env->spr[asrr0] = env->spr[srr0];
2576
    if (asrr1 != -1)
2577
        env->spr[asrr1] = env->spr[srr1];
2578
    /* If we disactivated any translation, flush TLBs */
2579
    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
2580
        tlb_flush(env, 1);
2581
    /* reload MSR with correct bits */
2582
    new_msr &= ~((target_ulong)1 << MSR_EE);
2583
    new_msr &= ~((target_ulong)1 << MSR_PR);
2584
    new_msr &= ~((target_ulong)1 << MSR_FP);
2585
    new_msr &= ~((target_ulong)1 << MSR_FE0);
2586
    new_msr &= ~((target_ulong)1 << MSR_SE);
2587
    new_msr &= ~((target_ulong)1 << MSR_BE);
2588
    new_msr &= ~((target_ulong)1 << MSR_FE1);
2589
    new_msr &= ~((target_ulong)1 << MSR_IR);
2590
    new_msr &= ~((target_ulong)1 << MSR_DR);
2591
#if 0 /* Fix this: not on all targets */
2592
    new_msr &= ~((target_ulong)1 << MSR_PMM);
2593
#endif
2594
    new_msr &= ~((target_ulong)1 << MSR_LE);
2595
    if (msr_ile)
2596
        new_msr |= (target_ulong)1 << MSR_LE;
2597
    else
2598
        new_msr &= ~((target_ulong)1 << MSR_LE);
2599
    /* Jump to handler */
2600
    vector = env->excp_vectors[excp];
2601
    if (vector == (target_ulong)-1ULL) {
2602
        cpu_abort(env, "Raised an exception without defined vector %d\n",
2603
                  excp);
2604
    }
2605
    vector |= env->excp_prefix;
2606
#if defined(TARGET_PPC64)
2607
    if (excp_model == POWERPC_EXCP_BOOKE) {
2608
        if (!msr_icm) {
2609
            new_msr &= ~((target_ulong)1 << MSR_CM);
2610
            vector = (uint32_t)vector;
2611
        } else {
2612
            new_msr |= (target_ulong)1 << MSR_CM;
2613
        }
2614
    } else {
2615
        if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
2616
            new_msr &= ~((target_ulong)1 << MSR_SF);
2617
            vector = (uint32_t)vector;
2618
        } else {
2619
            new_msr |= (target_ulong)1 << MSR_SF;
2620
        }
2621
    }
2622
#endif
2623
    /* XXX: we don't use hreg_store_msr here as already have treated
2624
     *      any special case that could occur. Just store MSR and update hflags
2625
     */
2626
    env->msr = new_msr & env->msr_mask;
2627
    hreg_compute_hflags(env);
2628
    env->nip = vector;
2629
    /* Reset exception state */
2630
    env->exception_index = POWERPC_EXCP_NONE;
2631
    env->error_code = 0;
2632
}
2633

    
2634
void do_interrupt (CPUState *env)
2635
{
2636
    powerpc_excp(env, env->excp_model, env->exception_index);
2637
}
2638

    
2639
void ppc_hw_interrupt (CPUPPCState *env)
2640
{
2641
    int hdice;
2642

    
2643
#if 0
2644
    qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
2645
                __func__, env, env->pending_interrupts,
2646
                env->interrupt_request, (int)msr_me, (int)msr_ee);
2647
#endif
2648
    /* External reset */
2649
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2650
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2651
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
2652
        return;
2653
    }
2654
    /* Machine check exception */
2655
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2656
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2657
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
2658
        return;
2659
    }
2660
#if 0 /* TODO */
2661
    /* External debug exception */
2662
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2663
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2664
        powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
2665
        return;
2666
    }
2667
#endif
2668
    if (0) {
2669
        /* XXX: find a suitable condition to enable the hypervisor mode */
2670
        hdice = env->spr[SPR_LPCR] & 1;
2671
    } else {
2672
        hdice = 0;
2673
    }
2674
    if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
2675
        /* Hypervisor decrementer exception */
2676
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2677
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2678
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
2679
            return;
2680
        }
2681
    }
2682
    if (msr_ce != 0) {
2683
        /* External critical interrupt */
2684
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2685
            /* Taking a critical external interrupt does not clear the external
2686
             * critical interrupt status
2687
             */
2688
#if 0
2689
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
2690
#endif
2691
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
2692
            return;
2693
        }
2694
    }
2695
    if (msr_ee != 0) {
2696
        /* Watchdog timer on embedded PowerPC */
2697
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2698
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2699
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
2700
            return;
2701
        }
2702
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2703
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2704
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
2705
            return;
2706
        }
2707
        /* Fixed interval timer on embedded PowerPC */
2708
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2709
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2710
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
2711
            return;
2712
        }
2713
        /* Programmable interval timer on embedded PowerPC */
2714
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2715
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2716
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
2717
            return;
2718
        }
2719
        /* Decrementer exception */
2720
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2721
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2722
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
2723
            return;
2724
        }
2725
        /* External interrupt */
2726
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2727
            /* Taking an external interrupt does not clear the external
2728
             * interrupt status
2729
             */
2730
#if 0
2731
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2732
#endif
2733
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
2734
            return;
2735
        }
2736
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2737
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2738
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
2739
            return;
2740
        }
2741
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2742
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2743
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
2744
            return;
2745
        }
2746
        /* Thermal interrupt */
2747
        if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2748
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2749
            powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
2750
            return;
2751
        }
2752
    }
2753
}
2754
#endif /* !CONFIG_USER_ONLY */
2755

    
2756
void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2757
{
2758
    qemu_log("Return from exception at " ADDRX " with flags " ADDRX "\n",
2759
             RA, msr);
2760
}
2761

    
2762
void cpu_ppc_reset (void *opaque)
2763
{
2764
    CPUPPCState *env = opaque;
2765
    target_ulong msr;
2766

    
2767
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
2768
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
2769
        log_cpu_state(env, 0);
2770
    }
2771

    
2772
    msr = (target_ulong)0;
2773
    if (0) {
2774
        /* XXX: find a suitable condition to enable the hypervisor mode */
2775
        msr |= (target_ulong)MSR_HVB;
2776
    }
2777
    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
2778
    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
2779
    msr |= (target_ulong)1 << MSR_EP;
2780
#if defined (DO_SINGLE_STEP) && 0
2781
    /* Single step trace mode */
2782
    msr |= (target_ulong)1 << MSR_SE;
2783
    msr |= (target_ulong)1 << MSR_BE;
2784
#endif
2785
#if defined(CONFIG_USER_ONLY)
2786
    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
2787
    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
2788
    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
2789
    msr |= (target_ulong)1 << MSR_PR;
2790
#else
2791
    env->nip = env->hreset_vector | env->excp_prefix;
2792
    if (env->mmu_model != POWERPC_MMU_REAL)
2793
        ppc_tlb_invalidate_all(env);
2794
#endif
2795
    env->msr = msr & env->msr_mask;
2796
#if defined(TARGET_PPC64)
2797
    if (env->mmu_model & POWERPC_MMU_64)
2798
        env->msr |= (1ULL << MSR_SF);
2799
#endif
2800
    hreg_compute_hflags(env);
2801
    env->reserve = (target_ulong)-1ULL;
2802
    /* Be sure no exception or interrupt is pending */
2803
    env->pending_interrupts = 0;
2804
    env->exception_index = POWERPC_EXCP_NONE;
2805
    env->error_code = 0;
2806
    /* Flush all TLBs */
2807
    tlb_flush(env, 1);
2808
}
2809

    
2810
CPUPPCState *cpu_ppc_init (const char *cpu_model)
2811
{
2812
    CPUPPCState *env;
2813
    const ppc_def_t *def;
2814

    
2815
    def = cpu_ppc_find_by_name(cpu_model);
2816
    if (!def)
2817
        return NULL;
2818

    
2819
    env = qemu_mallocz(sizeof(CPUPPCState));
2820
    cpu_exec_init(env);
2821
    ppc_translate_init();
2822
    env->cpu_model_str = cpu_model;
2823
    cpu_ppc_register_internal(env, def);
2824
    cpu_ppc_reset(env);
2825

    
2826
    if (kvm_enabled())
2827
        kvm_init_vcpu(env);
2828

    
2829
    return env;
2830
}
2831

    
2832
void cpu_ppc_close (CPUPPCState *env)
2833
{
2834
    /* Should also remove all opcode tables... */
2835
    qemu_free(env);
2836
}