Statistics
| Branch: | Revision:

root / hw / ppc.c @ 9bfa659e

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 (CPUPPCState *env);
51
static void cpu_ppc_tb_start (CPUPPCState *env);
52

    
53
void ppc_set_irq(CPUPPCState *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
    CPUPPCState *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
                cpu_interrupt(env, CPU_INTERRUPT_RESET);
135
            }
136
            break;
137
        case PPC6xx_INPUT_SRESET:
138
            LOG_IRQ("%s: set the RESET IRQ state to %d\n",
139
                        __func__, level);
140
            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
141
            break;
142
        default:
143
            /* Unknown pin - do nothing */
144
            LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
145
            return;
146
        }
147
        if (level)
148
            env->irq_input_state |= 1 << pin;
149
        else
150
            env->irq_input_state &= ~(1 << pin);
151
    }
152
}
153

    
154
void ppc6xx_irq_init (CPUPPCState *env)
155
{
156
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env,
157
                                                  PPC6xx_INPUT_NB);
158
}
159

    
160
#if defined(TARGET_PPC64)
161
/* PowerPC 970 internal IRQ controller */
162
static void ppc970_set_irq (void *opaque, int pin, int level)
163
{
164
    CPUPPCState *env = opaque;
165
    int cur_level;
166

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

    
236
void ppc970_irq_init (CPUPPCState *env)
237
{
238
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env,
239
                                                  PPC970_INPUT_NB);
240
}
241

    
242
/* POWER7 internal IRQ controller */
243
static void power7_set_irq (void *opaque, int pin, int level)
244
{
245
    CPUPPCState *env = opaque;
246

    
247
    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
248
                env, pin, level);
249

    
250
    switch (pin) {
251
    case POWER7_INPUT_INT:
252
        /* Level sensitive - active high */
253
        LOG_IRQ("%s: set the external IRQ state to %d\n",
254
                __func__, level);
255
        ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
256
        break;
257
    default:
258
        /* Unknown pin - do nothing */
259
        LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
260
        return;
261
    }
262
    if (level) {
263
        env->irq_input_state |= 1 << pin;
264
    } else {
265
        env->irq_input_state &= ~(1 << pin);
266
    }
267
}
268

    
269
void ppcPOWER7_irq_init (CPUPPCState *env)
270
{
271
    env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, env,
272
                                                  POWER7_INPUT_NB);
273
}
274
#endif /* defined(TARGET_PPC64) */
275

    
276
/* PowerPC 40x internal IRQ controller */
277
static void ppc40x_set_irq (void *opaque, int pin, int level)
278
{
279
    CPUPPCState *env = opaque;
280
    int cur_level;
281

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

    
349
void ppc40x_irq_init (CPUPPCState *env)
350
{
351
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq,
352
                                                  env, PPC40x_INPUT_NB);
353
}
354

    
355
/* PowerPC E500 internal IRQ controller */
356
static void ppce500_set_irq (void *opaque, int pin, int level)
357
{
358
    CPUPPCState *env = opaque;
359
    int cur_level;
360

    
361
    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
362
                env, pin, level);
363
    cur_level = (env->irq_input_state >> pin) & 1;
364
    /* Don't generate spurious events */
