Revision a541f297 target-ppc/helper.c

b/target-ppc/helper.c
21 21

  
22 22
#include "exec.h"
23 23
#if defined (USE_OPEN_FIRMWARE)
24
#include <time.h>
24 25
#include "of.h"
25 26
#endif
26 27

  
......
28 29
//#define DEBUG_BATS
29 30
//#define DEBUG_EXCEPTIONS
30 31

  
31
extern FILE *logfile, *stderr;
32
extern FILE *logfile, *stdout, *stderr;
32 33
void exit (int);
33 34
void abort (void);
34 35

  
......
74 75

  
75 76
/*****************************************************************************/
76 77
/* PPC MMU emulation */
78
int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
79
                              int is_user, int is_softmmu);
80

  
77 81
/* Perform BAT hit & translation */
78 82
static int get_bat (CPUState *env, uint32_t *real, int *prot,
79 83
                    uint32_t virtual, int rw, int type)
......
88 92
        fprintf(logfile, "%s: %cBAT v 0x%08x\n", __func__,
89 93
               type == ACCESS_CODE ? 'I' : 'D', virtual);
90 94
    }
91
    printf("%s: %cBAT v 0x%08x\n", __func__,
92
           type == ACCESS_CODE ? 'I' : 'D', virtual);
93 95
#endif
94 96
    switch (type) {
95 97
    case ACCESS_CODE:
......
106 108
        fprintf(logfile, "%s...: %cBAT v 0x%08x\n", __func__,
107 109
               type == ACCESS_CODE ? 'I' : 'D', virtual);
108 110
    }
109
    printf("%s...: %cBAT v 0x%08x\n", __func__,
110
           type == ACCESS_CODE ? 'I' : 'D', virtual);
111 111
#endif
112 112
    base = virtual & 0xFFFC0000;
113 113
    for (i = 0; i < 4; i++) {
......
121 121
            fprintf(logfile, "%s: %cBAT%d v 0x%08x BATu 0x%08x BATl 0x%08x\n",
122 122
                    __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
123 123
                    *BATu, *BATl);
124
        } else {
125
            printf("%s: %cBAT%d v 0x%08x BATu 0x%08x BATl 0x%08x\n",
126
                   __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
127
                   *BATu, *BATl);
128 124
        }
129 125
#endif
130 126
        if ((virtual & 0xF0000000) == BEPIu &&
......
135 131
                /* Get physical address */
136 132
                *real = (*BATl & 0xF0000000) |
137 133
                    ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
138
                    (virtual & 0x0001FFFF);
134
                    (virtual & 0x0001F000);
139 135
                if (*BATl & 0x00000001)
140 136
                    *prot = PROT_READ;
141 137
                if (*BATl & 0x00000002)
......
145 141
                    fprintf(logfile, "BAT %d match: r 0x%08x prot=%c%c\n",
146 142
                            i, *real, *prot & PROT_READ ? 'R' : '-',
147 143
                            *prot & PROT_WRITE ? 'W' : '-');
148
                } else {
149
                    printf("BAT %d match: 0x%08x => 0x%08x prot=%c%c\n",
150
                           i, virtual, *real, *prot & PROT_READ ? 'R' : '-',
151
                           *prot & PROT_WRITE ? 'W' : '-');
152 144
                }
153 145
#endif
154 146
                ret = 0;
......
181 173
static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va,
182 174
                     int h, int key, int rw)
