Statistics
| Branch: | Revision:

root / hw / ppc.c @ 03f48b07

History | View | Annotate | Download (38.3 kB)

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 "hw.h"
25
#include "ppc.h"
26
#include "qemu-timer.h"
27
#include "sysemu.h"
28
#include "nvram.h"
29
#include "qemu-log.h"
30
#include "loader.h"
31
#include "kvm.h"
32
#include "kvm_ppc.h"
33

    
34
//#define PPC_DEBUG_IRQ
35
//#define PPC_DEBUG_TB
36

    
37
#ifdef PPC_DEBUG_IRQ
38
#  define LOG_IRQ(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
39
#else
40
#  define LOG_IRQ(...) do { } while (0)
41
#endif
42

    
43

    
44
#ifdef PPC_DEBUG_TB
45
#  define LOG_TB(...) qemu_log(__VA_ARGS__)
46
#else
47
#  define LOG_TB(...) do { } while (0)
48
#endif
49

    
50
static void cpu_ppc_tb_stop (CPUState *env);
51
static void cpu_ppc_tb_start (CPUState *env);
52

    
53
void ppc_set_irq(CPUState *env, int n_IRQ, int level)
54
{
55
    unsigned int old_pending = env->pending_interrupts;
56

    
57
    if (level) {
58
        env->pending_interrupts |= 1 << n_IRQ;
59
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
60
    } else {
61
        env->pending_interrupts &= ~(1 << n_IRQ);
62
        if (env->pending_interrupts == 0)
63
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
64
    }
65

    
66
    if (old_pending != env->pending_interrupts) {
67
#ifdef CONFIG_KVM
68
        kvmppc_set_interrupt(env, n_IRQ, level);
69
#endif
70
    }
71

    
72
    LOG_IRQ("%s: %p n_IRQ %d level %d => pending %08" PRIx32
73
                "req %08x\n", __func__, env, n_IRQ, level,
74
                env->pending_interrupts, env->interrupt_request);
75
}
76

    
77
/* PowerPC 6xx / 7xx internal IRQ controller */
78
static void ppc6xx_set_irq (void *opaque, int pin, int level)
79
{
80
    CPUState *env = opaque;
81
    int cur_level;
82

    
83
    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
84
                env, pin, level);
85
    cur_level = (env->irq_input_state >> pin) & 1;
86
    /* Don't generate spurious events */
87
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
88
        switch (pin) {
89
        case PPC6xx_INPUT_TBEN:
90
            /* Level sensitive - active high */
91
            LOG_IRQ("%s: %s the time base\n",
92
                        __func__, level ? "start" : "stop");
93
            if (level) {
94
                cpu_ppc_tb_start(env);
95
            } else {
96
                cpu_ppc_tb_stop(env);
97
            }
98
        case PPC6xx_INPUT_INT:
99
            /* Level sensitive - active high */
100
            LOG_IRQ("%s: set the external IRQ state to %d\n",
101
                        __func__, level);
102
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
103
            break;
104
        case PPC6xx_INPUT_SMI:
105
            /* Level sensitive - active high */
106
            LOG_IRQ("%s: set the SMI IRQ state to %d\n",
107
                        __func__, level);
108
            ppc_set_irq(env, PPC_INTERRUPT_SMI, level);
109
            break;
110
        case PPC6xx_INPUT_MCP:
111
            /* Negative edge sensitive */
112
            /* XXX: TODO: actual reaction may depends on HID0 status
113
             *            603/604/740/750: check HID0[EMCP]
114
             */
115
            if (cur_level == 1 && level == 0) {
116
                LOG_IRQ("%s: raise machine check state\n",
117
                            __func__);
118
                ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
119
            }
120
            break;
121
        case PPC6xx_INPUT_CKSTP_IN:
122
            /* Level sensitive - active low */
123
            /* XXX: TODO: relay the signal to CKSTP_OUT pin */
124
            /* XXX: Note that the only way to restart the CPU is to reset it */
125
            if (level) {
126
                LOG_IRQ("%s: stop the CPU\n", __func__);
127
                env->halted = 1;
128
            }
129
            break;
130
        case PPC6xx_INPUT_HRESET:
131
            /* Level sensitive - active low */
132
            if (level) {
133
                LOG_IRQ("%s: reset the CPU\n", __func__);
134
                env->interrupt_request |= CPU_INTERRUPT_EXITTB;
135
                /* XXX: TOFIX */
136
#if 0
137
                cpu_reset(env);
138
#else
139
                qemu_system_reset_request();
140
#endif
141
            }
142
            break;
143
        case PPC6xx_INPUT_SRESET:
144
            LOG_IRQ("%s: set the RESET IRQ state to %d\n",
145
                        __func__, level);
146
            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
147
            break;
148
        default:
149
            /* Unknown pin - do nothing */
150
            LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
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,
163
                                                  PPC6xx_INPUT_NB);
164
}
165

    
166
#if defined(TARGET_PPC64)
167
/* PowerPC 970 internal IRQ controller */
168
static void ppc970_set_irq (void *opaque, int pin, int level)
169
{
170
    CPUState *env = opaque;
171
    int cur_level;
172

    
173
    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
174
                env, pin, level);
175
    cur_level = (env->irq_input_state >> pin) & 1;
176
    /* Don't generate spurious events */
