Blame view

hw/ppc_prep.c 22 KB
1
/*
2
 * QEMU PPC PREP hardware System Emulator
3
 *
4
 * Copyright (c) 2003-2007 Jocelyn Mayer
5
 *
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
23
 */
pbrook authored
24
25
26
27
28
29
30
31
32
33
#include "hw.h"
#include "nvram.h"
#include "pc.h"
#include "fdc.h"
#include "net.h"
#include "sysemu.h"
#include "isa.h"
#include "pci.h"
#include "ppc.h"
#include "boards.h"
34
35
//#define HARD_DEBUG_PPC_IO
36
//#define DEBUG_PPC_IO
37
38
39
40
/* SMP is not enabled, for now */
#define MAX_CPUS 1
41
42
#define MAX_IDE_BUS 2
bellard authored
43
44
45
#define BIOS_FILENAME "ppc_rom.bin"
#define KERNEL_LOAD_ADDR 0x01000000
#define INITRD_LOAD_ADDR 0x01800000
46
47
48
49
50
51
52
53
54
55
56
extern int loglevel;
extern FILE *logfile;

#if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
#define DEBUG_PPC_IO
#endif

#if defined (HARD_DEBUG_PPC_IO)
#define PPC_IO_DPRINTF(fmt, args...)                     \
do {                                                     \
bellard authored
57
    if (loglevel & CPU_LOG_IOPORT) {                     \
58
59
60
61
62
63
64
65
        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
    } else {                                             \
        printf("%s : " fmt, __func__ , ##args);          \
    }                                                    \
} while (0)
#elif defined (DEBUG_PPC_IO)
#define PPC_IO_DPRINTF(fmt, args...)                     \
do {                                                     \
bellard authored
66
    if (loglevel & CPU_LOG_IOPORT) {                     \
67
68
69
70
71
72
73
        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
    }                                                    \
} while (0)
#else
#define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
#endif
74
/* Constants for devices init */
75
76
77
78
79
80
81
82
static const int ide_iobase[2] = { 0x1f0, 0x170 };
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
static const int ide_irq[2] = { 13, 13 };

#define NE2000_NB_MAX 6

static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
83
84
85
86
//static PITState *pit;

/* ISA IO ports bridge */
87
88
#define PPC_IO_BASE 0x80000000
89
90
91
92
/* Speaker port 0x61 */
int speaker_data_on;
int dummy_refresh_clock;
93
static void speaker_ioport_write (void *opaque, uint32_t addr, uint32_t val)
94
{
95
#if 0
96
97
    speaker_data_on = (val >> 1) & 1;
    pit_set_gate(pit, 2, val & 1);
98
#endif
99
100
}
101
static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
102
{
103
#if 0
104
105
106
107
    int out;
    out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
    dummy_refresh_clock ^= 1;
    return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
108
        (dummy_refresh_clock << 4);
109
#endif
110
    return 0;
111
112
}
113
114
/* PCI intack register */
/* Read-only register (?) */
115
116
static void _PPC_intack_write (void *opaque,
                               target_phys_addr_t addr, uint32_t value)
117
{
118
//    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
119
120
}
121
static always_inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
122
123
124
125
{
    uint32_t retval = 0;

    if (addr == 0xBFFFFFF0)
bellard authored
126
        retval = pic_intack_read(isa_pic);
127
//   printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
128
129
130
131

    return retval;
}
132
static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
133
134
135
136
{
    return _PPC_intack_read(addr);
}
137
static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
138
{
bellard authored
139
#ifdef TARGET_WORDS_BIGENDIAN
140
141
142
    return bswap16(_PPC_intack_read(addr));
#else
    return _PPC_intack_read(addr);
bellard authored
143
#endif
144
145
}
146
static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
147
{
bellard authored
148
#ifdef TARGET_WORDS_BIGENDIAN
149
150
151
    return bswap32(_PPC_intack_read(addr));
#else
    return _PPC_intack_read(addr);
bellard authored
152
#endif
153
154
}
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
static CPUWriteMemoryFunc *PPC_intack_write[] = {
    &_PPC_intack_write,
    &_PPC_intack_write,
    &_PPC_intack_write,
};

static CPUReadMemoryFunc *PPC_intack_read[] = {
    &PPC_intack_readb,
    &PPC_intack_readw,
    &PPC_intack_readl,
};

/* PowerPC control and status registers */
#if 0 // Not used
static struct {
    /* IDs */
    uint32_t veni_devi;
    uint32_t revi;
    /* Control and status */
    uint32_t gcsr;
    uint32_t xcfr;
    uint32_t ct32;
    uint32_t mcsr;
    /* General purpose registers */
    uint32_t gprg[6];
    /* Exceptions */
    uint32_t feen;
    uint32_t fest;
    uint32_t fema;
    uint32_t fecl;
    uint32_t eeen;
    uint32_t eest;
    uint32_t eecl;
    uint32_t eeint;
    uint32_t eemck0;
    uint32_t eemck1;
    /* Error diagnostic */
} XCSR;
194
195
static void PPC_XCSR_writeb (void *opaque,
                             target_phys_addr_t addr, uint32_t value)
196
{
197
    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
198
199
}
200
201
static void PPC_XCSR_writew (void *opaque,
                             target_phys_addr_t addr, uint32_t value)
202
{
bellard authored
203
#ifdef TARGET_WORDS_BIGENDIAN
204
    value = bswap16(value);
bellard authored
205
#endif
206
    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
207
208
}
209
210
static void PPC_XCSR_writel (void *opaque,
                             target_phys_addr_t addr, uint32_t value)
211
{
bellard authored
212
#ifdef TARGET_WORDS_BIGENDIAN
213
    value = bswap32(value);
bellard authored
214
#endif
215
    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
216
217
}
218
static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
219
220
{
    uint32_t retval = 0;
221
222
    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
223
224
225
226
    return retval;
}
227
static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
228
{
229
230
    uint32_t retval = 0;
231
    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
232
233
234
235
236
#ifdef TARGET_WORDS_BIGENDIAN
    retval = bswap16(retval);
#endif

    return retval;
237
238
}
239
static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
240
241
242
{
    uint32_t retval = 0;
243
    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
244
245
246
#ifdef TARGET_WORDS_BIGENDIAN
    retval = bswap32(retval);
#endif
247
248
249
250

    return retval;
}
251
252
253
254
static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
    &PPC_XCSR_writeb,
    &PPC_XCSR_writew,
    &PPC_XCSR_writel,
255
256
};
257
258
259
260
static CPUReadMemoryFunc *PPC_XCSR_read[] = {
    &PPC_XCSR_readb,
    &PPC_XCSR_readw,
    &PPC_XCSR_readl,
261
};
bellard authored
262
#endif
263
264
265
/* Fake super-io ports for PREP platform (Intel 82378ZB) */
typedef struct sysctrl_t {
j_mayer authored
266
    qemu_irq reset_irq;
267
268
269
270
    m48t59_t *nvram;
    uint8_t state;
    uint8_t syscontrol;
    uint8_t fake_io[2];
271
    int contiguous_map;
bellard authored
272
    int endian;
273
} sysctrl_t;
274
275
276
enum {
    STATE_HARDFILE = 0x01,
277
278
};
279
static sysctrl_t *sysctrl;
280
281
static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
282
{
283
284
    sysctrl_t *sysctrl = opaque;
285
286
    PPC_IO_DPRINTF("0x%08" PRIx32 " => 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
                   val);
287
    sysctrl->fake_io[addr - 0x0398] = val;
288
289
}
290
static uint32_t PREP_io_read (void *opaque, uint32_t addr)
291
{
292
    sysctrl_t *sysctrl = opaque;
293
294
    PPC_IO_DPRINTF("0x%08" PRIx32 " <= 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
295
296
297
                   sysctrl->fake_io[addr - 0x0398]);
    return sysctrl->fake_io[addr - 0x0398];
}
298
299
static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
300
{
301
302
    sysctrl_t *sysctrl = opaque;
303
304
    PPC_IO_DPRINTF("0x%08" PRIx32 " => 0x%02" PRIx32 "\n",
                   addr - PPC_IO_BASE, val);
305
306
307
308
    switch (addr) {
    case 0x0092:
        /* Special port 92 */
        /* Check soft reset asked */
309
        if (val & 0x01) {
j_mayer authored
310
311
312
            qemu_irq_raise(sysctrl->reset_irq);
        } else {
            qemu_irq_lower(sysctrl->reset_irq);
313
314
        }
        /* Check LE mode */
315
        if (val & 0x02) {
bellard authored
316
317
318
            sysctrl->endian = 1;
        } else {
            sysctrl->endian = 0;
319
320
        }
        break;
321
322
323
324
325
326
327
328
329
    case 0x0800:
        /* Motorola CPU configuration register : read-only */
        break;
    case 0x0802:
        /* Motorola base module feature register : read-only */
        break;
    case 0x0803:
        /* Motorola base module status register : read-only */
        break;
330
    case 0x0808:
331
332
333
334
335
        /* Hardfile light register */
        if (val & 1)
            sysctrl->state |= STATE_HARDFILE;
        else
            sysctrl->state &= ~STATE_HARDFILE;
336
337
338
        break;
    case 0x0810:
        /* Password protect 1 register */
339
340
        if (sysctrl->nvram != NULL)
            m48t59_toggle_lock(sysctrl->nvram, 1);
341
342
343
        break;
    case 0x0812:
        /* Password protect 2 register */
344
345
        if (sysctrl->nvram != NULL)
            m48t59_toggle_lock(sysctrl->nvram, 2);
346
347
        break;
    case 0x0814:
348
        /* L2 invalidate register */
bellard authored
349
        //        tlb_flush(first_cpu, 1);
350
351
352
        break;
    case 0x081C:
        /* system control register */
353
        sysctrl->syscontrol = val & 0x0F;
354
355
356
        break;
    case 0x0850:
        /* I/O map type register */
357
        sysctrl->contiguous_map = val & 0x01;
358
359
        break;
    default:
360
361
        printf("ERROR: unaffected IO port write: %04" PRIx32
               " => %02" PRIx32"\n", addr, val);
362
363
364
365
        break;
    }
}
366
static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
367
{
368
    sysctrl_t *sysctrl = opaque;
369
370
371
372
373
    uint32_t retval = 0xFF;

    switch (addr) {
    case 0x0092:
        /* Special port 92 */
374
375
376
377
378
379
380
381
382
383
384
385
386
        retval = 0x00;
        break;
    case 0x0800:
        /* Motorola CPU configuration register */
        retval = 0xEF; /* MPC750 */
        break;
    case 0x0802:
        /* Motorola Base module feature register */
        retval = 0xAD; /* No ESCC, PMC slot neither ethernet */
        break;
    case 0x0803:
        /* Motorola base module status register */
        retval = 0xE0; /* Standard MPC750 */
387
388
389
390
391
392
393
394
        break;
    case 0x080C:
        /* Equipment present register:
         *  no L2 cache
         *  no upgrade processor
         *  no cards in PCI slots
         *  SCSI fuse is bad
         */
395
396
397
398
399
        retval = 0x3C;
        break;
    case 0x0810:
        /* Motorola base module extended feature register */
        retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
400
        break;
401
402
403
    case 0x0814:
        /* L2 invalidate: don't care */
        break;
404
405
406
407
408
409
410
411
    case 0x0818:
        /* Keylock */
        retval = 0x00;
        break;
    case 0x081C:
        /* system control register
         * 7 - 6 / 1 - 0: L2 cache enable
         */
412
        retval = sysctrl->syscontrol;
413
414
415
416
417
418
419
        break;
    case 0x0823:
        /* */
        retval = 0x03; /* no L2 cache */
        break;
    case 0x0850:
        /* I/O map type register */
420
        retval = sysctrl->contiguous_map;
421
422
        break;
    default:
423
        printf("ERROR: unaffected IO port: %04" PRIx32 " read\n", addr);
424
425
        break;
    }
426
427
    PPC_IO_DPRINTF("0x%08" PRIx32 " <= 0x%02" PRIx32 "\n",
                   addr - PPC_IO_BASE, retval);
428
429
430
431

    return retval;
}
432
433
434
static always_inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
                                                         target_phys_addr_t
                                                         addr)
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
{
    if (sysctrl->contiguous_map == 0) {
        /* 64 KB contiguous space for IOs */
        addr &= 0xFFFF;
    } else {
        /* 8 MB non-contiguous space for IOs */
        addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7);
    }

    return addr;
}

