Revision 9fddaa0c

b/cpu-all.h
627 627
   if no page found. */
628 628
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
629 629

  
630
#define CPU_LOG_TB_OUT_ASM  (1 << 0) 
631
#define CPU_LOG_TB_IN_ASM     (1 << 1)
630
#define CPU_LOG_TB_OUT_ASM (1 << 0) 
631
#define CPU_LOG_TB_IN_ASM  (1 << 1)
632 632
#define CPU_LOG_TB_OP      (1 << 2)
633 633
#define CPU_LOG_TB_OP_OPT  (1 << 3)
634 634
#define CPU_LOG_INT        (1 << 4)
635 635
#define CPU_LOG_EXEC       (1 << 5)
636 636
#define CPU_LOG_PCALL      (1 << 6)
637 637
#define CPU_LOG_IOPORT     (1 << 7)
638
#define CPU_LOG_TB_CPU     (1 << 8)
638 639

  
639 640
/* define log items */
640 641
typedef struct CPULogItem {
b/cpu-exec.c
241 241
#endif
242 242
                    }
243 243
#elif defined(TARGET_PPC)
244
#if 0
245
                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {
246
                        cpu_ppc_reset(env);
247
                    }
248
#endif
249
                    if (msr_ee != 0) {
244 250
                    if ((interrupt_request & CPU_INTERRUPT_HARD)) {
245
                        do_queue_exception(EXCP_EXTERNAL);
246
                        if (check_exception_state(env))
251
			    /* Raise it */
252
			    env->exception_index = EXCP_EXTERNAL;
253
			    env->error_code = 0;
247 254
                            do_interrupt(env);
248 255
                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
256
			} else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {
257
			    /* Raise it */
258
			    env->exception_index = EXCP_DECR;
259
			    env->error_code = 0;
260
			    do_interrupt(env);
261
                            env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
262
			}
249 263
                    }
250 264
#endif
251 265
                    if (interrupt_request & CPU_INTERRUPT_EXITTB) {
......
757 771
    /* we restore the process signal mask as the sigreturn should
758 772
       do it (XXX: use sigsetjmp) */
759 773
        sigprocmask(SIG_SETMASK, old_set, NULL);
760
        do_queue_exception_err(env->exception_index, env->error_code);
774
        do_raise_exception_err(env->exception_index, env->error_code);
761 775
    } else {
762 776
        /* activate soft MMU for this block */
763 777
        cpu_resume_from_signal(env, puc);
b/exec.c
1132 1132
      "show interrupts/exceptions in short format" },
1133 1133
    { CPU_LOG_EXEC, "exec",
1134 1134
      "show trace before each executed TB (lots of logs)" },
1135
    { CPU_LOG_TB_CPU, "cpu",
1136
      "show CPU state before bloc translation" },
1135 1137
#ifdef TARGET_I386
1136 1138
    { CPU_LOG_PCALL, "pcall",
1137 1139
      "show protected mode far calls/returns/exceptions" },
b/hw/ppc.c
28 28
		    const char *kernel_filename, const char *kernel_cmdline,
29 29
		    const char *initrd_filename);
30 30

  
31
/*****************************************************************************/
32
/* PPC time base and decrementer emulation */
33
//#define DEBUG_TB
34

  
35
struct ppc_tb_t {
36
    /* Time base management */
37
    int64_t  tb_offset;    /* Compensation               */
38
    uint32_t tb_freq;      /* TB frequency               */
39
    /* Decrementer management */
40
    uint64_t decr_next;    /* Tick for next decr interrupt  */
41
    struct QEMUTimer *decr_timer;
42
};
43

  
44
static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
45
{
46
    /* TB time in tb periods */
47
    return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
48
		    tb_env->tb_freq, ticks_per_sec);
49
}
50

  
51
uint32_t cpu_ppc_load_tbl (CPUState *env)
52
{
53
    ppc_tb_t *tb_env = env->tb_env;
54
    uint64_t tb;
55

  
56
    tb = cpu_ppc_get_tb(tb_env);
57
#ifdef DEBUG_TB
58
    {
59
         static int last_time;
60
	 int now;
61
	 now = time(NULL);
62
	 if (last_time != now) {
63
	     last_time = now;
64
	     printf("%s: tb=0x%016lx %d %08lx\n",
65
                    __func__, tb, now, tb_env->tb_offset);
66
	 }
67
    }
68
#endif
69

  
70
    return tb & 0xFFFFFFFF;
71
}
72

  
73
uint32_t cpu_ppc_load_tbu (CPUState *env)
74
{
75
    ppc_tb_t *tb_env = env->tb_env;
76
    uint64_t tb;
77

  
78
    tb = cpu_ppc_get_tb(tb_env);
79
#ifdef DEBUG_TB
80
    printf("%s: tb=0x%016lx\n", __func__, tb);
81
#endif
82
    return tb >> 32;
83
}
84

  
85
static void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t value)
86
{
87
    tb_env->tb_offset = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
88
        - qemu_get_clock(vm_clock);
89
#ifdef DEBUG_TB
90
    printf("%s: tb=0x%016lx offset=%08x\n", __func__, value);
91
#endif
92
}
93

  
94
void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
95
{
96
    ppc_tb_t *tb_env = env->tb_env;
97

  
98
    cpu_ppc_store_tb(tb_env,
99
                     ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
100
}
101

  
102
void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
103
{
104
    ppc_tb_t *tb_env = env->tb_env;
105

  
106
    cpu_ppc_store_tb(tb_env,
107
                     ((uint64_t)cpu_ppc_load_tbu(env) << 32) | value);
108
}
109

  
110
uint32_t cpu_ppc_load_decr (CPUState *env)
111
{
112
    ppc_tb_t *tb_env = env->tb_env;
113
    uint32_t decr;
114

  
115
    decr = muldiv64(tb_env->decr_next - qemu_get_clock(vm_clock),
116
                    tb_env->tb_freq, ticks_per_sec);
117
#ifdef DEBUG_TB
118
    printf("%s: 0x%08x\n", __func__, decr);
119
#endif
120

  
121
    return decr;
122
}
123

  
124
/* When decrementer expires,
125
 * all we need to do is generate or queue a CPU exception
126
 */
127
static inline void cpu_ppc_decr_excp (CPUState *env)
128
{
129
    /* Raise it */
130
#ifdef DEBUG_TB
131
    printf("raise decrementer exception\n");
132
#endif
133
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
134
}
135

  
136
static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
137
                                 uint32_t value, int is_excp)