177
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
178
        switch (pin) {
179
        case PPC970_INPUT_INT:
180
            /* Level sensitive - active high */
181
            LOG_IRQ("%s: set the external IRQ state to %d\n",
182
                        __func__, level);
183
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
184
            break;
185
        case PPC970_INPUT_THINT:
186
            /* Level sensitive - active high */
187
            LOG_IRQ("%s: set the SMI IRQ state to %d\n", __func__,
188
                        level);
189
            ppc_set_irq(env, PPC_INTERRUPT_THERM, level);
190
            break;
191
        case PPC970_INPUT_MCP:
192
            /* Negative edge sensitive */
193
            /* XXX: TODO: actual reaction may depends on HID0 status
194
             *            603/604/740/750: check HID0[EMCP]
195
             */
196
            if (cur_level == 1 && level == 0) {
197
                LOG_IRQ("%s: raise machine check state\n",
198
                            __func__);
199
                ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
200
            }
201
            break;
202
        case PPC970_INPUT_CKSTP:
203
            /* Level sensitive - active low */
204
            /* XXX: TODO: relay the signal to CKSTP_OUT pin */
205
            if (level) {
206
                LOG_IRQ("%s: stop the CPU\n", __func__);
207
                env->halted = 1;
208
            } else {
209
                LOG_IRQ("%s: restart the CPU\n", __func__);
210
                env->halted = 0;
211
                qemu_cpu_kick(env);
212
            }
213
            break;
214
        case PPC970_INPUT_HRESET:
215
            /* Level sensitive - active low */
216
            if (level) {
217
#if 0 // XXX: TOFIX
218
                LOG_IRQ("%s: reset the CPU\n", __func__);
219
                cpu_reset(env);
220
#endif
221
            }
222
            break;
223
        case PPC970_INPUT_SRESET:
224
            LOG_IRQ("%s: set the RESET IRQ state to %d\n",
225
                        __func__, level);
226
            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
227
            break;
228
        case PPC970_INPUT_TBEN:
229
            LOG_IRQ("%s: set the TBEN state to %d\n", __func__,
230
                        level);
231
            /* XXX: TODO */
232
            break;
233
        default:
234
            /* Unknown pin - do nothing */
235
            LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
236
            return;
237
        }
238
        if (level)
239
            env->irq_input_state |= 1 << pin;
240
        else
241
            env->irq_input_state &= ~(1 << pin);
242
    }
243
}
244

    
245
void ppc970_irq_init (CPUState *env)
246
{
247
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env,
248
                                                  PPC970_INPUT_NB);
249
}
250

    
251
/* POWER7 internal IRQ controller */
252
static void power7_set_irq (void *opaque, int pin, int level)
253
{
254
    CPUState *env = opaque;
255

    
256
    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
257
                env, pin, level);
258

    
259
    switch (pin) {
260
    case POWER7_INPUT_INT:
261
        /* Level sensitive - active high */
262
        LOG_IRQ("%s: set the external IRQ state to %d\n",
263
                __func__, level);
264
        ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
265
        break;
266
    default:
267
        /* Unknown pin - do nothing */
268
        LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
269
        return;
270
    }
271
    if (level) {
272
        env->irq_input_state |= 1 << pin;
273
    } else {
274
        env->irq_input_state &= ~(1 << pin);
275
    }
276
}
277

    
278
void ppcPOWER7_irq_init (CPUState *env)
279
{
280
    env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, env,
281
                                                  POWER7_INPUT_NB);
282
}
283
#endif /* defined(TARGET_PPC64) */
284

    
285
/* PowerPC 40x internal IRQ controller */
286
static void ppc40x_set_irq (void *opaque, int pin, int level)
287
{
288
    CPUState *env = opaque;
289
    int cur_level;
290

    
291
    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
292
                env, pin, level);
293
    cur_level = (env->irq_input_state >> pin) & 1;
294
    /* Don't generate spurious events */
295
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
296
        switch (pin) {
297
        case PPC40x_INPUT_RESET_SYS:
298
            if (level) {
299
                LOG_IRQ("%s: reset the PowerPC system\n",
300
                            __func__);
301
                ppc40x_system_reset(env);
302
            }
303
            break;
304
        case PPC40x_INPUT_RESET_CHIP:
305
            if (level) {
306
                LOG_IRQ("%s: reset the PowerPC chip\n", __func__);
307
                ppc40x_chip_reset(env);
308
            }
309
            break;
310
        case PPC40x_INPUT_RESET_CORE:
311
            /* XXX: TODO: update DBSR[MRR] */
312
            if (level) {
313
                LOG_IRQ("%s: reset the PowerPC core\n", __func__);
314
                ppc40x_core_reset(env);
315
            }
316
            break;
317
        case PPC40x_INPUT_CINT:
318
            /* Level sensitive - active high */
319
            LOG_IRQ("%s: set the critical IRQ state to %d\n",
320
                        __func__, level);
321
            ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
322
            break;
323
        case PPC40x_INPUT_INT:
324
            /* Level sensitive - active high */
325
            LOG_IRQ("%s: set the external IRQ state to %d\n",
326
                        __func__, level);
327
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
328
            break;
329
        case PPC40x_INPUT_HALT:
330
            /* Level sensitive - active low */
331
            if (level) {
332
                LOG_IRQ("%s: stop the CPU\n", __func__);
333
                env->halted = 1;
334
            } else {
335
                LOG_IRQ("%s: restart the CPU\n", __func__);
336
                env->halted = 0;
337
                qemu_cpu_kick(env);
338
            }
339
            break;
340
        case PPC40x_INPUT_DEBUG:
341
            /* Level sensitive - active high */
342
            LOG_IRQ("%s: set the debug pin state to %d\n",
343
                        __func__, level);
344
            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
345
            break;
346
        default:
347
            /* Unknown pin - do nothing */
348
            LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
349
            return;
350
        }
351
        if (level)
352
            env->irq_input_state |= 1 << pin;
