Blame view

hw/ppc_prep.c 22.2 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"
blueswir1 authored
34
#include "qemu-log.h"
35
36
//#define HARD_DEBUG_PPC_IO
37
//#define DEBUG_PPC_IO
38
39
40
41
/* SMP is not enabled, for now */
#define MAX_CPUS 1
42
43
#define MAX_IDE_BUS 2
44
#define BIOS_SIZE (1024 * 1024)
bellard authored
45
46
47
#define BIOS_FILENAME "ppc_rom.bin"
#define KERNEL_LOAD_ADDR 0x01000000
#define INITRD_LOAD_ADDR 0x01800000
48
49
50
51
52
53
#if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
#define DEBUG_PPC_IO
#endif

#if defined (HARD_DEBUG_PPC_IO)
54
#define PPC_IO_DPRINTF(fmt, ...)                         \
55
do {                                                     \
56
    if (qemu_loglevel_mask(CPU_LOG_IOPORT)) {            \
57
        qemu_log("%s: " fmt, __func__ , ## __VA_ARGS__); \
58
    } else {                                             \
59
        printf("%s : " fmt, __func__ , ## __VA_ARGS__);  \
60
61
62
    }                                                    \
} while (0)
#elif defined (DEBUG_PPC_IO)
63
#define PPC_IO_DPRINTF(fmt, ...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
64
#else
65
#define PPC_IO_DPRINTF(fmt, ...) do { } while (0)
66
67
#endif
68
/* Constants for devices init */
69
70
71
72
73
74
75
76
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 };
77
78
79
80
//static PITState *pit;

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

    return retval;
}
128
static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
129
130
131
132
{
    return _PPC_intack_read(addr);
}
133
static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
134
{
bellard authored
135
#ifdef TARGET_WORDS_BIGENDIAN
136
137
138
    return bswap16(_PPC_intack_read(addr));
#else
    return _PPC_intack_read(addr);
bellard authored
139
#endif
140
141
}
142
static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
143
{
bellard authored
144
#ifdef TARGET_WORDS_BIGENDIAN
145
146
147
    return bswap32(_PPC_intack_read(addr));
#else
    return _PPC_intack_read(addr);
bellard authored
148
#endif
149
150
}
151
152
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
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;
190
191
static void PPC_XCSR_writeb (void *opaque,
                             target_phys_addr_t addr, uint32_t value)
192
{
193
    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
194
195
}
196
197
static void PPC_XCSR_writew (void *opaque,
                             target_phys_addr_t addr, uint32_t value)
198
{
bellard authored
199
#ifdef TARGET_WORDS_BIGENDIAN
200
    value = bswap16(value);
bellard authored
201
#endif
202
    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
203
204
}
205
206
static void PPC_XCSR_writel (void *opaque,
                             target_phys_addr_t addr, uint32_t value)
207
{
bellard authored
208
#ifdef TARGET_WORDS_BIGENDIAN
209
    value = bswap32(value);
bellard authored
210
#endif
211
    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
212
213
}
214
static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
215
216
{
    uint32_t retval = 0;
217
218
    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
219
220
221
222
    return retval;
}
223
static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
224
{
225
226
    uint32_t retval = 0;
227
    printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
228
229
230
231
232
#ifdef TARGET_WORDS_BIGENDIAN
    retval = bswap16(retval);
#endif

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

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

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

    return retval;
}
428
429
430
static always_inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
                                                         target_phys_addr_t
                                                         addr)