138
{
139
    ppc_tb_t *tb_env = env->tb_env;
140
    uint64_t now, next;
141

  
142
#ifdef DEBUG_TB
143
    printf("%s: 0x%08x => 0x%08x\n", __func__, decr, value);
144
#endif
145
    now = qemu_get_clock(vm_clock);
146
    next = now + muldiv64(value, ticks_per_sec, tb_env->tb_freq);
147
    if (is_excp)
148
        next += tb_env->decr_next - now;
149
    if (next == now)
150
	next++;
151
    tb_env->decr_next = next;
152
    /* Adjust timer */
153
    qemu_mod_timer(tb_env->decr_timer, next);
154
    /* If we set a negative value and the decrementer was positive,
155
     * raise an exception.
156
     */
157
    if ((value & 0x80000000) && !(decr & 0x80000000))
158
	cpu_ppc_decr_excp(env);
159
}
160

  
161
void cpu_ppc_store_decr (CPUState *env, uint32_t value)
162
{
163
    _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
164
}
165

  
166
static void cpu_ppc_decr_cb (void *opaque)
167
{
168
    _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
169
}
170

  
171
/* Set up (once) timebase frequency (in Hz) */
172
ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq)
173
{
174
    ppc_tb_t *tb_env;
175

  
176
    tb_env = qemu_mallocz(sizeof(ppc_tb_t));
177
    if (tb_env == NULL)
178
        return NULL;
179
    env->tb_env = tb_env;
180
    if (tb_env->tb_freq == 0 || 1) {
181
	tb_env->tb_freq = freq;
182
	/* Create new timer */
183
	tb_env->decr_timer =
184
            qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
185
	/* There is a bug in  2.4 kernels:
186
	 * if a decrementer exception is pending when it enables msr_ee,
187
	 * it's not ready to handle it...
188
	 */
189
	_cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
190
    }
191

  
192
    return tb_env;
193
}
194

  
195
#if 0
196
/*****************************************************************************/
197
/* Handle system reset (for now, just stop emulation) */
198
void cpu_ppc_reset (CPUState *env)
199
{
200
    printf("Reset asked... Stop emulation\n");
201
    abort();
202
}
203
#endif
204

  
205
/*****************************************************************************/
31 206
void ppc_init (int ram_size, int vga_ram_size, int boot_device,
32 207
	       DisplayState *ds, const char **fd_filename, int snapshot,
33 208
	       const char *kernel_filename, const char *kernel_cmdline,
b/hw/ppc_prep.c
24 24
#include "vl.h"
25 25
#include "m48t59.h"
26 26

  
27
/* XXX: move all TB related stuff in ppc_prep.c and suppress ppc.c ? */
28
ppc_tb_t *cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq);
29

  
27 30
//#define HARD_DEBUG_PPC_IO
28 31
//#define DEBUG_PPC_IO
29 32

  
......
663 666
static void VGA_init (void)
664 667
{
665 668
    /* Basic VGA init, inspired by plex86 VGAbios */
666
    printf("Init VGA...\n");
667 669
#if 1
668 670
    /* switch to color mode and enable CPU access 480 lines */
669 671
    PPC_io_writeb(PPC_IO_BASE + 0x3C2, 0xC3);
......
725 727
     * if a decrementer exception is pending when it enables msr_ee,
726 728
     * it's not ready to handle it...
727 729
     */
728
    env->decr = 0xFFFFFFFF;
729 730
    p = phys_ram_base + kernel_addr;
730 731
#if !defined (USE_OPEN_FIRMWARE)
731 732
    /* Let's register the whole memory available only in supervisor mode */
......
948 949
	}
949 950
    }
950 951

  
952
    cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
953

  
951 954
    /* init basic PC hardware */
952 955
    vga_initialize(ds, phys_ram_base + ram_size, ram_size, 
953 956
                   vga_ram_size, 0);
b/linux-user/main.c
504 504
#endif
505 505

  
506 506
#ifdef TARGET_PPC
507

  
508
static inline uint64_t cpu_ppc_get_tb (CPUState *env)
509
{
510
    /* TO FIX */
511
    return 0;
512
}
513
  
514
uint32_t cpu_ppc_load_tbl (CPUState *env)
515
{
516
    return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
517
}
518
  
519
uint32_t cpu_ppc_load_tbu (CPUState *env)
520
{
521
    return cpu_ppc_get_tb(env) >> 32;
522
}
523
  
524
static void cpu_ppc_store_tb (CPUState *env, uint64_t value)
525
{
526
    /* TO FIX */
527
}
528

  
529
void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
530
{
531
    cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
532
}
533
 
534
void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
535
{
536
    cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
537
}
538
  
539
uint32_t cpu_ppc_load_decr (CPUState *env)
540
{
541
    /* TO FIX */
542
    return -1;
543
}
544
 
545
void cpu_ppc_store_decr (CPUState *env, uint32_t value)
546
{
547
    /* TO FIX */
548
}
549
 
507 550
void cpu_loop(CPUPPCState *env)
508 551
{
509 552
    target_siginfo_t info;
......
812 855
            abort();
813 856
        case EXCP_MTMSR:
814 857
            /* We reloaded the msr, just go on */
815
            if (msr_pr) {
858
            if (msr_pr == 0) {
816 859
                fprintf(stderr, "Tried to go into supervisor mode !\n");
817 860
                if (loglevel)
818 861
                    fprintf(logfile, "Tried to go into supervisor mode !\n");
......
842 885
            }
843 886
            abort();
844 887
        }
845
        if (trapnr < EXCP_PPC_MAX)
846
            env->exceptions &= ~(1 << trapnr);
847 888
        process_pending_signals(env);
848
        if (env->exceptions != 0) {
849
            check_exception_state(env);
850
        }
851 889
    }
852 890
}
853 891
#endif
b/monitor.c
589 589
        (cpu_single_env->xer[XER_CA] << XER_CA) |
590 590
        (cpu_single_env->xer[XER_BC] << XER_BC);