353
        else
354
            env->irq_input_state &= ~(1 << pin);
355
    }
356
}
357

    
358
void ppc40x_irq_init (CPUState *env)
359
{
360
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq,
361
                                                  env, PPC40x_INPUT_NB);
362
}
363

    
364
/* PowerPC E500 internal IRQ controller */
365
static void ppce500_set_irq (void *opaque, int pin, int level)
366
{
367
    CPUState *env = opaque;
368
    int cur_level;
369

    
370
    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
371
                env, pin, level);
372
    cur_level = (env->irq_input_state >> pin) & 1;
373
    /* Don't generate spurious events */
374
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
375
        switch (pin) {
376
        case PPCE500_INPUT_MCK:
377
            if (level) {
378
                LOG_IRQ("%s: reset the PowerPC system\n",
379
                            __func__);
380
                qemu_system_reset_request();
381
            }
382
            break;
383
        case PPCE500_INPUT_RESET_CORE:
384
            if (level) {
385
                LOG_IRQ("%s: reset the PowerPC core\n", __func__);
386
                ppc_set_irq(env, PPC_INTERRUPT_MCK, level);
387
            }
388
            break;
389
        case PPCE500_INPUT_CINT:
390
            /* Level sensitive - active high */
391
            LOG_IRQ("%s: set the critical IRQ state to %d\n",
392
                        __func__, level);
393
            ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
394
            break;
395
        case PPCE500_INPUT_INT:
396
            /* Level sensitive - active high */
397
            LOG_IRQ("%s: set the core IRQ state to %d\n",
398
                        __func__, level);
399
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
400
            break;
401
        case PPCE500_INPUT_DEBUG:
402
            /* Level sensitive - active high */
403
            LOG_IRQ("%s: set the debug pin state to %d\n",
404
                        __func__, level);
405
            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
406
            break;
407
        default:
408
            /* Unknown pin - do nothing */
409
            LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
410
            return;
411
        }
412
        if (level)
413
            env->irq_input_state |= 1 << pin;
414
        else
415
            env->irq_input_state &= ~(1 << pin);
416
    }
417
}
418

    
419
void ppce500_irq_init (CPUState *env)
420
{
421
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
422
                                        env, PPCE500_INPUT_NB);
423
}
424
/*****************************************************************************/
425
/* PowerPC time base and decrementer emulation */
426

    
427
uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset)
428
{
429
    /* TB time in tb periods */
430
    return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset;
431
}
432

    
433
uint64_t cpu_ppc_load_tbl (CPUState *env)
434
{
435
    ppc_tb_t *tb_env = env->tb_env;
436
    uint64_t tb;
437

    
438
    if (kvm_enabled()) {
439
        return env->spr[SPR_TBL];
440
    }
441

    
442
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
443
    LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
444

    
445
    return tb;
446
}
447

    
448
static inline uint32_t _cpu_ppc_load_tbu(CPUState *env)
449
{
450
    ppc_tb_t *tb_env = env->tb_env;
451
    uint64_t tb;
452

    
453
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
454
    LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
455

    
456
    return tb >> 32;
457
}
458

    
459
uint32_t cpu_ppc_load_tbu (CPUState *env)
460
{
461
    if (kvm_enabled()) {
462
        return env->spr[SPR_TBU];
463
    }
464

    
465
    return _cpu_ppc_load_tbu(env);
466
}
467

    
468
static inline void cpu_ppc_store_tb(ppc_tb_t *tb_env, uint64_t vmclk,
469
                                    int64_t *tb_offsetp, uint64_t value)
470
{
471
    *tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec());
472
    LOG_TB("%s: tb %016" PRIx64 " offset %08" PRIx64 "\n",
473
                __func__, value, *tb_offsetp);
474
}
475

    
476
void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
477
{
478
    ppc_tb_t *tb_env = env->tb_env;
479
    uint64_t tb;
480

    
481
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
482
    tb &= 0xFFFFFFFF00000000ULL;
483
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
484
                     &tb_env->tb_offset, tb | (uint64_t)value);
485
}
486

    
487
static inline void _cpu_ppc_store_tbu(CPUState *env, uint32_t value)
488
{
489
    ppc_tb_t *tb_env = env->tb_env;
490
    uint64_t tb;
491

    
492
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
493
    tb &= 0x00000000FFFFFFFFULL;
494
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
495
                     &tb_env->tb_offset, ((uint64_t)value << 32) | tb);
496
}
497

    
498
void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
499
{
500
    _cpu_ppc_store_tbu(env, value);
501
}
502

    
503
uint64_t cpu_ppc_load_atbl (CPUState *env)
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_ns(vm_clock), tb_env->atb_offset);
509
    LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
510

    
511
    return tb;
512
}
513

    
514
uint32_t cpu_ppc_load_atbu (CPUState *env)
515
{
516
    ppc_tb_t *tb_env = env->tb_env;
517
    uint64_t tb;
518

    
519
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
520
    LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
521

    
522
    return tb >> 32;
523
}
524

    
525
void cpu_ppc_store_atbl (CPUState *env, uint32_t value)
526
{
527
    ppc_tb_t *tb_env = env->tb_env;
528
    uint64_t tb;
529

    
530
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
531
    tb &= 0xFFFFFFFF00000000ULL;
532
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
533
                     &tb_env->atb_offset, tb | (uint64_t)value);
534
}
535

    
536
void cpu_ppc_store_atbu (CPUState *env, uint32_t value)
537
{
538
    ppc_tb_t *tb_env = env->tb_env;
539
    uint64_t tb;
540

    
541
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
542
    tb &= 0x00000000FFFFFFFFULL;
543
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
544
                     &tb_env->atb_offset, ((uint64_t)value << 32) | tb);
