Statistics
| Branch: | Revision:

root / hw / ppc_prep.c @ 47103572

History | View | Annotate | Download (19.5 kB)

1
/*
2
 * QEMU PPC PREP hardware System Emulator
3
 * 
4
 * Copyright (c) 2003-2007 Jocelyn Mayer
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25

    
26
//#define 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
static void pic_irq_request (void *opaque, int level)
100
{
101
    ppc_set_irq(opaque, PPC_INTERRUPT_EXT, level);
102
}
103

    
104
/* PCI intack register */
105
/* Read-only register (?) */
106
static void _PPC_intack_write (void *opaque,
107
                               target_phys_addr_t addr, uint32_t value)
108
{
109
    //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
110
}
111

    
112
static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
113
{
114
    uint32_t retval = 0;
115

    
116
    if (addr == 0xBFFFFFF0)
117
        retval = pic_intack_read(isa_pic);
118
       //   printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
119

    
120
    return retval;
121
}
122

    
123
static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
124
{
125
    return _PPC_intack_read(addr);
126
}
127

    
128
static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
129
{
130
#ifdef TARGET_WORDS_BIGENDIAN
131
    return bswap16(_PPC_intack_read(addr));
132
#else
133
    return _PPC_intack_read(addr);
134
#endif
135
}
136

    
137
static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
138
{
139
#ifdef TARGET_WORDS_BIGENDIAN
140
    return bswap32(_PPC_intack_read(addr));
141
#else
142
    return _PPC_intack_read(addr);
143
#endif
144
}
145

    
146
static CPUWriteMemoryFunc *PPC_intack_write[] = {
147
    &_PPC_intack_write,
148
    &_PPC_intack_write,
149
    &_PPC_intack_write,
150
};
151

    
152
static CPUReadMemoryFunc *PPC_intack_read[] = {
153
    &PPC_intack_readb,
154
    &PPC_intack_readw,
155
    &PPC_intack_readl,
156
};
157

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

185
static void PPC_XCSR_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
186
{
187
    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
188
}
189

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

    
198
static void PPC_XCSR_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
199
{
200
#ifdef TARGET_WORDS_BIGENDIAN
201
    value = bswap32(value);
202
#endif
203
    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
204
}
205

    
206
static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
207
{
208
    uint32_t retval = 0;
209

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

    
212
    return retval;
213
}
214

    
215
static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
216
{
217
    uint32_t retval = 0;
218

    
219
    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
220
#ifdef TARGET_WORDS_BIGENDIAN
221
    retval = bswap16(retval);
222
#endif
223

    
224
    return retval;
225
}
226

    
227
static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
228
{
229
    uint32_t retval = 0;
230

    
231
    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
232
#ifdef TARGET_WORDS_BIGENDIAN
233
    retval = bswap32(retval);
234
#endif
235

    
236
    return retval;
237
}
238

    
239
static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
240
    &PPC_XCSR_writeb,
241
    &PPC_XCSR_writew,
242
    &PPC_XCSR_writel,
243
};
244

    
245
static CPUReadMemoryFunc *PPC_XCSR_read[] = {
246
    &PPC_XCSR_readb,
247
    &PPC_XCSR_readw,
248
    &PPC_XCSR_readl,
249
};
250
#endif
251

    
252
/* Fake super-io ports for PREP platform (Intel 82378ZB) */
253
typedef struct sysctrl_t {
254
    m48t59_t *nvram;
255
    uint8_t state;
256
    uint8_t syscontrol;
257
    uint8_t fake_io[2];
258
    int contiguous_map;
259
    int endian;
260
} sysctrl_t;
261

    
262
enum {
263
    STATE_HARDFILE = 0x01,
264
};
265

    
266
static sysctrl_t *sysctrl;
267

    
268
static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
269
{
270
    sysctrl_t *sysctrl = opaque;
271

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

    
276
static uint32_t PREP_io_read (void *opaque, uint32_t addr)
277
{
278
    sysctrl_t *sysctrl = opaque;
279

    
280
    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE,
281
                   sysctrl->fake_io[addr - 0x0398]);
282
    return sysctrl->fake_io[addr - 0x0398];
283
}
284

    
285
static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
286
{
287
    sysctrl_t *sysctrl = opaque;
288

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

    
349
static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
350
{
351
    sysctrl_t *sysctrl = opaque;
352
    uint32_t retval = 0xFF;
353

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

    
411
    return retval;
412
}
413

    
414
static inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
415
                                                  target_phys_addr_t addr)
