Statistics
| Branch: | Revision:

root / hw / ppc_prep.c @ c0e564d5

History | View | Annotate | Download (18.6 kB)

1
/*
2
 * QEMU PPC PREP hardware System Emulator
3
 * 
4
 * Copyright (c) 2003-2004 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 HARD_DEBUG_PPC_IO
27
//#define DEBUG_PPC_IO
28

    
29
#define BIOS_FILENAME "ppc_rom.bin"
30
#define KERNEL_LOAD_ADDR 0x01000000
31
#define INITRD_LOAD_ADDR 0x01800000
32

    
33
extern int loglevel;
34
extern FILE *logfile;
35

    
36
#if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
37
#define DEBUG_PPC_IO
38
#endif
39

    
40
#if defined (HARD_DEBUG_PPC_IO)
41
#define PPC_IO_DPRINTF(fmt, args...)                     \
42
do {                                                     \
43
    if (loglevel & CPU_LOG_IOPORT) {                     \
44
        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
45
    } else {                                             \
46
        printf("%s : " fmt, __func__ , ##args);          \
47
    }                                                    \
48
} while (0)
49
#elif defined (DEBUG_PPC_IO)
50
#define PPC_IO_DPRINTF(fmt, args...)                     \
51
do {                                                     \
52
    if (loglevel & CPU_LOG_IOPORT) {                     \
53
        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
54
    }                                                    \
55
} while (0)
56
#else
57
#define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
58
#endif
59

    
60
/* Constants for devices init */
61
static const int ide_iobase[2] = { 0x1f0, 0x170 };
62
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
63
static const int ide_irq[2] = { 13, 13 };
64

    
65
#define NE2000_NB_MAX 6
66

    
67
static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
68
static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
69

    
70
//static PITState *pit;
71

    
72
/* ISA IO ports bridge */
73
#define PPC_IO_BASE 0x80000000
74

    
75
/* Speaker port 0x61 */
76
int speaker_data_on;
77
int dummy_refresh_clock;
78

    
79
static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
80
{
81
#if 0
82
    speaker_data_on = (val >> 1) & 1;
83
    pit_set_gate(pit, 2, val & 1);
84
#endif
85
}
86

    
87
static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
88
{
89
#if 0
90
    int out;
91
    out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
92
    dummy_refresh_clock ^= 1;
93
    return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
94
      (dummy_refresh_clock << 4);
95
#endif
96
    return 0;
97
}
98

    
99
/* PCI intack register */
100
/* Read-only register (?) */
101
static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value)
102
{
103
    //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
104
}
105

    
106
static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
107
{
108
    uint32_t retval = 0;
109

    
110
    if (addr == 0xBFFFFFF0)
111
        retval = pic_intack_read(NULL);
112
       //   printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
113

    
114
    return retval;
115
}
116

    
117
static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
118
{
119
    return _PPC_intack_read(addr);
120
}
121

    
122
static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
123
{
124
#ifdef TARGET_WORDS_BIGENDIAN
125
    return bswap16(_PPC_intack_read(addr));
126
#else
127
    return _PPC_intack_read(addr);
128
#endif
129
}
130

    
131
static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
132
{
133
#ifdef TARGET_WORDS_BIGENDIAN
134
    return bswap32(_PPC_intack_read(addr));
135
#else
136
    return _PPC_intack_read(addr);
137
#endif
138
}
139

    
140
static CPUWriteMemoryFunc *PPC_intack_write[] = {
141
    &_PPC_intack_write,
142
    &_PPC_intack_write,
143
    &_PPC_intack_write,
144
};
145

    
146
static CPUReadMemoryFunc *PPC_intack_read[] = {
147
    &PPC_intack_readb,
148
    &PPC_intack_readw,
149
    &PPC_intack_readl,
150
};
151

    
152
/* PowerPC control and status registers */
153
#if 0 // Not used
154
static struct {
155
    /* IDs */
156
    uint32_t veni_devi;
157
    uint32_t revi;
158
    /* Control and status */
159
    uint32_t gcsr;
160
    uint32_t xcfr;
161
    uint32_t ct32;
162
    uint32_t mcsr;
163
    /* General purpose registers */
164
    uint32_t gprg[6];
165
    /* Exceptions */
166
    uint32_t feen;
167
    uint32_t fest;
168
    uint32_t fema;
169
    uint32_t fecl;
170
    uint32_t eeen;
171
    uint32_t eest;
172
    uint32_t eecl;
173
    uint32_t eeint;
174
    uint32_t eemck0;
175
    uint32_t eemck1;
176
    /* Error diagnostic */
177
} XCSR;
178

179
static void PPC_XCSR_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
180
{
181
    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
182
}
183