static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr,
                                uint32_t value)
{
    sysctrl_t *sysctrl = opaque;

    addr = prep_IO_address(sysctrl, addr);
    cpu_outb(NULL, addr, value);
}

static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
{
    sysctrl_t *sysctrl = opaque;
    uint32_t ret;

    addr = prep_IO_address(sysctrl, addr);
    ret = cpu_inb(NULL, addr);

    return ret;
}

static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
                                uint32_t value)
{
    sysctrl_t *sysctrl = opaque;

    addr = prep_IO_address(sysctrl, addr);
#ifdef TARGET_WORDS_BIGENDIAN
    value = bswap16(value);
#endif
476
    PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
477
478
479
480
481
482
483
484
485
486
487
488
489
    cpu_outw(NULL, addr, value);
}

static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
{
    sysctrl_t *sysctrl = opaque;
    uint32_t ret;

    addr = prep_IO_address(sysctrl, addr);
    ret = cpu_inw(NULL, addr);
#ifdef TARGET_WORDS_BIGENDIAN
    ret = bswap16(ret);
#endif
490
    PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
491
492
493
494
495
496
497
498
499
500
501
502
503

    return ret;
}

static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
                                uint32_t value)
{
    sysctrl_t *sysctrl = opaque;

    addr = prep_IO_address(sysctrl, addr);
#ifdef TARGET_WORDS_BIGENDIAN
    value = bswap32(value);
#endif
504
    PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
505
506
507
508
509
510
511
512
513
514
515
516
517
    cpu_outl(NULL, addr, value);
}