416
{
417
    if (sysctrl->contiguous_map == 0) {
418
        /* 64 KB contiguous space for IOs */
419
        addr &= 0xFFFF;
420
    } else {
421
        /* 8 MB non-contiguous space for IOs */
422
        addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7);
423
    }
424

    
425
    return addr;
426
}
427

    
428
static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr,
429
                                uint32_t value)
430
{
431
    sysctrl_t *sysctrl = opaque;
432

    
433
    addr = prep_IO_address(sysctrl, addr);
434
    cpu_outb(NULL, addr, value);
435
}
436

    
437
static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
438
{
439
    sysctrl_t *sysctrl = opaque;
440
    uint32_t ret;
441

    
442
    addr = prep_IO_address(sysctrl, addr);
443
    ret = cpu_inb(NULL, addr);
444

    
445
    return ret;
446
}
447

    
448
static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
449
                                uint32_t value)
450
{
451
    sysctrl_t *sysctrl = opaque;
452

    
453
    addr = prep_IO_address(sysctrl, addr);
454
#ifdef TARGET_WORDS_BIGENDIAN
455
    value = bswap16(value);
456
#endif
457
    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
458
    cpu_outw(NULL, addr, value);
459
}
460

    
461
static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
462
{
463
    sysctrl_t *sysctrl = opaque;
464
    uint32_t ret;
465

    
466
    addr = prep_IO_address(sysctrl, addr);
467
    ret = cpu_inw(NULL, addr);
468
#ifdef TARGET_WORDS_BIGENDIAN
469
    ret = bswap16(ret);
470
#endif
471
    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
472

    
473
    return ret;
474
}
475

    
476
static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
477
                                uint32_t value)
478
{
479
    sysctrl_t *sysctrl = opaque;
480

    
481
    addr = prep_IO_address(sysctrl, addr);
482
#ifdef TARGET_WORDS_BIGENDIAN
483
    value = bswap32(value);
484
#endif
485
    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
486
    cpu_outl(NULL, addr, value);
487
}
488

    
489
static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
490
{
491
    sysctrl_t *sysctrl = opaque;
492
    uint32_t ret;
493

    
494
    addr = prep_IO_address(sysctrl, addr);
495
    ret = cpu_inl(NULL, addr);
496
#ifdef TARGET_WORDS_BIGENDIAN
497
    ret = bswap32(ret);
498
#endif
499
    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
500

    
501
    return ret;
502
}
503

    
504
CPUWriteMemoryFunc *PPC_prep_io_write[] = {
505
    &PPC_prep_io_writeb,
506
    &PPC_prep_io_writew,
507
    &PPC_prep_io_writel,
508
};
509

    
510
CPUReadMemoryFunc *PPC_prep_io_read[] = {
511
    &PPC_prep_io_readb,
512
    &PPC_prep_io_readw,
513
    &PPC_prep_io_readl,
514
};
515

    
516
#define NVRAM_SIZE        0x2000
517

    
518
/* PowerPC PREP hardware initialisation */
519
static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
520
                           DisplayState *ds, const char **fd_filename,
521
                           int snapshot, const char *kernel_filename,
522
                           const char *kernel_cmdline,
523
                           const char *initrd_filename,
524
                           const char *cpu_model)
525
{
526
    CPUState *env;
527
    char buf[1024];
528
    m48t59_t *nvram;
529
    int PPC_io_memory;
530
    int linux_boot, i, nb_nics1, bios_size;
531
    unsigned long bios_offset;
532
    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
533
    ppc_def_t *def;
534
    PCIBus *pci_bus;
535

    
536
    sysctrl = qemu_mallocz(sizeof(sysctrl_t));
537
    if (sysctrl == NULL)
538
        return;
539

    
540
    linux_boot = (kernel_filename != NULL);
541
    
542
    /* init CPUs */
543

    
544
    env = cpu_init();
545
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
546

    
547
    /* Default CPU is a 604 */
548
    if (cpu_model == NULL)
549
        cpu_model = "604";
550
    ppc_find_by_name(cpu_model, &def);
551
    if (def == NULL) {
552
        cpu_abort(env, "Unable to find PowerPC CPU definition\n");
553
    }
554
    cpu_ppc_register(env, def);
555
    /* Set time-base frequency to 100 Mhz */
556
    cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
557

    
558
    /* allocate RAM */
559
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
560

    
561
    /* allocate and load BIOS */
562
    bios_offset = ram_size + vga_ram_size;
563
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
564
    bios_size = load_image(buf, phys_ram_base + bios_offset);
565
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
566
        fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
567
        exit(1);
568
    }