365
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
366
        switch (pin) {
367
        case PPCE500_INPUT_MCK:
368
            if (level) {
369
                LOG_IRQ("%s: reset the PowerPC system\n",
370
                            __func__);
371
                qemu_system_reset_request();
372
            }
373
            break;
374
        case PPCE500_INPUT_RESET_CORE:
375
            if (level) {
376
                LOG_IRQ("%s: reset the PowerPC core\n", __func__);
377
                ppc_set_irq(env, PPC_INTERRUPT_MCK, level);
378
            }
379
            break;
380
        case PPCE500_INPUT_CINT:
381
            /* Level sensitive - active high */
382
            LOG_IRQ("%s: set the critical IRQ state to %d\n",
383
                        __func__, level);
384
            ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
385
            break;
386
        case PPCE500_INPUT_INT:
387
            /* Level sensitive - active high */
388
            LOG_IRQ("%s: set the core IRQ state to %d\n",
389
                        __func__, level);
390
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
391
            break;
392
        case PPCE500_INPUT_DEBUG:
393
            /* Level sensitive - active high */
394
            LOG_IRQ("%s: set the debug pin state to %d\n",
395
                        __func__, level);
396
            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
397
            break;
398
        default:
399
            /* Unknown pin - do nothing */
400
            LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
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 ppce500_irq_init (CPUPPCState *env)
411
{
412
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
413
                                        env, PPCE500_INPUT_NB);
414
}
415
/*****************************************************************************/
416
/* PowerPC time base and decrementer emulation */
417

    
418
uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset)
419
{
420
    /* TB time in tb periods */
421
    return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset;
422
}
423

    
424
uint64_t cpu_ppc_load_tbl (CPUPPCState *env)
425
{
426
    ppc_tb_t *tb_env = env->tb_env;
427
    uint64_t tb;
428

    
429
    if (kvm_enabled()) {
430
        return env->spr[SPR_TBL];
431
    }
432

    
433
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
434
    LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
435

    
436
    return tb;
437
}
438

    
439
static inline uint32_t _cpu_ppc_load_tbu(CPUPPCState *env)
440
{
441
    ppc_tb_t *tb_env = env->tb_env;
442
    uint64_t tb;
443

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

    
447
    return tb >> 32;
448
}
449

    
450
uint32_t cpu_ppc_load_tbu (CPUPPCState *env)
451
{
452
    if (kvm_enabled()) {
453
        return env->spr[SPR_TBU];
454
    }
455

    
456
    return _cpu_ppc_load_tbu(env);
457
}
458

    
459
static inline void cpu_ppc_store_tb(ppc_tb_t *tb_env, uint64_t vmclk,
460
                                    int64_t *tb_offsetp, uint64_t value)
461
{
462
    *tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec());
463
    LOG_TB("%s: tb %016" PRIx64 " offset %08" PRIx64 "\n",
464
                __func__, value, *tb_offsetp);
465
}
466

    
467
void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value)
468
{
469
    ppc_tb_t *tb_env = env->tb_env;
470
    uint64_t tb;
471

    
472
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
473
    tb &= 0xFFFFFFFF00000000ULL;
474
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
475
                     &tb_env->tb_offset, tb | (uint64_t)value);
476
}
477

    
478
static inline void _cpu_ppc_store_tbu(CPUPPCState *env, uint32_t value)
479
{
480
    ppc_tb_t *tb_env = env->tb_env;
481
    uint64_t tb;
482

    
483
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
484
    tb &= 0x00000000FFFFFFFFULL;
485
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
486
                     &tb_env->tb_offset, ((uint64_t)value << 32) | tb);
487
}
488

    
489
void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value)
490
{
491
    _cpu_ppc_store_tbu(env, value);
492
}
493

    
494
uint64_t cpu_ppc_load_atbl (CPUPPCState *env)
495
{
496
    ppc_tb_t *tb_env = env->tb_env;
497
    uint64_t tb;
498

    
499
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
500
    LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
501

    
502
    return tb;
503
}
504

    
505
uint32_t cpu_ppc_load_atbu (CPUPPCState *env)
506
{
507
    ppc_tb_t *tb_env = env->tb_env;
508
    uint64_t tb;
509

    
510
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
511
    LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
512

    
513
    return tb >> 32;
514
}
515

    
516
void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value)
517
{
518
    ppc_tb_t *tb_env = env->tb_env;
519
    uint64_t tb;
520

    
521
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
522
    tb &= 0xFFFFFFFF00000000ULL;
523
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
524
                     &tb_env->atb_offset, tb | (uint64_t)value);
