]> git.proxmox.com Git - mirror_qemu.git/blame - hw/alpha/dp264.c
hw: Replace global smp variables with MachineState for all remaining archs
[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
PB
10#include "qemu-common.h"
11#include "cpu.h"
83c9f4ca 12#include "hw/hw.h"
80bb2ff7 13#include "elf.h"
83c9f4ca
PB
14#include "hw/loader.h"
15#include "hw/boards.h"
47b43a1f 16#include "alpha_sys.h"
c525436e 17#include "qemu/error-report.h"
9c17d615 18#include "sysemu/sysemu.h"
0d09e41a 19#include "hw/timer/mc146818rtc.h"
83c9f4ca 20#include "hw/ide.h"
0d09e41a 21#include "hw/timer/i8254.h"
a4cb7739 22#include "hw/isa/superio.h"
f4564fc0 23#include "hw/dma/i8257.h"
f348b6d1 24#include "qemu/cutils.h"
80bb2ff7
RH
25
26#define MAX_IDE_BUS 2
27
28static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
29{
30 if (((addr >> 41) & 3) == 2) {
31 addr &= 0xffffffffffull;
32 }
33 return addr;
34}
35
36/* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
37 (0) The dev_irq_n lines into the cpu, which we totally ignore,
38 (1) The DRIR lines in the typhoon chipset,
39 (2) The "vector" aka mangled interrupt number reported by SRM PALcode,
40 (3) The interrupt number assigned by the kernel.
41 The following function is concerned with (1) only. */
42
43static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
44{
45 int slot = d->devfn >> 3;
46
47 assert(irq_num >= 0 && irq_num <= 3);
48
49 return (slot + 1) * 4 + irq_num;
50}
51
3ef96221 52static void clipper_init(MachineState *machine)
80bb2ff7 53{
3ef96221 54 ram_addr_t ram_size = machine->ram_size;
3ef96221
MA
55 const char *kernel_filename = machine->kernel_filename;
56 const char *kernel_cmdline = machine->kernel_cmdline;
57 const char *initrd_filename = machine->initrd_filename;
ad601177 58 AlphaCPU *cpus[4];
80bb2ff7 59 PCIBus *pci_bus;
48a18b3c 60 ISABus *isa_bus;
80bb2ff7
RH
61 qemu_irq rtc_irq;
62 long size, i;
c18f8556 63 char *palcode_filename;
80bb2ff7
RH
64 uint64_t palcode_entry, palcode_low, palcode_high;
65 uint64_t kernel_entry, kernel_low, kernel_high;
33decbd2 66 unsigned int smp_cpus = machine->smp.cpus;
80bb2ff7
RH
67
68 /* Create up to 4 cpus. */
69 memset(cpus, 0, sizeof(cpus));
70 for (i = 0; i < smp_cpus; ++i) {
fb92da84 71 cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
80bb2ff7
RH
72 }
73
ad601177
AF
74 cpus[0]->env.trap_arg0 = ram_size;
75 cpus[0]->env.trap_arg1 = 0;
76 cpus[0]->env.trap_arg2 = smp_cpus;
80bb2ff7
RH
77
78 /* Init the chipset. */
71baa303
HP
79 pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus,
80 clipper_pci_map_irq);
80bb2ff7 81
e605e969 82 /* Since we have an SRM-compatible PALcode, use the SRM epoch. */
6c646a11 83 mc146818_rtc_init(isa_bus, 1900, rtc_irq);
e605e969 84
acf695ec 85 i8254_pit_init(isa_bus, 0x40, 0, NULL);
80bb2ff7
RH
86
87 /* VGA setup. Don't bother loading the bios. */
606f90cc 88 pci_vga_init(pci_bus);
80bb2ff7 89
80bb2ff7
RH
90 /* Network setup. e1000 is good enough, failing Tulip support. */
91 for (i = 0; i < nb_nics; i++) {
29b358f9 92 pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL);
80bb2ff7
RH
93 }
94
f4564fc0
PMD
95 /* 2 82C37 (dma) */
96 isa_create_simple(isa_bus, "i82374");
97
a4cb7739
PMD
98 /* Super I/O */
99 isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO);
100
80bb2ff7
RH
101 /* IDE disk setup. */
102 {
103 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
d8f94e1b 104 ide_drive_get(hd, ARRAY_SIZE(hd));
80bb2ff7
RH
105
106 pci_cmd646_ide_init(pci_bus, hd, 0);
107 }
108
109 /* Load PALcode. Given that this is not "real" cpu palcode,
110 but one explicitly written for the emulation, we might as
111 well load it directly from and ELF image. */
c18f8556
SZ
112 palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
113 bios_name ? bios_name : "palcode-clipper");
80bb2ff7 114 if (palcode_filename == NULL) {
c525436e 115 error_report("no palcode provided");
80bb2ff7
RH
116 exit(1);
117 }
4366e1db 118 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
80bb2ff7 119 NULL, &palcode_entry, &palcode_low, &palcode_high,
7ef295ea 120 0, EM_ALPHA, 0, 0);
80bb2ff7 121 if (size < 0) {
c525436e 122 error_report("could not load palcode '%s'", palcode_filename);
80bb2ff7
RH
123 exit(1);
124 }
c18f8556 125 g_free(palcode_filename);
80bb2ff7
RH
126
127 /* Start all cpus at the PALcode RESET entry point. */
128 for (i = 0; i < smp_cpus; ++i) {
ad601177
AF
129 cpus[i]->env.pc = palcode_entry;
130 cpus[i]->env.palbr = palcode_entry;
80bb2ff7
RH
131 }
132
133 /* Load a kernel. */
134 if (kernel_filename) {
135 uint64_t param_offset;
136
4366e1db 137 size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
80bb2ff7 138 NULL, &kernel_entry, &kernel_low, &kernel_high,
7ef295ea 139 0, EM_ALPHA, 0, 0);
80bb2ff7 140 if (size < 0) {
c525436e 141 error_report("could not load kernel '%s'", kernel_filename);
80bb2ff7
RH
142 exit(1);
143 }
144
ad601177 145 cpus[0]->env.trap_arg1 = kernel_entry;
80bb2ff7
RH
146
147 param_offset = kernel_low - 0x6000;
148
149 if (kernel_cmdline) {
150 pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
151 }
152
153 if (initrd_filename) {
f3839fda
LZ
154 long initrd_base;
155 int64_t initrd_size;
80bb2ff7
RH
156
157 initrd_size = get_image_size(initrd_filename);
158 if (initrd_size < 0) {
c525436e
MA
159 error_report("could not load initial ram disk '%s'",
160 initrd_filename);
80bb2ff7
RH
161 exit(1);
162 }
163
164 /* Put the initrd image as high in memory as possible. */
165 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
166 load_image_targphys(initrd_filename, initrd_base,
167 ram_size - initrd_base);
168
42874d3a
PM
169 address_space_stq(&address_space_memory, param_offset + 0x100,
170 initrd_base + 0xfffffc0000000000ULL,
171 MEMTXATTRS_UNSPECIFIED,
172 NULL);
173 address_space_stq(&address_space_memory, param_offset + 0x108,
174 initrd_size, MEMTXATTRS_UNSPECIFIED, NULL);
80bb2ff7
RH
175 }
176 }
177}
178
e264d29d 179static void clipper_machine_init(MachineClass *mc)
80bb2ff7 180{
e264d29d
EH
181 mc->desc = "Alpha DP264/CLIPPER";
182 mc->init = clipper_init;
2059839b 183 mc->block_default_type = IF_IDE;
e264d29d
EH
184 mc->max_cpus = 4;
185 mc->is_default = 1;
fb92da84 186 mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67");
80bb2ff7
RH
187}
188
e264d29d 189DEFINE_MACHINE("clipper", clipper_machine_init)