183 175
{
184
    uint32_t pte0, pte1, keep = 0;
176
    uint32_t pte0, pte1, keep = 0, access = 0;
185 177
    int i, good = -1, store = 0;
186 178
    int ret = -1; /* No entry found */
187 179

  
......
189 181
        pte0 = ldl_raw((void *)((uint32_t)phys_ram_base + base + (i * 8)));
190 182
        pte1 =  ldl_raw((void *)((uint32_t)phys_ram_base + base + (i * 8) + 4));
191 183
#if defined (DEBUG_MMU)
192
        printf("Load pte from 0x%08x => 0x%08x 0x%08x\n", base + (i * 8),
193
               pte0, pte1);
184
	if (loglevel > 0) {
185
	    fprintf(logfile, "Load pte from 0x%08x => 0x%08x 0x%08x "
186
		    "%d %d %d 0x%08x\n", base + (i * 8), pte0, pte1,
187
		    pte0 >> 31, h, (pte0 >> 6) & 1, va);
188
	}
194 189
#endif
195 190
        /* Check validity and table match */
196 191
        if (pte0 & 0x80000000 && (h == ((pte0 >> 6) & 1))) {
197
#if defined (DEBUG_MMU)
198
            printf("PTE is valid and table matches... compare 0x%08x:%08x\n",
199
                   pte0 & 0x7FFFFFBF, va);
200
#endif
201 192
            /* Check vsid & api */
202 193
            if ((pte0 & 0x7FFFFFBF) == va) {
203
#if defined (DEBUG_MMU)
204
                printf("PTE match !\n");
205
#endif
206 194
                if (good == -1) {
207 195
                    good = i;
208 196
                    keep = pte1;
209 197
                } else {
210 198
                    /* All matches should have equal RPN, WIMG & PP */
211 199
                    if ((keep & 0xFFFFF07B) != (pte1 & 0xFFFFF07B)) {
212
                        printf("Bad RPN/WIMG/PP\n");
200
			if (loglevel > 0)
201
			    fprintf(logfile, "Bad RPN/WIMG/PP\n");
213 202
                        return -1;
214 203
                    }
215 204
                }
216 205
                /* Check access rights */
217 206
                if (key == 0) {
218
                    *prot = PROT_READ;
207
                    access = PROT_READ;
219 208
                    if ((pte1 & 0x00000003) != 0x3)
220
                        *prot |= PROT_WRITE;
209
                        access |= PROT_WRITE;
221 210
                } else {
222 211
                    switch (pte1 & 0x00000003) {
223 212
                    case 0x0:
224
                        *prot = 0;
213
                        access = 0;
225 214
                        break;
226 215
                    case 0x1:
227 216
                    case 0x3:
228
                        *prot = PROT_READ;
217
                        access = PROT_READ;
229 218
                        break;
230 219
                    case 0x2:
231
                        *prot = PROT_READ | PROT_WRITE;
220
                        access = PROT_READ | PROT_WRITE;
232 221
                        break;
233 222
                    }
234 223
                }
235
                if ((rw == 0 && *prot != 0) ||
236
                    (rw == 1 && (*prot & PROT_WRITE))) {
224
                if (ret < 0) {
225
		    if ((rw == 0 && (access & PROT_READ)) ||
226
			(rw == 1 && (access & PROT_WRITE))) {
237 227
#if defined (DEBUG_MMU)
238
                    printf("PTE access granted !\n");
228
			if (loglevel > 0)
229
			    fprintf(logfile, "PTE access granted !\n");
239 230
#endif
240 231
                    good = i;
241 232
                    keep = pte1;
242 233
                    ret = 0;
243
                } else if (ret == -1) {
244
                    ret = -2; /* Access right violation */
234
		    } else {
235
			/* Access right violation */
236
			ret = -2;
245 237
#if defined (DEBUG_MMU)
246
                    printf("PTE access rejected\n");
238
			if (loglevel > 0)
239
			    fprintf(logfile, "PTE access rejected\n");
247 240
#endif
248 241
                }
242
		    *prot = access;
243
		}
249 244
            }
250 245
        }
251 246
    }
252 247
    if (good != -1) {
253 248
        *RPN = keep & 0xFFFFF000;
254 249
#if defined (DEBUG_MMU)
255
        printf("found PTE at addr 0x%08x prot=0x%01x ret=%d\n",
250
	if (loglevel > 0) {
251
	    fprintf(logfile, "found PTE at addr 0x%08x prot=0x%01x ret=%d\n",
256 252
               *RPN, *prot, ret);
253
	}
257 254
#endif
258 255
        /* Update page flags */
259 256
        if (!(keep & 0x00000100)) {
257
	    /* Access flag */
260 258
            keep |= 0x00000100;
261 259
            store = 1;
262 260
        }
263
        if (rw) {
264 261
            if (!(keep & 0x00000080)) {
262
	    if (rw && ret == 0) {
263
		/* Change flag */
265 264
                keep |= 0x00000080;
266 265
                store = 1;
266
	    } else {
267
		/* Force page fault for first write access */
268
		*prot &= ~PROT_WRITE;
267 269
            }
268 270
        }
269
        if (store)
270
            stl_raw((void *)(base + (good * 2) + 1), keep);
271
        if (store) {
272
	    stl_raw((void *)((uint32_t)phys_ram_base + base + (good * 8) + 4),
273
		    keep);
274
	}
271 275
    }
272 276

  
273 277
    return ret;
......
290 294

  
291 295
    sr = env->sr[virtual >> 28];
292 296
#if defined (DEBUG_MMU)
293
    printf("Check segment v=0x%08x %d 0x%08x nip=0x%08x lr=0x%08x ir=%d dr=%d "
294
           "pr=%d t=%d\n", virtual, virtual >> 28, sr, env->nip,
295
           env->lr, msr_ir, msr_dr, msr_pr, type);
297
    if (loglevel > 0) {
298
	fprintf(logfile, "Check segment v=0x%08x %d 0x%08x nip=0x%08x "
299
		"lr=0x%08x ir=%d dr=%d pr=%d %d t=%d\n",
300
		virtual, virtual >> 28, sr, env->nip,
301
		env->lr, msr_ir, msr_dr, msr_pr, rw, type);
302
    }
296 303
#endif
297
    key = ((sr & 0x20000000) && msr_pr == 1) ||
298
        ((sr & 0x40000000) && msr_pr == 0) ? 1 : 0;
304
    key = (((sr & 0x20000000) && msr_pr == 1) ||
305
        ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0;
299 306
    if ((sr & 0x80000000) == 0) {
300 307
#if defined (DEBUG_MMU)
301
        printf("pte segment: key=%d n=0x%08x\n", key, sr & 0x10000000);
308
	if (loglevel > 0)
309
	    fprintf(logfile, "pte segment: key=%d n=0x%08x\n",
310
		    key, sr & 0x10000000);
302 311
#endif
303 312
        /* Check if instruction fetch is allowed, if needed */
304 313
        if (type != ACCESS_CODE || (sr & 0x10000000) == 0) {
305 314
            /* Page address translation */
306 315
            vsid = sr & 0x00FFFFFF;
307 316
            pgidx = (virtual >> 12) & 0xFFFF;
308
            sdr = env->spr[SDR1];
309
            hash = ((vsid ^ pgidx) & 0x07FFFF) << 6;
317
            sdr = env->sdr1;
318
            hash = ((vsid ^ pgidx) & 0x0007FFFF) << 6;
310 319
            mask = ((sdr & 0x000001FF) << 16) | 0xFFC0;
311 320
            pg_addr = get_pgaddr(sdr, hash, mask);
312 321
            ptem = (vsid << 7) | (pgidx >> 10);
313 322
#if defined (DEBUG_MMU)
314
            printf("0 sdr1=0x%08x vsid=0x%06x api=0x%04x hash=0x%07x "
315
                   "pg_addr=0x%08x\n", sdr, vsid, pgidx, hash, pg_addr);
323
	    if (loglevel > 0) {
324
		fprintf(logfile, "0 sdr1=0x%08x vsid=0x%06x api=0x%04x "
325
			"hash=0x%07x pg_addr=0x%08x\n", sdr, vsid, pgidx, hash,
326
			pg_addr);
327
	    }
316 328
#endif
317 329
            /* Primary table lookup */
318 330
            ret = find_pte(real, prot, pg_addr, ptem, 0, key, rw);
......
321 333
                hash = (~hash) & 0x01FFFFC0;
322 334
                pg_addr = get_pgaddr(sdr, hash, mask);
323 335
#if defined (DEBUG_MMU)
324
                printf("1 sdr1=0x%08x vsid=0x%06x api=0x%04x hash=0x%05x "
325
                       "pg_addr=0x%08x\n", sdr, vsid, pgidx, hash, pg_addr);
336
		if (virtual != 0xEFFFFFFF && loglevel > 0) {
337
		    fprintf(logfile, "1 sdr1=0x%08x vsid=0x%06x api=0x%04x "
338
			    "hash=0x%05x pg_addr=0x%08x\n", sdr, vsid, pgidx,
339
			    hash, pg_addr);
340
		}
326 341
#endif
327 342
                ret2 = find_pte(real, prot, pg_addr, ptem, 1, key, rw);
328 343
                if (ret2 != -1)
329 344
                    ret = ret2;
330 345
            }
331
            if (ret != -1)
332
                *real |= (virtual & 0x00000FFF);
333
            if (ret == -2 && type == ACCESS_CODE && (sr & 0x10000000))
334
                ret = -3;
335 346
        } else {
336 347
#if defined (DEBUG_MMU)
337
            printf("No access allowed\n");
348
	    if (loglevel > 0)
349
		fprintf(logfile, "No access allowed\n");
338 350
#endif
351
	    ret = -3;
339 352
        }
340 353
    } else {
341 354
#if defined (DEBUG_MMU)
342
        printf("direct store...\n");
355
        if (loglevel > 0)
356
	    fprintf(logfile, "direct store...\n");
343 357
#endif
344 358
        /* Direct-store segment : absolutely *BUGGY* for now */
345 359
        switch (type) {
......
393 407
    if (loglevel > 0) {
394 408
        fprintf(logfile, "%s\n", __func__);
395 409
    }
410
    
396 411
    if ((access_type == ACCESS_CODE && msr_ir == 0) || msr_dr == 0) {
397 412
        /* No address translation */
398
        *physical = address;
413
        *physical = address & ~0xFFF;
399 414
        *prot = PROT_READ | PROT_WRITE;
400 415
        ret = 0;
401 416
    } else {
......
406 421
            ret = get_segment(env, physical, prot, address, rw, access_type);
407 422
        }
408 423
    }
424
    if (loglevel > 0) {
425
        fprintf(logfile, "%s address %08x => %08x\n",
426
		__func__, address, *physical);
427
    }
409 428
    
410 429
    return ret;
411 430
}
......
448 467
   NULL, it means that the function was called in C code (i.e. not
449 468
   from generated code or from helper.c) */
450 469
/* XXX: fix it to restore all registers */
451
void tlb_fill(unsigned long addr, int is_write, int flags, void *retaddr)
470
void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr)
452 471
{
453 472
    TranslationBlock *tb;
454
    int ret, is_user;
455
    unsigned long pc;
456 473
    CPUState *saved_env;
474
    unsigned long pc;
475
    int ret;
457 476

  
458 477
    /* XXX: hack to restore env in all cases, even if not called from
459 478
       generated code */
460 479
    saved_env = env;
461 480
    env = cpu_single_env;
462
    is_user = flags & 0x01;
463 481
    {
464 482
        unsigned long tlb_addrr, tlb_addrw;
465 483
        int index;
......
474 492
               tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK));
475 493
#endif
476 494
    }
477
    ret = cpu_handle_mmu_fault(env, addr, is_write, flags, 1);
495
    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1);