525
}
526

    
527
void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value)
528
{
529
    ppc_tb_t *tb_env = env->tb_env;
530
    uint64_t tb;
531

    
532
    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
533
    tb &= 0x00000000FFFFFFFFULL;
534
    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
535
                     &tb_env->atb_offset, ((uint64_t)value << 32) | tb);
536
}
537

    
538
static void cpu_ppc_tb_stop (CPUPPCState *env)
539
{
540
    ppc_tb_t *tb_env = env->tb_env;
541
    uint64_t tb, atb, vmclk;
542

    
543
    /* If the time base is already frozen, do nothing */
544
    if (tb_env->tb_freq != 0) {
545
        vmclk = qemu_get_clock_ns(vm_clock);
546
        /* Get the time base */
547
        tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
548
        /* Get the alternate time base */
549
        atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset);
550
        /* Store the time base value (ie compute the current offset) */
551
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
552
        /* Store the alternate time base value (compute the current offset) */
553
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
554
        /* Set the time base frequency to zero */
555
        tb_env->tb_freq = 0;
556
        /* Now, the time bases are frozen to tb_offset / atb_offset value */
557
    }
558
}
559

    
560
static void cpu_ppc_tb_start (CPUPPCState *env)
561
{
562
    ppc_tb_t *tb_env = env->tb_env;
563
    uint64_t tb, atb, vmclk;
564

    
565
    /* If the time base is not frozen, do nothing */
566
    if (tb_env->tb_freq == 0) {
567
        vmclk = qemu_get_clock_ns(vm_clock);
568
        /* Get the time base from tb_offset */
569
        tb = tb_env->tb_offset;
570
        /* Get the alternate time base from atb_offset */
571
        atb = tb_env->atb_offset;
572
        /* Restore the tb frequency from the decrementer frequency */
573
        tb_env->tb_freq = tb_env->decr_freq;
574
        /* Store the time base value */
575
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
576
        /* Store the alternate time base value */
577
        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
578
    }
579
}
580

    
581
static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
582
{
583
    ppc_tb_t *tb_env = env->tb_env;
584
    uint32_t decr;
585
    int64_t diff;
586

    
587
    diff = next - qemu_get_clock_ns(vm_clock);
588
    if (diff >= 0) {
589
        decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec());
590
    } else if (tb_env->flags & PPC_TIMER_BOOKE) {
591
        decr = 0;
592
    }  else {
593
        decr = -muldiv64(-diff, tb_env->decr_freq, get_ticks_per_sec());
594
    }
595
    LOG_TB("%s: %08" PRIx32 "\n", __func__, decr);
596

    
597
    return decr;
598
}
599

    
600
uint32_t cpu_ppc_load_decr (CPUPPCState *env)
601
{
602
    ppc_tb_t *tb_env = env->tb_env;
603

    
604
    if (kvm_enabled()) {
605
        return env->spr[SPR_DECR];
606
    }
607

    
608
    return _cpu_ppc_load_decr(env, tb_env->decr_next);
609
}
610

    
611
uint32_t cpu_ppc_load_hdecr (CPUPPCState *env)
612
{
613
    ppc_tb_t *tb_env = env->tb_env;
614

    
615
    return _cpu_ppc_load_decr(env, tb_env->hdecr_next);
616
}
617

    
618
uint64_t cpu_ppc_load_purr (CPUPPCState *env)
619
{
620
    ppc_tb_t *tb_env = env->tb_env;
621
    uint64_t diff;
622

    
623
    diff = qemu_get_clock_ns(vm_clock) - tb_env->purr_start;
624

    
625
    return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec());
626
}
627

    
628
/* When decrementer expires,
629
 * all we need to do is generate or queue a CPU exception
630
 */