431
432
433
434
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
{
    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
472
    PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
473
474
475
476
477
478
479
480
481
482
483
484
485
    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
486
    PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
487
488
489
490
491
492
493
494
495
496
497
498
499

    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
500
    PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
501
502
503
504
505
506
507
508
509
510
511
512
513
    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
514
    PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
515
516
517
518

    return ret;
}
519
static CPUWriteMemoryFunc *PPC_prep_io_write[] = {
520
521
522
523
524
    &PPC_prep_io_writeb,
    &PPC_prep_io_writew,
    &PPC_prep_io_writel,
};
525
static CPUReadMemoryFunc *PPC_prep_io_read[] = {
526
527
528
529
530
    &PPC_prep_io_readb,
    &PPC_prep_io_readw,
    &PPC_prep_io_readl,
};
531
#define NVRAM_SIZE        0x2000
532
533
/* PowerPC PREP hardware initialisation */
Paul Brook authored
534
static void ppc_prep_init (ram_addr_t ram_size,
535
                           const char *boot_device,
536
                           const char *kernel_filename,
537
538
539
                           const char *kernel_cmdline,
                           const char *initrd_filename,
                           const char *cpu_model)
540
{
541
    CPUState *env = NULL, *envs[MAX_CPUS];
542
    char *filename;
543
544
    nvram_t nvram;
    m48t59_t *m48t59;
545
    int PPC_io_memory;
bellard authored
546
    int linux_boot, i, nb_nics1, bios_size;
pbrook authored
547
    ram_addr_t ram_offset, bios_offset;
548
    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
bellard authored
549
    PCIBus *pci_bus;
pbrook authored
550
    qemu_irq *i8259;
551
    int ppc_boot_device;
552
553
554
    int index;
    BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    BlockDriverState *fd[MAX_FD];
555
556

    sysctrl = qemu_mallocz(sizeof(sysctrl_t));
557
558

    linux_boot = (kernel_filename != NULL);
559
bellard authored
560
    /* init CPUs */
561
    if (cpu_model == NULL)
562
        cpu_model = "default";
563
    for (i = 0; i < smp_cpus; i++) {
564
565
566
567
568
        env = cpu_init(cpu_model);
        if (!env) {
            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
            exit(1);
        }
569
570
571
572
573
574
575
        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);
        }
576
        qemu_register_reset(&cpu_ppc_reset, env);
577
578
        envs[i] = env;
    }
579
580

    /* allocate RAM */
blueswir1 authored
581
582
583
    ram_offset = qemu_ram_alloc(ram_size);
    cpu_register_physical_memory(0, ram_size, ram_offset);
584
    /* allocate and load BIOS */
blueswir1 authored
585
    bios_offset = qemu_ram_alloc(BIOS_SIZE);
586
587
    if (bios_name == NULL)
        bios_name = BIOS_FILENAME;
588
589
590
591
592
593
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    if (filename) {
        bios_size = get_image_size(filename);
    } else {
        bios_size = -1;
    }
594
595
596
597
598
599
    if (bios_size > 0 && bios_size <= BIOS_SIZE) {
        target_phys_addr_t bios_addr;
        bios_size = (bios_size + 0xfff) & ~0xfff;
        bios_addr = (uint32_t)(-bios_size);
        cpu_register_physical_memory(bios_addr, bios_size,
                                     bios_offset | IO_MEM_ROM);
600
        bios_size = load_image_targphys(filename, bios_addr, bios_size);
601
    }
bellard authored
602
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
603
604
605
606
        hw_error("qemu: could not load PPC PREP bios '%s'\n", bios_name);
    }
    if (filename) {
        qemu_free(filename);
607
    }
608
    if (env->nip < 0xFFF80000 && bios_size < 0x00100000) {
609
        hw_error("PowerPC 601 / 620 / 970 need a 1MB BIOS\n");
610
    }
611
612
    if (linux_boot) {
613
        kernel_base = KERNEL_LOAD_ADDR;
614
        /* now we can load the kernel */
615
616
        kernel_size = load_image_targphys(kernel_filename, kernel_base,
                                          ram_size - kernel_base);
617
        if (kernel_size < 0) {
618
            hw_error("qemu: could not load kernel '%s'\n", kernel_filename);
619
620
621
622
            exit(1);
        }
        /* load initrd */
        if (initrd_filename) {
623
            initrd_base = INITRD_LOAD_ADDR;
624
625
            initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                              ram_size - initrd_base);
626
            if (initrd_size < 0) {
627
                hw_error("qemu: could not load initial ram disk '%s'\n",
j_mayer authored
628
                          initrd_filename);
629
            }
630
631
632
        } else {
            initrd_base = 0;
            initrd_size = 0;
633
        }