545
}
546

    
547
static void cpu_ppc_tb_stop (CPUState *env)
548
{
549
    ppc_tb_t *tb_env = env->tb_env;
550
    uint64_t tb, atb, vmclk;
551

    
552
    /* If the time base is already frozen, do nothing */
553
    if (tb_env->tb_freq != 0) {
554
        vmclk = qemu_get_clock_ns(vm_clock);
555
        /* Get the time base */
556
        tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
557
        /* Get the alternate time base */
558
        atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset);
559
        /* Store the time base value (ie compute the current offset) */
560
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
561
        /* Store the alternate time base value (compute the current offset) */
562
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
563
        /* Set the time base frequency to zero */
564
        tb_env->tb_freq = 0;
565
        /* Now, the time bases are frozen to tb_offset / atb_offset value */
566
    }
567
}
568

    
569
static void cpu_ppc_tb_start (CPUState *env)
570
{
571
    ppc_tb_t *tb_env = env->tb_env;
572
    uint64_t tb, atb, vmclk;
573

    
574
    /* If the time base is not frozen, do nothing */
575
    if (tb_env->tb_freq == 0) {
576
        vmclk = qemu_get_clock_ns(vm_clock);
577
        /* Get the time base from tb_offset */
578
        tb = tb_env->tb_offset;
579
        /* Get the alternate time base from atb_offset */
580
        atb = tb_env->atb_offset;
581
        /* Restore the tb frequency from the decrementer frequency */
582
        tb_env->tb_freq = tb_env->decr_freq;
583
        /* Store the time base value */
584
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
585
        /* Store the alternate time base value */
586
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
587
    }
588
}
589

    
590
static inline uint32_t _cpu_ppc_load_decr(CPUState *env, uint64_t next)
591
{
592
    ppc_tb_t *tb_env = env->tb_env;
593
    uint32_t decr;
594
    int64_t diff;
595

    
596
    diff = next - qemu_get_clock_ns(vm_clock);
597
    if (diff >= 0) {
598
        decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec());
599
    } else if (tb_env->flags & PPC_TIMER_BOOKE) {
600
        decr = 0;
601
    }  else {
602
        decr = -muldiv64(-diff, tb_env->decr_freq, get_ticks_per_sec());
603
    }
604
    LOG_TB("%s: %08" PRIx32 "\n", __func__, decr);
605

    
606
    return decr;
607
}
608

    
609
uint32_t cpu_ppc_load_decr (CPUState *env)
610
{
611
    ppc_tb_t *tb_env = env->tb_env;
612

    
613
    if (kvm_enabled()) {
614
        return env->spr[SPR_DECR];
615
    }
616

    
617
    return _cpu_ppc_load_decr(env, tb_env->decr_next);
618
}
619

    
620
uint32_t cpu_ppc_load_hdecr (CPUState *env)
621
{
622
    ppc_tb_t *tb_env = env->tb_env;
623

    
624
    return _cpu_ppc_load_decr(env, tb_env->hdecr_next);
625
}
626

    
627
uint64_t cpu_ppc_load_purr (CPUState *env)
628
{
629
    ppc_tb_t *tb_env = env->tb_env;
630
    uint64_t diff;
631

    
632
    diff = qemu_get_clock_ns(vm_clock) - tb_env->purr_start;
633

    
634
    return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec());
635
}
636

    
637
/* When decrementer expires,
638
 * all we need to do is generate or queue a CPU exception
639
 */
640
static inline void cpu_ppc_decr_excp(CPUState *env)
641
{
642
    /* Raise it */
643
    LOG_TB("raise decrementer exception\n");
644
    ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
645
}
646

    
647
static inline void cpu_ppc_hdecr_excp(CPUState *env)
648
{
649
    /* Raise it */
650
    LOG_TB("raise decrementer exception\n");
651
    ppc_set_irq(env, PPC_INTERRUPT_HDECR, 1);
652
}
653

    
654
static void __cpu_ppc_store_decr (CPUState *env, uint64_t *nextp,
655
                                  struct QEMUTimer *timer,
656
                                  void (*raise_excp)(CPUState *),
657
                                  uint32_t decr, uint32_t value,
658
                                  int is_excp)
659
{
660
    ppc_tb_t *tb_env = env->tb_env;
661
    uint64_t now, next;
662

    
663
    LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
664
                decr, value);
665

    
666
    if (kvm_enabled()) {
667
        /* KVM handles decrementer exceptions, we don't need our own timer */
668
        return;
669
    }
670

    
671
    now = qemu_get_clock_ns(vm_clock);
672
    next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq);
673
    if (is_excp) {
674
        next += *nextp - now;
675
    }
676
    if (next == now) {
677
        next++;
678
    }
679
    *nextp = next;
680
    /* Adjust timer */
681
    qemu_mod_timer(timer, next);
682

    
683
    /* If we set a negative value and the decrementer was positive, raise an
684
     * exception.
685
     */
686
    if ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED)
687
        && (value & 0x80000000)
688
        && !(decr & 0x80000000)) {
689
        (*raise_excp)(env);
690
    }
691
}
692

    
693
static inline void _cpu_ppc_store_decr(CPUState *env, uint32_t decr,
694
                                       uint32_t value, int is_excp)