static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
{
    sysctrl_t *sysctrl = opaque;
    uint32_t ret;

    addr = prep_IO_address(sysctrl, addr);
    ret = cpu_inl(NULL, addr);
#ifdef TARGET_WORDS_BIGENDIAN
    ret = bswap32(ret);
#endif
518
    PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

    return ret;
}

CPUWriteMemoryFunc *PPC_prep_io_write[] = {
    &PPC_prep_io_writeb,
    &PPC_prep_io_writew,
    &PPC_prep_io_writel,
};

CPUReadMemoryFunc *PPC_prep_io_read[] = {
    &PPC_prep_io_readb,
    &PPC_prep_io_readw,
    &PPC_prep_io_readl,
};
535
#define NVRAM_SIZE        0x2000
536
537
/* PowerPC PREP hardware initialisation */
538
static void ppc_prep_init (int ram_size, int vga_ram_size,
539
540
                           const char *boot_device, DisplayState *ds,
                           const char *kernel_filename,
541
542
543
                           const char *kernel_cmdline,
                           const char *initrd_filename,
                           const char *cpu_model)
544
{
545
    CPUState *env = NULL, *envs[MAX_CPUS];
546
    char buf[1024];
547
548
    nvram_t nvram;
    m48t59_t *m48t59;
549
    int PPC_io_memory;
bellard authored
550
    int linux_boot, i, nb_nics1, bios_size;
551
552
    unsigned long bios_offset;
    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
bellard authored
553
    PCIBus *pci_bus;
pbrook authored
554
    qemu_irq *i8259;
555
    int ppc_boot_device;
556
557
558
    int index;
    BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    BlockDriverState *fd[MAX_FD];
559
560
561

    sysctrl = qemu_mallocz(sizeof(sysctrl_t));
    if (sysctrl == NULL)
562
        return;
563
564

    linux_boot = (kernel_filename != NULL);
565
bellard authored
566
    /* init CPUs */
567
    if (cpu_model == NULL)
568
        cpu_model = "default";
569
    for (i = 0; i < smp_cpus; i++) {
570
571
572
573
574
        env = cpu_init(cpu_model);
        if (!env) {
            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
            exit(1);
        }
575
576
577
578
579
580
581
        if (env->flags & POWERPC_FLAG_RTC_CLK) {
            /* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */
            cpu_ppc_tb_init(env, 7812500UL);
        } else {
            /* Set time-base frequency to 100 Mhz */
            cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
        }
582
583
584
585
        qemu_register_reset(&cpu_ppc_reset, env);
        register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
        envs[i] = env;
    }
586
587

    /* allocate RAM */
588
589
590
591
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);

    /* allocate and load BIOS */
    bios_offset = ram_size + vga_ram_size;