591 591
}
592

  
593
uint32_t cpu_ppc_load_decr (CPUState *env);
594
static int monitor_get_decr (struct MonitorDef *md)
595
{
596
    return cpu_ppc_load_decr(cpu_single_env);
597
}
598

  
599
uint32_t cpu_ppc_load_tbu (CPUState *env);
600
static int monitor_get_tbu (struct MonitorDef *md)
601
{
602
    return cpu_ppc_load_tbu(cpu_single_env);
603
}
604

  
605
uint32_t cpu_ppc_load_tbl (CPUState *env);
606
static int monitor_get_tbl (struct MonitorDef *md)
607
{
608
    return cpu_ppc_load_tbl(cpu_single_env);
609
}
592 610
#endif
593 611

  
594 612
static MonitorDef monitor_defs[] = {
......
651 669
    { "nip|pc", offsetof(CPUState, nip) },
652 670
    { "lr", offsetof(CPUState, lr) },
653 671
    { "ctr", offsetof(CPUState, ctr) },
654
    { "decr", offsetof(CPUState, decr) },
672
    { "decr", 0, &monitor_get_decr, },
655 673
    { "ccr", 0, &monitor_get_ccr, },
656 674
    { "msr", 0, &monitor_get_msr, },
657 675
    { "xer", 0, &monitor_get_xer, },
658
    { "tbu", offsetof(CPUState, tb[0]) },
659
    { "tbl", offsetof(CPUState, tb[1]) },
676
    { "tbu", 0, &monitor_get_tbu, },
677
    { "tbl", 0, &monitor_get_tbl, },
660 678
    { "sdr1", offsetof(CPUState, sdr1) },
661 679
    { "sr0", offsetof(CPUState, sr[0]) },
662 680
    { "sr1", offsetof(CPUState, sr[1]) },
b/target-ppc/cpu.h
78 78
#define PPC_750 (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM |               \
79 79
                 PPC_RES | PPC_CACHE | PPC_MISC | PPC_EXTERN | PPC_SEGMENT)
80 80

  
81
typedef struct ppc_tb_t ppc_tb_t;
82

  
81 83
/* Supervisor mode registers */
82 84
/* Machine state register */
83 85
#define MSR_POW 18
......
134 136
    /* special purpose registers */
135 137
    uint32_t lr;
136 138
    uint32_t ctr;
137
    /* Time base */
138
    uint32_t tb[2];
139
    /* decrementer */
140
    uint32_t decr;
141 139
    /* BATs */
142 140
    uint32_t DBAT[2][8];
143 141
    uint32_t IBAT[2][8];
......
154 152
    int error_code;
155 153
    int access_type; /* when a memory exception occurs, the access
156 154
                        type is stored here */
157
#if 0 /* TODO */
158
    uint32_t pending_exceptions; /* For external & decr exception,
159
				  * that can be delayed */
160
#else
161
    uint32_t exceptions; /* exception queue */
162
    uint32_t errors[32];
163
#endif
164 155
    int user_mode_only; /* user mode only simulation */
165 156
    struct TranslationBlock *current_tb; /* currently executing TB */
166 157
    /* soft mmu support */
......
178 169
    /* ice debug support */
179 170
    uint32_t breakpoints[MAX_BREAKPOINTS];
180 171
    int nb_breakpoints;
181
    int brkstate;
182
    int singlestep_enabled;
172
    int singlestep_enabled; /* XXX: should use CPU single step mode instead */
173

  
174
    /* Time base and decrementer */
175
    ppc_tb_t *tb_env;
176

  
177
    /* Power management */
178
    int power_mode;
183 179

  
184 180
    /* user data */
185 181
    void *opaque;
......
206 202
uint32_t _load_msr (CPUPPCState *env);
207 203
void _store_msr (CPUPPCState *env, uint32_t value);
208 204

  
209
void PPC_init_hw (uint32_t mem_size,
210
                  uint32_t kernel_addr, uint32_t kernel_size,
211
                  uint32_t stack_addr, int boot_device,
212
		  const unsigned char *initrd_file);
205
/* Time-base and decrementer management */
206
#ifndef NO_CPU_IO_DEFS
207
uint32_t cpu_ppc_load_tbl (CPUPPCState *env);
208
uint32_t cpu_ppc_load_tbu (CPUPPCState *env);
209
void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value);
210
void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value);
211
uint32_t cpu_ppc_load_decr (CPUPPCState *env);
212
void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
213
#endif
213 214

  
214 215
#define TARGET_PAGE_BITS 12
215 216
#include "cpu-all.h"
b/target-ppc/exec.h
119 119

  
120 120
#endif /* !defined(CONFIG_USER_ONLY) */
121 121

  
122
int check_exception_state (CPUState *env);
123

  
124
void do_queue_exception_err (uint32_t exception, int error_code);
125
void do_queue_exception (uint32_t exception);
126
void do_process_exceptions (void);
127
void do_check_exception_state (void);
122
void do_raise_exception_err (uint32_t exception, int error_code);
123
void do_raise_exception (uint32_t exception);
128 124

  
129 125
void do_load_cr (void);
130 126
void do_store_cr (uint32_t mask);
b/target-ppc/helper.c
27 27
//#define DEBUG_BATS
28 28
//#define DEBUG_EXCEPTIONS
29 29

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

  
34
void cpu_loop_exit(void)
35
{
36
    longjmp(env->jmp_env, 1);
37
}
38

  
39
void do_process_exceptions (void)
40
{
41
    cpu_loop_exit();
42
}
43

  
44
int check_exception_state (CPUState *env)
45
{
46
    int i;
47

  
48
    /* Process PPC exceptions */
49
    for (i = 1; i  < EXCP_PPC_MAX; i++) {
50
        if (env->exceptions & (1 << i)) {
51
            switch (i) {
52
            case EXCP_EXTERNAL:
53
            case EXCP_DECR:
54
                if (msr_ee == 0)
55
                    return 0;
56
                break;
57
            case EXCP_PROGRAM:
58
                if (env->errors[EXCP_PROGRAM] == EXCP_FP &&
59
                    msr_fe0 == 0 && msr_fe1 == 0)
60
                    return 0;
61
                break;
62
            default:
63
                break;
64
            }
65
            env->exception_index = i;
66
            env->error_code = env->errors[i];
67
            return 1;
68
        }
69
    }
70

  
71
    return 0;
72
}
33
/*****************************************************************************/
73 34

  
74 35
/*****************************************************************************/
75 36
/* PPC MMU emulation */
......
500 461
                cpu_restore_state(tb, env, pc, NULL);
501 462
            }
502 463
        }
503
        do_queue_exception_err(env->exception_index, env->error_code);
504
        do_process_exceptions();
464
        do_raise_exception_err(env->exception_index, env->error_code);
505 465
    }
506 466
    {
507 467
        unsigned long tlb_addrr, tlb_addrw;
......
701 661
    uint32_t msr;
702 662
    int excp = env->exception_index;
703 663

  
704
    /* Dequeue PPC exceptions */
705
    if (excp < EXCP_PPC_MAX)
706
        env->exceptions &= ~(1 << excp);
707 664
    msr = _load_msr(env);
708 665
#if defined (DEBUG_EXCEPTIONS)
709 666
    if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) 
......
812 769
    }
813 770
#endif
814 771
            /* Requeue it */
815
            do_queue_exception(EXCP_EXTERNAL);
772
            do_raise_exception(EXCP_EXTERNAL);
816 773
            return;
817 774
            }
818 775
        goto store_next;