478 496
    if (ret) {
479 497
        if (retaddr) {
480 498
            /* now we have a real cpu fault */
......
506 524
    env = saved_env;
507 525
}
508 526

  
509
void cpu_ppc_init_mmu(CPUPPCState *env)
527
void cpu_ppc_init_mmu(CPUState *env)
510 528
{
511 529
    /* Nothing to do: all translation are disabled */
512 530
}
......
514 532

  
515 533
/* Perform address translation */
516 534
int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
517
                              int flags, int is_softmmu)
535
                              int is_user, int is_softmmu)
518 536
{
519 537
    uint32_t physical;
520 538
    int prot;
521 539
    int exception = 0, error_code = 0;
522
    int is_user, access_type;
540
    int access_type;
523 541
    int ret = 0;
524 542

  
525 543
//    printf("%s 0\n", __func__);
526
    is_user = flags & 0x01;
527 544
    access_type = env->access_type;
528 545
    if (env->user_mode_only) {
529 546
        /* user mode only emulation */
530 547
        ret = -1;
531 548
        goto do_fault;
532 549
    }
550
    /* NASTY BUG workaround */
551
    if (access_type == ACCESS_CODE && rw) {
552
	//	printf("%s: ERROR WRITE CODE ACCESS\n", __func__);
553
	access_type = ACCESS_INT;
554
    }
533 555
    ret = get_physical_address(env, &physical, &prot,
534 556
                               address, rw, access_type);
535 557
    if (ret == 0) {
536
        ret = tlb_set_page(env, address, physical, prot, is_user, is_softmmu);
558
	ret = tlb_set_page(env, address & ~0xFFF, physical, prot,
559
			   is_user, is_softmmu);
537 560
    } else if (ret < 0) {
538 561
    do_fault:
539 562
#if defined (DEBUG_MMU)
540
        printf("%s 5\n", __func__);
541
        printf("nip=0x%08x LR=0x%08x CTR=0x%08x MSR=0x%08x TBL=0x%08x\n",
542
               env->nip, env->lr, env->ctr, /*msr*/0, env->tb[0]);
543
        {
544
            int  i;
545
            for (i = 0; i < 32; i++) {
546
                if ((i & 7) == 0)
547
                    printf("GPR%02d:", i);
548
                printf(" %08x", env->gpr[i]);
549
                if ((i & 7) == 7)
550
                    printf("\n");
551
            }
552
            printf("CR: 0x");
553
            for (i = 0; i < 8; i++)
554
                printf("%01x", env->crf[i]);
555
            printf("  [");
556
            for (i = 0; i < 8; i++) {
557
                char a = '-';
558
                if (env->crf[i] & 0x08)
559
                    a = 'L';
560
                else if (env->crf[i] & 0x04)
561
                    a = 'G';
562
                else if (env->crf[i] & 0x02)
563
                    a = 'E';
564
                printf(" %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
565
            }
566
            printf(" ] ");
567
        }
568
        printf("TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);
569
        printf("SRR0 0x%08x SRR1 0x%08x\n", env->spr[SRR0], env->spr[SRR1]);
563
	if (loglevel > 0)
564
	    cpu_ppc_dump_state(env, logfile, 0);
570 565
#endif
571 566
        if (access_type == ACCESS_CODE) {
572 567
            exception = EXCP_ISI;
......
580 575
                error_code = EXCP_ISI_PROT;
581 576
                break;
582 577
            case -3:
578
		/* No execute protection violation */
583 579
                error_code = EXCP_ISI_NOEXEC;
584 580
                break;
585 581
            case -4:
586 582
                /* Direct store exception */
587 583
                /* No code fetch is allowed in direct-store areas */
588
                exception = EXCP_ISI;
589
                error_code = EXCP_ISI_NOEXEC;
584
                error_code = EXCP_ISI_DIRECT;
590 585
                break;
591 586
            }
592 587
        } else {
......
612 607
                    /* lwarx, ldarx or srwcx. */
613 608
                    exception = EXCP_DSI;
614 609
                    error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT;
615
                    if (rw)
616
                        error_code |= EXCP_DSI_STORE;
617 610
                    break;
618 611
                case ACCESS_EXT:
619 612
                    /* eciwx or ecowx */
620 613
                    exception = EXCP_DSI;
621
                    error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT | EXCP_ECXW;
614
                    error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT |
615
			EXCP_DSI_ECXW;
622 616
                    break;
623 617
                default:
618
		    printf("DSI: invalid exception (%d)\n", ret);
624 619
                    exception = EXCP_PROGRAM;
625 620
                    error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
626 621
                    break;
......
628 623
            }
629 624
            if (rw)
630 625
                error_code |= EXCP_DSI_STORE;
631
            /* Should find a better solution:
632
             * this will be invalid for some exception if more than one
633
             * exception occurs for one instruction
634
             */
635
            env->spr[DSISR] = 0;
636
            if (error_code & EXCP_DSI_DIRECT) {
637
                env->spr[DSISR] |= 0x80000000;
638
                if (access_type == ACCESS_EXT ||
639
                    access_type == ACCESS_RES)
640
                    env->spr[DSISR] |= 0x04000000;
641
            }
642
            if ((error_code & 0xF) == EXCP_DSI_TRANSLATE)
643
                env->spr[DSISR] |= 0x40000000;
644
            if (error_code & EXCP_DSI_PROT)
645
                env->spr[DSISR] |= 0x08000000;
646
            if (error_code & EXCP_DSI_STORE)
647
                env->spr[DSISR] |= 0x02000000;
648
            if ((error_code & 0xF) == EXCP_DSI_DABR)
649
                env->spr[DSISR] |= 0x00400000;
650
            if (access_type == ACCESS_EXT)
651
                env->spr[DSISR] |= 0x00100000;
626
	    /* Store fault address */
627
	    env->spr[DAR] = address;
652 628
        }
653 629
#if 0
654 630
        printf("%s: set exception to %d %02x\n",
......
656 632
#endif
657 633
        env->exception_index = exception;
658 634
        env->error_code = error_code;
659
        /* Store fault address */
660
        env->spr[DAR] = address;
661 635
        ret = 1;
662 636
    }
663 637

  
664 638
    return ret;
665 639
}
666 640

  
667
uint32_t _load_xer (void)
641
uint32_t _load_xer (CPUState *env)
668 642
{
669 643
    return (xer_so << XER_SO) |
670 644
        (xer_ov << XER_OV) |
......
672 646
        (xer_bc << XER_BC);
673 647
}
674 648

  
675
void _store_xer (uint32_t value)
649
void _store_xer (CPUState *env, uint32_t value)
676 650
{
677 651
    xer_so = (value >> XER_SO) & 0x01;
678 652
    xer_ov = (value >> XER_OV) & 0x01;
......
680 654
    xer_bc = (value >> XER_BC) & 0x1f;
681 655
}
682 656

  
683
uint32_t _load_msr (void)
657
uint32_t _load_msr (CPUState *env)
684 658
{
685 659
    return (msr_pow << MSR_POW) |
686 660
        (msr_ile << MSR_ILE) |
......
699 673
        (msr_le << MSR_LE);
700 674
}
701 675

  
702
void _store_msr (uint32_t value)
676
void _store_msr (CPUState *env, uint32_t value)
703 677
{
678
    if (((T0 >> MSR_IR) & 0x01) != msr_ir ||
679
        ((T0 >> MSR_DR) & 0x01) != msr_dr) {
680
        /* Flush all tlb when changing translation mode or privilege level */
681
        do_tlbia();
682
    }
704 683
    msr_pow = (value >> MSR_POW) & 0x03;
705 684
    msr_ile = (value >> MSR_ILE) & 0x01;
706 685
    msr_ee = (value >> MSR_EE) & 0x01;
......
729 708
    /* Dequeue PPC exceptions */
730 709
    if (excp < EXCP_PPC_MAX)
731 710
        env->exceptions &= ~(1 << excp);
732
    msr = _load_msr();
711
    msr = _load_msr(env);
733 712
#if defined (DEBUG_EXCEPTIONS)
734
    if (excp != EXCP_DECR && excp == EXCP_PROGRAM && excp < EXCP_PPC_MAX) 
713
    if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) 
735 714
    {
736 715
        if (loglevel > 0) {
737 716
            fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",
738 717
                    env->nip, excp << 8, env->error_code);
739
        } else {
740
            printf("Raise exception at 0x%08x => 0x%08x (%02x)\n",
741
                   env->nip, excp << 8, env->error_code);
742
        }
743
        printf("nip=0x%08x LR=0x%08x CTR=0x%08x MSR=0x%08x DECR=0x%08x\n",
744
               env->nip, env->lr, env->ctr, msr, env->decr);
745
        {
746
    int i;
747
            for (i = 0; i < 32; i++) {
748
                if ((i & 7) == 0)
749
                    printf("GPR%02d:", i);
750
                printf(" %08x", env->gpr[i]);
751
                if ((i & 7) == 7)
752
                    printf("\n");
753
    }
754
            printf("CR: 0x");
755
    for (i = 0; i < 8; i++)
756
                printf("%01x", env->crf[i]);
757
            printf("  [");
758
            for (i = 0; i < 8; i++) {
759
                char a = '-';
760
                if (env->crf[i] & 0x08)
761
                    a = 'L';
762
                else if (env->crf[i] & 0x04)
763
                    a = 'G';
764
                else if (env->crf[i] & 0x02)
765
                    a = 'E';
766
                printf(" %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
767 718
    }
768
            printf(" ] ");
769
    }
770
        printf("TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);
771
        printf("XER 0x%08x SRR0 0x%08x SRR1 0x%08x\n",
772
               _load_xer(), env->spr[SRR0], env->spr[SRR1]);
719
	if (loglevel > 0)
720
	    cpu_ppc_dump_state(env, logfile, 0);
773 721
    }
774 722
#endif
775 723
    /* Generate informations in save/restore registers */
......
812 760
        /* data location address has been stored
813 761
         * when the fault has been detected
814 762
     */
815
        goto store_current;
763
	msr &= ~0xFFFF0000;
764
	env->spr[DSISR] = 0;
765
	if (env->error_code &  EXCP_DSI_TRANSLATE)
766
	    env->spr[DSISR] |= 0x40000000;
767
	else if (env->error_code & EXCP_DSI_PROT)
768
	    env->spr[DSISR] |= 0x08000000;
769
	else if (env->error_code & EXCP_DSI_NOTSUP) {
770
	    env->spr[DSISR] |= 0x80000000;
771
	    if (env->error_code & EXCP_DSI_DIRECT)
772
		env->spr[DSISR] |= 0x04000000;
773
	}
774
	if (env->error_code & EXCP_DSI_STORE)
775
	    env->spr[DSISR] |= 0x02000000;
776
	if ((env->error_code & 0xF) == EXCP_DSI_DABR)
777
	    env->spr[DSISR] |= 0x00400000;
778
	if (env->error_code & EXCP_DSI_ECXW)
779
	    env->spr[DSISR] |= 0x00100000;
780
#if defined (DEBUG_EXCEPTIONS)
781
	if (loglevel) {
782
	    fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
783
		    env->spr[DSISR], env->spr[DAR]);
784
	} else {
785
	    printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",
786
		   env->spr[DSISR], env->spr[DAR], env->nip);
787
	}