695
{
696
    ppc_tb_t *tb_env = env->tb_env;
697

    
698
    __cpu_ppc_store_decr(env, &tb_env->decr_next, tb_env->decr_timer,
699
                         &cpu_ppc_decr_excp, decr, value, is_excp);
700
}
701

    
702
void cpu_ppc_store_decr (CPUState *env, uint32_t value)
703
{
704
    _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
705
}
706

    
707
static void cpu_ppc_decr_cb (void *opaque)
708
{
709
    _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
710
}
711

    
712
static inline void _cpu_ppc_store_hdecr(CPUState *env, uint32_t hdecr,
713
                                        uint32_t value, int is_excp)
714
{
715
    ppc_tb_t *tb_env = env->tb_env;
716

    
717
    if (tb_env->hdecr_timer != NULL) {
718
        __cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer,
719
                             &cpu_ppc_hdecr_excp, hdecr, value, is_excp);
720
    }
721
}
722

    
723
void cpu_ppc_store_hdecr (CPUState *env, uint32_t value)
724
{
725
    _cpu_ppc_store_hdecr(env, cpu_ppc_load_hdecr(env), value, 0);
726
}
727

    
728
static void cpu_ppc_hdecr_cb (void *opaque)
729
{
730
    _cpu_ppc_store_hdecr(opaque, 0x00000000, 0xFFFFFFFF, 1);
731
}
732

    
733
void cpu_ppc_store_purr (CPUState *env, uint64_t value)
734
{
735
    ppc_tb_t *tb_env = env->tb_env;
736

    
737
    tb_env->purr_load = value;
738
    tb_env->purr_start = qemu_get_clock_ns(vm_clock);
739
}
740

    
741
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
742
{
743
    CPUState *env = opaque;
744
    ppc_tb_t *tb_env = env->tb_env;
745

    
746
    tb_env->tb_freq = freq;
747
    tb_env->decr_freq = freq;
748
    /* There is a bug in Linux 2.4 kernels:
749
     * if a decrementer exception is pending when it enables msr_ee at startup,
750
     * it's not ready to handle it...
751
     */
752
    _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
753
    _cpu_ppc_store_hdecr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
754
    cpu_ppc_store_purr(env, 0x0000000000000000ULL);
755
}
756

    
757
/* Set up (once) timebase frequency (in Hz) */
758
clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq)
759
{
760
    ppc_tb_t *tb_env;
761

    
762
    tb_env = g_malloc0(sizeof(ppc_tb_t));
763
    env->tb_env = tb_env;
764
    tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
765
    /* Create new timer */
766
    tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_decr_cb, env);
767
    if (0) {
768
        /* XXX: find a suitable condition to enable the hypervisor decrementer
769
         */
770
        tb_env->hdecr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_hdecr_cb, env);
771
    } else {
772
        tb_env->hdecr_timer = NULL;
773
    }
774
    cpu_ppc_set_tb_clk(env, freq);
775

    
776
    return &cpu_ppc_set_tb_clk;
777
}
778

    
779
/* Specific helpers for POWER & PowerPC 601 RTC */
780
#if 0
781
static clk_setup_cb cpu_ppc601_rtc_init (CPUState *env)
782
{
783
    return cpu_ppc_tb_init(env, 7812500);
784
}
785
#endif
786

    
787
void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
788
{
789
    _cpu_ppc_store_tbu(env, value);
790
}
791

    
792
uint32_t cpu_ppc601_load_rtcu (CPUState *env)
793
{
794
    return _cpu_ppc_load_tbu(env);
795
}
796

    
797
void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
798
{
799
    cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
800
}
801

    
802
uint32_t cpu_ppc601_load_rtcl (CPUState *env)
803
{
804
    return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
805
}
806

    
807
/*****************************************************************************/
808
/* PowerPC 40x timers */
809

    
810
/* PIT, FIT & WDT */
811
typedef struct ppc40x_timer_t ppc40x_timer_t;
812
struct ppc40x_timer_t {
813
    uint64_t pit_reload;  /* PIT auto-reload value        */
814
    uint64_t fit_next;    /* Tick for next FIT interrupt  */
815
    struct QEMUTimer *fit_timer;
816
    uint64_t wdt_next;    /* Tick for next WDT interrupt  */
817
    struct QEMUTimer *wdt_timer;
818

    
819
    /* 405 have the PIT, 440 have a DECR.  */
820
    unsigned int decr_excp;
821
};
822

    
823
/* Fixed interval timer */
824
static void cpu_4xx_fit_cb (void *opaque)
825
{
826
    CPUState *env;
827
    ppc_tb_t *tb_env;
828
    ppc40x_timer_t *ppc40x_timer;
829
    uint64_t now, next;
830

    
831
    env = opaque;
832
    tb_env = env->tb_env;
833
    ppc40x_timer = tb_env->opaque;
834
    now = qemu_get_clock_ns(vm_clock);
835
    switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
836
    case 0:
837
        next = 1 << 9;
838
        break;
839
    case 1:
840
        next = 1 << 13;
841
        break;
842
    case 2:
843
        next = 1 << 17;
844
        break;
845
    case 3:
846
        next = 1 << 21;
847
        break;
848
    default:
849
        /* Cannot occur, but makes gcc happy */
850
        return;
851
    }
852
    next = now + muldiv64(next, get_ticks_per_sec(), tb_env->tb_freq);
853
    if (next == now)
854
        next++;
855
    qemu_mod_timer(ppc40x_timer->fit_timer, next);
856
    env->spr[SPR_40x_TSR] |= 1 << 26;
857
    if ((env->spr[SPR_40x_TCR] >> 23) & 0x1)
858
        ppc_set_irq(env, PPC_INTERRUPT_FIT, 1);