......
864 821
    case EXCP_DECR:
865 822
        if (msr_ee == 0) {
866 823
            /* Requeue it */
867
            do_queue_exception(EXCP_DECR);
824
            do_raise_exception(EXCP_DECR);
868 825
            return;
869 826
        }
870 827
        goto store_next;
......
937 894
    T0 = 0;
938 895
#endif
939 896
#endif
897
    env->exception_index = -1;
940 898
}
b/target-ppc/op.c
208 208
}
209 209

  
210 210
/* Generate exceptions */
211
PPC_OP(queue_exception_err)
211
PPC_OP(raise_exception_err)
212 212
{
213
    do_queue_exception_err(PARAM(1), PARAM(2));
213
    do_raise_exception_err(PARAM(1), PARAM(2));
214 214
}
215 215

  
216
PPC_OP(queue_exception)
216
PPC_OP(raise_exception)
217 217
{
218
    do_queue_exception(PARAM(1));
218
    do_raise_exception(PARAM(1));
219 219
}
220 220

  
221
PPC_OP(process_exceptions)
221
PPC_OP(update_nip)
222 222
{
223 223
    env->nip = PARAM(1);
224
    if (env->exceptions != 0) {
225
        do_check_exception_state();
226
    }
227 224
}
228 225

  
229 226
PPC_OP(debug)
230 227
{
231 228
    env->nip = PARAM(1);
232
    env->brkstate = 1;
233 229
#if defined (DEBUG_OP)
234 230
    dump_state();
235 231
#endif
236
    do_queue_exception(EXCP_DEBUG);
232
    do_raise_exception(EXCP_DEBUG);
237 233
    RETURN();
238 234
}
239 235

  
......
364 360
    RETURN();
365 361
}
366 362

  
367
/* Update time base */
368
PPC_OP(update_tb)
363
PPC_OP(load_tbl)
369 364
{
370
    T0 = regs->tb[0];
371
    T1 = T0;
372
    T0 += PARAM(1);
373
#if defined (DEBUG_OP)
374
    dump_update_tb(PARAM(1));
375
#endif
376
    if (T0 < T1) {
377
        T1 = regs->tb[1] + 1;
378
        regs->tb[1] = T1;
379
    }
380
    regs->tb[0] = T0;
365
    T0 = cpu_ppc_load_tbl(regs);
381 366
    RETURN();
382 367
}
383 368

  
384
PPC_OP(load_tb)
369
PPC_OP(load_tbu)
385 370
{
386
    T0 = regs->tb[PARAM(1)];
371
    T0 = cpu_ppc_load_tbu(regs);
387 372
    RETURN();
388 373
}
389 374

  
390
PPC_OP(store_tb)
375
PPC_OP(store_tbl)
391 376
{
392
    regs->tb[PARAM(1)] = T0;
393
#if defined (DEBUG_OP)
394
    dump_store_tb(PARAM(1));
395
#endif
377
    cpu_ppc_store_tbl(regs, T0);
396 378
    RETURN();
397 379
}
398 380

  
399
/* Update decrementer */
400
PPC_OP(update_decr)
381
PPC_OP(store_tbu)
401 382
{
402
    T0 = regs->decr;
403
    T1 = T0;
404
    T0 -= PARAM(1);
405
    regs->decr = T0;
406
    if (PARAM(1) > T1) {
407
        do_queue_exception(EXCP_DECR);
408
    }
383
    cpu_ppc_store_tbu(regs, T0);
409 384
    RETURN();
410 385
}
411 386

  
412
PPC_OP(store_decr)
387
PPC_OP(load_decr)
413 388
{
414
    T1 = regs->decr;
415
    regs->decr = T0;
416
    if (Ts0 < 0 && Ts1 > 0) {
417
        do_queue_exception(EXCP_DECR);
389
    T0 = cpu_ppc_load_decr(regs);
418 390
    }
391

  
392
PPC_OP(store_decr)
393
{
394
    cpu_ppc_store_decr(regs, T0);
419 395
    RETURN();
420 396
}
421 397

  
......
1471 1447
/* Return from interrupt */
1472 1448
PPC_OP(rfi)
1473 1449
{
1450
    regs->nip = regs->spr[SRR0] & ~0x00000003;
1474 1451
    T0 = regs->spr[SRR1] & ~0xFFFF0000;
1475 1452
    do_store_msr();
1476
    do_tlbia();
1477 1453
#if defined (DEBUG_OP)
1478 1454
    dump_rfi();
1479 1455
#endif
1480
    regs->nip = regs->spr[SRR0] & ~0x00000003;
1481
    do_queue_exception(EXCP_RFI);
1482
    if (env->exceptions != 0) {
1483
        do_check_exception_state();
1484
    }
1456
    //    do_tlbia();
1457
    do_raise_exception(EXCP_RFI);
1485 1458
    RETURN();
1486 1459
}
1487 1460

  
......
1493 1466
        (Ts0 == Ts1 && (PARAM(1) & 0x04)) ||
1494 1467
        (T0 < T1 && (PARAM(1) & 0x02)) ||
1495 1468
        (T0 > T1 && (PARAM(1) & 0x01)))
1496
        do_queue_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1469
        do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1497 1470
    RETURN();
1498 1471
}
1499 1472

  
......
1504 1477
        (Ts0 == SPARAM(1) && (PARAM(2) & 0x04)) ||
1505 1478
        (T0 < (uint32_t)SPARAM(1) && (PARAM(2) & 0x02)) ||
1506 1479
        (T0 > (uint32_t)SPARAM(1) && (PARAM(2) & 0x01)))
1507
        do_queue_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1480
        do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1508 1481
    RETURN();
