]> git.proxmox.com Git - mirror_qemu.git/blame - hw/alpha/dp264.c
change get_image_size return type to int64_t
[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;
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 }
117 size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,
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
136 size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys,
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)