631
static inline void cpu_ppc_decr_excp(CPUPPCState *env)
632
{
633
    /* Raise it */
634
    LOG_TB("raise decrementer exception\n");
635
    ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
636
}
637

    
638
static inline void cpu_ppc_hdecr_excp(CPUPPCState *env)
639
{
640
    /* Raise it */
641
    LOG_TB("raise decrementer exception\n");
642
    ppc_set_irq(env, PPC_INTERRUPT_HDECR, 1);
643
}
644

    
645
static void __cpu_ppc_store_decr (CPUPPCState *env, uint64_t *nextp,
646
                                  struct QEMUTimer *timer,
647
                                  void (*raise_excp)(CPUPPCState *),
648
                                  uint32_t decr, uint32_t value,
649
                                  int is_excp)
650
{
651
    ppc_tb_t *tb_env = env->tb_env;
652
    uint64_t now, next;
653

    
654
    LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
655
                decr, value);
656

    
657
    if (kvm_enabled()) {
658
        /* KVM handles decrementer exceptions, we don't need our own timer */
659
        return;
660
    }
661

    
662
    now = qemu_get_clock_ns(vm_clock);
663
    next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq);
664
    if (is_excp) {
665
        next += *nextp - now;
666
    }
667
    if (next == now) {
668
        next++;
669
    }
670
    *nextp = next;
671
    /* Adjust timer */
672
    qemu_mod_timer(timer, next);
673

    
674
    /* If we set a negative value and the decrementer was positive, raise an
675
     * exception.
676
     */
677
    if ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED)
678
        && (value & 0x80000000)
679
        && !(decr & 0x80000000)) {
680
        (*raise_excp)(env);
681
    }
682
}
683

    
684
static inline void _cpu_ppc_store_decr(CPUPPCState *env, uint32_t decr,
685
                                       uint32_t value, int is_excp)
686
{
687
    ppc_tb_t *tb_env = env->tb_env;
688

    
689
    __cpu_ppc_store_decr(env, &tb_env->decr_next, tb_env->decr_timer,
690
                         &cpu_ppc_decr_excp, decr, value, is_excp);
691
}
692

    
693
void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value)
694
{
695
    _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
696
}
697

    
698
static void cpu_ppc_decr_cb (void *opaque)
699
{
700
    _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
701
}
702

    
703
static inline void _cpu_ppc_store_hdecr(CPUPPCState *env, uint32_t hdecr,
704
                                        uint32_t value, int is_excp)
705
{
706
    ppc_tb_t *tb_env = env->tb_env;
707

    
708
    if (tb_env->hdecr_timer != NULL) {
709
        __cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer,
710
                             &cpu_ppc_hdecr_excp, hdecr, value, is_excp);
711
    }
712
}
713

    
714
void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value)
715
{
716
    _cpu_ppc_store_hdecr(env, cpu_ppc_load_hdecr(env), value, 0);
717
}
718

    
719
static void cpu_ppc_hdecr_cb (void *opaque)
720
{
721
    _cpu_ppc_store_hdecr(opaque, 0x00000000, 0xFFFFFFFF, 1);
722
}
723

    
724
void cpu_ppc_store_purr (CPUPPCState *env, uint64_t value)
725
{
726
    ppc_tb_t *tb_env = env->tb_env;
727

    
728
    tb_env->purr_load = value;
729
    tb_env->purr_start = qemu_get_clock_ns(vm_clock);
730
}
731

    
732
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
733
{
734
    CPUPPCState *env = opaque;
735
    ppc_tb_t *tb_env = env->tb_env;
736

    
737
    tb_env->tb_freq = freq;
738
    tb_env->decr_freq = freq;
739
    /* There is a bug in Linux 2.4 kernels:
740
     * if a decrementer exception is pending when it enables msr_ee at startup,
741
     * it's not ready to handle it...
742
     */
743
    _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
744
    _cpu_ppc_store_hdecr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
745
    cpu_ppc_store_purr(env, 0x0000000000000000ULL);
746
}
747

    
748
/* Set up (once) timebase frequency (in Hz) */
749
clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
750
{
751
    ppc_tb_t *tb_env;
752

    
753
    tb_env = g_malloc0(sizeof(ppc_tb_t));
754
    env->tb_env = tb_env;
755
    tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
756
    /* Create new timer */
757
    tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_decr_cb, env);
