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