184
static void PPC_XCSR_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
185
{
186
#ifdef TARGET_WORDS_BIGENDIAN
187
    value = bswap16(value);
188
#endif
189
    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
190
}
191

    
192
static void PPC_XCSR_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
193
{
194
#ifdef TARGET_WORDS_BIGENDIAN
195
    value = bswap32(value);
196
#endif
197
    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
198
}
199

    
200
static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
201
{
202
    uint32_t retval = 0;
203

    
204
    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
205

    
206
    return retval;
207
}
208

    
209
static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
210
{
211
    uint32_t retval = 0;
212

    
213
    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
214
#ifdef TARGET_WORDS_BIGENDIAN
215
    retval = bswap16(retval);
216
#endif
217

    
218
    return retval;
219
}
220

    
221
static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
222
{
223
    uint32_t retval = 0;
224

    
225
    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
226
#ifdef TARGET_WORDS_BIGENDIAN
227
    retval = bswap32(retval);
228
#endif
229

    
230
    return retval;
231
}
232

    
233
static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
234
    &PPC_XCSR_writeb,
235
    &PPC_XCSR_writew,
236
    &PPC_XCSR_writel,
237
};
238

    
239
static CPUReadMemoryFunc *PPC_XCSR_read[] = {
240
    &PPC_XCSR_readb,
241
    &PPC_XCSR_readw,
242
    &PPC_XCSR_readl,
243
};
244
#endif
245

    
246
/* Fake super-io ports for PREP platform (Intel 82378ZB) */
247
typedef struct sysctrl_t {
248
    m48t59_t *nvram;
249
    uint8_t state;
250
    uint8_t syscontrol;
251
    uint8_t fake_io[2];
252
    int contiguous_map;
253
} sysctrl_t;
254

    
255
enum {
256
    STATE_HARDFILE = 0x01,
257
};
258

    
259
static sysctrl_t *sysctrl;
260

    
261
static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
262
{
263
    sysctrl_t *sysctrl = opaque;
264

    
265
    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
266
    sysctrl->fake_io[addr - 0x0398] = val;
267
}
268

    
269
static uint32_t PREP_io_read (void *opaque, uint32_t addr)
270
{
271
    sysctrl_t *sysctrl = opaque;
272

    
273
    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE,
274
                   sysctrl->fake_io[addr - 0x0398]);
275
    return sysctrl->fake_io[addr - 0x0398];
276
}
277

    
278
static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
279
{
280
    sysctrl_t *sysctrl = opaque;
281

    
282
    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
283
    switch (addr) {
284
    case 0x0092:
285
        /* Special port 92 */
286
        /* Check soft reset asked */
287
        if (val & 0x01) {
288
            //            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_RESET);
289
        }
290
        /* Check LE mode */
291
        if (val & 0x02) {
292
            printf("Little Endian mode isn't supported (yet ?)\n");
293
            abort();
294
        }
295
        break;
296
    case 0x0800:
297
        /* Motorola CPU configuration register : read-only */
298
        break;
299
    case 0x0802:
300
        /* Motorola base module feature register : read-only */
301
        break;
302
    case 0x0803:
303
        /* Motorola base module status register : read-only */
304
        break;
305
    case 0x0808:
306
        /* Hardfile light register */
307
        if (val & 1)
308
            sysctrl->state |= STATE_HARDFILE;
309
        else
310
            sysctrl->state &= ~STATE_HARDFILE;
311
        break;
312
    case 0x0810:
313
        /* Password protect 1 register */
314
        if (sysctrl->nvram != NULL)
315
            m48t59_toggle_lock(sysctrl->nvram, 1);
316
        break;
317
    case 0x0812:
318
        /* Password protect 2 register */
319
        if (sysctrl->nvram != NULL)
320
            m48t59_toggle_lock(sysctrl->nvram, 2);
321
        break;
322
    case 0x0814:
323
        /* L2 invalidate register */
324
        //        tlb_flush(cpu_single_env, 1);
325
        break;
326
    case 0x081C:
327
        /* system control register */
328
        sysctrl->syscontrol = val & 0x0F;
329
        break;
330
    case 0x0850:
331
        /* I/O map type register */
332
        sysctrl->contiguous_map = val & 0x01;
333
        break;
334
    default:
335
        printf("ERROR: unaffected IO port write: %04lx => %02x\n",
336
               (long)addr, val);
337
        break;
338
    }
339
}
340

    
341
static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
342
{
343
    sysctrl_t *sysctrl = opaque;
344
    uint32_t retval = 0xFF;
345

    
346
    switch (addr) {
347
    case 0x0092:
348
        /* Special port 92 */
349
        retval = 0x00;
350
        break;
351
    case 0x0800:
352
        /* Motorola CPU configuration register */
353
        retval = 0xEF; /* MPC750 */
354
        break;
355
    case 0x0802:
356
        /* Motorola Base module feature register */
357
        retval = 0xAD; /* No ESCC, PMC slot neither ethernet */
358
        break;
359
    case 0x0803:
360
        /* Motorola base module status register */
361
        retval = 0xE0; /* Standard MPC750 */
362
        break;
363
    case 0x080C:
364
        /* Equipment present register:
365
         *  no L2 cache
366
         *  no upgrade processor
367
         *  no cards in PCI slots
368
         *  SCSI fuse is bad
369
         */
370
        retval = 0x3C;
371
        break;
372
    case 0x0810:
373
        /* Motorola base module extended feature register */
374
        retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
375
        break;
376
    case 0x0814:
377
        /* L2 invalidate: don't care */
378
        break;
379
    case 0x0818:
380
        /* Keylock */
381
        retval = 0x00;
382
        break;
383
    case 0x081C:
384
        /* system control register
385
         * 7 - 6 / 1 - 0: L2 cache enable
386
         */
387
        retval = sysctrl->syscontrol;
388
        break;
389
    case 0x0823:
390
        /* */
391
        retval = 0x03; /* no L2 cache */
392
        break;
393
    case 0x0850:
394
        /* I/O map type register */
395
        retval = sysctrl->contiguous_map;
396
        break;
397
    default:
398
        printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
399
        break;
400
    }
401
    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE, retval);