758
    if (0) {
759
        /* XXX: find a suitable condition to enable the hypervisor decrementer
760
         */
761
        tb_env->hdecr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_hdecr_cb, env);
762
    } else {
763
        tb_env->hdecr_timer = NULL;
764
    }
765
    cpu_ppc_set_tb_clk(env, freq);
766

    
767
    return &cpu_ppc_set_tb_clk;
768
}
769

    
770
/* Specific helpers for POWER & PowerPC 601 RTC */
771
#if 0
772
static clk_setup_cb cpu_ppc601_rtc_init (CPUPPCState *env)
773
{
774
    return cpu_ppc_tb_init(env, 7812500);
775
}
776
#endif
777

    
778
void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value)
779
{
780
    _cpu_ppc_store_tbu(env, value);
781
}
782

    
783
uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env)
784
{
785
    return _cpu_ppc_load_tbu(env);
786
}
787

    
788
void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value)
789
{
790
    cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
791
}
792

    
793
uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env)
794
{
795
    return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
796
}
797

    
798
/*****************************************************************************/
799
/* PowerPC 40x timers */
800

    
801
/* PIT, FIT & WDT */
802
typedef struct ppc40x_timer_t ppc40x_timer_t;
803
struct ppc40x_timer_t {
804
    uint64_t pit_reload;  /* PIT auto-reload value        */
805
    uint64_t fit_next;    /* Tick for next FIT interrupt  */
806
    struct QEMUTimer *fit_timer;
807
    uint64_t wdt_next;    /* Tick for next WDT interrupt  */
808
    struct QEMUTimer *wdt_timer;
809

    
810
    /* 405 have the PIT, 440 have a DECR.  */
811
    unsigned int decr_excp;
812
};
813

    
814
/* Fixed interval timer */
815
static void cpu_4xx_fit_cb (void *opaque)
816
{
817
    CPUPPCState *env;
818
    ppc_tb_t *tb_env;
819
    ppc40x_timer_t *ppc40x_timer;
820
    uint64_t now, next;
821

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

    
855
/* Programmable interval timer */
856
static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp)
857
{
858
    ppc40x_timer_t *ppc40x_timer;
859
    uint64_t now, next;
860

    
861
    ppc40x_timer = tb_env->opaque;
862
    if (ppc40x_timer->pit_reload <= 1 ||
863
        !((env->spr[SPR_40x_TCR] >> 26) & 0x1) ||
864
        (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
865
        /* Stop PIT */
866
        LOG_TB("%s: stop PIT\n", __func__);
867
        qemu_del_timer(tb_env->decr_timer);
868
    } else {
869
        LOG_TB("%s: start PIT %016" PRIx64 "\n",
870
                    __func__, ppc40x_timer->pit_reload);
871
        now = qemu_get_clock_ns(vm_clock);
872
        next = now + muldiv64(ppc40x_timer->pit_reload,
873
                              get_ticks_per_sec(), tb_env->decr_freq);
874
        if (is_excp)
875
            next += tb_env->decr_next - now;
876
        if (next == now)
877
            next++;
878
        qemu_mod_timer(tb_env->decr_timer, next);
879
        tb_env->decr_next = next;
880
    }
881
}
882

    
883
static void cpu_4xx_pit_cb (void *opaque)
884
{
885
    CPUPPCState *env;
886
    ppc_tb_t *tb_env;
887
    ppc40x_timer_t *ppc40x_timer;
888

    
889
    env = opaque;
890
    tb_env = env->tb_env;
891
    ppc40x_timer = tb_env->opaque;
892
    env->spr[SPR_40x_TSR] |= 1 << 27;
893
    if ((env->spr[SPR_40x_TCR] >> 26) & 0x1)
894
        ppc_set_irq(env, ppc40x_timer->decr_excp, 1);
895
    start_stop_pit(env, tb_env, 1);
896
    LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " "
897
           "%016" PRIx64 "\n", __func__,
898
           (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1),
899
           (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1),
900
           env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
901
           ppc40x_timer->pit_reload);
902
}
903

    
904
/* Watchdog timer */
905
static void cpu_4xx_wdt_cb (void *opaque)
906
{
907
    CPUPPCState *env;
908
    ppc_tb_t *tb_env;
909
    ppc40x_timer_t *ppc40x_timer;
910
    uint64_t now, next;
911

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

    
972
void store_40x_pit (CPUPPCState *env, target_ulong val)
973
{
974
    ppc_tb_t *tb_env;
975
    ppc40x_timer_t *ppc40x_timer;
976

    
977
    tb_env = env->tb_env;
978
    ppc40x_timer = tb_env->opaque;
979
    LOG_TB("%s val" TARGET_FMT_lx "\n", __func__, val);
980
    ppc40x_timer->pit_reload = val;
981
    start_stop_pit(env, tb_env, 0);
982
}
983

    
984
target_ulong load_40x_pit (CPUPPCState *env)
985
{
986
    return cpu_ppc_load_decr(env);
987
}
988

    
989
static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq)
990
{
991
    CPUPPCState *env = opaque;
992
    ppc_tb_t *tb_env = env->tb_env;
993

    
994
    LOG_TB("%s set new frequency to %" PRIu32 "\n", __func__,
995
                freq);
996
    tb_env->tb_freq = freq;
997
    tb_env->decr_freq = freq;
998
    /* XXX: we should also update all timers */
999
}
1000

    
1001
clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
1002
                                  unsigned int decr_excp)
