]>
Commit | Line | Data |
---|---|---|
75dd595b AJ |
1 | /* |
2 | * Qemu PowerPC 440 chip emulation | |
3 | * | |
4 | * Copyright 2007 IBM Corporation. | |
5 | * Authors: | |
6 | * Jerone Young <[email protected]> | |
7 | * Christian Ehrhardt <[email protected]> | |
8 | * Hollis Blanchard <[email protected]> | |
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 | { | |
39 | target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS]; | |
40 | target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS]; | |
41 | CPUState *env; | |
42 | ppc4xx_mmio_t *mmio; | |
43 | qemu_irq *pic; | |
44 | qemu_irq *irqs; | |
45 | qemu_irq *pci_irqs; | |
46 | ||
47 | env = cpu_ppc_init("440EP"); | |
48 | if (!env && kvm_enabled()) { | |
49 | /* XXX Since qemu doesn't yet emulate 440, we just say it's a 405. | |
50 | * Since KVM doesn't use qemu's CPU emulation it seems to be working | |
51 | * OK. */ | |
52 | env = cpu_ppc_init("405"); | |
53 | } | |
54 | if (!env) { | |
55 | fprintf(stderr, "Unable to initialize CPU!\n"); | |
56 | exit(1); | |
57 | } | |
58 | ||
59 | ppc_dcr_init(env, NULL, NULL); | |
60 | ||
61 | /* interrupt controller */ | |
62 | irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); | |
63 | irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; | |
64 | irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; | |
65 | pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); | |
66 | ||
67 | /* SDRAM controller */ | |
68 | memset(ram_bases, 0, sizeof(ram_bases)); | |
69 | memset(ram_sizes, 0, sizeof(ram_sizes)); | |
70 | *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS, | |
71 | ram_bases, ram_sizes, | |
72 | ppc440ep_sdram_bank_sizes); | |
73 | /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */ | |
74 | ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases, | |
75 | ram_sizes, do_init); | |
76 | ||
77 | /* PCI */ | |
78 | pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4); | |
79 | pci_irqs[0] = pic[pci_irq_nrs[0]]; | |
80 | pci_irqs[1] = pic[pci_irq_nrs[1]]; | |
81 | pci_irqs[2] = pic[pci_irq_nrs[2]]; | |
82 | pci_irqs[3] = pic[pci_irq_nrs[3]]; | |
83 | *pcip = ppc4xx_pci_init(env, pci_irqs, | |
84 | PPC440EP_PCI_CONFIG, | |
85 | PPC440EP_PCI_INTACK, | |
86 | PPC440EP_PCI_SPECIAL, | |
87 | PPC440EP_PCI_REGS); | |
88 | if (!*pcip) | |
89 | printf("couldn't create PCI controller!\n"); | |
90 | ||
91 | isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN); | |
92 | ||
93 | /* MMIO -- most "miscellaneous" devices live above 0xef600000. */ | |
94 | mmio = ppc4xx_mmio_init(env, 0xef600000); | |
95 | ||
96 | if (serial_hds[0]) | |
97 | ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]); | |
98 | ||
99 | if (serial_hds[1]) | |
100 | ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]); | |
101 | ||
102 | return env; | |
103 | } |