402

    
403
    return retval;
404
}
405

    
406
static inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
407
                                                  target_phys_addr_t addr)
408
{
409
    if (sysctrl->contiguous_map == 0) {
410
        /* 64 KB contiguous space for IOs */
411
        addr &= 0xFFFF;
412
    } else {
413
        /* 8 MB non-contiguous space for IOs */
414
        addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7);
415
    }
416

    
417
    return addr;
418
}
419

    
420
static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr,
421
                                uint32_t value)
422
{
423
    sysctrl_t *sysctrl = opaque;
424

    
425
    addr = prep_IO_address(sysctrl, addr);
426
    cpu_outb(NULL, addr, value);
427
}
428

    
429
static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
430
{
431
    sysctrl_t *sysctrl = opaque;
432
    uint32_t ret;
433

    
434
    addr = prep_IO_address(sysctrl, addr);
435
    ret = cpu_inb(NULL, addr);
436

    
437
    return ret;
438
}
439

    
440
static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
441
                                uint32_t value)
442
{
443
    sysctrl_t *sysctrl = opaque;
444

    
445
    addr = prep_IO_address(sysctrl, addr);
446
#ifdef TARGET_WORDS_BIGENDIAN
447
    value = bswap16(value);
448
#endif
449
    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
450
    cpu_outw(NULL, addr, value);
451
}
452

    
453
static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
454
{
455
    sysctrl_t *sysctrl = opaque;
456
    uint32_t ret;
457

    
458
    addr = prep_IO_address(sysctrl, addr);
459
    ret = cpu_inw(NULL, addr);
460
#ifdef TARGET_WORDS_BIGENDIAN
461
    ret = bswap16(ret);
462
#endif
463
    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
464

    
465
    return ret;
466
}
467

    
468
static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
469
                                uint32_t value)
470
{
471
    sysctrl_t *sysctrl = opaque;
472

    
473
    addr = prep_IO_address(sysctrl, addr);
474
#ifdef TARGET_WORDS_BIGENDIAN
475
    value = bswap32(value);
476
#endif
477
    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
478
    cpu_outl(NULL, addr, value);
479
}
480

    
481
static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
482
{
483
    sysctrl_t *sysctrl = opaque;
484
    uint32_t ret;
485

    
486
    addr = prep_IO_address(sysctrl, addr);
487
    ret = cpu_inl(NULL, addr);
488
#ifdef TARGET_WORDS_BIGENDIAN
489
    ret = bswap32(ret);
490
#endif
491
    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
492

    
493
    return ret;
494
}
495

    
496
CPUWriteMemoryFunc *PPC_prep_io_write[] = {
497
    &PPC_prep_io_writeb,
498
    &PPC_prep_io_writew,
499
    &PPC_prep_io_writel,
500
};
501

    
502
CPUReadMemoryFunc *PPC_prep_io_read[] = {
503
    &PPC_prep_io_readb,
504
    &PPC_prep_io_readw,
505
    &PPC_prep_io_readl,
506
};
507

    
508
extern CPUPPCState *global_env;
509

    
510
#define NVRAM_SIZE        0x2000
511

    
512
/* PowerPC PREP hardware initialisation */
513
static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
514
                          DisplayState *ds, const char **fd_filename, int snapshot,