859
    LOG_TB("%s: ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__,
860
           (int)((env->spr[SPR_40x_TCR] >> 23) & 0x1),
861
           env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
862
}
863

    
864
/* Programmable interval timer */
865
static void start_stop_pit (CPUState *env, ppc_tb_t *tb_env, int is_excp)
866
{
867
    ppc40x_timer_t *ppc40x_timer;
868
    uint64_t now, next;
869

    
870
    ppc40x_timer = tb_env->opaque;
871
    if (ppc40x_timer->pit_reload <= 1 ||
872
        !((env->spr[SPR_40x_TCR] >> 26) & 0x1) ||
873
        (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
874
        /* Stop PIT */
875
        LOG_TB("%s: stop PIT\n", __func__);
876
        qemu_del_timer(tb_env->decr_timer);
877
    } else {
878
        LOG_TB("%s: start PIT %016" PRIx64 "\n",
879
                    __func__, ppc40x_timer->pit_reload);
880
        now = qemu_get_clock_ns(vm_clock);
881
        next = now + muldiv64(ppc40x_timer->pit_reload,
882
                              get_ticks_per_sec(), tb_env->decr_freq);
883
        if (is_excp)
884
            next += tb_env->decr_next - now;
885
        if (next == now)
886
            next++;
887
        qemu_mod_timer(tb_env->decr_timer, next);
888
        tb_env->decr_next = next;
889
    }
890
}
891

    
892
static void cpu_4xx_pit_cb (void *opaque)
893
{
894
    CPUState *env;
895
    ppc_tb_t *tb_env;
896
    ppc40x_timer_t *ppc40x_timer;
897

    
898
    env = opaque;
899
    tb_env = env->tb_env;
900
    ppc40x_timer = tb_env->opaque;
901
    env->spr[SPR_40x_TSR] |= 1 << 27;
902
    if ((env->spr[SPR_40x_TCR] >> 26) & 0x1)
903
        ppc_set_irq(env, ppc40x_timer->decr_excp, 1);
904
    start_stop_pit(env, tb_env, 1);
905
    LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " "
906
           "%016" PRIx64 "\n", __func__,
907
           (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1),
908
           (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1),
909
           env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
910
           ppc40x_timer->pit_reload);
911
}
912

    
913
/* Watchdog timer */
914
static void cpu_4xx_wdt_cb (void *opaque)
915
{
916
    CPUState *env;
917
    ppc_tb_t *tb_env;
918
    ppc40x_timer_t *ppc40x_timer;
919
    uint64_t now, next;
920

    
921
    env = opaque;
922
    tb_env = env->tb_env;
923
    ppc40x_timer = tb_env->opaque;
924
    now = qemu_get_clock_ns(vm_clock);
925
    switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
926
    case 0:
927
        next = 1 << 17;
928
        break;
929
    case 1:
930
        next = 1 << 21;
931
        break;
932
    case 2:
933
        next = 1 << 25;
934
        break;
935
    case 3:
936
        next = 1 << 29;
937
        break;
938
    default:
939
        /* Cannot occur, but makes gcc happy */
940
        return;
941
    }
942
    next = now + muldiv64(next, get_ticks_per_sec(), tb_env->decr_freq);
943
    if (next == now)
944
        next++;
945
    LOG_TB("%s: TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__,
946
           env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
947
    switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
948
    case 0x0:
949
    case 0x1:
950
        qemu_mod_timer(ppc40x_timer->wdt_timer, next);
951
        ppc40x_timer->wdt_next = next;
952
        env->spr[SPR_40x_TSR] |= 1 << 31;
953
        break;
954
    case 0x2:
955
        qemu_mod_timer(ppc40x_timer->wdt_timer, next);
956
        ppc40x_timer->wdt_next = next;
957
        env->spr[SPR_40x_TSR] |= 1 << 30;
958
        if ((env->spr[SPR_40x_TCR] >> 27) & 0x1)
959
            ppc_set_irq(env, PPC_INTERRUPT_WDT, 1);
960
        break;
961
    case 0x3:
962
        env->spr[SPR_40x_TSR] &= ~0x30000000;
963
        env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000;
964
        switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) {
965
        case 0x0:
966
            /* No reset */
967
            break;
968
        case 0x1: /* Core reset */
969
            ppc40x_core_reset(env);
970
            break;
971
        case 0x2: /* Chip reset */
972
            ppc40x_chip_reset(env);
973
            break;
974
        case 0x3: /* System reset */
975
            ppc40x_system_reset(env);
976
            break;
977
        }
978
    }
979
}
980

    
981
void store_40x_pit (CPUState *env, target_ulong val)
982
{
983
    ppc_tb_t *tb_env;
984
    ppc40x_timer_t *ppc40x_timer;
985

    
986
    tb_env = env->tb_env;
987
    ppc40x_timer = tb_env->opaque;
988
    LOG_TB("%s val" TARGET_FMT_lx "\n", __func__, val);
989
    ppc40x_timer->pit_reload = val;
990
    start_stop_pit(env, tb_env, 0);
991
}
992

    
993
target_ulong load_40x_pit (CPUState *env)
994
{
995
    return cpu_ppc_load_decr(env);
996
}
997

    
998
static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq)
999
{
1000
    CPUState *env = opaque;
1001
    ppc_tb_t *tb_env = env->tb_env;
1002

    
1003
    LOG_TB("%s set new frequency to %" PRIu32 "\n", __func__,
1004
                freq);
1005
    tb_env->tb_freq = freq;
1006
    tb_env->decr_freq = freq;
1007
    /* XXX: we should also update all timers */
1008
}
1009

    
1010
clk_setup_cb ppc_40x_timers_init (CPUState *env, uint32_t freq,
1011
                                  unsigned int decr_excp)