592
593
594
    if (bios_name == NULL)
        bios_name = BIOS_FILENAME;
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
bellard authored
595
596
    bios_size = load_image(buf, phys_ram_base + bios_offset);
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
j_mayer authored
597
        cpu_abort(env, "qemu: could not load PPC PREP bios '%s'\n", buf);
598
599
        exit(1);
    }
600
601
602
    if (env->nip < 0xFFF80000 && bios_size < 0x00100000) {
        cpu_abort(env, "PowerPC 601 / 620 / 970 need a 1MB BIOS\n");
    }
bellard authored
603
    bios_size = (bios_size + 0xfff) & ~0xfff;
j_mayer authored
604
    cpu_register_physical_memory((uint32_t)(-bios_size),
bellard authored
605
                                 bios_size, bios_offset | IO_MEM_ROM);
606
607
    if (linux_boot) {
608
        kernel_base = KERNEL_LOAD_ADDR;
609
        /* now we can load the kernel */
610
611
        kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
        if (kernel_size < 0) {
j_mayer authored
612
613
            cpu_abort(env, "qemu: could not load kernel '%s'\n",
                      kernel_filename);
614
615
616
617
            exit(1);
        }
        /* load initrd */
        if (initrd_filename) {
618
619
620
            initrd_base = INITRD_LOAD_ADDR;
            initrd_size = load_image(initrd_filename,
                                     phys_ram_base + initrd_base);
621
            if (initrd_size < 0) {
j_mayer authored
622
623
                cpu_abort(env, "qemu: could not load initial ram disk '%s'\n",
                          initrd_filename);
624
625
                exit(1);
            }
626
627
628
        } else {
            initrd_base = 0;
            initrd_size = 0;
629
        }
630
        ppc_boot_device = 'm';
631
    } else {
632
633
634
635
        kernel_base = 0;
        kernel_size = 0;
        initrd_base = 0;
        initrd_size = 0;
636
637
        ppc_boot_device = '\0';
        /* For now, OHW cannot boot from the network. */
638
639
640
        for (i = 0; boot_device[i] != '\0'; i++) {
            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
                ppc_boot_device = boot_device[i];
641
                break;
642
            }
643
644
645
646
647
        }
        if (ppc_boot_device == '\0') {
            fprintf(stderr, "No valid boot device for Mac99 machine\n");
            exit(1);
        }
