~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to target-ppc/helper.c

  • Committer: ths
  • Date: 2007-06-17 15:32:30 UTC
  • Revision ID: git-v1:ffb04fcf089865952592f1f8855c2848d4514a89
Allow relative paths for the interpreter prefix in linux-user emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2984 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

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