1012
{
1013
    ppc_tb_t *tb_env;
1014
    ppc40x_timer_t *ppc40x_timer;
1015

    
1016
    tb_env = g_malloc0(sizeof(ppc_tb_t));
1017
    env->tb_env = tb_env;
1018
    tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
1019
    ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
1020
    tb_env->tb_freq = freq;
1021
    tb_env->decr_freq = freq;
1022
    tb_env->opaque = ppc40x_timer;
1023
    LOG_TB("%s freq %" PRIu32 "\n", __func__, freq);
1024
    if (ppc40x_timer != NULL) {
1025
        /* We use decr timer for PIT */
1026
        tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_4xx_pit_cb, env);
1027
        ppc40x_timer->fit_timer =
1028
            qemu_new_timer_ns(vm_clock, &cpu_4xx_fit_cb, env);
1029
        ppc40x_timer->wdt_timer =
1030
            qemu_new_timer_ns(vm_clock, &cpu_4xx_wdt_cb, env);
1031
        ppc40x_timer->decr_excp = decr_excp;
1032
    }
1033

    
1034
    return &ppc_40x_set_tb_clk;
1035
}
1036

    
1037
/*****************************************************************************/
1038
/* Embedded PowerPC Device Control Registers */
1039
typedef struct ppc_dcrn_t ppc_dcrn_t;
1040
struct ppc_dcrn_t {
1041
    dcr_read_cb dcr_read;
1042
    dcr_write_cb dcr_write;
1043
    void *opaque;
1044
};
1045

    
1046
/* XXX: on 460, DCR addresses are 32 bits wide,
1047
 *      using DCRIPR to get the 22 upper bits of the DCR address
1048
 */
1049
#define DCRN_NB 1024
1050
struct ppc_dcr_t {
1051
    ppc_dcrn_t dcrn[DCRN_NB];
1052
    int (*read_error)(int dcrn);
1053
    int (*write_error)(int dcrn);
1054
};
1055

    
1056
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
1057
{
1058
    ppc_dcrn_t *dcr;
1059

    
1060
    if (dcrn < 0 || dcrn >= DCRN_NB)
1061
        goto error;
1062
    dcr = &dcr_env->dcrn[dcrn];
1063
    if (dcr->dcr_read == NULL)
1064
        goto error;
1065
    *valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
1066

    
1067
    return 0;
1068

    
1069
 error:
1070
    if (dcr_env->read_error != NULL)
1071
        return (*dcr_env->read_error)(dcrn);
1072

    
1073
    return -1;
1074
}
1075

    
1076
int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
1077
{
1078
    ppc_dcrn_t *dcr;
1079

    
1080
    if (dcrn < 0 || dcrn >= DCRN_NB)
1081
        goto error;
1082
    dcr = &dcr_env->dcrn[dcrn];
1083
    if (dcr->dcr_write == NULL)
1084
        goto error;
1085
    (*dcr->dcr_write)(dcr->opaque, dcrn, val);
1086

    
1087
    return 0;
1088

    
1089
 error:
1090
    if (dcr_env->write_error != NULL)
1091
        return (*dcr_env->write_error)(dcrn);
1092

    
1093
    return -1;
1094
}
1095

    
1096
int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
1097
                      dcr_read_cb dcr_read, dcr_write_cb dcr_write)
1098
{
1099
    ppc_dcr_t *dcr_env;
1100
    ppc_dcrn_t *dcr;
1101

    
1102
    dcr_env = env->dcr_env;
1103
    if (dcr_env == NULL)
1104
        return -1;
1105
    if (dcrn < 0 || dcrn >= DCRN_NB)
1106
        return -1;
1107
    dcr = &dcr_env->dcrn[dcrn];
1108
    if (dcr->opaque != NULL ||
1109
        dcr->dcr_read != NULL ||
1110
        dcr->dcr_write != NULL)
1111
        return -1;
1112
    dcr->opaque = opaque;
1113
    dcr->dcr_read = dcr_read;
1114
    dcr->dcr_write = dcr_write;
1115

    
1116
    return 0;
1117
}
1118

    
1119
int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn),
1120
                  int (*write_error)(int dcrn))