788
#endif
789
        goto store_next;
816 790
    case EXCP_ISI:
817 791
        /* Store exception cause */
792
	msr &= ~0xFFFF0000;
818 793
        if (env->error_code == EXCP_ISI_TRANSLATE)
819 794
            msr |= 0x40000000;
820 795
        else if (env->error_code == EXCP_ISI_NOEXEC ||
821
            env->error_code == EXCP_ISI_GUARD)
796
		 env->error_code == EXCP_ISI_GUARD ||
797
		 env->error_code == EXCP_ISI_DIRECT)
822 798
            msr |= 0x10000000;
823 799
        else
824 800
            msr |= 0x08000000;
801
#if defined (DEBUG_EXCEPTIONS)
802
	if (loglevel) {
803
	    fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",
804
		    msr, env->nip);
805
	} else {
806
	    printf("ISI exception: msr=0x%08x, nip=0x%08x tbl:0x%08x\n",
807
		   msr, env->nip, env->spr[V_TBL]);
808
	}
809
#endif
825 810
        goto store_next;
826 811
    case EXCP_EXTERNAL:
827 812
        if (msr_ee == 0) {
828 813
#if defined (DEBUG_EXCEPTIONS)
829 814
            if (loglevel > 0) {
830 815
                fprintf(logfile, "Skipping hardware interrupt\n");
831
            } else {
832
                printf("Skipping hardware interrupt\n");
833 816
    }
834 817
#endif
818
            /* Requeue it */
819
            do_queue_exception(EXCP_EXTERNAL);
835 820
            return;
836 821
            }