1509 1482
}
1510 1483

  
b/target-ppc/op_helper.c
31 31

  
32 32
/*****************************************************************************/
33 33
/* Exceptions processing helpers */
34
void do_queue_exception_err (uint32_t exception, int error_code)
34
void cpu_loop_exit(void)
35 35
{
36
    /* Queue real PPC exceptions */
37
    if (exception < EXCP_PPC_MAX) {
38
        env->exceptions |= 1 << exception;
39
        env->errors[exception] = error_code;
40
    } else {
41
        /* Preserve compatibility with qemu core */
42
        env->exceptions |= 1;
43
        env->exception_index = exception;
44
        env->error_code = error_code;
45
    }
36
    longjmp(env->jmp_env, 1);
46 37
}
47 38

  
48
void do_queue_exception (uint32_t exception)
39
void do_raise_exception_err (uint32_t exception, int error_code)
49 40
{
50
    do_queue_exception_err(exception, 0);
51
}
52

  
53
void do_check_exception_state (void)
54
{
55
    if ((env->exceptions & 1) == 1 || check_exception_state(env)) {
56
        env->exceptions &= ~1;
41
#if 0
42
    printf("Raise exception %3x code : %d\n", exception, error_code);
43
#endif
44
    switch (exception) {
45
    case EXCP_EXTERNAL:
46
    case EXCP_DECR:
47
	printf("DECREMENTER & EXTERNAL exceptions should be hard interrupts !\n");
48
	if (msr_ee == 0)
49
	    return;
50
	break;
51
    case EXCP_PROGRAM:
52
	if (error_code == EXCP_FP && msr_fe0 == 0 && msr_fe1 == 0)
53
	    return;
54
	break;
55
    default:
56
	break;
57
}
58
    env->exception_index = exception;
59
    env->error_code = error_code;
57 60
        cpu_loop_exit();
58 61
    }
62

  
63
void do_raise_exception (uint32_t exception)
64
{
65
    do_raise_exception_err(exception, 0);
59 66
}
60 67

  
61 68
/*****************************************************************************/
......
125 132
        /* Flush all tlb when changing translation mode or privilege level */
126 133
        do_tlbia();
127 134
    }
128
#if 0
129
    if ((T0 >> MSR_IP) & 0x01) {
130
        printf("Halting CPU. Stop emulation\n");
131
        do_queue_exception(EXCP_HLT);
132
        cpu_loop_exit();
133
    }
134
#endif
135 135
    msr_pow = (T0 >> MSR_POW) & 0x03;
136 136
    msr_ile = (T0 >> MSR_ILE) & 0x01;
137 137
    msr_ee = (T0 >> MSR_EE) & 0x01;
b/target-ppc/op_mem.h
97 97
    if (T1 > 0) {
98 98
        if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) ||
99 99
            (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) {
100
            do_queue_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
101
            do_process_exceptions();
100
            do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
102 101
        } else {
103 102
            glue(do_lsw, MEMSUFFIX)(PARAM(1));
104 103
        }
