root / hw / ppc440.c @ 96cc1810
History | View | Annotate | Download (3.1 kB)
1 |
/*
|
---|---|
2 |
* Qemu PowerPC 440 chip emulation
|
3 |
*
|
4 |
* Copyright 2007 IBM Corporation.
|
5 |
* Authors:
|
6 |
* Jerone Young <jyoung5@us.ibm.com>
|
7 |
* Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
|
8 |
* Hollis Blanchard <hollisb@us.ibm.com>
|
9 |
*
|
10 |
* This work is licensed under the GNU GPL license version 2 or later.
|
11 |
*
|
12 |
*/
|
13 |
|
14 |
#include "hw.h" |
15 |
#include "isa.h" |
16 |
#include "ppc.h" |
17 |
#include "ppc4xx.h" |
18 |
#include "ppc440.h" |
19 |
#include "ppc405.h" |
20 |
#include "sysemu.h" |
21 |
#include "kvm.h" |
22 |
|
23 |
#define PPC440EP_PCI_CONFIG 0xeec00000 |
24 |
#define PPC440EP_PCI_INTACK 0xeed00000 |
25 |
#define PPC440EP_PCI_SPECIAL 0xeed00000 |
26 |
#define PPC440EP_PCI_REGS 0xef400000 |
27 |
#define PPC440EP_PCI_IO 0xe8000000 |
28 |
#define PPC440EP_PCI_IOLEN 0x00010000 |
29 |
|
30 |
#define PPC440EP_SDRAM_NR_BANKS 4 |
31 |
|
32 |
static const unsigned int ppc440ep_sdram_bank_sizes[] = { |
33 |
256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0 |
34 |
}; |
35 |
|
36 |
CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, |
37 |
const unsigned int pci_irq_nrs[4], int do_init, |
38 |
const char *cpu_model) |
39 |
{ |
40 |
target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS]; |
41 |
target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS]; |
42 |
CPUState *env; |
43 |
ppc4xx_mmio_t *mmio; |
44 |
qemu_irq *pic; |
45 |
qemu_irq *irqs; |
46 |
qemu_irq *pci_irqs; |
47 |
|
48 |
if (cpu_model == NULL) |
49 |
cpu_model = "405"; // XXX: should be 440EP |
50 |
env = cpu_init(cpu_model); |
51 |
if (!env) {
|
52 |
fprintf(stderr, "Unable to initialize CPU!\n");
|
53 |
exit(1);
|
54 |
} |
55 |
|
56 |
ppc_dcr_init(env, NULL, NULL); |
57 |
|
58 |
/* interrupt controller */
|
59 |
irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
|
60 |
irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; |
61 |
irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; |
62 |
pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); |
63 |
|
64 |
/* SDRAM controller */
|
65 |
memset(ram_bases, 0, sizeof(ram_bases)); |
66 |
memset(ram_sizes, 0, sizeof(ram_sizes)); |
67 |
*ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS, |
68 |
ram_bases, ram_sizes, |
69 |
ppc440ep_sdram_bank_sizes); |
70 |
/* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
|
71 |
ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases,
|
72 |
ram_sizes, do_init); |
73 |
|
74 |
/* PCI */
|
75 |
pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4); |
76 |
pci_irqs[0] = pic[pci_irq_nrs[0]]; |
77 |
pci_irqs[1] = pic[pci_irq_nrs[1]]; |
78 |
pci_irqs[2] = pic[pci_irq_nrs[2]]; |
79 |
pci_irqs[3] = pic[pci_irq_nrs[3]]; |
80 |
*pcip = ppc4xx_pci_init(env, pci_irqs, |
81 |
PPC440EP_PCI_CONFIG, |
82 |
PPC440EP_PCI_INTACK, |
83 |
PPC440EP_PCI_SPECIAL, |
84 |
PPC440EP_PCI_REGS); |
85 |
if (!*pcip)
|
86 |
printf("couldn't create PCI controller!\n");
|
87 |
|
88 |
isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN); |
89 |
|
90 |
/* MMIO -- most "miscellaneous" devices live above 0xef600000. */
|
91 |
mmio = ppc4xx_mmio_init(env, 0xef600000);
|
92 |
|
93 |
if (serial_hds[0]) |
94 |
ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]); |
95 |
|
96 |
if (serial_hds[1]) |
97 |
ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]); |
98 |
|
99 |
return env;
|
100 |
} |