648
649
    }
650
    isa_mem_base = 0xc0000000;
651
652
653
654
    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
        cpu_abort(env, "Only 6xx bus is supported on PREP machine\n");
        exit(1);
    }
655
    i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
pbrook authored
656
    pci_bus = pci_prep_init(i8259);
657
658
659
660
661
    //    pci_bus = i440fx_init();
    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
    PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,
                                           PPC_prep_io_write, sysctrl);
    cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
662
663
    /* init basic PC hardware */
664
    pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
bellard authored
665
                 vga_ram_size, 0, 0);
666
    //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
pbrook authored
667
668
    //    pit = pit_init(0x40, i8259[0]);
    rtc_init(0x70, i8259[8]);
669
pbrook authored
670
    serial_init(0x3f8, i8259[4], serial_hds[0]);
671
672
673
674
    nb_nics1 = nb_nics;
    if (nb_nics1 > NE2000_NB_MAX)
        nb_nics1 = NE2000_NB_MAX;
    for(i = 0; i < nb_nics1; i++) {
675
676
        if (nd_table[i].model == NULL
            || strcmp(nd_table[i].model, "ne2k_isa") == 0) {
pbrook authored
677
            isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);
678
        } else {
679
            pci_nic_init(pci_bus, &nd_table[i], -1);
680
        }