1003
{
1004
    ppc_tb_t *tb_env;
1005
    ppc40x_timer_t *ppc40x_timer;
1006

    
1007
    tb_env = g_malloc0(sizeof(ppc_tb_t));
1008
    env->tb_env = tb_env;
1009
    tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
1010
    ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
1011
    tb_env->tb_freq = freq;
1012
    tb_env->decr_freq = freq;
1013
    tb_env->opaque = ppc40x_timer;
1014
    LOG_TB("%s freq %" PRIu32 "\n", __func__, freq);
1015
    if (ppc40x_timer != NULL) {
1016
        /* We use decr timer for PIT */
1017
        tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_4xx_pit_cb, env);
1018
        ppc40x_timer->fit_timer =
1019
            qemu_new_timer_ns(vm_clock, &cpu_4xx_fit_cb, env);
1020
        ppc40x_timer->wdt_timer =
1021
            qemu_new_timer_ns(vm_clock, &cpu_4xx_wdt_cb, env);
1022
        ppc40x_timer->decr_excp = decr_excp;
1023
    }
1024

    
1025
    return &ppc_40x_set_tb_clk;
1026
}
1027

    
1028
/*****************************************************************************/
1029
/* Embedded PowerPC Device Control Registers */
1030
typedef struct ppc_dcrn_t ppc_dcrn_t;
1031
struct ppc_dcrn_t {
1032
    dcr_read_cb dcr_read;
1033
    dcr_write_cb dcr_write;
1034
    void *opaque;
1035
};
1036

    
1037
/* XXX: on 460, DCR addresses are 32 bits wide,
1038
 *      using DCRIPR to get the 22 upper bits of the DCR address
1039
 */
