]>
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" | |
802670e6 | 15 | #include "pc.h" |
75dd595b AJ |
16 | #include "isa.h" |
17 | #include "ppc.h" | |
18 | #include "ppc4xx.h" | |
19 | #include "ppc440.h" | |
20 | #include "ppc405.h" | |
21 | #include "sysemu.h" | |
22 | #include "kvm.h" | |
23 | ||
24 | #define PPC440EP_PCI_CONFIG 0xeec00000 | |
25 | #define PPC440EP_PCI_INTACK 0xeed00000 | |
26 | #define PPC440EP_PCI_SPECIAL 0xeed00000 | |
27 | #define PPC440EP_PCI_REGS 0xef400000 | |
28 | #define PPC440EP_PCI_IO 0xe8000000 | |
29 | #define PPC440EP_PCI_IOLEN 0x00010000 | |
30 | ||
31 | #define PPC440EP_SDRAM_NR_BANKS 4 | |
32 | ||
33 | static const unsigned int ppc440ep_sdram_bank_sizes[] = { | |
34 | 256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0 | |
35 | }; | |
36 | ||
c227f099 | 37 | CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, |
727170b6 BS |
38 | const unsigned int pci_irq_nrs[4], int do_init, |
39 | const char *cpu_model) | |
75dd595b | 40 | { |
c227f099 AL |
41 | target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS]; |
42 | target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS]; | |
75dd595b | 43 | CPUState *env; |
75dd595b AJ |
44 | qemu_irq *pic; |
45 | qemu_irq *irqs; | |
46 | qemu_irq *pci_irqs; | |
47 | ||
727170b6 BS |
48 | if (cpu_model == NULL) |
49 | cpu_model = "405"; // XXX: should be 440EP | |
50 | env = cpu_init(cpu_model); | |
75dd595b AJ |
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 | ||
968d683c | 88 | isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN); |
75dd595b | 89 | |
802670e6 BS |
90 | if (serial_hds[0] != NULL) { |
91 | serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE, | |
2d48377a | 92 | serial_hds[0], 1, 1); |
802670e6 BS |
93 | } |
94 | if (serial_hds[1] != NULL) { | |
95 | serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE, | |
2d48377a | 96 | serial_hds[1], 1, 1); |
802670e6 | 97 | } |
75dd595b AJ |
98 | |
99 | return env; | |
100 | } |