681
682
    }
683
684
685
686
687
688
689
690
691
692
693
694
695
696
    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
        fprintf(stderr, "qemu: too many IDE bus\n");
        exit(1);
    }

    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
        index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
        if (index != -1)
            hd[i] = drives_table[index].bdrv;
        else
            hd[i] = NULL;
    }

    for(i = 0; i < MAX_IDE_BUS; i++) {
pbrook authored
697
        isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
698
699
                     hd[2 * i],
		     hd[2 * i + 1]);
700
    }
pbrook authored
701
    i8042_init(i8259[1], i8259[12], 0x60);
bellard authored
702
    DMA_init(1);
703
    //    AUD_init();
704
705
    //    SB16_init();
706
707
708
709
710
711
712
713
    for(i = 0; i < MAX_FD; i++) {
        index = drive_get_index(IF_FLOPPY, 0, i);
        if (index != -1)
            fd[i] = drives_table[index].bdrv;
        else
            fd[i] = NULL;
    }
    fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
714
715
716
717
    /* Register speaker port */
    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
718
    /* Register fake IO ports for PREP */
j_mayer authored
719
    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
720
721
    register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
    register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
722
    /* System control ports */
723
724
725
726
727
728
    register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
    register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
    register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
    register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
    /* PCI intack location */
    PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
729
                                           PPC_intack_write, NULL);
730
    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
731
    /* PowerPC control and status register group */
bellard authored
732
#if 0
733
734
    PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write,
                                           NULL);
735
    cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
bellard authored
736
#endif
737
pbrook authored
738
    if (usb_enabled) {
739
        usb_ohci_init_pci(pci_bus, 3, -1);
pbrook authored
740
741
    }
742
743
    m48t59 = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
    if (m48t59 == NULL)
744
        return;
745
    sysctrl->nvram = m48t59;
746
747

    /* Initialise NVRAM */
748
749
750
    nvram.opaque = m48t59;
    nvram.read_fn = &m48t59_read;
    nvram.write_fn = &m48t59_write;
751
    PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device,
752
                         kernel_base, kernel_size,
bellard authored
753
                         kernel_cmdline,
754
755
                         initrd_base, initrd_size,
                         /* XXX: need an option to load a NVRAM image */
bellard authored
756
757
                         0,
                         graphic_width, graphic_height, graphic_depth);
bellard authored
758
759
760

    /* Special port to get debug messages from Open-Firmware */
    register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
761
}
bellard authored
762
763
764
765
766
767

QEMUMachine prep_machine = {
    "prep",
    "PowerPC PREP platform",
    ppc_prep_init,
};