Great rework and cleanups to ease PowerPC implementations definitions.
[qemu] / hw / ppc.c
1 /*
2  * QEMU generic PowerPC hardware System Emulator
3  *
4  * Copyright (c) 2003-2007 Jocelyn Mayer
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "vl.h"
25 #include "m48t59.h"
26
27 //#define PPC_DEBUG_IRQ
28 //#define PPC_DEBUG_TB
29
30 extern FILE *logfile;
31 extern int loglevel;
32
33 void ppc_set_irq (CPUState *env, int n_IRQ, int level)
34 {
35     if (level) {
36         env->pending_interrupts |= 1 << n_IRQ;
37         cpu_interrupt(env, CPU_INTERRUPT_HARD);
38     } else {
39         env->pending_interrupts &= ~(1 << n_IRQ);
40         if (env->pending_interrupts == 0)
41             cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
42     }
43 #if defined(PPC_DEBUG_IRQ)
44     if (loglevel & CPU_LOG_INT) {
45         fprintf(logfile, "%s: %p n_IRQ %d level %d => pending %08x req %08x\n",
46                 __func__, env, n_IRQ, level,
47                 env->pending_interrupts, env->interrupt_request);
48     }
49 #endif
50 }
51
52 /* PowerPC 6xx / 7xx internal IRQ controller */
53 static void ppc6xx_set_irq (void *opaque, int pin, int level)
54 {
55     CPUState *env = opaque;
56     int cur_level;
57
58 #if defined(PPC_DEBUG_IRQ)
59     if (loglevel & CPU_LOG_INT) {
60         fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
61                 env, pin, level);
62     }
63 #endif
64     cur_level = (env->irq_input_state >> pin) & 1;
65     /* Don't generate spurious events */
66     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
67         switch (pin) {
68         case PPC6xx_INPUT_INT:
69             /* Level sensitive - active high */
70 #if defined(PPC_DEBUG_IRQ)
71             if (loglevel & CPU_LOG_INT) {
72                 fprintf(logfile, "%s: set the external IRQ state to %d\n",
73                         __func__, level);
74             }
75 #endif
76             ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
77             break;
78         case PPC6xx_INPUT_SMI:
79             /* Level sensitive - active high */
80 #if defined(PPC_DEBUG_IRQ)
81             if (loglevel & CPU_LOG_INT) {
82                 fprintf(logfile, "%s: set the SMI IRQ state to %d\n",
83                         __func__, level);
84             }
85 #endif
86             ppc_set_irq(env, PPC_INTERRUPT_SMI, level);
87             break;
88         case PPC6xx_INPUT_MCP:
89             /* Negative edge sensitive */
90             /* XXX: TODO: actual reaction may depends on HID0 status
91              *            603/604/740/750: check HID0[EMCP]
92              */
93             if (cur_level == 1 && level == 0) {
94 #if defined(PPC_DEBUG_IRQ)
95                 if (loglevel & CPU_LOG_INT) {
96                     fprintf(logfile, "%s: raise machine check state\n",
97                             __func__);
98                 }
99 #endif
100                 ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
101             }
102             break;
103         case PPC6xx_INPUT_CKSTP_IN:
104             /* Level sensitive - active low */
105             /* XXX: TODO: relay the signal to CKSTP_OUT pin */
106             if (level) {
107 #if defined(PPC_DEBUG_IRQ)
108                 if (loglevel & CPU_LOG_INT) {
109                     fprintf(logfile, "%s: stop the CPU\n", __func__);
110                 }
111 #endif
112                 env->halted = 1;
113             } else {
114 #if defined(PPC_DEBUG_IRQ)
115                 if (loglevel & CPU_LOG_INT) {
116                     fprintf(logfile, "%s: restart the CPU\n", __func__);
117                 }
118 #endif
119                 env->halted = 0;
120             }
121             break;
122         case PPC6xx_INPUT_HRESET:
123             /* Level sensitive - active low */
124             if (level) {
125 #if 0 // XXX: TOFIX
126 #if defined(PPC_DEBUG_IRQ)
127                 if (loglevel & CPU_LOG_INT) {
128                     fprintf(logfile, "%s: reset the CPU\n", __func__);
129                 }
130 #endif
131                 cpu_reset(env);
132 #endif
133             }
134             break;
135         case PPC6xx_INPUT_SRESET:
136 #if defined(PPC_DEBUG_IRQ)
137             if (loglevel & CPU_LOG_INT) {
138                 fprintf(logfile, "%s: set the RESET IRQ state to %d\n",
139                         __func__, level);
140             }
141 #endif
142             ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
143             break;
144         default:
145             /* Unknown pin - do nothing */
146 #if defined(PPC_DEBUG_IRQ)
147             if (loglevel & CPU_LOG_INT) {
148                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
149             }
150 #endif
151             return;
152         }
153         if (level)
154             env->irq_input_state |= 1 << pin;
155         else
156             env->irq_input_state &= ~(1 << pin);
157     }
158 }
159
160 void ppc6xx_irq_init (CPUState *env)
161 {
162     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6);
163 }
164
165 /* PowerPC 970 internal IRQ controller */
166 static void ppc970_set_irq (void *opaque, int pin, int level)
167 {
168     CPUState *env = opaque;
169     int cur_level;
170
171 #if defined(PPC_DEBUG_IRQ)
172     if (loglevel & CPU_LOG_INT) {
173         fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
174                 env, pin, level);
175     }
176 #endif
177     cur_level = (env->irq_input_state >> pin) & 1;
178     /* Don't generate spurious events */
179     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
180         switch (pin) {
181         case PPC970_INPUT_INT:
182             /* Level sensitive - active high */
183 #if defined(PPC_DEBUG_IRQ)
184             if (loglevel & CPU_LOG_INT) {
185                 fprintf(logfile, "%s: set the external IRQ state to %d\n",
186                         __func__, level);
187             }
188 #endif
189             ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
190             break;
191         case PPC970_INPUT_THINT:
192             /* Level sensitive - active high */
193 #if defined(PPC_DEBUG_IRQ)
194             if (loglevel & CPU_LOG_INT) {
195                 fprintf(logfile, "%s: set the SMI IRQ state to %d\n", __func__,
196                         level);
197             }
198 #endif
199             ppc_set_irq(env, PPC_INTERRUPT_THERM, level);
200             break;
201         case PPC970_INPUT_MCP:
202             /* Negative edge sensitive */
203             /* XXX: TODO: actual reaction may depends on HID0 status
204              *            603/604/740/750: check HID0[EMCP]
205              */
206             if (cur_level == 1 && level == 0) {
207 #if defined(PPC_DEBUG_IRQ)
208                 if (loglevel & CPU_LOG_INT) {
209                     fprintf(logfile, "%s: raise machine check state\n",
210                             __func__);
211                 }
212 #endif
213                 ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
214             }
215             break;
216         case PPC970_INPUT_CKSTP:
217             /* Level sensitive - active low */
218             /* XXX: TODO: relay the signal to CKSTP_OUT pin */
219             if (level) {
220 #if defined(PPC_DEBUG_IRQ)
221                 if (loglevel & CPU_LOG_INT) {
222                     fprintf(logfile, "%s: stop the CPU\n", __func__);
223                 }
224 #endif
225                 env->halted = 1;
226             } else {
227 #if defined(PPC_DEBUG_IRQ)
228                 if (loglevel & CPU_LOG_INT) {
229                     fprintf(logfile, "%s: restart the CPU\n", __func__);
230                 }
231 #endif
232                 env->halted = 0;
233             }
234             break;
235         case PPC970_INPUT_HRESET:
236             /* Level sensitive - active low */
237             if (level) {
238 #if 0 // XXX: TOFIX
239 #if defined(PPC_DEBUG_IRQ)
240                 if (loglevel & CPU_LOG_INT) {
241                     fprintf(logfile, "%s: reset the CPU\n", __func__);
242                 }
243 #endif
244                 cpu_reset(env);
245 #endif
246             }
247             break;
248         case PPC970_INPUT_SRESET:
249 #if defined(PPC_DEBUG_IRQ)
250             if (loglevel & CPU_LOG_INT) {
251                 fprintf(logfile, "%s: set the RESET IRQ state to %d\n",
252                         __func__, level);
253             }
254 #endif
255             ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
256             break;
257         case PPC970_INPUT_TBEN:
258 #if defined(PPC_DEBUG_IRQ)
259             if (loglevel & CPU_LOG_INT) {
260                 fprintf(logfile, "%s: set the TBEN state to %d\n", __func__,
261                         level);
262             }
263 #endif
264             /* XXX: TODO */
265             break;
266         default:
267             /* Unknown pin - do nothing */
268 #if defined(PPC_DEBUG_IRQ)
269             if (loglevel & CPU_LOG_INT) {
270                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
271             }
272 #endif
273             return;
274         }
275         if (level)
276             env->irq_input_state |= 1 << pin;
277         else
278             env->irq_input_state &= ~(1 << pin);
279     }
280 }
281
282 void ppc970_irq_init (CPUState *env)
283 {
284     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env, 7);
285 }
286
287 /* PowerPC 405 internal IRQ controller */
288 static void ppc405_set_irq (void *opaque, int pin, int level)
289 {
290     CPUState *env = opaque;
291     int cur_level;
292
293 #if defined(PPC_DEBUG_IRQ)
294     if (loglevel & CPU_LOG_INT) {
295         fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
296                 env, pin, level);
297     }
298 #endif
299     cur_level = (env->irq_input_state >> pin) & 1;
300     /* Don't generate spurious events */
301     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
302         switch (pin) {
303         case PPC405_INPUT_RESET_SYS:
304             if (level) {
305 #if defined(PPC_DEBUG_IRQ)
306                 if (loglevel & CPU_LOG_INT) {
307                     fprintf(logfile, "%s: reset the PowerPC system\n",
308                             __func__);
309                 }
310 #endif
311                 ppc40x_system_reset(env);
312             }
313             break;
314         case PPC405_INPUT_RESET_CHIP:
315             if (level) {
316 #if defined(PPC_DEBUG_IRQ)
317                 if (loglevel & CPU_LOG_INT) {
318                     fprintf(logfile, "%s: reset the PowerPC chip\n", __func__);
319                 }
320 #endif
321                 ppc40x_chip_reset(env);
322             }
323             break;
324             /* No break here */
325         case PPC405_INPUT_RESET_CORE:
326             /* XXX: TODO: update DBSR[MRR] */
327             if (level) {
328 #if defined(PPC_DEBUG_IRQ)
329                 if (loglevel & CPU_LOG_INT) {
330                     fprintf(logfile, "%s: reset the PowerPC core\n", __func__);
331                 }
332 #endif
333                 ppc40x_core_reset(env);
334             }
335             break;
336         case PPC405_INPUT_CINT:
337             /* Level sensitive - active high */
338 #if defined(PPC_DEBUG_IRQ)
339             if (loglevel & CPU_LOG_INT) {
340                 fprintf(logfile, "%s: set the critical IRQ state to %d\n",
341                         __func__, level);
342             }
343 #endif
344             /* XXX: TOFIX */
345             ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
346             break;
347         case PPC405_INPUT_INT:
348             /* Level sensitive - active high */
349 #if defined(PPC_DEBUG_IRQ)
350             if (loglevel & CPU_LOG_INT) {
351                 fprintf(logfile, "%s: set the external IRQ state to %d\n",
352                         __func__, level);
353             }
354 #endif
355             ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
356             break;
357         case PPC405_INPUT_HALT:
358             /* Level sensitive - active low */
359             if (level) {
360 #if defined(PPC_DEBUG_IRQ)
361                 if (loglevel & CPU_LOG_INT) {
362                     fprintf(logfile, "%s: stop the CPU\n", __func__);
363                 }
364 #endif
365                 env->halted = 1;
366             } else {
367 #if defined(PPC_DEBUG_IRQ)
368                 if (loglevel & CPU_LOG_INT) {
369                     fprintf(logfile, "%s: restart the CPU\n", __func__);
370                 }
371 #endif
372                 env->halted = 0;
373             }
374             break;
375         case PPC405_INPUT_DEBUG:
376             /* Level sensitive - active high */
377 #if defined(PPC_DEBUG_IRQ)
378             if (loglevel & CPU_LOG_INT) {
379                 fprintf(logfile, "%s: set the debug pin state to %d\n",
380                         __func__, level);
381             }
382 #endif
383             ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
384             break;
385         default:
386             /* Unknown pin - do nothing */
387 #if defined(PPC_DEBUG_IRQ)
388             if (loglevel & CPU_LOG_INT) {
389                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
390             }
391 #endif
392             return;
393         }
394         if (level)
395             env->irq_input_state |= 1 << pin;
396         else
397             env->irq_input_state &= ~(1 << pin);
398     }
399 }
400
401 void ppc405_irq_init (CPUState *env)
402 {
403     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc405_set_irq, env, 7);
404 }
405
406 /*****************************************************************************/
407 /* PowerPC time base and decrementer emulation */
408 struct ppc_tb_t {
409     /* Time base management */
410     int64_t  tb_offset;    /* Compensation               */
411     uint32_t tb_freq;      /* TB frequency               */
412     /* Decrementer management */
413     uint64_t decr_next;    /* Tick for next decr interrupt  */
414     struct QEMUTimer *decr_timer;
415     void *opaque;
416 };
417
418 static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
419 {
420     /* TB time in tb periods */
421     return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
422                     tb_env->tb_freq, ticks_per_sec);
423 }
424
425 uint32_t cpu_ppc_load_tbl (CPUState *env)
426 {
427     ppc_tb_t *tb_env = env->tb_env;
428     uint64_t tb;
429
430     tb = cpu_ppc_get_tb(tb_env);
431 #ifdef PPC_DEBUG_TB
432     {
433         static int last_time;
434         int now;
435         now = time(NULL);
436         if (last_time != now) {
437             last_time = now;
438             if (loglevel != 0) {
439                 fprintf(logfile, "%s: tb=0x%016lx %d %08lx\n",
440                         __func__, tb, now, tb_env->tb_offset);
441             }
442         }
443     }
444 #endif
445
446     return tb & 0xFFFFFFFF;
447 }
448
449 uint32_t cpu_ppc_load_tbu (CPUState *env)
450 {
451     ppc_tb_t *tb_env = env->tb_env;
452     uint64_t tb;
453
454     tb = cpu_ppc_get_tb(tb_env);
455 #if defined(PPC_DEBUG_TB)
456     if (loglevel != 0) {
457         fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
458     }
459 #endif
460
461     return tb >> 32;
462 }
463
464 static void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t value)
465 {
466     tb_env->tb_offset = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
467         - qemu_get_clock(vm_clock);
468 #ifdef PPC_DEBUG_TB
469     if (loglevel != 0) {
470         fprintf(logfile, "%s: tb=0x%016lx offset=%08lx\n", __func__, value,
471                 tb_env->tb_offset);
472     }
473 #endif
474 }
475
476 void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
477 {
478     ppc_tb_t *tb_env = env->tb_env;
479
480     cpu_ppc_store_tb(tb_env,
481                      ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
482 }
483
484 void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
485 {
486     ppc_tb_t *tb_env = env->tb_env;
487
488     cpu_ppc_store_tb(tb_env,
489                      ((uint64_t)cpu_ppc_load_tbu(env) << 32) | value);
490 }
491
492 uint32_t cpu_ppc_load_decr (CPUState *env)
493 {
494     ppc_tb_t *tb_env = env->tb_env;
495     uint32_t decr;
496     int64_t diff;
497
498     diff = tb_env->decr_next - qemu_get_clock(vm_clock);
499     if (diff >= 0)
500         decr = muldiv64(diff, tb_env->tb_freq, ticks_per_sec);
501     else
502         decr = -muldiv64(-diff, tb_env->tb_freq, ticks_per_sec);
503 #if defined(PPC_DEBUG_TB)
504     if (loglevel != 0) {
505         fprintf(logfile, "%s: 0x%08x\n", __func__, decr);
506     }
507 #endif
508
509     return decr;
510 }
511
512 /* When decrementer expires,
513  * all we need to do is generate or queue a CPU exception
514  */
515 static inline void cpu_ppc_decr_excp (CPUState *env)
516 {
517     /* Raise it */
518 #ifdef PPC_DEBUG_TB
519     if (loglevel != 0) {
520         fprintf(logfile, "raise decrementer exception\n");
521     }
522 #endif
523     ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
524 }
525
526 static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
527                                  uint32_t value, int is_excp)
528 {
529     ppc_tb_t *tb_env = env->tb_env;
530     uint64_t now, next;
531
532 #ifdef PPC_DEBUG_TB
533     if (loglevel != 0) {
534         fprintf(logfile, "%s: 0x%08x => 0x%08x\n", __func__, decr, value);
535     }
536 #endif
537     now = qemu_get_clock(vm_clock);
538     next = now + muldiv64(value, ticks_per_sec, tb_env->tb_freq);
539     if (is_excp)
540         next += tb_env->decr_next - now;
541     if (next == now)
542         next++;
543     tb_env->decr_next = next;
544     /* Adjust timer */
545     qemu_mod_timer(tb_env->decr_timer, next);
546     /* If we set a negative value and the decrementer was positive,
547      * raise an exception.
548      */
549     if ((value & 0x80000000) && !(decr & 0x80000000))
550         cpu_ppc_decr_excp(env);
551 }
552
553 void cpu_ppc_store_decr (CPUState *env, uint32_t value)
554 {
555     _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
556 }
557
558 static void cpu_ppc_decr_cb (void *opaque)
559 {
560     _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
561 }
562
563 static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
564 {
565     CPUState *env = opaque;
566     ppc_tb_t *tb_env = env->tb_env;
567
568     tb_env->tb_freq = freq;
569     /* There is a bug in Linux 2.4 kernels:
570      * if a decrementer exception is pending when it enables msr_ee at startup,
571      * it's not ready to handle it...
572      */
573     _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
574 }
575
576 /* Set up (once) timebase frequency (in Hz) */
577 clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq)
578 {
579     ppc_tb_t *tb_env;
580
581     tb_env = qemu_mallocz(sizeof(ppc_tb_t));
582     if (tb_env == NULL)
583         return NULL;
584     env->tb_env = tb_env;
585     /* Create new timer */
586     tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
587     cpu_ppc_set_tb_clk(env, freq);
588
589     return &cpu_ppc_set_tb_clk;
590 }
591
592 /* Specific helpers for POWER & PowerPC 601 RTC */
593 clk_setup_cb cpu_ppc601_rtc_init (CPUState *env)
594 {
595     return cpu_ppc_tb_init(env, 7812500);
596 }
597
598 void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
599 __attribute__ (( alias ("cpu_ppc_store_tbu") ));
600
601 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
602 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
603
604 void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
605 {
606     cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
607 }
608
609 uint32_t cpu_ppc601_load_rtcl (CPUState *env)
610 {
611     return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
612 }
613
614 /*****************************************************************************/
615 /* Embedded PowerPC timers */
616
617 /* PIT, FIT & WDT */
618 typedef struct ppcemb_timer_t ppcemb_timer_t;
619 struct ppcemb_timer_t {
620     uint64_t pit_reload;  /* PIT auto-reload value        */
621     uint64_t fit_next;    /* Tick for next FIT interrupt  */
622     struct QEMUTimer *fit_timer;
623     uint64_t wdt_next;    /* Tick for next WDT interrupt  */
624     struct QEMUTimer *wdt_timer;
625 };
626
627 /* Fixed interval timer */
628 static void cpu_4xx_fit_cb (void *opaque)
629 {
630     CPUState *env;
631     ppc_tb_t *tb_env;
632     ppcemb_timer_t *ppcemb_timer;
633     uint64_t now, next;
634
635     env = opaque;
636     tb_env = env->tb_env;
637     ppcemb_timer = tb_env->opaque;
638     now = qemu_get_clock(vm_clock);
639     switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
640     case 0:
641         next = 1 << 9;
642         break;
643     case 1:
644         next = 1 << 13;
645         break;
646     case 2:
647         next = 1 << 17;
648         break;
649     case 3:
650         next = 1 << 21;
651         break;
652     default:
653         /* Cannot occur, but makes gcc happy */
654         return;
655     }
656     next = now + muldiv64(next, ticks_per_sec, tb_env->tb_freq);
657     if (next == now)
658         next++;
659     qemu_mod_timer(ppcemb_timer->fit_timer, next);
660     env->spr[SPR_40x_TSR] |= 1 << 26;
661     if ((env->spr[SPR_40x_TCR] >> 23) & 0x1)
662         ppc_set_irq(env, PPC_INTERRUPT_FIT, 1);
663 #ifdef PPC_DEBUG_TB
664     if (loglevel != 0) {
665         fprintf(logfile, "%s: ir %d TCR " ADDRX " TSR " ADDRX "\n", __func__,
666                 (int)((env->spr[SPR_40x_TCR] >> 23) & 0x1),
667                 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
668     }
669 #endif
670 }
671
672 /* Programmable interval timer */
673 static void start_stop_pit (CPUState *env, ppc_tb_t *tb_env, int is_excp)
674 {
675     ppcemb_timer_t *ppcemb_timer;
676     uint64_t now, next;
677
678     ppcemb_timer = tb_env->opaque;
679     if (ppcemb_timer->pit_reload <= 1 ||
680         !((env->spr[SPR_40x_TCR] >> 26) & 0x1) ||
681         (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
682         /* Stop PIT */
683 #ifdef PPC_DEBUG_TB
684         if (loglevel != 0) {
685             fprintf(logfile, "%s: stop PIT\n", __func__);
686         }
687 #endif
688         qemu_del_timer(tb_env->decr_timer);
689     } else {
690 #ifdef PPC_DEBUG_TB
691         if (loglevel != 0) {
692             fprintf(logfile, "%s: start PIT 0x" REGX "\n",
693                     __func__, ppcemb_timer->pit_reload);
694         }
695 #endif
696         now = qemu_get_clock(vm_clock);
697         next = now + muldiv64(ppcemb_timer->pit_reload,
698                               ticks_per_sec, tb_env->tb_freq);
699         if (is_excp)
700             next += tb_env->decr_next - now;
701         if (next == now)
702             next++;
703         qemu_mod_timer(tb_env->decr_timer, next);
704         tb_env->decr_next = next;
705     }
706 }
707
708 static void cpu_4xx_pit_cb (void *opaque)
709 {
710     CPUState *env;
711     ppc_tb_t *tb_env;
712     ppcemb_timer_t *ppcemb_timer;
713
714     env = opaque;
715     tb_env = env->tb_env;
716     ppcemb_timer = tb_env->opaque;
717     env->spr[SPR_40x_TSR] |= 1 << 27;
718     if ((env->spr[SPR_40x_TCR] >> 26) & 0x1)
719         ppc_set_irq(env, PPC_INTERRUPT_PIT, 1);
720     start_stop_pit(env, tb_env, 1);
721 #ifdef PPC_DEBUG_TB
722     if (loglevel != 0) {
723         fprintf(logfile, "%s: ar %d ir %d TCR " ADDRX " TSR " ADDRX " "
724                 "%016" PRIx64 "\n", __func__,
725                 (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1),
726                 (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1),
727                 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
728                 ppcemb_timer->pit_reload);
729     }
730 #endif
731 }
732
733 /* Watchdog timer */
734 static void cpu_4xx_wdt_cb (void *opaque)
735 {
736     CPUState *env;
737     ppc_tb_t *tb_env;
738     ppcemb_timer_t *ppcemb_timer;
739     uint64_t now, next;
740
741     env = opaque;
742     tb_env = env->tb_env;
743     ppcemb_timer = tb_env->opaque;
744     now = qemu_get_clock(vm_clock);
745     switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
746     case 0:
747         next = 1 << 17;
748         break;
749     case 1:
750         next = 1 << 21;
751         break;
752     case 2:
753         next = 1 << 25;
754         break;
755     case 3:
756         next = 1 << 29;
757         break;
758     default:
759         /* Cannot occur, but makes gcc happy */
760         return;
761     }
762     next = now + muldiv64(next, ticks_per_sec, tb_env->tb_freq);
763     if (next == now)
764         next++;
765 #ifdef PPC_DEBUG_TB
766     if (loglevel != 0) {
767         fprintf(logfile, "%s: TCR " ADDRX " TSR " ADDRX "\n", __func__,
768                 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
769     }
770 #endif
771     switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
772     case 0x0:
773     case 0x1:
774         qemu_mod_timer(ppcemb_timer->wdt_timer, next);
775         ppcemb_timer->wdt_next = next;
776         env->spr[SPR_40x_TSR] |= 1 << 31;
777         break;
778     case 0x2:
779         qemu_mod_timer(ppcemb_timer->wdt_timer, next);
780         ppcemb_timer->wdt_next = next;
781         env->spr[SPR_40x_TSR] |= 1 << 30;
782         if ((env->spr[SPR_40x_TCR] >> 27) & 0x1)
783             ppc_set_irq(env, PPC_INTERRUPT_WDT, 1);
784         break;
785     case 0x3:
786         env->spr[SPR_40x_TSR] &= ~0x30000000;
787         env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000;
788         switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) {
789         case 0x0:
790             /* No reset */
791             break;
792         case 0x1: /* Core reset */
793             ppc40x_core_reset(env);
794             break;
795         case 0x2: /* Chip reset */
796             ppc40x_chip_reset(env);
797             break;
798         case 0x3: /* System reset */
799             ppc40x_system_reset(env);
800             break;
801         }
802     }
803 }
804
805 void store_40x_pit (CPUState *env, target_ulong val)
806 {
807     ppc_tb_t *tb_env;
808     ppcemb_timer_t *ppcemb_timer;
809
810     tb_env = env->tb_env;
811     ppcemb_timer = tb_env->opaque;
812 #ifdef PPC_DEBUG_TB
813     if (loglevel != 0) {
814         fprintf(logfile, "%s %p %p\n", __func__, tb_env, ppcemb_timer);
815     }
816 #endif
817     ppcemb_timer->pit_reload = val;
818     start_stop_pit(env, tb_env, 0);
819 }
820
821 target_ulong load_40x_pit (CPUState *env)
822 {
823     return cpu_ppc_load_decr(env);
824 }
825
826 void store_booke_tsr (CPUState *env, target_ulong val)
827 {
828 #ifdef PPC_DEBUG_TB
829     if (loglevel != 0) {
830         fprintf(logfile, "%s: val=" ADDRX "\n", __func__, val);
831     }
832 #endif
833     env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000);
834     if (val & 0x80000000)
835         ppc_set_irq(env, PPC_INTERRUPT_PIT, 0);
836 }
837
838 void store_booke_tcr (CPUState *env, target_ulong val)
839 {
840     ppc_tb_t *tb_env;
841
842     tb_env = env->tb_env;
843 #ifdef PPC_DEBUG_TB
844     if (loglevel != 0) {
845         fprintf(logfile, "%s: val=" ADDRX "\n", __func__, val);
846     }
847 #endif
848     env->spr[SPR_40x_TCR] = val & 0xFFC00000;
849     start_stop_pit(env, tb_env, 1);
850     cpu_4xx_wdt_cb(env);
851 }
852
853 static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq)
854 {
855     CPUState *env = opaque;
856     ppc_tb_t *tb_env = env->tb_env;
857
858 #ifdef PPC_DEBUG_TB
859     if (loglevel != 0) {
860         fprintf(logfile, "%s set new frequency to %u\n", __func__, freq);
861     }
862 #endif
863     tb_env->tb_freq = freq;
864     /* XXX: we should also update all timers */
865 }
866
867 clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
868 {
869     ppc_tb_t *tb_env;
870     ppcemb_timer_t *ppcemb_timer;
871
872     tb_env = qemu_mallocz(sizeof(ppc_tb_t));
873     if (tb_env == NULL) {
874         return NULL;
875     }
876     env->tb_env = tb_env;
877     ppcemb_timer = qemu_mallocz(sizeof(ppcemb_timer_t));
878     tb_env->tb_freq = freq;
879     tb_env->opaque = ppcemb_timer;
880 #ifdef PPC_DEBUG_TB
881     if (loglevel != 0) {
882         fprintf(logfile, "%s %p %p %p\n", __func__, tb_env, ppcemb_timer,
883                 &ppc_emb_set_tb_clk);
884     }
885 #endif
886     if (ppcemb_timer != NULL) {
887         /* We use decr timer for PIT */
888         tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_4xx_pit_cb, env);
889         ppcemb_timer->fit_timer =
890             qemu_new_timer(vm_clock, &cpu_4xx_fit_cb, env);
891         ppcemb_timer->wdt_timer =
892             qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env);
893     }
894
895     return &ppc_emb_set_tb_clk;
896 }
897
898 /*****************************************************************************/
899 /* Embedded PowerPC Device Control Registers */
900 typedef struct ppc_dcrn_t ppc_dcrn_t;
901 struct ppc_dcrn_t {
902     dcr_read_cb dcr_read;
903     dcr_write_cb dcr_write;
904     void *opaque;
905 };
906
907 /* XXX: on 460, DCR addresses are 32 bits wide,
908  *      using DCRIPR to get the 22 upper bits of the DCR address
909  */
910 #define DCRN_NB 1024
911 struct ppc_dcr_t {
912     ppc_dcrn_t dcrn[DCRN_NB];
913     int (*read_error)(int dcrn);
914     int (*write_error)(int dcrn);
915 };
916
917 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
918 {
919     ppc_dcrn_t *dcr;
920
921     if (dcrn < 0 || dcrn >= DCRN_NB)
922         goto error;
923     dcr = &dcr_env->dcrn[dcrn];
924     if (dcr->dcr_read == NULL)
925         goto error;
926     *valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
927
928     return 0;
929
930  error:
931     if (dcr_env->read_error != NULL)
932         return (*dcr_env->read_error)(dcrn);
933
934     return -1;
935 }
936
937 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
938 {
939     ppc_dcrn_t *dcr;
940
941     if (dcrn < 0 || dcrn >= DCRN_NB)
942         goto error;
943     dcr = &dcr_env->dcrn[dcrn];
944     if (dcr->dcr_write == NULL)
945         goto error;
946     (*dcr->dcr_write)(dcr->opaque, dcrn, val);
947
948     return 0;
949
950  error:
951     if (dcr_env->write_error != NULL)
952         return (*dcr_env->write_error)(dcrn);
953
954     return -1;
955 }
956
957 int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
958                       dcr_read_cb dcr_read, dcr_write_cb dcr_write)
959 {
960     ppc_dcr_t *dcr_env;
961     ppc_dcrn_t *dcr;
962
963     dcr_env = env->dcr_env;
964     if (dcr_env == NULL)
965         return -1;
966     if (dcrn < 0 || dcrn >= DCRN_NB)
967         return -1;
968     dcr = &dcr_env->dcrn[dcrn];
969     if (dcr->opaque != NULL ||
970         dcr->dcr_read != NULL ||
971         dcr->dcr_write != NULL)
972         return -1;
973     dcr->opaque = opaque;
974     dcr->dcr_read = dcr_read;
975     dcr->dcr_write = dcr_write;
976
977     return 0;
978 }
979
980 int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn),
981                   int (*write_error)(int dcrn))
982 {
983     ppc_dcr_t *dcr_env;
984
985     dcr_env = qemu_mallocz(sizeof(ppc_dcr_t));
986     if (dcr_env == NULL)
987         return -1;
988     dcr_env->read_error = read_error;
989     dcr_env->write_error = write_error;
990     env->dcr_env = dcr_env;
991
992     return 0;
993 }
994
995
996 #if 0
997 /*****************************************************************************/
998 /* Handle system reset (for now, just stop emulation) */
999 void cpu_ppc_reset (CPUState *env)
1000 {
1001     printf("Reset asked... Stop emulation\n");
1002     abort();
1003 }
1004 #endif
1005
1006 /*****************************************************************************/
1007 /* Debug port */
1008 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
1009 {
1010     addr &= 0xF;
1011     switch (addr) {
1012     case 0:
1013         printf("%c", val);
1014         break;
1015     case 1:
1016         printf("\n");
1017         fflush(stdout);
1018         break;
1019     case 2:
1020         printf("Set loglevel to %04x\n", val);
1021         cpu_set_log(val | 0x100);
1022         break;
1023     }
1024 }
1025
1026 /*****************************************************************************/
1027 /* NVRAM helpers */
1028 void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
1029 {
1030     m48t59_write(nvram, addr, value);
1031 }
1032
1033 uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
1034 {
1035     return m48t59_read(nvram, addr);
1036 }
1037
1038 void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
1039 {
1040     m48t59_write(nvram, addr, value >> 8);
1041     m48t59_write(nvram, addr + 1, value & 0xFF);
1042 }
1043
1044 uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
1045 {
1046     uint16_t tmp;
1047
1048     tmp = m48t59_read(nvram, addr) << 8;
1049     tmp |= m48t59_read(nvram, addr + 1);
1050     return tmp;
1051 }
1052
1053 void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
1054 {
1055     m48t59_write(nvram, addr, value >> 24);
1056     m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);
1057     m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);
1058     m48t59_write(nvram, addr + 3, value & 0xFF);
1059 }
1060
1061 uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
1062 {
1063     uint32_t tmp;
1064
1065     tmp = m48t59_read(nvram, addr) << 24;
1066     tmp |= m48t59_read(nvram, addr + 1) << 16;
1067     tmp |= m48t59_read(nvram, addr + 2) << 8;
1068     tmp |= m48t59_read(nvram, addr + 3);
1069
1070     return tmp;
1071 }
1072
1073 void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
1074                        const unsigned char *str, uint32_t max)
1075 {
1076     int i;
1077
1078     for (i = 0; i < max && str[i] != '\0'; i++) {
1079         m48t59_write(nvram, addr + i, str[i]);
1080     }
1081     m48t59_write(nvram, addr + max - 1, '\0');
1082 }
1083
1084 int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
1085 {
1086     int i;
1087
1088     memset(dst, 0, max);
1089     for (i = 0; i < max; i++) {
1090         dst[i] = NVRAM_get_byte(nvram, addr + i);
1091         if (dst[i] == '\0')
1092             break;
1093     }
1094
1095     return i;
1096 }
1097
1098 static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
1099 {
1100     uint16_t tmp;
1101     uint16_t pd, pd1, pd2;
1102
1103     tmp = prev >> 8;
1104     pd = prev ^ value;
1105     pd1 = pd & 0x000F;
1106     pd2 = ((pd >> 4) & 0x000F) ^ pd1;
1107     tmp ^= (pd1 << 3) | (pd1 << 8);
1108     tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
1109
1110     return tmp;
1111 }
1112
1113 uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
1114 {
1115     uint32_t i;
1116     uint16_t crc = 0xFFFF;
1117     int odd;
1118
1119     odd = count & 1;
1120     count &= ~1;
1121     for (i = 0; i != count; i++) {
1122         crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
1123     }
1124     if (odd) {
1125         crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
1126     }
1127
1128     return crc;
1129 }
1130
1131 #define CMDLINE_ADDR 0x017ff000
1132
1133 int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
1134                           const unsigned char *arch,
1135                           uint32_t RAM_size, int boot_device,
1136                           uint32_t kernel_image, uint32_t kernel_size,
1137                           const char *cmdline,
1138                           uint32_t initrd_image, uint32_t initrd_size,
1139                           uint32_t NVRAM_image,
1140                           int width, int height, int depth)
1141 {
1142     uint16_t crc;
1143
1144     /* Set parameters for Open Hack'Ware BIOS */
1145     NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
1146     NVRAM_set_lword(nvram,  0x10, 0x00000002); /* structure v2 */
1147     NVRAM_set_word(nvram,   0x14, NVRAM_size);
1148     NVRAM_set_string(nvram, 0x20, arch, 16);
1149     NVRAM_set_lword(nvram,  0x30, RAM_size);
1150     NVRAM_set_byte(nvram,   0x34, boot_device);
1151     NVRAM_set_lword(nvram,  0x38, kernel_image);
1152     NVRAM_set_lword(nvram,  0x3C, kernel_size);
1153     if (cmdline) {
1154         /* XXX: put the cmdline in NVRAM too ? */
1155         strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
1156         NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
1157         NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
1158     } else {
1159         NVRAM_set_lword(nvram,  0x40, 0);
1160         NVRAM_set_lword(nvram,  0x44, 0);
1161     }
1162     NVRAM_set_lword(nvram,  0x48, initrd_image);
1163     NVRAM_set_lword(nvram,  0x4C, initrd_size);
1164     NVRAM_set_lword(nvram,  0x50, NVRAM_image);
1165
1166     NVRAM_set_word(nvram,   0x54, width);
1167     NVRAM_set_word(nvram,   0x56, height);
1168     NVRAM_set_word(nvram,   0x58, depth);
1169     crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
1170     NVRAM_set_word(nvram,  0xFC, crc);
1171
1172     return 0;
1173 }