1121
{
1122
    ppc_dcr_t *dcr_env;
1123

    
1124
    dcr_env = g_malloc0(sizeof(ppc_dcr_t));
1125
    dcr_env->read_error = read_error;
1126
    dcr_env->write_error = write_error;
1127
    env->dcr_env = dcr_env;
1128

    
1129
    return 0;
1130
}
1131

    
1132
/*****************************************************************************/
1133
/* Debug port */
1134
void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
1135
{
1136
    addr &= 0xF;
1137
    switch (addr) {
1138
    case 0:
1139
        printf("%c", val);
1140
        break;
1141
    case 1:
1142
        printf("\n");
1143
        fflush(stdout);
1144
        break;
1145
    case 2:
1146
        printf("Set loglevel to %04" PRIx32 "\n", val);
1147
        cpu_set_log(val | 0x100);
1148
        break;
1149
    }
1150
}
1151

    
1152
/*****************************************************************************/
1153
/* NVRAM helpers */
1154
static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr)
1155
{
1156
    return (*nvram->read_fn)(nvram->opaque, addr);
1157
}
1158

    
1159
static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val)
1160
{
1161
    (*nvram->write_fn)(nvram->opaque, addr, val);
1162
}
1163

    
1164
void NVRAM_set_byte (nvram_t *nvram, uint32_t addr, uint8_t value)
1165
{
1166
    nvram_write(nvram, addr, value);
1167
}
1168

    
1169
uint8_t NVRAM_get_byte (nvram_t *nvram, uint32_t addr)
1170
{
1171
    return nvram_read(nvram, addr);
1172
}
1173

    
1174
void NVRAM_set_word (nvram_t *nvram, uint32_t addr, uint16_t value)
1175
{
1176
    nvram_write(nvram, addr, value >> 8);
1177
    nvram_write(nvram, addr + 1, value & 0xFF);
1178
}
1179

    
1180
uint16_t NVRAM_get_word (nvram_t *nvram, uint32_t addr)
1181
{
1182
    uint16_t tmp;
1183

    
1184
    tmp = nvram_read(nvram, addr) << 8;
1185
    tmp |= nvram_read(nvram, addr + 1);
1186

    
1187
    return tmp;
1188
}
1189

    
1190
void NVRAM_set_lword (nvram_t *nvram, uint32_t addr, uint32_t value)
1191
{
1192
    nvram_write(nvram, addr, value >> 24);
1193
    nvram_write(nvram, addr + 1, (value >> 16) & 0xFF);
1194
    nvram_write(nvram, addr + 2, (value >> 8) & 0xFF);
1195
    nvram_write(nvram, addr + 3, value & 0xFF);
1196
}
1197

    
1198
uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr)
1199
{
1200
    uint32_t tmp;
1201

    
1202
    tmp = nvram_read(nvram, addr) << 24;
1203
    tmp |= nvram_read(nvram, addr + 1) << 16;
1204
    tmp |= nvram_read(nvram, addr + 2) << 8;
1205
    tmp |= nvram_read(nvram, addr + 3);
1206

    
1207
    return tmp;
1208
}
1209

    
1210
void NVRAM_set_string (nvram_t *nvram, uint32_t addr,
1211
                       const char *str, uint32_t max)
1212
{
1213
    int i;
1214

    
1215
    for (i = 0; i < max && str[i] != '\0'; i++) {
1216
        nvram_write(nvram, addr + i, str[i]);
1217
    }
1218
    nvram_write(nvram, addr + i, str[i]);
1219
    nvram_write(nvram, addr + max - 1, '\0');
1220
}
1221

    
1222
int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max)
1223
{
1224
    int i;
1225

    
1226
    memset(dst, 0, max);
1227
    for (i = 0; i < max; i++) {
1228
        dst[i] = NVRAM_get_byte(nvram, addr + i);
1229
        if (dst[i] == '\0')
1230
            break;
1231
    }
1232

    
1233
    return i;
1234
}
1235

    
1236
static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
1237
{
1238
    uint16_t tmp;
1239
    uint16_t pd, pd1, pd2;
1240

    
1241
    tmp = prev >> 8;
1242
    pd = prev ^ value;
1243
    pd1 = pd & 0x000F;
1244
    pd2 = ((pd >> 4) & 0x000F) ^ pd1;
1245
    tmp ^= (pd1 << 3) | (pd1 << 8);
1246
    tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
1247

    
1248
    return tmp;
1249
}
1250

    
1251
static uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count)
1252
{
1253
    uint32_t i;
1254
    uint16_t crc = 0xFFFF;
1255
    int odd;
1256

    
1257
    odd = count & 1;
1258
    count &= ~1;
1259
    for (i = 0; i != count; i++) {
1260
        crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
1261
    }
1262
    if (odd) {
1263
        crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
1264
    }
1265

    
1266
    return crc;
1267
}
1268

    
1269
#define CMDLINE_ADDR 0x017ff000
1270

    
1271
int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
1272
                          const char *arch,
1273
                          uint32_t RAM_size, int boot_device,
1274
                          uint32_t kernel_image, uint32_t kernel_size,
1275
                          const char *cmdline,
1276
                          uint32_t initrd_image, uint32_t initrd_size,
1277
                          uint32_t NVRAM_image,
1278
                          int width, int height, int depth)
1279
{
1280
    uint16_t crc;
1281

    
1282
    /* Set parameters for Open Hack'Ware BIOS */
1283
    NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
1284
    NVRAM_set_lword(nvram,  0x10, 0x00000002); /* structure v2 */
1285
    NVRAM_set_word(nvram,   0x14, NVRAM_size);
1286
    NVRAM_set_string(nvram, 0x20, arch, 16);
1287
    NVRAM_set_lword(nvram,  0x30, RAM_size);
1288
    NVRAM_set_byte(nvram,   0x34, boot_device);
1289
    NVRAM_set_lword(nvram,  0x38, kernel_image);
1290
    NVRAM_set_lword(nvram,  0x3C, kernel_size);
1291
    if (cmdline) {
1292
        /* XXX: put the cmdline in NVRAM too ? */
1293
        pstrcpy_targphys("cmdline", CMDLINE_ADDR, RAM_size - CMDLINE_ADDR, cmdline);
1294
        NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
1295
        NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
1296
    } else {
1297
        NVRAM_set_lword(nvram,  0x40, 0);
1298
        NVRAM_set_lword(nvram,  0x44, 0);
1299
    }
1300
    NVRAM_set_lword(nvram,  0x48, initrd_image);
1301
    NVRAM_set_lword(nvram,  0x4C, initrd_size);
1302
    NVRAM_set_lword(nvram,  0x50, NVRAM_image);
1303

    
1304
    NVRAM_set_word(nvram,   0x54, width);
1305
    NVRAM_set_word(nvram,   0x56, height);
1306
    NVRAM_set_word(nvram,   0x58, depth);
1307
    crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
1308
    NVRAM_set_word(nvram,   0xFC, crc);
1309

    
1310
    return 0;
1311
}