* sort the PowerPC target object files
[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
26 //#define PPC_DEBUG_IRQ
27 //#define PPC_DEBUG_TB
28
29 extern FILE *logfile;
30 extern int loglevel;
31
32 static void cpu_ppc_tb_stop (CPUState *env);
33 static void cpu_ppc_tb_start (CPUState *env);
34
35 static void ppc_set_irq (CPUState *env, int n_IRQ, int level)
36 {
37     if (level) {
38         env->pending_interrupts |= 1 << n_IRQ;
39         cpu_interrupt(env, CPU_INTERRUPT_HARD);
40     } else {
41         env->pending_interrupts &= ~(1 << n_IRQ);
42         if (env->pending_interrupts == 0)
43             cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
44     }
45 #if defined(PPC_DEBUG_IRQ)
46     if (loglevel & CPU_LOG_INT) {
47         fprintf(logfile, "%s: %p n_IRQ %d level %d => pending %08x req %08x\n",
48                 __func__, env, n_IRQ, level,
49                 env->pending_interrupts, env->interrupt_request);
50     }
51 #endif
52 }
53
54 /* PowerPC 6xx / 7xx internal IRQ controller */
55 static void ppc6xx_set_irq (void *opaque, int pin, int level)
56 {
57     CPUState *env = opaque;
58     int cur_level;
59
60 #if defined(PPC_DEBUG_IRQ)
61     if (loglevel & CPU_LOG_INT) {
62         fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
63                 env, pin, level);
64     }
65 #endif
66     cur_level = (env->irq_input_state >> pin) & 1;
67     /* Don't generate spurious events */
68     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
69         switch (pin) {
70         case PPC6xx_INPUT_TBEN:
71             /* Level sensitive - active high */
72 #if defined(PPC_DEBUG_IRQ)
73             if (loglevel & CPU_LOG_INT) {
74                 fprintf(logfile, "%s: %s the time base\n",
75                         __func__, level ? "start" : "stop");
76             }
77 #endif
78             if (level) {
79                 cpu_ppc_tb_start(env);
80             } else {
81                 cpu_ppc_tb_stop(env);
82             }
83         case PPC6xx_INPUT_INT:
84             /* Level sensitive - active high */
85 #if defined(PPC_DEBUG_IRQ)
86             if (loglevel & CPU_LOG_INT) {
87                 fprintf(logfile, "%s: set the external IRQ state to %d\n",
88                         __func__, level);
89             }
90 #endif
91             ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
92             break;
93         case PPC6xx_INPUT_SMI:
94             /* Level sensitive - active high */
95 #if defined(PPC_DEBUG_IRQ)
96             if (loglevel & CPU_LOG_INT) {
97                 fprintf(logfile, "%s: set the SMI IRQ state to %d\n",
98                         __func__, level);
99             }
100 #endif
101             ppc_set_irq(env, PPC_INTERRUPT_SMI, level);
102             break;
103         case PPC6xx_INPUT_MCP:
104             /* Negative edge sensitive */
105             /* XXX: TODO: actual reaction may depends on HID0 status
106              *            603/604/740/750: check HID0[EMCP]
107              */
108             if (cur_level == 1 && level == 0) {
109 #if defined(PPC_DEBUG_IRQ)
110                 if (loglevel & CPU_LOG_INT) {
111                     fprintf(logfile, "%s: raise machine check state\n",
112                             __func__);
113                 }
114 #endif
115                 ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
116             }
117             break;
118         case PPC6xx_INPUT_CKSTP_IN:
119             /* Level sensitive - active low */
120             /* XXX: TODO: relay the signal to CKSTP_OUT pin */
121             /* XXX: Note that the only way to restart the CPU is to reset it */
122             if (level) {
123 #if defined(PPC_DEBUG_IRQ)
124                 if (loglevel & CPU_LOG_INT) {
125                     fprintf(logfile, "%s: stop the CPU\n", __func__);
126                 }
127 #endif
128                 env->halted = 1;
129             }
130             break;
131         case PPC6xx_INPUT_HRESET:
132             /* Level sensitive - active low */
133             if (level) {
134 #if 0 // XXX: TOFIX
135 #if defined(PPC_DEBUG_IRQ)
136                 if (loglevel & CPU_LOG_INT) {
137                     fprintf(logfile, "%s: reset the CPU\n", __func__);
138                 }
139 #endif
140                 cpu_reset(env);
141 #endif
142             }
143             break;
144         case PPC6xx_INPUT_SRESET:
145 #if defined(PPC_DEBUG_IRQ)
146             if (loglevel & CPU_LOG_INT) {
147                 fprintf(logfile, "%s: set the RESET IRQ state to %d\n",
148                         __func__, level);
149             }
150 #endif
151             ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
152             break;
153         default:
154             /* Unknown pin - do nothing */
155 #if defined(PPC_DEBUG_IRQ)
156             if (loglevel & CPU_LOG_INT) {
157                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
158             }
159 #endif
160             return;
161         }
162         if (level)
163             env->irq_input_state |= 1 << pin;
164         else
165             env->irq_input_state &= ~(1 << pin);
166     }
167 }
168
169 void ppc6xx_irq_init (CPUState *env)
170 {
171     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6);
172 }
173
174 #if defined(TARGET_PPC64)
175 /* PowerPC 970 internal IRQ controller */
176 static void ppc970_set_irq (void *opaque, int pin, int level)
177 {
178     CPUState *env = opaque;
179     int cur_level;
180
181 #if defined(PPC_DEBUG_IRQ)
182     if (loglevel & CPU_LOG_INT) {
183         fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
184                 env, pin, level);
185     }
186 #endif
187     cur_level = (env->irq_input_state >> pin) & 1;
188     /* Don't generate spurious events */
189     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
190         switch (pin) {
191         case PPC970_INPUT_INT:
192             /* Level sensitive - active high */
193 #if defined(PPC_DEBUG_IRQ)
194             if (loglevel & CPU_LOG_INT) {
195                 fprintf(logfile, "%s: set the external IRQ state to %d\n",
196                         __func__, level);
197             }
198 #endif
199             ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
200             break;
201         case PPC970_INPUT_THINT:
202             /* Level sensitive - active high */
203 #if defined(PPC_DEBUG_IRQ)
204             if (loglevel & CPU_LOG_INT) {
205                 fprintf(logfile, "%s: set the SMI IRQ state to %d\n", __func__,
206                         level);
207             }
208 #endif
209             ppc_set_irq(env, PPC_INTERRUPT_THERM, level);
210             break;
211         case PPC970_INPUT_MCP:
212             /* Negative edge sensitive */
213             /* XXX: TODO: actual reaction may depends on HID0 status
214              *            603/604/740/750: check HID0[EMCP]
215              */
216             if (cur_level == 1 && level == 0) {
217 #if defined(PPC_DEBUG_IRQ)
218                 if (loglevel & CPU_LOG_INT) {
219                     fprintf(logfile, "%s: raise machine check state\n",
220                             __func__);
221                 }
222 #endif
223                 ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
224             }
225             break;
226         case PPC970_INPUT_CKSTP:
227             /* Level sensitive - active low */
228             /* XXX: TODO: relay the signal to CKSTP_OUT pin */
229             if (level) {
230 #if defined(PPC_DEBUG_IRQ)
231                 if (loglevel & CPU_LOG_INT) {
232                     fprintf(logfile, "%s: stop the CPU\n", __func__);
233                 }
234 #endif
235                 env->halted = 1;
236             } else {
237 #if defined(PPC_DEBUG_IRQ)
238                 if (loglevel & CPU_LOG_INT) {
239                     fprintf(logfile, "%s: restart the CPU\n", __func__);
240                 }
241 #endif
242                 env->halted = 0;
243             }
244             break;
245         case PPC970_INPUT_HRESET:
246             /* Level sensitive - active low */
247             if (level) {
248 #if 0 // XXX: TOFIX
249 #if defined(PPC_DEBUG_IRQ)
250                 if (loglevel & CPU_LOG_INT) {
251                     fprintf(logfile, "%s: reset the CPU\n", __func__);
252                 }
253 #endif
254                 cpu_reset(env);
255 #endif
256             }
257             break;
258         case PPC970_INPUT_SRESET:
259 #if defined(PPC_DEBUG_IRQ)
260             if (loglevel & CPU_LOG_INT) {
261                 fprintf(logfile, "%s: set the RESET IRQ state to %d\n",
262                         __func__, level);
263             }
264 #endif
265             ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
266             break;
267         case PPC970_INPUT_TBEN:
268 #if defined(PPC_DEBUG_IRQ)
269             if (loglevel & CPU_LOG_INT) {
270                 fprintf(logfile, "%s: set the TBEN state to %d\n", __func__,
271                         level);
272             }
273 #endif
274             /* XXX: TODO */
275             break;
276         default:
277             /* Unknown pin - do nothing */
278 #if defined(PPC_DEBUG_IRQ)
279             if (loglevel & CPU_LOG_INT) {
280                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
281             }
282 #endif
283             return;
284         }
285         if (level)
286             env->irq_input_state |= 1 << pin;
287         else
288             env->irq_input_state &= ~(1 << pin);
289     }
290 }
291
292 void ppc970_irq_init (CPUState *env)
293 {
294     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env, 7);
295 }
296 #endif /* defined(TARGET_PPC64) */
297
298 /* PowerPC 40x internal IRQ controller */
299 static void ppc40x_set_irq (void *opaque, int pin, int level)
300 {
301     CPUState *env = opaque;
302     int cur_level;
303
304 #if defined(PPC_DEBUG_IRQ)
305     if (loglevel & CPU_LOG_INT) {
306         fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
307                 env, pin, level);
308     }
309 #endif
310     cur_level = (env->irq_input_state >> pin) & 1;
311     /* Don't generate spurious events */
312     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
313         switch (pin) {
314         case PPC40x_INPUT_RESET_SYS:
315             if (level) {
316 #if defined(PPC_DEBUG_IRQ)
317                 if (loglevel & CPU_LOG_INT) {
318                     fprintf(logfile, "%s: reset the PowerPC system\n",
319                             __func__);
320                 }
321 #endif
322                 ppc40x_system_reset(env);
323             }
324             break;
325         case PPC40x_INPUT_RESET_CHIP:
326             if (level) {
327 #if defined(PPC_DEBUG_IRQ)
328                 if (loglevel & CPU_LOG_INT) {
329                     fprintf(logfile, "%s: reset the PowerPC chip\n", __func__);
330                 }
331 #endif
332                 ppc40x_chip_reset(env);
333             }
334             break;
335         case PPC40x_INPUT_RESET_CORE:
336             /* XXX: TODO: update DBSR[MRR] */
337             if (level) {
338 #if defined(PPC_DEBUG_IRQ)
339                 if (loglevel & CPU_LOG_INT) {
340                     fprintf(logfile, "%s: reset the PowerPC core\n", __func__);
341                 }
342 #endif
343                 ppc40x_core_reset(env);
344             }
345             break;
346         case PPC40x_INPUT_CINT:
347             /* Level sensitive - active high */
348 #if defined(PPC_DEBUG_IRQ)
349             if (loglevel & CPU_LOG_INT) {
350                 fprintf(logfile, "%s: set the critical IRQ state to %d\n",
351                         __func__, level);
352             }
353 #endif
354             ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
355             break;
356         case PPC40x_INPUT_INT:
357             /* Level sensitive - active high */
358 #if defined(PPC_DEBUG_IRQ)
359             if (loglevel & CPU_LOG_INT) {
360                 fprintf(logfile, "%s: set the external IRQ state to %d\n",
361                         __func__, level);
362             }
363 #endif
364             ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
365             break;
366         case PPC40x_INPUT_HALT:
367             /* Level sensitive - active low */
368             if (level) {
369 #if defined(PPC_DEBUG_IRQ)
370                 if (loglevel & CPU_LOG_INT) {
371                     fprintf(logfile, "%s: stop the CPU\n", __func__);
372                 }
373 #endif
374                 env->halted = 1;
375             } else {
376 #if defined(PPC_DEBUG_IRQ)
377                 if (loglevel & CPU_LOG_INT) {
378                     fprintf(logfile, "%s: restart the CPU\n", __func__);
379                 }
380 #endif
381                 env->halted = 0;
382             }
383             break;
384         case PPC40x_INPUT_DEBUG:
385             /* Level sensitive - active high */
386 #if defined(PPC_DEBUG_IRQ)
387             if (loglevel & CPU_LOG_INT) {
388                 fprintf(logfile, "%s: set the debug pin state to %d\n",
389                         __func__, level);
390             }
391 #endif
392             ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
393             break;
394         default:
395             /* Unknown pin - do nothing */
396 #if defined(PPC_DEBUG_IRQ)
397             if (loglevel & CPU_LOG_INT) {
398                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
399             }
400 #endif
401             return;
402         }
403         if (level)
404             env->irq_input_state |= 1 << pin;
405         else
406             env->irq_input_state &= ~(1 << pin);
407     }
408 }
409
410 void ppc40x_irq_init (CPUState *env)
411 {
412     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq,
413                                                   env, PPC40x_INPUT_NB);
414 }
415
416 /*****************************************************************************/
417 /* PowerPC time base and decrementer emulation */
418 struct ppc_tb_t {
419     /* Time base management */
420     int64_t  tb_offset;    /* Compensation                    */
421     int64_t  atb_offset;   /* Compensation                    */
422     uint32_t tb_freq;      /* TB frequency                    */
423     /* Decrementer management */
424     uint64_t decr_next;    /* Tick for next decr interrupt    */
425     uint32_t decr_freq;    /* decrementer frequency           */
426     struct QEMUTimer *decr_timer;
427 #if defined(TARGET_PPC64H)
428     /* Hypervisor decrementer management */
429     uint64_t hdecr_next;    /* Tick for next hdecr interrupt  */
430     struct QEMUTimer *hdecr_timer;
431     uint64_t purr_load;
432     uint64_t purr_start;
433 #endif
434     void *opaque;
435 };
436
437 static always_inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env, uint64_t vmclk,
438                                               int64_t tb_offset)
439 {
440     /* TB time in tb periods */
441     return muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec) + tb_offset;
442 }
443
444 uint32_t cpu_ppc_load_tbl (CPUState *env)
445 {
446     ppc_tb_t *tb_env = env->tb_env;
447     uint64_t tb;
448
449     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
450 #if defined(PPC_DEBUG_TB)
451     if (loglevel != 0) {
452         fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
453     }
454 #endif
455
456     return tb & 0xFFFFFFFF;
457 }
458
459 static always_inline uint32_t _cpu_ppc_load_tbu (CPUState *env)
460 {
461     ppc_tb_t *tb_env = env->tb_env;
462     uint64_t tb;
463
464     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
465 #if defined(PPC_DEBUG_TB)
466     if (loglevel != 0) {
467         fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
468     }
469 #endif
470
471     return tb >> 32;
472 }
473
474 uint32_t cpu_ppc_load_tbu (CPUState *env)
475 {
476     return _cpu_ppc_load_tbu(env);
477 }
478
479 static always_inline void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t vmclk,
480                                             int64_t *tb_offsetp,
481                                             uint64_t value)
482 {
483     *tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec);
484 #ifdef PPC_DEBUG_TB
485     if (loglevel != 0) {
486         fprintf(logfile, "%s: tb=0x%016lx offset=%08lx\n", __func__, value,
487                 *tb_offsetp);
488     }
489 #endif
490 }
491
492 void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
493 {
494     ppc_tb_t *tb_env = env->tb_env;
495     uint64_t tb;
496
497     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
498     tb &= 0xFFFFFFFF00000000ULL;
499     cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
500                      &tb_env->tb_offset, tb | (uint64_t)value);
501 }
502
503 static always_inline void _cpu_ppc_store_tbu (CPUState *env, uint32_t value)
504 {
505     ppc_tb_t *tb_env = env->tb_env;
506     uint64_t tb;
507
508     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
509     tb &= 0x00000000FFFFFFFFULL;
510     cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
511                      &tb_env->tb_offset, ((uint64_t)value << 32) | tb);
512 }
513
514 void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
515 {
516     _cpu_ppc_store_tbu(env, value);
517 }
518
519 uint32_t cpu_ppc_load_atbl (CPUState *env)
520 {
521     ppc_tb_t *tb_env = env->tb_env;
522     uint64_t tb;
523
524     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
525 #if defined(PPC_DEBUG_TB)
526     if (loglevel != 0) {
527         fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
528     }
529 #endif
530
531     return tb & 0xFFFFFFFF;
532 }
533
534 uint32_t cpu_ppc_load_atbu (CPUState *env)
535 {
536     ppc_tb_t *tb_env = env->tb_env;
537     uint64_t tb;
538
539     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
540 #if defined(PPC_DEBUG_TB)
541     if (loglevel != 0) {
542         fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
543     }
544 #endif
545
546     return tb >> 32;
547 }
548
549 void cpu_ppc_store_atbl (CPUState *env, uint32_t value)
550 {
551     ppc_tb_t *tb_env = env->tb_env;
552     uint64_t tb;
553
554     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
555     tb &= 0xFFFFFFFF00000000ULL;
556     cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
557                      &tb_env->atb_offset, tb | (uint64_t)value);
558 }
559
560 void cpu_ppc_store_atbu (CPUState *env, uint32_t value)
561 {
562     ppc_tb_t *tb_env = env->tb_env;
563     uint64_t tb;
564
565     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
566     tb &= 0x00000000FFFFFFFFULL;
567     cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
568                      &tb_env->atb_offset, ((uint64_t)value << 32) | tb);
569 }
570
571 static void cpu_ppc_tb_stop (CPUState *env)
572 {
573     ppc_tb_t *tb_env = env->tb_env;
574     uint64_t tb, atb, vmclk;
575
576     /* If the time base is already frozen, do nothing */
577     if (tb_env->tb_freq != 0) {
578         vmclk = qemu_get_clock(vm_clock);
579         /* Get the time base */
580         tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
581         /* Get the alternate time base */
582         atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset);
583         /* Store the time base value (ie compute the current offset) */
584         cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
585         /* Store the alternate time base value (compute the current offset) */
586         cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
587         /* Set the time base frequency to zero */
588         tb_env->tb_freq = 0;
589         /* Now, the time bases are frozen to tb_offset / atb_offset value */
590     }
591 }
592
593 static void cpu_ppc_tb_start (CPUState *env)
594 {
595     ppc_tb_t *tb_env = env->tb_env;
596     uint64_t tb, atb, vmclk;
597     
598     /* If the time base is not frozen, do nothing */
599     if (tb_env->tb_freq == 0) {
600         vmclk = qemu_get_clock(vm_clock);
601         /* Get the time base from tb_offset */
602         tb = tb_env->tb_offset;
603         /* Get the alternate time base from atb_offset */
604         atb = tb_env->atb_offset;
605         /* Restore the tb frequency from the decrementer frequency */
606         tb_env->tb_freq = tb_env->decr_freq;
607         /* Store the time base value */
608         cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
609         /* Store the alternate time base value */
610         cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
611     }
612 }
613
614 static always_inline uint32_t _cpu_ppc_load_decr (CPUState *env,
615                                                   uint64_t *next)
616 {
617     ppc_tb_t *tb_env = env->tb_env;
618     uint32_t decr;
619     int64_t diff;
620
621     diff = tb_env->decr_next - qemu_get_clock(vm_clock);
622     if (diff >= 0)
623         decr = muldiv64(diff, tb_env->decr_freq, ticks_per_sec);
624     else
625         decr = -muldiv64(-diff, tb_env->decr_freq, ticks_per_sec);
626 #if defined(PPC_DEBUG_TB)
627     if (loglevel != 0) {
628         fprintf(logfile, "%s: 0x%08x\n", __func__, decr);
629     }
630 #endif
631
632     return decr;
633 }
634
635 uint32_t cpu_ppc_load_decr (CPUState *env)
636 {
637     ppc_tb_t *tb_env = env->tb_env;
638
639     return _cpu_ppc_load_decr(env, &tb_env->decr_next);
640 }
641
642 #if defined(TARGET_PPC64H)
643 uint32_t cpu_ppc_load_hdecr (CPUState *env)
644 {
645     ppc_tb_t *tb_env = env->tb_env;
646
647     return _cpu_ppc_load_decr(env, &tb_env->hdecr_next);
648 }
649
650 uint64_t cpu_ppc_load_purr (CPUState *env)
651 {
652     ppc_tb_t *tb_env = env->tb_env;
653     uint64_t diff;
654
655     diff = qemu_get_clock(vm_clock) - tb_env->purr_start;
656
657     return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, ticks_per_sec);
658 }
659 #endif /* defined(TARGET_PPC64H) */
660
661 /* When decrementer expires,
662  * all we need to do is generate or queue a CPU exception
663  */
664 static always_inline void cpu_ppc_decr_excp (CPUState *env)
665 {
666     /* Raise it */
667 #ifdef PPC_DEBUG_TB
668     if (loglevel != 0) {
669         fprintf(logfile, "raise decrementer exception\n");
670     }
671 #endif
672     ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
673 }
674
675 static always_inline void cpu_ppc_hdecr_excp (CPUState *env)
676 {
677     /* Raise it */
678 #ifdef PPC_DEBUG_TB
679     if (loglevel != 0) {
680         fprintf(logfile, "raise decrementer exception\n");
681     }
682 #endif
683     ppc_set_irq(env, PPC_INTERRUPT_HDECR, 1);
684 }
685
686 static void __cpu_ppc_store_decr (CPUState *env, uint64_t *nextp,
687                                   struct QEMUTimer *timer,
688                                   void (*raise_excp)(CPUState *),
689                                   uint32_t decr, uint32_t value,
690                                   int is_excp)
691 {
692     ppc_tb_t *tb_env = env->tb_env;
693     uint64_t now, next;
694
695 #ifdef PPC_DEBUG_TB
696     if (loglevel != 0) {
697         fprintf(logfile, "%s: 0x%08x => 0x%08x\n", __func__, decr, value);
698     }
699 #endif
700     now = qemu_get_clock(vm_clock);
701     next = now + muldiv64(value, ticks_per_sec, tb_env->decr_freq);
702     if (is_excp)
703         next += *nextp - now;
704     if (next == now)
705         next++;
706     *nextp = next;
707     /* Adjust timer */
708     qemu_mod_timer(timer, next);
709     /* If we set a negative value and the decrementer was positive,
710      * raise an exception.
711      */
712     if ((value & 0x80000000) && !(decr & 0x80000000))
713         (*raise_excp)(env);
714 }
715
716 static always_inline void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
717                                                uint32_t value, int is_excp)
718 {
719     ppc_tb_t *tb_env = env->tb_env;
720
721     __cpu_ppc_store_decr(env, &tb_env->decr_next, tb_env->decr_timer,
722                          &cpu_ppc_decr_excp, decr, value, is_excp);
723 }
724
725 void cpu_ppc_store_decr (CPUState *env, uint32_t value)
726 {
727     _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
728 }
729
730 static void cpu_ppc_decr_cb (void *opaque)
731 {
732     _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
733 }
734
735 #if defined(TARGET_PPC64H)
736 static always_inline void _cpu_ppc_store_hdecr (CPUState *env, uint32_t hdecr,
737                                                 uint32_t value, int is_excp)
738 {
739     ppc_tb_t *tb_env = env->tb_env;
740
741     __cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer,
742                          &cpu_ppc_hdecr_excp, hdecr, value, is_excp);
743 }
744
745 void cpu_ppc_store_hdecr (CPUState *env, uint32_t value)
746 {
747     _cpu_ppc_store_hdecr(env, cpu_ppc_load_hdecr(env), value, 0);
748 }
749
750 static void cpu_ppc_hdecr_cb (void *opaque)
751 {
752     _cpu_ppc_store_hdecr(opaque, 0x00000000, 0xFFFFFFFF, 1);
753 }
754
755 void cpu_ppc_store_purr (CPUState *env, uint64_t value)
756 {
757     ppc_tb_t *tb_env = env->tb_env;
758
759     tb_env->purr_load = value;
760     tb_env->purr_start = qemu_get_clock(vm_clock);
761 }
762 #endif /* defined(TARGET_PPC64H) */
763
764 static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
765 {
766     CPUState *env = opaque;
767     ppc_tb_t *tb_env = env->tb_env;
768
769     tb_env->tb_freq = freq;
770     tb_env->decr_freq = freq;
771     /* There is a bug in Linux 2.4 kernels:
772      * if a decrementer exception is pending when it enables msr_ee at startup,
773      * it's not ready to handle it...
774      */
775     _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
776 #if defined(TARGET_PPC64H)
777     _cpu_ppc_store_hdecr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
778     cpu_ppc_store_purr(env, 0x0000000000000000ULL);
779 #endif /* defined(TARGET_PPC64H) */
780 }
781
782 /* Set up (once) timebase frequency (in Hz) */
783 clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq)
784 {
785     ppc_tb_t *tb_env;
786
787     tb_env = qemu_mallocz(sizeof(ppc_tb_t));
788     if (tb_env == NULL)
789         return NULL;
790     env->tb_env = tb_env;
791     /* Create new timer */
792     tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
793 #if defined(TARGET_PPC64H)
794     tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env);
795 #endif /* defined(TARGET_PPC64H) */
796     cpu_ppc_set_tb_clk(env, freq);
797
798     return &cpu_ppc_set_tb_clk;
799 }
800
801 /* Specific helpers for POWER & PowerPC 601 RTC */
802 clk_setup_cb cpu_ppc601_rtc_init (CPUState *env)
803 {
804     return cpu_ppc_tb_init(env, 7812500);
805 }
806
807 void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
808 {
809     _cpu_ppc_store_tbu(env, value);
810 }
811
812 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
813 {
814     return _cpu_ppc_load_tbu(env);
815 }
816
817 void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
818 {
819     cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
820 }
821
822 uint32_t cpu_ppc601_load_rtcl (CPUState *env)
823 {
824     return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
825 }
826
827 /*****************************************************************************/
828 /* Embedded PowerPC timers */
829
830 /* PIT, FIT & WDT */
831 typedef struct ppcemb_timer_t ppcemb_timer_t;
832 struct ppcemb_timer_t {
833     uint64_t pit_reload;  /* PIT auto-reload value        */
834     uint64_t fit_next;    /* Tick for next FIT interrupt  */
835     struct QEMUTimer *fit_timer;
836     uint64_t wdt_next;    /* Tick for next WDT interrupt  */
837     struct QEMUTimer *wdt_timer;
838 };
839
840 /* Fixed interval timer */
841 static void cpu_4xx_fit_cb (void *opaque)
842 {
843     CPUState *env;
844     ppc_tb_t *tb_env;
845     ppcemb_timer_t *ppcemb_timer;
846     uint64_t now, next;
847
848     env = opaque;
849     tb_env = env->tb_env;
850     ppcemb_timer = tb_env->opaque;
851     now = qemu_get_clock(vm_clock);
852     switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
853     case 0:
854         next = 1 << 9;
855         break;
856     case 1:
857         next = 1 << 13;
858         break;
859     case 2:
860         next = 1 << 17;
861         break;
862     case 3:
863         next = 1 << 21;
864         break;
865     default:
866         /* Cannot occur, but makes gcc happy */
867         return;
868     }
869     next = now + muldiv64(next, ticks_per_sec, tb_env->tb_freq);
870     if (next == now)
871         next++;
872     qemu_mod_timer(ppcemb_timer->fit_timer, next);
873     env->spr[SPR_40x_TSR] |= 1 << 26;
874     if ((env->spr[SPR_40x_TCR] >> 23) & 0x1)
875         ppc_set_irq(env, PPC_INTERRUPT_FIT, 1);
876 #ifdef PPC_DEBUG_TB
877     if (loglevel != 0) {
878         fprintf(logfile, "%s: ir %d TCR " ADDRX " TSR " ADDRX "\n", __func__,
879                 (int)((env->spr[SPR_40x_TCR] >> 23) & 0x1),
880                 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
881     }
882 #endif
883 }
884
885 /* Programmable interval timer */
886 static void start_stop_pit (CPUState *env, ppc_tb_t *tb_env, int is_excp)
887 {
888     ppcemb_timer_t *ppcemb_timer;
889     uint64_t now, next;
890
891     ppcemb_timer = tb_env->opaque;
892     if (ppcemb_timer->pit_reload <= 1 ||
893         !((env->spr[SPR_40x_TCR] >> 26) & 0x1) ||
894         (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
895         /* Stop PIT */
896 #ifdef PPC_DEBUG_TB
897         if (loglevel != 0) {
898             fprintf(logfile, "%s: stop PIT\n", __func__);
899         }
900 #endif
901         qemu_del_timer(tb_env->decr_timer);
902     } else {
903 #ifdef PPC_DEBUG_TB
904         if (loglevel != 0) {
905             fprintf(logfile, "%s: start PIT 0x" REGX "\n",
906                     __func__, ppcemb_timer->pit_reload);
907         }
908 #endif
909         now = qemu_get_clock(vm_clock);
910         next = now + muldiv64(ppcemb_timer->pit_reload,
911                               ticks_per_sec, tb_env->decr_freq);
912         if (is_excp)
913             next += tb_env->decr_next - now;
914         if (next == now)
915             next++;
916         qemu_mod_timer(tb_env->decr_timer, next);
917         tb_env->decr_next = next;
918     }
919 }
920
921 static void cpu_4xx_pit_cb (void *opaque)
922 {
923     CPUState *env;
924     ppc_tb_t *tb_env;
925     ppcemb_timer_t *ppcemb_timer;
926
927     env = opaque;
928     tb_env = env->tb_env;
929     ppcemb_timer = tb_env->opaque;
930     env->spr[SPR_40x_TSR] |= 1 << 27;
931     if ((env->spr[SPR_40x_TCR] >> 26) & 0x1)
932         ppc_set_irq(env, PPC_INTERRUPT_PIT, 1);
933     start_stop_pit(env, tb_env, 1);
934 #ifdef PPC_DEBUG_TB
935     if (loglevel != 0) {
936         fprintf(logfile, "%s: ar %d ir %d TCR " ADDRX " TSR " ADDRX " "
937                 "%016" PRIx64 "\n", __func__,
938                 (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1),
939                 (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1),
940                 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
941                 ppcemb_timer->pit_reload);
942     }
943 #endif
944 }
945
946 /* Watchdog timer */
947 static void cpu_4xx_wdt_cb (void *opaque)
948 {
949     CPUState *env;
950     ppc_tb_t *tb_env;
951     ppcemb_timer_t *ppcemb_timer;
952     uint64_t now, next;
953
954     env = opaque;
955     tb_env = env->tb_env;
956     ppcemb_timer = tb_env->opaque;
957     now = qemu_get_clock(vm_clock);
958     switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
959     case 0:
960         next = 1 << 17;
961         break;
962     case 1:
963         next = 1 << 21;
964         break;
965     case 2:
966         next = 1 << 25;
967         break;
968     case 3:
969         next = 1 << 29;
970         break;
971     default:
972         /* Cannot occur, but makes gcc happy */
973         return;
974     }
975     next = now + muldiv64(next, ticks_per_sec, tb_env->decr_freq);
976     if (next == now)
977         next++;
978 #ifdef PPC_DEBUG_TB
979     if (loglevel != 0) {
980         fprintf(logfile, "%s: TCR " ADDRX " TSR " ADDRX "\n", __func__,
981                 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
982     }
983 #endif
984     switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
985     case 0x0:
986     case 0x1:
987         qemu_mod_timer(ppcemb_timer->wdt_timer, next);
988         ppcemb_timer->wdt_next = next;
989         env->spr[SPR_40x_TSR] |= 1 << 31;
990         break;
991     case 0x2:
992         qemu_mod_timer(ppcemb_timer->wdt_timer, next);
993         ppcemb_timer->wdt_next = next;
994         env->spr[SPR_40x_TSR] |= 1 << 30;
995         if ((env->spr[SPR_40x_TCR] >> 27) & 0x1)
996             ppc_set_irq(env, PPC_INTERRUPT_WDT, 1);
997         break;
998     case 0x3:
999         env->spr[SPR_40x_TSR] &= ~0x30000000;
1000         env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000;
1001         switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) {
1002         case 0x0:
1003             /* No reset */
1004             break;
1005         case 0x1: /* Core reset */
1006             ppc40x_core_reset(env);
1007             break;
1008         case 0x2: /* Chip reset */
1009             ppc40x_chip_reset(env);
1010             break;
1011         case 0x3: /* System reset */
1012             ppc40x_system_reset(env);
1013             break;
1014         }
1015     }
1016 }
1017
1018 void store_40x_pit (CPUState *env, target_ulong val)
1019 {
1020     ppc_tb_t *tb_env;
1021     ppcemb_timer_t *ppcemb_timer;
1022
1023     tb_env = env->tb_env;
1024     ppcemb_timer = tb_env->opaque;
1025 #ifdef PPC_DEBUG_TB
1026     if (loglevel != 0) {
1027         fprintf(logfile, "%s %p %p\n", __func__, tb_env, ppcemb_timer);
1028     }
1029 #endif
1030     ppcemb_timer->pit_reload = val;
1031     start_stop_pit(env, tb_env, 0);
1032 }
1033
1034 target_ulong load_40x_pit (CPUState *env)
1035 {
1036     return cpu_ppc_load_decr(env);
1037 }
1038
1039 void store_booke_tsr (CPUState *env, target_ulong val)
1040 {
1041 #ifdef PPC_DEBUG_TB
1042     if (loglevel != 0) {
1043         fprintf(logfile, "%s: val=" ADDRX "\n", __func__, val);
1044     }
1045 #endif
1046     env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000);
1047     if (val & 0x80000000)
1048         ppc_set_irq(env, PPC_INTERRUPT_PIT, 0);
1049 }
1050
1051 void store_booke_tcr (CPUState *env, target_ulong val)
1052 {
1053     ppc_tb_t *tb_env;
1054
1055     tb_env = env->tb_env;
1056 #ifdef PPC_DEBUG_TB
1057     if (loglevel != 0) {
1058         fprintf(logfile, "%s: val=" ADDRX "\n", __func__, val);
1059     }
1060 #endif
1061     env->spr[SPR_40x_TCR] = val & 0xFFC00000;
1062     start_stop_pit(env, tb_env, 1);
1063     cpu_4xx_wdt_cb(env);
1064 }
1065
1066 static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq)
1067 {
1068     CPUState *env = opaque;
1069     ppc_tb_t *tb_env = env->tb_env;
1070
1071 #ifdef PPC_DEBUG_TB
1072     if (loglevel != 0) {
1073         fprintf(logfile, "%s set new frequency to %u\n", __func__, freq);
1074     }
1075 #endif
1076     tb_env->tb_freq = freq;
1077     tb_env->decr_freq = freq;
1078     /* XXX: we should also update all timers */
1079 }
1080
1081 clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
1082 {
1083     ppc_tb_t *tb_env;
1084     ppcemb_timer_t *ppcemb_timer;
1085
1086     tb_env = qemu_mallocz(sizeof(ppc_tb_t));
1087     if (tb_env == NULL) {
1088         return NULL;
1089     }
1090     env->tb_env = tb_env;
1091     ppcemb_timer = qemu_mallocz(sizeof(ppcemb_timer_t));
1092     tb_env->tb_freq = freq;
1093     tb_env->decr_freq = freq;
1094     tb_env->opaque = ppcemb_timer;
1095 #ifdef PPC_DEBUG_TB
1096     if (loglevel != 0) {
1097         fprintf(logfile, "%s %p %p %p\n", __func__, tb_env, ppcemb_timer,
1098                 &ppc_emb_set_tb_clk);
1099     }
1100 #endif
1101     if (ppcemb_timer != NULL) {
1102         /* We use decr timer for PIT */
1103         tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_4xx_pit_cb, env);
1104         ppcemb_timer->fit_timer =
1105             qemu_new_timer(vm_clock, &cpu_4xx_fit_cb, env);
1106         ppcemb_timer->wdt_timer =
1107             qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env);
1108     }
1109
1110     return &ppc_emb_set_tb_clk;
1111 }
1112
1113 /*****************************************************************************/
1114 /* Embedded PowerPC Device Control Registers */
1115 typedef struct ppc_dcrn_t ppc_dcrn_t;
1116 struct ppc_dcrn_t {
1117     dcr_read_cb dcr_read;
1118     dcr_write_cb dcr_write;
1119     void *opaque;
1120 };
1121
1122 /* XXX: on 460, DCR addresses are 32 bits wide,
1123  *      using DCRIPR to get the 22 upper bits of the DCR address
1124  */
1125 #define DCRN_NB 1024
1126 struct ppc_dcr_t {
1127     ppc_dcrn_t dcrn[DCRN_NB];
1128     int (*read_error)(int dcrn);
1129     int (*write_error)(int dcrn);
1130 };
1131
1132 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
1133 {
1134     ppc_dcrn_t *dcr;
1135
1136     if (dcrn < 0 || dcrn >= DCRN_NB)
1137         goto error;
1138     dcr = &dcr_env->dcrn[dcrn];
1139     if (dcr->dcr_read == NULL)
1140         goto error;
1141     *valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
1142
1143     return 0;
1144
1145  error:
1146     if (dcr_env->read_error != NULL)
1147         return (*dcr_env->read_error)(dcrn);
1148
1149     return -1;
1150 }
1151
1152 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
1153 {
1154     ppc_dcrn_t *dcr;
1155
1156     if (dcrn < 0 || dcrn >= DCRN_NB)
1157         goto error;
1158     dcr = &dcr_env->dcrn[dcrn];
1159     if (dcr->dcr_write == NULL)
1160         goto error;
1161     (*dcr->dcr_write)(dcr->opaque, dcrn, val);
1162
1163     return 0;
1164
1165  error:
1166     if (dcr_env->write_error != NULL)
1167         return (*dcr_env->write_error)(dcrn);
1168
1169     return -1;
1170 }
1171
1172 int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
1173                       dcr_read_cb dcr_read, dcr_write_cb dcr_write)
1174 {
1175     ppc_dcr_t *dcr_env;
1176     ppc_dcrn_t *dcr;
1177
1178     dcr_env = env->dcr_env;
1179     if (dcr_env == NULL)
1180         return -1;
1181     if (dcrn < 0 || dcrn >= DCRN_NB)
1182         return -1;
1183     dcr = &dcr_env->dcrn[dcrn];
1184     if (dcr->opaque != NULL ||
1185         dcr->dcr_read != NULL ||
1186         dcr->dcr_write != NULL)
1187         return -1;
1188     dcr->opaque = opaque;
1189     dcr->dcr_read = dcr_read;
1190     dcr->dcr_write = dcr_write;
1191
1192     return 0;
1193 }
1194
1195 int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn),
1196                   int (*write_error)(int dcrn))
1197 {
1198     ppc_dcr_t *dcr_env;
1199
1200     dcr_env = qemu_mallocz(sizeof(ppc_dcr_t));
1201     if (dcr_env == NULL)
1202         return -1;
1203     dcr_env->read_error = read_error;
1204     dcr_env->write_error = write_error;
1205     env->dcr_env = dcr_env;
1206
1207     return 0;
1208 }
1209
1210 #if 0
1211 /*****************************************************************************/
1212 /* Handle system reset (for now, just stop emulation) */
1213 void cpu_ppc_reset (CPUState *env)
1214 {
1215     printf("Reset asked... Stop emulation\n");
1216     abort();
1217 }
1218 #endif
1219
1220 /*****************************************************************************/
1221 /* Debug port */
1222 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
1223 {
1224     addr &= 0xF;
1225     switch (addr) {
1226     case 0:
1227         printf("%c", val);
1228         break;
1229     case 1:
1230         printf("\n");
1231         fflush(stdout);
1232         break;
1233     case 2:
1234         printf("Set loglevel to %04x\n", val);
1235         cpu_set_log(val | 0x100);
1236         break;
1237     }
1238 }
1239
1240 /*****************************************************************************/
1241 /* NVRAM helpers */
1242 static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr)
1243 {
1244     return (*nvram->read_fn)(nvram->opaque, addr);;
1245 }
1246
1247 static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val)
1248 {
1249     (*nvram->write_fn)(nvram->opaque, addr, val);
1250 }
1251
1252 void NVRAM_set_byte (nvram_t *nvram, uint32_t addr, uint8_t value)
1253 {
1254     nvram_write(nvram, addr, value);
1255 }
1256
1257 uint8_t NVRAM_get_byte (nvram_t *nvram, uint32_t addr)
1258 {
1259     return nvram_read(nvram, addr);
1260 }
1261
1262 void NVRAM_set_word (nvram_t *nvram, uint32_t addr, uint16_t value)
1263 {
1264     nvram_write(nvram, addr, value >> 8);
1265     nvram_write(nvram, addr + 1, value & 0xFF);
1266 }
1267
1268 uint16_t NVRAM_get_word (nvram_t *nvram, uint32_t addr)
1269 {
1270     uint16_t tmp;
1271
1272     tmp = nvram_read(nvram, addr) << 8;
1273     tmp |= nvram_read(nvram, addr + 1);
1274
1275     return tmp;
1276 }
1277
1278 void NVRAM_set_lword (nvram_t *nvram, uint32_t addr, uint32_t value)
1279 {
1280     nvram_write(nvram, addr, value >> 24);
1281     nvram_write(nvram, addr + 1, (value >> 16) & 0xFF);
1282     nvram_write(nvram, addr + 2, (value >> 8) & 0xFF);
1283     nvram_write(nvram, addr + 3, value & 0xFF);
1284 }
1285
1286 uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr)
1287 {
1288     uint32_t tmp;
1289
1290     tmp = nvram_read(nvram, addr) << 24;
1291     tmp |= nvram_read(nvram, addr + 1) << 16;
1292     tmp |= nvram_read(nvram, addr + 2) << 8;
1293     tmp |= nvram_read(nvram, addr + 3);
1294
1295     return tmp;
1296 }
1297
1298 void NVRAM_set_string (nvram_t *nvram, uint32_t addr,
1299                        const unsigned char *str, uint32_t max)
1300 {
1301     int i;
1302
1303     for (i = 0; i < max && str[i] != '\0'; i++) {
1304         nvram_write(nvram, addr + i, str[i]);
1305     }
1306     nvram_write(nvram, addr + i, str[i]);
1307     nvram_write(nvram, addr + max - 1, '\0');
1308 }
1309
1310 int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max)
1311 {
1312     int i;
1313
1314     memset(dst, 0, max);
1315     for (i = 0; i < max; i++) {
1316         dst[i] = NVRAM_get_byte(nvram, addr + i);
1317         if (dst[i] == '\0')
1318             break;
1319     }
1320
1321     return i;
1322 }
1323
1324 static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
1325 {
1326     uint16_t tmp;
1327     uint16_t pd, pd1, pd2;
1328
1329     tmp = prev >> 8;
1330     pd = prev ^ value;
1331     pd1 = pd & 0x000F;
1332     pd2 = ((pd >> 4) & 0x000F) ^ pd1;
1333     tmp ^= (pd1 << 3) | (pd1 << 8);
1334     tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
1335
1336     return tmp;
1337 }
1338
1339 uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count)
1340 {
1341     uint32_t i;
1342     uint16_t crc = 0xFFFF;
1343     int odd;
1344
1345     odd = count & 1;
1346     count &= ~1;
1347     for (i = 0; i != count; i++) {
1348         crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
1349     }
1350     if (odd) {
1351         crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
1352     }
1353
1354     return crc;
1355 }
1356
1357 #define CMDLINE_ADDR 0x017ff000
1358
1359 int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
1360                           const unsigned char *arch,
1361                           uint32_t RAM_size, int boot_device,
1362                           uint32_t kernel_image, uint32_t kernel_size,
1363                           const char *cmdline,
1364                           uint32_t initrd_image, uint32_t initrd_size,
1365                           uint32_t NVRAM_image,
1366                           int width, int height, int depth)
1367 {
1368     uint16_t crc;
1369
1370     /* Set parameters for Open Hack'Ware BIOS */
1371     NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
1372     NVRAM_set_lword(nvram,  0x10, 0x00000002); /* structure v2 */
1373     NVRAM_set_word(nvram,   0x14, NVRAM_size);
1374     NVRAM_set_string(nvram, 0x20, arch, 16);
1375     NVRAM_set_lword(nvram,  0x30, RAM_size);
1376     NVRAM_set_byte(nvram,   0x34, boot_device);
1377     NVRAM_set_lword(nvram,  0x38, kernel_image);
1378     NVRAM_set_lword(nvram,  0x3C, kernel_size);
1379     if (cmdline) {
1380         /* XXX: put the cmdline in NVRAM too ? */
1381         strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
1382         NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
1383         NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
1384     } else {
1385         NVRAM_set_lword(nvram,  0x40, 0);
1386         NVRAM_set_lword(nvram,  0x44, 0);
1387     }
1388     NVRAM_set_lword(nvram,  0x48, initrd_image);
1389     NVRAM_set_lword(nvram,  0x4C, initrd_size);
1390     NVRAM_set_lword(nvram,  0x50, NVRAM_image);
1391
1392     NVRAM_set_word(nvram,   0x54, width);
1393     NVRAM_set_word(nvram,   0x56, height);
1394     NVRAM_set_word(nvram,   0x58, depth);
1395     crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
1396     NVRAM_set_word(nvram,   0xFC, crc);
1397
1398     return 0;
1399 }