1040
#define DCRN_NB 1024
1041
struct ppc_dcr_t {
1042
    ppc_dcrn_t dcrn[DCRN_NB];
1043
    int (*read_error)(int dcrn);
1044
    int (*write_error)(int dcrn);
1045
};
1046

    
1047
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
1048
{
1049
    ppc_dcrn_t *dcr;
1050

    
1051
    if (dcrn < 0 || dcrn >= DCRN_NB)
1052
        goto error;
1053
    dcr = &dcr_env->dcrn[dcrn];
1054
    if (dcr->dcr_read == NULL)
1055
        goto error;
1056
    *valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
1057

    
1058
    return 0;
1059

    
1060
 error:
1061
    if (dcr_env->read_error != NULL)
1062
        return (*dcr_env->read_error)(dcrn);
1063

    
1064
    return -1;
1065
}
1066

    
1067
int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
1068
{
1069
    ppc_dcrn_t *dcr;
1070

    
1071
    if (dcrn < 0 || dcrn >= DCRN_NB)
1072
        goto error;
1073
    dcr = &dcr_env->dcrn[dcrn];
1074
    if (dcr->dcr_write == NULL)
1075
        goto error;
1076
    (*dcr->dcr_write)(dcr->opaque, dcrn, val);
1077

    
1078
    return 0;
1079

    
1080
 error:
1081
    if (dcr_env->write_error != NULL)
1082
        return (*dcr_env->write_error)(dcrn);
1083

    
1084
    return -1;
1085
}
1086

    
1087
int ppc_dcr_register (CPUPPCState *env, int dcrn, void *opaque,
1088
                      dcr_read_cb dcr_read, dcr_write_cb dcr_write)
1089
{
1090
    ppc_dcr_t *dcr_env;
1091
    ppc_dcrn_t *dcr;
1092

    
1093
    dcr_env = env->dcr_env;
1094
    if (dcr_env == NULL)
1095
        return -1;
1096
    if (dcrn < 0 || dcrn >= DCRN_NB)
1097
        return -1;
1098
    dcr = &dcr_env->dcrn[dcrn];
1099
    if (dcr->opaque != NULL ||
1100
        dcr->dcr_read != NULL ||
1101
        dcr->dcr_write != NULL)
1102
        return -1;
1103
    dcr->opaque = opaque;
1104
    dcr->dcr_read = dcr_read;
1105
    dcr->dcr_write = dcr_write;
1106

    
1107
    return 0;
1108
}
1109

    
1110
int ppc_dcr_init (CPUPPCState *env, int (*read_error)(int dcrn),
1111
                  int (*write_error)(int dcrn))
1112
{
1113
    ppc_dcr_t *dcr_env;
1114

    
1115
    dcr_env = g_malloc0(sizeof(ppc_dcr_t));
1116
    dcr_env->read_error = read_error;
1117
    dcr_env->write_error = write_error;
1118
    env->dcr_env = dcr_env;
1119

    
1120
    return 0;
1121
}
1122

    
1123
/*****************************************************************************/
1124
/* Debug port */
1125
void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
1126
{
1127
    addr &= 0xF;
1128
    switch (addr) {
1129
    case 0:
1130
        printf("%c", val);
1131
        break;
1132
    case 1:
1133
        printf("\n");
1134
        fflush(stdout);
1135
        break;
1136
    case 2:
1137
        printf("Set loglevel to %04" PRIx32 "\n", val);
1138
        cpu_set_log(val | 0x100);
1139
        break;
1140
    }
1141
}
1142

    
1143
/*****************************************************************************/
1144
/* NVRAM helpers */
1145
static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr)
1146
{
1147
    return (*nvram->read_fn)(nvram->opaque, addr);
1148
}
1149

    
1150
static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val)
1151
{
1152
    (*nvram->write_fn)(nvram->opaque, addr, val);
1153
}
1154

    
1155
void NVRAM_set_byte (nvram_t *nvram, uint32_t addr, uint8_t value)
1156
{
1157
    nvram_write(nvram, addr, value);
1158
}
1159

    
1160
uint8_t NVRAM_get_byte (nvram_t *nvram, uint32_t addr)
1161
{
1162
    return nvram_read(nvram, addr);
1163
}
1164

    
1165
void NVRAM_set_word (nvram_t *nvram, uint32_t addr, uint16_t value)
1166
{
1167
    nvram_write(nvram, addr, value >> 8);
1168
    nvram_write(nvram, addr + 1, value & 0xFF);
1169
}
1170

    
1171
uint16_t NVRAM_get_word (nvram_t *nvram, uint32_t addr)
1172
{
1173
    uint16_t tmp;
1174

    
1175
    tmp = nvram_read(nvram, addr) << 8;
1176
    tmp |= nvram_read(nvram, addr + 1);
1177

    
1178
    return tmp;
1179
}
1180

    
1181
void NVRAM_set_lword (nvram_t *nvram, uint32_t addr, uint32_t value)
1182
{
1183
    nvram_write(nvram, addr, value >> 24);
1184
    nvram_write(nvram, addr + 1, (value >> 16) & 0xFF);
1185
    nvram_write(nvram, addr + 2, (value >> 8) & 0xFF);
1186
    nvram_write(nvram, addr + 3, value & 0xFF);
1187
}
1188

    
1189
uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr)
1190
{
1191
    uint32_t tmp;
1192

    
1193
    tmp = nvram_read(nvram, addr) << 24;
1194
    tmp |= nvram_read(nvram, addr + 1) << 16;
1195
    tmp |= nvram_read(nvram, addr + 2) << 8;
1196
    tmp |= nvram_read(nvram, addr + 3);
1197

    
1198
    return tmp;
1199
}
1200

    
1201
void NVRAM_set_string (nvram_t *nvram, uint32_t addr,
1202
                       const char *str, uint32_t max)