569
    bios_size = (bios_size + 0xfff) & ~0xfff;
570
    cpu_register_physical_memory((uint32_t)(-bios_size), 
571
                                 bios_size, bios_offset | IO_MEM_ROM);
572

    
573
    if (linux_boot) {
574
        kernel_base = KERNEL_LOAD_ADDR;
575
        /* now we can load the kernel */
576
        kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
577
        if (kernel_size < 0) {
578
            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
579
                    kernel_filename);
580
            exit(1);
581
        }
582
        /* load initrd */
583
        if (initrd_filename) {
584
            initrd_base = INITRD_LOAD_ADDR;
585
            initrd_size = load_image(initrd_filename,
586
                                     phys_ram_base + initrd_base);
587
            if (initrd_size < 0) {
588
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
589
                        initrd_filename);
590
                exit(1);
591
            }
592
        } else {
593
            initrd_base = 0;
594
            initrd_size = 0;
595
        }
596
        boot_device = 'm';
597
    } else {
598
        kernel_base = 0;
599
        kernel_size = 0;
600
        initrd_base = 0;
601
        initrd_size = 0;
602
    }
603

    
604
    isa_mem_base = 0xc0000000;
605
    pci_bus = pci_prep_init();
606
    //    pci_bus = i440fx_init();
607
    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
608
    PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,
609
                                           PPC_prep_io_write, sysctrl);
610
    cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
611

    
612
    /* init basic PC hardware */
613
    pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
614
                 vga_ram_size, 0, 0);
615
    rtc_init(0x70, 8);
616
    //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
617
    isa_pic = pic_init(pic_irq_request, first_cpu);
618
    //    pit = pit_init(0x40, 0);
619

    
620
    serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
621
    nb_nics1 = nb_nics;
622
    if (nb_nics1 > NE2000_NB_MAX)
623
        nb_nics1 = NE2000_NB_MAX;
624
    for(i = 0; i < nb_nics1; i++) {
625
        if (nd_table[0].model == NULL
626
            || strcmp(nd_table[0].model, "ne2k_isa") == 0) {
627
            isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
628
        } else {
629
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
630
            exit (1);
631
        }
632
    }
633

    
634
    for(i = 0; i < 2; i++) {
635
        isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
636
                     bs_table[2 * i], bs_table[2 * i + 1]);
637
    }
638
    kbd_init();
639
    DMA_init(1);
640
    //    AUD_init();
641
    //    SB16_init();
642

    
643
    fdctrl_init(6, 2, 0, 0x3f0, fd_table);
644

    
645
    /* Register speaker port */
646
    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
647
    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
648
    /* Register fake IO ports for PREP */
649
    register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
650
    register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
651
    /* System control ports */
652
    register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
653
    register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
654
    register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
655
    register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
656
    /* PCI intack location */
657
    PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
658
                                           PPC_intack_write, NULL);
659
    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
660
    /* PowerPC control and status register group */
661
#if 0
662
    PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write, NULL);
663
    cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
664
#endif
665

    
666
    if (usb_enabled) {
667
        usb_ohci_init_pci(pci_bus, 3, -1);
668
    }
669

    
670
    nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE, 59);
671
    if (nvram == NULL)
672
        return;
673
    sysctrl->nvram = nvram;
674

    
675
    /* Initialise NVRAM */
676
    PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
677
                         kernel_base, kernel_size,
678
                         kernel_cmdline,
679
                         initrd_base, initrd_size,
680
                         /* XXX: need an option to load a NVRAM image */
681
                         0,
682
                         graphic_width, graphic_height, graphic_depth);
683

    
684
    /* Special port to get debug messages from Open-Firmware */
685
    register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
686
}
687

    
688
QEMUMachine prep_machine = {
689
    "prep",
690
    "PowerPC PREP platform",
691
    ppc_prep_init,
692
};