......
138 137
PPC_OP(glue(lwarx, MEMSUFFIX))
139 138
{
140 139
    if (T0 & 0x03) {
141
        do_queue_exception(EXCP_ALIGN);
142
        do_process_exceptions();
140
        do_raise_exception(EXCP_ALIGN);
143 141
    } else {
144 142
       T1 = glue(ldl, MEMSUFFIX)((void *)T0);
145 143
       regs->reserve = T0;
......
151 149
PPC_OP(glue(stwcx, MEMSUFFIX))
152 150
{
153 151
    if (T0 & 0x03) {
154
        do_queue_exception(EXCP_ALIGN);
155
        do_process_exceptions();
152
        do_raise_exception(EXCP_ALIGN);
156 153
    } else {
157 154
        if (regs->reserve != T0) {
158 155
            env->crf[0] = xer_ov;
b/target-ppc/translate.c
30 30
//#define DO_SINGLE_STEP
31 31
//#define DO_STEP_FLUSH
32 32
//#define DEBUG_DISAS
33
//#define PPC_DEBUG_DISAS
33 34

  
34 35
enum {
35 36
#define DEF(s, n, copy_size) INDEX_op_ ## s,
......
135 136
    uint32_t nip;
136 137
    uint32_t opcode;
137 138
    uint32_t exception;
138
    /* Time base offset */
139
    uint32_t tb_offset;
140
    /* Decrementer offset */
141
    uint32_t decr_offset;
142 139
    /* Execution mode */
143 140
#if !defined(CONFIG_USER_ONLY)
144 141
    int supervisor;
......
156 153
    void (*handler)(DisasContext *ctx);
157 154
} opc_handler_t;
158 155

  
159
#define RET_EXCP(excp, error)                                                 \
156
#define RET_EXCP(ctx, excp, error)                                            \
160 157
do {                                                                          \
161
    gen_op_queue_exception_err(excp, error);                                  \
162
    ctx->exception = excp;                                                    \
163
    return;                                                                   \
158
    if ((ctx)->exception == EXCP_NONE) {                                      \
159
        gen_op_update_nip((ctx)->nip);                                        \
160
    }                                                                         \
161
    gen_op_raise_exception_err((excp), (error));                              \
162
    ctx->exception = (excp);                                                  \
164 163
} while (0)
165 164

  
166
#define RET_INVAL()                                                           \
167
RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
165
#define RET_INVAL(ctx)                                                        \
166
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
167

  
168
#define RET_PRIVOPC(ctx)                                                      \
169
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
168 170

  
169
#define RET_PRIVOPC()                                                         \
170
RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
171
#define RET_PRIVREG(ctx)                                                      \
172
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
171 173

  
172
#define RET_PRIVREG()                                                         \
173
RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
174
#define RET_MTMSR(ctx)                                                        \
175
RET_EXCP((ctx), EXCP_MTMSR, 0)
174 176

  
175 177
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
176 178
static void gen_##name (DisasContext *ctx);                                   \
......
312 314
/* Invalid instruction */
313 315
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
314 316
{
315
    RET_INVAL();
317
    RET_INVAL(ctx);
316 318
}
317 319

  
318 320
/* Special opcode to stop emulation */
319 321
GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON)
320 322
{
321
    gen_op_queue_exception(EXCP_HLT);
322
    ctx->exception = EXCP_HLT;
323
    RET_EXCP(ctx, EXCP_HLT, 0);
323 324
}
324 325

  
325 326
/* Special opcode to call open-firmware */
326 327
GEN_HANDLER(of_enter, 0x06, 0x01, 0xFF, 0x03FFFFC1, PPC_COMMON)
327 328
{
328
    gen_op_queue_exception(EXCP_OFCALL);
329
    ctx->exception = EXCP_OFCALL;
329
    RET_EXCP(ctx, EXCP_OFCALL, 0);
330 330
}
331 331

  
332 332
/* Special opcode to call RTAS */
333 333
GEN_HANDLER(rtas_enter, 0x06, 0x02, 0xFF, 0x03FFFFC1, PPC_COMMON)
334 334
{
335 335
    printf("RTAS entry point !\n");
336
    gen_op_queue_exception(EXCP_RTASCALL);
337
    ctx->exception = EXCP_RTASCALL;
336
    RET_EXCP(ctx, EXCP_RTASCALL, 0);
338 337
}
339 338

  
340 339
static opc_handler_t invalid_handler = {
......
1010 1009
    uint32_t simm = SIMM(ctx->opcode);                                        \
1011 1010
    if (rA(ctx->opcode) == 0 ||                                               \
1012 1011
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1013
        RET_INVAL();                                                          \
1012
        RET_INVAL(ctx);                                                       \
1013
        return;                                                               \
1014 1014
    }                                                                         \
1015 1015
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1016 1016
    if (simm != 0)                                                            \
......
1025 1025
{                                                                             \
1026 1026
    if (rA(ctx->opcode) == 0 ||                                               \
1027 1027
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1028
        RET_INVAL();                                                          \
1028
        RET_INVAL(ctx);                                                       \
1029
        return;                                                               \
1029 1030
    }                                                                         \
1030 1031
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1031 1032
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
......
1086 1087
{                                                                             \
1087 1088
    uint32_t simm = SIMM(ctx->opcode);                                        \
1088 1089
    if (rA(ctx->opcode) == 0) {                                               \
1089
        RET_INVAL();                                                          \
1090
        RET_INVAL(ctx);                                                       \
1091
        return;                                                               \
1090 1092
    }                                                                         \
1091 1093
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1092 1094
    if (simm != 0)                                                            \
......
1100 1102
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1101 1103
{                                                                             \
1102 1104
    if (rA(ctx->opcode) == 0) {                                               \
1103
        RET_INVAL();                                                          \
1105
        RET_INVAL(ctx);                                                       \
1106
        return;                                                               \
1104 1107
    }                                                                         \
1105 1108
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1106 1109
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
......
1236 1239
    nr = nb / 4;
1237 1240
    if (((start + nr) > 32  && start <= ra && (start + nr - 32) > ra) ||
1238 1241
        ((start + nr) <= 32 && start <= ra && (start + nr) > ra)) {
1239
        RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
1242
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
1243
        return;
1240 1244
    }
1241 1245
    if (ra == 0) {
1242 1246
        gen_op_set_T0(0);
......
1376 1380
    uint32_t simm = SIMM(ctx->opcode);                                        \
1377 1381
    if (rA(ctx->opcode) == 0 ||                                               \
1378 1382
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1379
        RET_INVAL();                                                          \
1383
        RET_INVAL(ctx);                                                       \
1384
        return;                                                               \
1380 1385
    }                                                                         \
1381 1386
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1382 1387
    if (simm != 0)                                                            \
......
1391 1396
{                                                                             \
1392 1397
    if (rA(ctx->opcode) == 0 ||                                               \
1393 1398
        rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1394
        RET_INVAL();                                                          \
1399
        RET_INVAL(ctx);                                                       \
1400
        return;                                                               \
1395 1401
    }                                                                         \
1396 1402
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1397 1403
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
......
1448 1454
{                                                                             \
1449 1455
    uint32_t simm = SIMM(ctx->opcode);                                        \
1450 1456
    if (rA(ctx->opcode) == 0) {                                               \
1451
        RET_INVAL();                                                          \
1457
        RET_INVAL(ctx);                                                       \
1458
        return;                                                               \
1452 1459
    }                                                                         \
1453 1460
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1454 1461
    if (simm != 0)                                                            \
......
1462 1469
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1463 1470
{                                                                             \
1464 1471
    if (rA(ctx->opcode) == 0) {                                               \
1465
        RET_INVAL();                                                          \
1472
        RET_INVAL(ctx);                                                       \
1473
        return;                                                               \
1466 1474
    }                                                                         \
1467 1475
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1468 1476
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
......
1502 1510
/* stfiwx */
1503 1511
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1504 1512
{
1505
    RET_INVAL();
1513
    RET_INVAL(ctx);
1506 1514
}
1507 1515

  
1508 1516
/***                                Branch                                 ***/
......
1512 1520
{
1513 1521
    uint32_t li = s_ext24(LI(ctx->opcode)), target;
1514 1522

  
1515
    gen_op_update_tb(ctx->tb_offset);
1516
    gen_op_update_decr(ctx->decr_offset);
1517
    gen_op_process_exceptions(ctx->nip - 4);
1518 1523
    if (AA(ctx->opcode) == 0)
1519 1524
        target = ctx->nip + li - 4;
1520 1525
    else
......
1538 1543
    uint32_t mask;                                                            
1539 1544
    uint32_t li;
1540 1545

  
1541
    gen_op_update_tb(ctx->tb_offset);                                         
1542
    gen_op_update_decr(ctx->decr_offset);                                     
1543
    gen_op_process_exceptions(ctx->nip - 4);                        
1544

  
1545 1546
    if ((bo & 0x4) == 0)
1546 1547
        gen_op_dec_ctr();                                                     
1547 1548
    switch(type) {
......
1683 1684
GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1684 1685
{
1685 1686
#if defined(CONFIG_USER_ONLY)
1686
    RET_PRIVOPC();
1687
    RET_PRIVOPC(ctx);
1687 1688
#else
1688 1689
    /* Restore CPU state */
1689 1690
    if (!ctx->supervisor) {
1690
        RET_PRIVOPC();
1691
        RET_PRIVOPC(ctx);
1692
        return;
1691 1693
    }
1692 1694
    gen_op_rfi();
1693
    ctx->exception = EXCP_RFI;
1695
    RET_EXCP(ctx, EXCP_RFI, 0);
1694 1696
#endif
1695 1697
}
1696 1698

  
......
1698 1700
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1699 1701
{
1700 1702
#if defined(CONFIG_USER_ONLY)
1701
    gen_op_queue_exception(EXCP_SYSCALL_USER);
1703
    RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
1702 1704
#else
1703
    gen_op_queue_exception(EXCP_SYSCALL);
1705
    RET_EXCP(ctx, EXCP_SYSCALL, 0);
1704 1706
#endif
1705
    ctx->exception = EXCP_SYSCALL;
1706 1707
}
1707 1708

  
1708 1709
/***                                Trap                                   ***/
......
1770 1771
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1771 1772
{
1772 1773
#if defined(CONFIG_USER_ONLY)
1773
    RET_PRIVREG();
1774
    RET_PRIVREG(ctx);
1774 1775
#else
1775 1776
    if (!ctx->supervisor) {
1776
        RET_PRIVREG();
1777
        RET_PRIVREG(ctx);
1778
        return;
1777 1779
    }
1778 1780
    gen_op_load_msr();
1779 1781
    gen_op_store_T0_gpr(rD(ctx->opcode));
......
1792 1794
#endif
1793 1795
    {
1794 1796
    case -1:
1795
        RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1796
        break;
1797
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1798
        return;
1797 1799
    case 0:
1798
        RET_PRIVREG();
1799
        break;
1800
        RET_PRIVREG(ctx);
1801
        return;
1800 1802
    default:
1801 1803
        break;
1802 1804
        }
......
1910 1912
        gen_op_load_sdr1();
1911 1913
        break;
1912 1914
    case V_TBL:
1913
        gen_op_update_tb(ctx->tb_offset);
1914
        ctx->tb_offset = 0;
1915
        /* TBL is still in T0 */
1915
        gen_op_load_tbl();
1916 1916
        break;
1917 1917
    case V_TBU:
1918
        gen_op_update_tb(ctx->tb_offset);
1919
        ctx->tb_offset = 0;
1920
        gen_op_load_tb(1);
1918
        gen_op_load_tbu();
1921 1919
        break;
1922 1920
    case DECR:
1923
        gen_op_update_decr(ctx->decr_offset);
1924
        ctx->decr_offset = 0;
1925
        /* decr is still in T0 */
1921
        gen_op_load_decr();
1926 1922
        break;
1927 1923
    default:
1928 1924
        gen_op_load_spr(sprn);
......
1939 1935
        /* We need to update the time base before reading it */
1940 1936
    switch (sprn) {
1941 1937
    case V_TBL:
1942
        gen_op_update_tb(ctx->tb_offset);
1943 1938
        /* TBL is still in T0 */
1939
        gen_op_load_tbl();
1944 1940
        break;
1945 1941
    case V_TBU:
1946
        gen_op_update_tb(ctx->tb_offset);
1947
        gen_op_load_tb(1);
1942
        gen_op_load_tbu();
1948 1943
        break;
1949 1944
    default:
1950
        RET_INVAL();
1951
        break;
1945
        RET_INVAL(ctx);
1946
        return;
1952 1947
    }
1953
    ctx->tb_offset = 0;
1954 1948
    gen_op_store_T0_gpr(rD(ctx->opcode));
1955 1949
}
1956 1950

  
......
1965 1959
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
1966 1960
{
1967 1961
#if defined(CONFIG_USER_ONLY)
1968
    RET_PRIVREG();
1962
    RET_PRIVREG(ctx);
1969 1963
#else
1970 1964
    if (!ctx->supervisor) {
1971
        RET_PRIVREG();
1965
        RET_PRIVREG(ctx);
1966
        return;
1972 1967
    }
1973 1968
    gen_op_load_gpr_T0(rS(ctx->opcode));
1974 1969
    gen_op_store_msr();
1975 1970
    /* Must stop the translation as machine state (may have) changed */
1976
    ctx->exception = EXCP_MTMSR;
1971
    RET_MTMSR(ctx);
1977 1972
#endif
1978 1973
}
1979 1974

  
......
1995 1990
#endif
1996 1991
    {
1997 1992
    case -1:
1998
        RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1993
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1999 1994
        break;
2000 1995
    case 0:
2001
        RET_PRIVREG();
1996
        RET_PRIVREG(ctx);
2002 1997
        break;
2003 1998
    default:
2004 1999
        break;
......
2147 2142
        gen_op_tlbia();
2148 2143
        break;
2149 2144
    case O_TBL:
2150
        gen_op_store_tb(0);
2151
        ctx->tb_offset = 0;
2145
        gen_op_store_tbl();
2152 2146
        break;
2153 2147
    case O_TBU:
2154
        gen_op_store_tb(1);
2155
        ctx->tb_offset = 0;
2148
        gen_op_store_tbu();
2156 2149
        break;
2157 2150
    case DECR:
2158 2151
        gen_op_store_decr();
2159
        ctx->decr_offset = 0;
2160 2152
        break;
2161 2153
    default:
2162 2154
        gen_op_store_spr(sprn);
......
2186 2178
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2187 2179
{
2188 2180
#if defined(CONFIG_USER_ONLY)
2189
    RET_PRIVOPC();
2181
    RET_PRIVOPC(ctx);
2190 2182
#else
2191 2183
    if (!ctx->supervisor) {
2192
        RET_PRIVOPC();
2184
        RET_PRIVOPC(ctx);
2185
        return;
2193 2186
    }
2194 2187
    if (rA(ctx->opcode) == 0) {
2195 2188
        gen_op_load_gpr_T0(rB(ctx->opcode));
......
2274 2267
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
2275 2268
{
2276 2269
#if defined(CONFIG_USER_ONLY)
2277
    RET_PRIVREG();
2270
    RET_PRIVREG(ctx);
2278 2271
#else
2279 2272
    if (!ctx->supervisor) {
2280
        RET_PRIVREG();
2273
        RET_PRIVREG(ctx);
2274
        return;
2281 2275
    }
2282 2276
    gen_op_load_sr(SR(ctx->opcode));
2283 2277
    gen_op_store_T0_gpr(rD(ctx->opcode));
......
2288 2282
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
2289 2283
{
2290 2284
#if defined(CONFIG_USER_ONLY)
2291
    RET_PRIVREG();
2285
    RET_PRIVREG(ctx);
2292 2286
#else
2293 2287
    if (!ctx->supervisor) {
2294
        RET_PRIVREG();
2288
        RET_PRIVREG(ctx);
2289
        return;
2295 2290
    }
2296 2291
    gen_op_load_gpr_T1(rB(ctx->opcode));
2297 2292
    gen_op_load_srin();
......
2303 2298
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
2304 2299
{
2305 2300
#if defined(CONFIG_USER_ONLY)
2306
    RET_PRIVREG();
2301
    RET_PRIVREG(ctx);
2307 2302
#else
2308 2303
    if (!ctx->supervisor) {
2309
        RET_PRIVREG();
2304
        RET_PRIVREG(ctx);
2305
        return;
2310 2306
    }
2311 2307
    gen_op_load_gpr_T0(rS(ctx->opcode));
2312 2308
    gen_op_store_sr(SR(ctx->opcode));
2309
#if 0
2313 2310
    gen_op_tlbia();
2311
    RET_MTMSR(ctx);
2312
#endif
2314 2313
#endif
2315 2314
}
2316 2315

  
......
2318 2317
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
2319 2318
{
2320 2319
#if defined(CONFIG_USER_ONLY)
2321
    RET_PRIVREG();
2320
    RET_PRIVREG(ctx);
2322 2321
#else
2323 2322
    if (!ctx->supervisor) {
2324
        RET_PRIVREG();
2323
        RET_PRIVREG(ctx);
2324
        return;
2325 2325
    }
2326 2326
    gen_op_load_gpr_T0(rS(ctx->opcode));
2327 2327
    gen_op_load_gpr_T1(rB(ctx->opcode));
......
2336 2336
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
2337 2337
{
2338 2338
#if defined(CONFIG_USER_ONLY)
2339
    RET_PRIVOPC();
2339
    RET_PRIVOPC(ctx);
2340 2340
#else
2341 2341
    if (!ctx->supervisor) {
2342
        RET_PRIVOPC();
2342
        if (loglevel)
2343
            fprintf(logfile, "%s: ! supervisor\n", __func__);
2344
        RET_PRIVOPC(ctx);
2345
        return;
2343 2346
    }
2344 2347
    gen_op_tlbia();
2345 2348
#endif
......
2349 2352
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
2350 2353
{
2351 2354
#if defined(CONFIG_USER_ONLY)
2352
    RET_PRIVOPC();
2355
    RET_PRIVOPC(ctx);
2353 2356
#else
2354 2357
    if (!ctx->supervisor) {
2355
        RET_PRIVOPC();
2358
        RET_PRIVOPC(ctx);
2359
        return;
2356 2360
    }
2357 2361
    gen_op_load_gpr_T0(rB(ctx->opcode));
2358 2362
    gen_op_tlbie();
......
2363 2367
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM)
2364 2368
{
2365 2369
#if defined(CONFIG_USER_ONLY)
2366
    RET_PRIVOPC();
2370
    RET_PRIVOPC(ctx);
2367 2371
#else
2368 2372
    if (!ctx->supervisor) {
2369
        RET_PRIVOPC();
2373
        RET_PRIVOPC(ctx);
2374
        return;
2370 2375
    }
2371 2376
    /* This has no effect: it should ensure that all previous
2372 2377
     * tlbie have completed
......
2916 2921
        fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
2917 2922
        }
2918 2923
    fprintf(f, " ] ");
2919
    fprintf(f, "TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);
2924
    fprintf(f, "TB: 0x%08x %08x\n", cpu_ppc_load_tbu(env),
2925
            cpu_ppc_load_tbl(env));
2920 2926
        for (i = 0; i < 16; i++) {
2921 2927
            if ((i & 3) == 0)
2922 2928
            fprintf(f, "FPR%02d:", i);
......
2924 2930
            if ((i & 3) == 3)
2925 2931
            fprintf(f, "\n");
2926 2932
    }
2927
    fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x excp:0x%08x\n",
2928
            env->spr[SRR0], env->spr[SRR1], env->decr, env->exceptions);
2933
    fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x\n",
2934
            env->spr[SRR0], env->spr[SRR1], cpu_ppc_load_decr(env));
2929 2935
    fprintf(f, "reservation 0x%08x\n", env->reserve);
2930 2936
    fflush(f);
2931 2937
}
......
2952 2958
//    env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
2953 2959
//    env->spr[PVR] = 0x00070100; /* IBM 750FX */
2954 2960
#endif
2955
    env->decr = 0xFFFFFFFF;
2956 2961
    if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0)
2957 2962
        return NULL;
2958 2963
    init_spr_rights(env->spr[PVR]);
......
2976 2981
}
2977 2982

  
2978 2983
/*****************************************************************************/
2979
void raise_exception_err (int exception_index, int error_code);
2980 2984
int print_insn_powerpc (FILE *out, unsigned long insn, unsigned memaddr,
2981 2985
                        int dialect);
2982 2986

  
2983 2987
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2984 2988
                                    int search_pc)
2985 2989
{
2986
    DisasContext ctx;
2990
    DisasContext ctx, *ctxp = &ctx;
2987 2991
    opc_handler_t **table, *handler;
2988 2992
    uint32_t pc_start;
2989 2993
    uint16_t *gen_opc_end;
......
2994 2998
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2995 2999
    gen_opparam_ptr = gen_opparam_buf;
2996 3000
    ctx.nip = pc_start;
2997
    ctx.tb_offset = 0;
2998
    ctx.decr_offset = 0;
2999 3001
    ctx.tb = tb;
3000 3002
    ctx.exception = EXCP_NONE;
3001 3003
#if defined(CONFIG_USER_ONLY)
......
3023 3025
                gen_opc_instr_start[lj] = 1;
3024 3026
            }
3025 3027
        }
3026
#if defined DEBUG_DISAS
3027
        if (loglevel > 0) {
3028
#if defined PPC_DEBUG_DISAS
3029
        if (loglevel & CPU_LOG_TB_IN_ASM) {
3028 3030
            fprintf(logfile, "----------------\n");
3029 3031
            fprintf(logfile, "nip=%08x super=%d ir=%d\n",
3030 3032
                    ctx.nip, 1 - msr_pr, msr_ir);
3031 3033
        }
3032 3034
#endif
3033 3035
        ctx.opcode = ldl_code((void *)ctx.nip);
3034
#if defined DEBUG_DISAS
3035
        if (loglevel > 0) {
3036
#if defined PPC_DEBUG_DISAS
3037
        if (loglevel & CPU_LOG_TB_IN_ASM) {
3036 3038
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n",
3037 3039
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
3038 3040
                    opc3(ctx.opcode));
3039 3041
        }
3040 3042
#endif
3041 3043
        ctx.nip += 4;
3042
        ctx.tb_offset++;
3043
        /* Check decrementer exception */
3044
        if (++ctx.decr_offset == env->decr + 1)
3045
            ctx.exception = EXCP_DECR;
3046 3044
        table = ppc_opcodes;
3047 3045
        handler = table[opc1(ctx.opcode)];
3048 3046
        if (is_indirect_opcode(handler)) {
......
3098 3096
                        (ctx.nip & 0xFC) != 0x04) &&
3099 3097
             ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI &&
3100 3098
             ctx.exception != EXCP_TRAP)) {
3101
#if !defined(CONFIG_USER_ONLY)
3102
            gen_op_queue_exception(EXCP_TRACE);
3103
#endif
3104
            if (ctx.exception == EXCP_NONE) {
3105
                ctx.exception = EXCP_TRACE;
3106
    }
3099
            RET_EXCP(ctxp, EXCP_TRACE, 0);
3107 3100
        }
3108 3101
        /* if we reach a page boundary, stop generation */
3109 3102
        if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
3110
            if (ctx.exception == EXCP_NONE) {
3111
        gen_op_b((long)ctx.tb, ctx.nip);
3112
                ctx.exception = EXCP_BRANCH;
3113
    }
3103
            RET_EXCP(ctxp, EXCP_BRANCH, 0);
3114 3104
    }
3115 3105
    }
3116
    /* In case of branch, this has already been done *BEFORE* the branch */
3117
    if (ctx.exception != EXCP_BRANCH && ctx.exception != EXCP_RFI) {
3118
        gen_op_update_tb(ctx.tb_offset);
3119
        gen_op_update_decr(ctx.decr_offset);
3120
        gen_op_process_exceptions(ctx.nip);
3106
    if (ctx.exception == EXCP_NONE) {
3107
        gen_op_b((unsigned long)ctx.tb, ctx.nip);
3108
    } else if (ctx.exception != EXCP_BRANCH) {
3109
        gen_op_set_T0(0);
3121 3110
    }
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff