ppc440.c 3.1 KB
Newer Older
A
aurel32 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Qemu PowerPC 440 chip emulation
 *
 * Copyright 2007 IBM Corporation.
 * Authors:
 * 	Jerone Young <jyoung5@us.ibm.com>
 * 	Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
 * 	Hollis Blanchard <hollisb@us.ibm.com>
 *
 * This work is licensed under the GNU GPL license version 2 or later.
 *
 */

#include "hw.h"
B
Blue Swirl 已提交
15
#include "pc.h"
A
aurel32 已提交
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#include "isa.h"
#include "ppc.h"
#include "ppc4xx.h"
#include "ppc440.h"
#include "ppc405.h"
#include "sysemu.h"
#include "kvm.h"

#define PPC440EP_PCI_CONFIG     0xeec00000
#define PPC440EP_PCI_INTACK     0xeed00000
#define PPC440EP_PCI_SPECIAL    0xeed00000
#define PPC440EP_PCI_REGS       0xef400000
#define PPC440EP_PCI_IO         0xe8000000
#define PPC440EP_PCI_IOLEN      0x00010000

#define PPC440EP_SDRAM_NR_BANKS 4

static const unsigned int ppc440ep_sdram_bank_sizes[] = {
    256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0
};

A
Anthony Liguori 已提交
37
CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,
B
Blue Swirl 已提交
38 39
                        const unsigned int pci_irq_nrs[4], int do_init,
                        const char *cpu_model)
A
aurel32 已提交
40
{
A
Anthony Liguori 已提交
41 42
    target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS];
    target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS];
A
aurel32 已提交
43 44 45 46 47
    CPUState *env;
    qemu_irq *pic;
    qemu_irq *irqs;
    qemu_irq *pci_irqs;

B
Blue Swirl 已提交
48 49 50
    if (cpu_model == NULL)
        cpu_model = "405"; // XXX: should be 440EP
    env = cpu_init(cpu_model);
A
aurel32 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
    if (!env) {
        fprintf(stderr, "Unable to initialize CPU!\n");
        exit(1);
    }

    ppc_dcr_init(env, NULL, NULL);

    /* interrupt controller */
    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
    irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
    irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);

    /* SDRAM controller */
    memset(ram_bases, 0, sizeof(ram_bases));
    memset(ram_sizes, 0, sizeof(ram_sizes));
    *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS,
                                    ram_bases, ram_sizes,
                                    ppc440ep_sdram_bank_sizes);
    /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
    ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases,
                      ram_sizes, do_init);

    /* PCI */
    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
    pci_irqs[0] = pic[pci_irq_nrs[0]];
    pci_irqs[1] = pic[pci_irq_nrs[1]];
    pci_irqs[2] = pic[pci_irq_nrs[2]];
    pci_irqs[3] = pic[pci_irq_nrs[3]];
    *pcip = ppc4xx_pci_init(env, pci_irqs,
                            PPC440EP_PCI_CONFIG,
                            PPC440EP_PCI_INTACK,
                            PPC440EP_PCI_SPECIAL,
                            PPC440EP_PCI_REGS);
    if (!*pcip)
        printf("couldn't create PCI controller!\n");

    isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN);

B
Blue Swirl 已提交
90 91 92 93 94 95 96 97
    if (serial_hds[0] != NULL) {
        serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE,
                       serial_hds[0], 1);
    }
    if (serial_hds[1] != NULL) {
        serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE,
                       serial_hds[1], 1);
    }
A
aurel32 已提交
98 99 100

    return env;
}