Statistics
| Branch: | Revision:

root / hw / ppc_prep.c @ 0d92ed30

History | View | Annotate | Download (19.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
static void pic_irq_request(void *opaque, int level)
100
{
101
    if (level)
102
        cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
103
    else
104
        cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
105
}
106

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

    
114
static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
115
{
116
    uint32_t retval = 0;
117

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

    
122
    return retval;
123
}
124

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

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

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

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

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

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

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

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

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

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

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

    
214
    return retval;
215
}
216

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

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

    
226
    return retval;
227
}
228

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

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

    
238
    return retval;
239
}
240

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

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

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

    
264
enum {
265
    STATE_HARDFILE = 0x01,
266
};
267

    
268
static sysctrl_t *sysctrl;
269

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

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

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

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

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

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

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

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

    
413
    return retval;
414
}
415

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

    
427
    return addr;
428
}
429

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

    
435
    addr = prep_IO_address(sysctrl, addr);
436
    cpu_outb(NULL, addr, value);
437
}
438

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

    
444
    addr = prep_IO_address(sysctrl, addr);
445
    ret = cpu_inb(NULL, addr);
446

    
447
    return ret;
448
}
449

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

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

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

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

    
475
    return ret;
476
}
477

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

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

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

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

    
503
    return ret;
504
}
505

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

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

    
518
#define NVRAM_SIZE        0x2000
519

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

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

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

    
545
    env = cpu_init();
546
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
547
    
548
    /* Register CPU as a 604 */
549
    /* XXX: CPU model (or PVR) should be provided on command line */
550
    //    ppc_find_by_name("604r", &def);
551
    //    ppc_find_by_name("604e", &def);
552
    ppc_find_by_name("604", &def);
553
    if (def == NULL) {
554
        cpu_abort(env, "Unable to find PowerPC CPU definition\n");
555
    }
556
    cpu_ppc_register(env, def);
557
    /* Set time-base frequency to 100 Mhz */
558
    cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
559

    
560
    /* allocate RAM */
561
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
562

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

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

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

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

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

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

    
645
    fdctrl_init(6, 2, 0, 0x3f0, fd_table);
646

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

    
668
    if (usb_enabled) {
669
        usb_ohci_init(pci_bus, 3, -1);
670
    }
671

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

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

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

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