634
        ppc_boot_device = 'm';
635
    } else {
636
637
638
639
        kernel_base = 0;
        kernel_size = 0;
        initrd_base = 0;
        initrd_size = 0;
640
641
        ppc_boot_device = '\0';
        /* For now, OHW cannot boot from the network. */
642
643
644
        for (i = 0; boot_device[i] != '\0'; i++) {
            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
                ppc_boot_device = boot_device[i];
645
                break;
646
            }
647
648
649
650
651
        }
        if (ppc_boot_device == '\0') {
            fprintf(stderr, "No valid boot device for Mac99 machine\n");
            exit(1);
        }
652
653
    }
654
    isa_mem_base = 0xc0000000;
655
    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
656
        hw_error("Only 6xx bus is supported on PREP machine\n");
657
    }
658
    i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
pbrook authored
659
    pci_bus = pci_prep_init(i8259);
660
661
    //    pci_bus = i440fx_init();
    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
662
    PPC_io_memory = cpu_register_io_memory(PPC_prep_io_read,
663
664
                                           PPC_prep_io_write, sysctrl);
    cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
665
666
    /* init basic PC hardware */
Paul Brook authored
667
    pci_vga_init(pci_bus, 0, 0);
668
    //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
pbrook authored
669
    //    pit = pit_init(0x40, i8259[0]);
670
    rtc_init(0x70, i8259[8], 2000);
671
672
    serial_init(0x3f8, i8259[4], 115200, serial_hds[0]);
673
674
675
676
    nb_nics1 = nb_nics;
    if (nb_nics1 > NE2000_NB_MAX)
        nb_nics1 = NE2000_NB_MAX;
    for(i = 0; i < nb_nics1; i++) {
677
678
679
680
        if (nd_table[i].model == NULL) {
	    nd_table[i].model = "ne2k_isa";
        }
        if (strcmp(nd_table[i].model, "ne2k_isa") == 0) {
pbrook authored
681
            isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);
682
        } else {
683
            pci_nic_init(&nd_table[i], "ne2k_pci", NULL);
684
        }
685
686
    }
687
688
689
690
691
692
693
694
695
696
697
698
699
700
    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
701
        isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
702
703
                     hd[2 * i],
		     hd[2 * i + 1]);
704
    }
pbrook authored
705
    i8042_init(i8259[1], i8259[12], 0x60);
bellard authored
706
    DMA_init(1);
707
708
    //    SB16_init();
709
710
711
712
713
714
715
716
    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);
717
718
719
720
    /* Register speaker port */
    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
721
    /* Register fake IO ports for PREP */
j_mayer authored
722
    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
723
724
    register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
    register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
725
    /* System control ports */
726
727
728
729
730
    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 */
731
    PPC_io_memory = cpu_register_io_memory(PPC_intack_read,
732
                                           PPC_intack_write, NULL);
733
    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
734
    /* PowerPC control and status register group */
bellard authored
735
#if 0
736
    PPC_io_memory = cpu_register_io_memory(PPC_XCSR_read, PPC_XCSR_write,
737
                                           NULL);
738
    cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
bellard authored
739
#endif
740
pbrook authored
741
    if (usb_enabled) {
742
        usb_ohci_init_pci(pci_bus, 3, -1);
pbrook authored
743
744
    }
745
746
    m48t59 = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
    if (m48t59 == NULL)
747
        return;
748
    sysctrl->nvram = m48t59;
749
750

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

    /* Special port to get debug messages from Open-Firmware */
    register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
764
}
bellard authored
765
766
static QEMUMachine prep_machine = {
767
768
769
    .name = "prep",
    .desc = "PowerPC PREP platform",
    .init = ppc_prep_init,
balrog authored
770
    .max_cpus = MAX_CPUS,
bellard authored
771
};
772
773
774
775
776
777
778

static void prep_machine_init(void)
{
    qemu_register_machine(&prep_machine);
}

machine_init(prep_machine_init);