1203
{
1204
    int i;
1205

    
1206
    for (i = 0; i < max && str[i] != '\0'; i++) {
1207
        nvram_write(nvram, addr + i, str[i]);
1208
    }
1209
    nvram_write(nvram, addr + i, str[i]);
1210
    nvram_write(nvram, addr + max - 1, '\0');
1211
}
1212

    
1213
int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max)
1214
{
1215
    int i;
1216

    
1217
    memset(dst, 0, max);
1218
    for (i = 0; i < max; i++) {
1219
        dst[i] = NVRAM_get_byte(nvram, addr + i);
1220
        if (dst[i] == '\0')
1221
            break;
1222
    }
1223

    
1224
    return i;
1225
}
1226

    
1227
static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
1228
{
1229
    uint16_t tmp;
1230
    uint16_t pd, pd1, pd2;
1231

    
1232
    tmp = prev >> 8;
1233
    pd = prev ^ value;
1234
    pd1 = pd & 0x000F;
1235
    pd2 = ((pd >> 4) & 0x000F) ^ pd1;
1236
    tmp ^= (pd1 << 3) | (pd1 << 8);
1237
    tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
1238

    
1239
    return tmp;
1240
}
1241

    
1242
static uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count)
1243
{
1244
    uint32_t i;
1245
    uint16_t crc = 0xFFFF;
1246
    int odd;
1247

    
1248
    odd = count & 1;
1249
    count &= ~1;
1250
    for (i = 0; i != count; i++) {
1251
        crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
1252
    }
1253
    if (odd) {
1254
        crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
1255
    }
1256

    
1257
    return crc;
1258
}
1259

    
1260
#define CMDLINE_ADDR 0x017ff000
1261

    
1262
int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
1263
                          const char *arch,
1264
                          uint32_t RAM_size, int boot_device,
1265
                          uint32_t kernel_image, uint32_t kernel_size,
1266
                          const char *cmdline,
1267
                          uint32_t initrd_image, uint32_t initrd_size,
1268
                          uint32_t NVRAM_image,
1269
                          int width, int height, int depth)
1270
{
1271
    uint16_t crc;
1272

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

    
1295
    NVRAM_set_word(nvram,   0x54, width);
1296
    NVRAM_set_word(nvram,   0x56, height);
1297
    NVRAM_set_word(nvram,   0x58, depth);
1298
    crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
1299
    NVRAM_set_word(nvram,   0xFC, crc);
1300

    
1301
    return 0;
1302
}