837 822
        goto store_next;
......
863 848
                env->fpscr[7] |= 0x4;
864 849
        break;
865 850
        case EXCP_INVAL:
851
	    printf("Invalid instruction at 0x%08x\n", env->nip);
866 852
            msr |= 0x00080000;
867 853
        break;
868 854
        case EXCP_PRIV:
......
888 874
        goto store_next;
889 875
    case EXCP_SYSCALL:
890 876
#if defined (DEBUG_EXCEPTIONS)
891
        printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",
892
               env->gpr[0], env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
877
	if (msr_pr) {
878
	    if (loglevel) {
879
		fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",
880
			env->gpr[0], env->gpr[3], env->gpr[4],
881
			env->gpr[5], env->gpr[6]);
882
	    } else {
883
		printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
884
		       env->gpr[0], env->nip, env->gpr[3], env->gpr[4],
885
		       env->gpr[5], env->gpr[6]);
886
	    }
887
	}
893 888
#endif
894 889
        goto store_next;
895 890
    case EXCP_TRACE:
......
898 893
        goto store_next;
899 894
    case EXCP_MTMSR:
900 895
        /* Nothing to do */
901
#if defined (DEBUG_EXCEPTIONS)
902
        printf("%s: escape EXCP_MTMSR\n", __func__);
903
#endif
904 896
        return;
905 897
    case EXCP_BRANCH:
906 898
        /* Nothing to do */
907
#if defined (DEBUG_EXCEPTIONS)
908
        printf("%s: escape EXCP_BRANCH\n", __func__);
909
#endif
910 899
        return;
911 900
    case EXCP_RFI:
912 901
        /* Restore user-mode state */
902
	tb_flush(env);
913 903
#if defined (DEBUG_EXCEPTIONS)
914
        printf("%s: escape EXCP_RFI\n", __func__);
904
	if (msr_pr == 1)
905
	    printf("Return from exception => 0x%08x\n", (uint32_t)env->nip);
915 906
#endif
916 907
        return;
917 908
    store_current:

Also available in: Unified diff