515
                          const char *kernel_filename, const char *kernel_cmdline,
516
                          const char *initrd_filename)
517
{
518
    char buf[1024];
519
    m48t59_t *nvram;
520
    int PPC_io_memory;
521
    int ret, linux_boot, i, nb_nics1;
522
    unsigned long bios_offset;
523
    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
524
    PCIBus *pci_bus;
525

    
526
    sysctrl = qemu_mallocz(sizeof(sysctrl_t));
527
    if (sysctrl == NULL)
528
        return;
529

    
530
    linux_boot = (kernel_filename != NULL);
531

    
532
    /* allocate RAM */
533
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
534

    
535
    /* allocate and load BIOS */
536
    bios_offset = ram_size + vga_ram_size;
537
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
538
    ret = load_image(buf, phys_ram_base + bios_offset);
539
    if (ret != BIOS_SIZE) {
540
        fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
541
        exit(1);
542
    }
543
    cpu_register_physical_memory((uint32_t)(-BIOS_SIZE), 
544
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
545
    cpu_single_env->nip = 0xfffffffc;
546

    
547
    if (linux_boot) {
548
        kernel_base = KERNEL_LOAD_ADDR;
549
        /* now we can load the kernel */
550
        kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
551
        if (kernel_size < 0) {
552
            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
553
                    kernel_filename);
554
            exit(1);
555
        }
556
        /* load initrd */
557
        if (initrd_filename) {
558
            initrd_base = INITRD_LOAD_ADDR;
559
            initrd_size = load_image(initrd_filename,
560
                                     phys_ram_base + initrd_base);
561
            if (initrd_size < 0) {
562
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
563
                        initrd_filename);
564
                exit(1);
565
            }
566
        } else {
567
            initrd_base = 0;
568
            initrd_size = 0;
569
        }
570
        boot_device = 'm';
571
    } else {
572
        kernel_base = 0;
573
        kernel_size = 0;
574
        initrd_base = 0;
575
        initrd_size = 0;
576
    }
577

    
578
    /* Register CPU as a 604 */
579
    cpu_ppc_register(cpu_single_env, 0x00040000);
580
    /* Set time-base frequency to 100 Mhz */
581
    cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
582

    
583
    isa_mem_base = 0xc0000000;
584
    pci_bus = pci_prep_init();
585
    //    pci_bus = i440fx_init();
586
    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
587
    PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,
588
                                           PPC_prep_io_write, sysctrl);
589
    cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
590

    
591
    /* init basic PC hardware */
592
    vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
593
                   vga_ram_size);
594
    rtc_init(0x70, 8);
595
    //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
596
    //    pic_init(openpic);
597
    pic_init();
598
    //    pit = pit_init(0x40, 0);
599

    
600
    serial_init(0x3f8, 4, serial_hds[0]);
601
    nb_nics1 = nb_nics;
602
    if (nb_nics1 > NE2000_NB_MAX)
603
        nb_nics1 = NE2000_NB_MAX;
604
    for(i = 0; i < nb_nics1; i++) {
605
        isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
606
    }
607

    
608
    for(i = 0; i < 2; i++) {
609
        isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
610
                     bs_table[2 * i], bs_table[2 * i + 1]);
611
    }
612
    kbd_init();
613
    DMA_init(1);
614
    //    AUD_init();
615
    //    SB16_init();
616

    
617
    fdctrl_init(6, 2, 0, 0x3f0, fd_table);
618

    
619
    /* Register speaker port */
620
    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
621
    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
622
    /* Register fake IO ports for PREP */
623
    register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
624
    register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
625
    /* System control ports */
626
    register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
627
    register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
628
    register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
629
    register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
630
    /* PCI intack location */
631
    PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
632
                                           PPC_intack_write, NULL);
633
    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
634
    /* PowerPC control and status register group */
635
#if 0
636
    PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write, NULL);
637
    cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
638
#endif
639

    
640
    nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE);
641
    if (nvram == NULL)
642
        return;
643
    sysctrl->nvram = nvram;
644

    
645
    /* Initialise NVRAM */
646
    PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
647
                         kernel_base, kernel_size,
648
                         kernel_cmdline,
649
                         initrd_base, initrd_size,
650
                         /* XXX: need an option to load a NVRAM image */
651
                         0,
652
                         graphic_width, graphic_height, graphic_depth);
653

    
654
    /* Special port to get debug messages from Open-Firmware */
655
    register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
656
}
657

    
658
QEMUMachine prep_machine = {
659
    "prep",
660
    "PowerPC PREP platform",
661
    ppc_prep_init,
662
};