]> git.proxmox.com Git - mirror_qemu.git/blame - hw/alpha/dp264.c
hw/alpha/dp264: use pci_init_nic_devices()
[mirror_qemu.git] / hw / alpha / dp264.c
CommitLineData
80bb2ff7
RH
1/*
2 * QEMU Alpha DP264/CLIPPER hardware system emulator.
3 *
4 * Choose CLIPPER IRQ mappings over, say, DP264, MONET, or WEBBRICK
66a0a2cb 5 * variants because CLIPPER doesn't have an SMC669 SuperIO controller
80bb2ff7
RH
6 * that we need to emulate as well.
7 */
8
e2e5e114 9#include "qemu/osdep.h"
4771d756 10#include "cpu.h"
80bb2ff7 11#include "elf.h"
83c9f4ca 12#include "hw/loader.h"
47b43a1f 13#include "alpha_sys.h"
c525436e 14#include "qemu/error-report.h"
bcdb9064 15#include "hw/rtc/mc146818rtc.h"
25297910 16#include "hw/ide/pci.h"
a4cb7739 17#include "hw/isa/superio.h"
852c27e2 18#include "net/net.h"
f348b6d1 19#include "qemu/cutils.h"
2c65db5e 20#include "qemu/datadir.h"
80bb2ff7 21
80bb2ff7
RH
22static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
23{
24 if (((addr >> 41) & 3) == 2) {
25 addr &= 0xffffffffffull;
26 }
27 return addr;
28}
29
30/* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
31 (0) The dev_irq_n lines into the cpu, which we totally ignore,
32 (1) The DRIR lines in the typhoon chipset,
33 (2) The "vector" aka mangled interrupt number reported by SRM PALcode,
34 (3) The interrupt number assigned by the kernel.
35 The following function is concerned with (1) only. */
36
37static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
38{
39 int slot = d->devfn >> 3;
40
41 assert(irq_num >= 0 && irq_num <= 3);
42
43 return (slot + 1) * 4 + irq_num;
44}
45
3ef96221 46static void clipper_init(MachineState *machine)
80bb2ff7 47{
3ef96221 48 ram_addr_t ram_size = machine->ram_size;
3ef96221
MA
49 const char *kernel_filename = machine->kernel_filename;
50 const char *kernel_cmdline = machine->kernel_cmdline;
51 const char *initrd_filename = machine->initrd_filename;
cdd684b8 52 MachineClass *mc = MACHINE_GET_CLASS(machine);
ad601177 53 AlphaCPU *cpus[4];
80bb2ff7 54 PCIBus *pci_bus;
be1765f3 55 PCIDevice *pci_dev;
5ec4f1d3 56 DeviceState *i82378_dev;
48a18b3c 57 ISABus *isa_bus;
80bb2ff7 58 qemu_irq rtc_irq;
5ec4f1d3 59 qemu_irq isa_irq;
80bb2ff7 60 long size, i;
c18f8556 61 char *palcode_filename;
617160c9
BZ
62 uint64_t palcode_entry;
63 uint64_t kernel_entry, kernel_low;
33decbd2 64 unsigned int smp_cpus = machine->smp.cpus;
80bb2ff7
RH
65
66 /* Create up to 4 cpus. */
67 memset(cpus, 0, sizeof(cpus));
68 for (i = 0; i < smp_cpus; ++i) {
fb92da84 69 cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
80bb2ff7
RH
70 }
71
387a1dcb
JT
72 /*
73 * arg0 -> memory size
74 * arg1 -> kernel entry point
75 * arg2 -> config word
76 *
77 * Config word: bits 0-5 -> ncpus
78 * bit 6 -> nographics option (for HWRPB CTB)
79 *
80 * See init_hwrpb() in the PALcode.
81 */
ad601177
AF
82 cpus[0]->env.trap_arg0 = ram_size;
83 cpus[0]->env.trap_arg1 = 0;
387a1dcb 84 cpus[0]->env.trap_arg2 = smp_cpus | (!machine->enable_graphics << 6);
80bb2ff7 85
3a8233dc
JT
86 /*
87 * Init the chipset. Because we're using CLIPPER IRQ mappings,
88 * the minimum PCI device IdSel is 1.
89 */
5ec4f1d3 90 pci_bus = typhoon_init(machine->ram, &isa_irq, &rtc_irq, cpus,
3a8233dc 91 clipper_pci_map_irq, PCI_DEVFN(1, 0));
80bb2ff7 92
5ec4f1d3
JT
93 /*
94 * Init the PCI -> ISA bridge.
95 *
96 * Technically, PCI-based Alphas shipped with one of three different
97 * PCI-ISA bridges:
98 *
99 * - Intel i82378 SIO
100 * - Cypress CY82c693UB
101 * - ALI M1533
102 *
103 * (An Intel i82375 PCI-EISA bridge was also used on some models.)
104 *
105 * For simplicity, we model an i82378 here, even though it wouldn't
106 * have been on any Tsunami/Typhoon systems; it's close enough, and
107 * we don't want to deal with modelling the CY82c693UB (which has
108 * incompatible edge/level control registers, plus other peripherals
109 * like IDE and USB) or the M1533 (which also has IDE and USB).
110 *
111 * Importantly, we need to provide a PCI device node for it, otherwise
112 * some operating systems won't notice there's an ISA bus to configure.
113 */
114 i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(7, 0), "i82378"));
115 isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0"));
116
117 /* Connect the ISA PIC to the Typhoon IRQ used for ISA interrupts. */
118 qdev_connect_gpio_out(i82378_dev, 0, isa_irq);
119
e605e969 120 /* Since we have an SRM-compatible PALcode, use the SRM epoch. */
6c646a11 121 mc146818_rtc_init(isa_bus, 1900, rtc_irq);
e605e969 122
80bb2ff7 123 /* VGA setup. Don't bother loading the bios. */
606f90cc 124 pci_vga_init(pci_bus);
80bb2ff7 125
80bb2ff7 126 /* Network setup. e1000 is good enough, failing Tulip support. */
861bbc88 127 pci_init_nic_devices(pci_bus, mc->default_nic);
80bb2ff7 128
a4cb7739
PMD
129 /* Super I/O */
130 isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO);
131
80bb2ff7 132 /* IDE disk setup. */
be1765f3
BZ
133 pci_dev = pci_create_simple(pci_bus, -1, "cmd646-ide");
134 pci_ide_create_devs(pci_dev);
80bb2ff7
RH
135
136 /* Load PALcode. Given that this is not "real" cpu palcode,
137 but one explicitly written for the emulation, we might as
138 well load it directly from and ELF image. */
c18f8556 139 palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
2c4a83eb 140 machine->firmware ?: "palcode-clipper");
80bb2ff7 141 if (palcode_filename == NULL) {
c525436e 142 error_report("no palcode provided");
80bb2ff7
RH
143 exit(1);
144 }
4366e1db 145 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
617160c9 146 NULL, &palcode_entry, NULL, NULL, NULL,
7ef295ea 147 0, EM_ALPHA, 0, 0);
80bb2ff7 148 if (size < 0) {
c525436e 149 error_report("could not load palcode '%s'", palcode_filename);
80bb2ff7
RH
150 exit(1);
151 }
c18f8556 152 g_free(palcode_filename);
80bb2ff7
RH
153
154 /* Start all cpus at the PALcode RESET entry point. */
155 for (i = 0; i < smp_cpus; ++i) {
ad601177
AF
156 cpus[i]->env.pc = palcode_entry;
157 cpus[i]->env.palbr = palcode_entry;
80bb2ff7
RH
158 }
159
160 /* Load a kernel. */
161 if (kernel_filename) {
162 uint64_t param_offset;
163
4366e1db 164 size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
617160c9 165 NULL, &kernel_entry, &kernel_low, NULL, NULL,
7ef295ea 166 0, EM_ALPHA, 0, 0);
80bb2ff7 167 if (size < 0) {
c525436e 168 error_report("could not load kernel '%s'", kernel_filename);
80bb2ff7
RH
169 exit(1);
170 }
171
ad601177 172 cpus[0]->env.trap_arg1 = kernel_entry;
80bb2ff7
RH
173
174 param_offset = kernel_low - 0x6000;
175
176 if (kernel_cmdline) {
177 pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
178 }
179
180 if (initrd_filename) {
f3839fda
LZ
181 long initrd_base;
182 int64_t initrd_size;
80bb2ff7
RH
183
184 initrd_size = get_image_size(initrd_filename);
185 if (initrd_size < 0) {
c525436e
MA
186 error_report("could not load initial ram disk '%s'",
187 initrd_filename);
80bb2ff7
RH
188 exit(1);
189 }
190
191 /* Put the initrd image as high in memory as possible. */
192 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
193 load_image_targphys(initrd_filename, initrd_base,
194 ram_size - initrd_base);
195
42874d3a
PM
196 address_space_stq(&address_space_memory, param_offset + 0x100,
197 initrd_base + 0xfffffc0000000000ULL,
198 MEMTXATTRS_UNSPECIFIED,
199 NULL);
200 address_space_stq(&address_space_memory, param_offset + 0x108,
201 initrd_size, MEMTXATTRS_UNSPECIFIED, NULL);
80bb2ff7
RH
202 }
203 }
204}
205
e264d29d 206static void clipper_machine_init(MachineClass *mc)
80bb2ff7 207{
e264d29d
EH
208 mc->desc = "Alpha DP264/CLIPPER";
209 mc->init = clipper_init;
2059839b 210 mc->block_default_type = IF_IDE;
e264d29d 211 mc->max_cpus = 4;
ea0ac7f6 212 mc->is_default = true;
fb92da84 213 mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67");
b844d822 214 mc->default_ram_id = "ram";
cdd684b8 215 mc->default_nic = "e1000";
80bb2ff7
RH
216}
217
e264d29d 218DEFINE_MACHINE("clipper", clipper_machine_init)