1
2
3
4
5
6
7
8
9#include "qemu/osdep.h"
10#include "qemu-common.h"
11#include "cpu.h"
12#include "elf.h"
13#include "hw/loader.h"
14#include "alpha_sys.h"
15#include "qemu/error-report.h"
16#include "hw/rtc/mc146818rtc.h"
17#include "hw/ide/pci.h"
18#include "hw/isa/superio.h"
19#include "net/net.h"
20#include "qemu/cutils.h"
21#include "qemu/datadir.h"
22#include "net/net.h"
23
24#define MAX_IDE_BUS 2
25
26static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
27{
28 if (((addr >> 41) & 3) == 2) {
29 addr &= 0xffffffffffull;
30 }
31 return addr;
32}
33
34
35
36
37
38
39
40
41static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
42{
43 int slot = d->devfn >> 3;
44
45 assert(irq_num >= 0 && irq_num <= 3);
46
47 return (slot + 1) * 4 + irq_num;
48}
49
50static void clipper_init(MachineState *machine)
51{
52 ram_addr_t ram_size = machine->ram_size;
53 const char *kernel_filename = machine->kernel_filename;
54 const char *kernel_cmdline = machine->kernel_cmdline;
55 const char *initrd_filename = machine->initrd_filename;
56 AlphaCPU *cpus[4];
57 PCIBus *pci_bus;
58 PCIDevice *pci_dev;
59 DeviceState *i82378_dev;
60 ISABus *isa_bus;
61 qemu_irq rtc_irq;
62 qemu_irq isa_irq;
63 long size, i;
64 char *palcode_filename;
65 uint64_t palcode_entry;
66 uint64_t kernel_entry, kernel_low;
67 unsigned int smp_cpus = machine->smp.cpus;
68
69
70 memset(cpus, 0, sizeof(cpus));
71 for (i = 0; i < smp_cpus; ++i) {
72 cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
73 }
74
75
76
77
78
79
80
81
82
83
84
85 cpus[0]->env.trap_arg0 = ram_size;
86 cpus[0]->env.trap_arg1 = 0;
87 cpus[0]->env.trap_arg2 = smp_cpus | (!machine->enable_graphics << 6);
88
89
90
91
92
93 pci_bus = typhoon_init(machine->ram, &isa_irq, &rtc_irq, cpus,
94 clipper_pci_map_irq, PCI_DEVFN(1, 0));
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(7, 0), "i82378"));
118 isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0"));
119
120
121 qdev_connect_gpio_out(i82378_dev, 0, isa_irq);
122
123
124 mc146818_rtc_init(isa_bus, 1900, rtc_irq);
125
126
127 pci_vga_init(pci_bus);
128
129
130 for (i = 0; i < nb_nics; i++) {
131 pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL);
132 }
133
134
135 isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO);
136
137
138 pci_dev = pci_create_simple(pci_bus, -1, "cmd646-ide");
139 pci_ide_create_devs(pci_dev);
140
141
142
143
144 palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
145 machine->firmware ?: "palcode-clipper");
146 if (palcode_filename == NULL) {
147 error_report("no palcode provided");
148 exit(1);
149 }
150 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
151 NULL, &palcode_entry, NULL, NULL, NULL,
152 0, EM_ALPHA, 0, 0);
153 if (size < 0) {
154 error_report("could not load palcode '%s'", palcode_filename);
155 exit(1);
156 }
157 g_free(palcode_filename);
158
159
160 for (i = 0; i < smp_cpus; ++i) {
161 cpus[i]->env.pc = palcode_entry;
162 cpus[i]->env.palbr = palcode_entry;
163 }
164
165
166 if (kernel_filename) {
167 uint64_t param_offset;
168
169 size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
170 NULL, &kernel_entry, &kernel_low, NULL, NULL,
171 0, EM_ALPHA, 0, 0);
172 if (size < 0) {
173 error_report("could not load kernel '%s'", kernel_filename);
174 exit(1);
175 }
176
177 cpus[0]->env.trap_arg1 = kernel_entry;
178
179 param_offset = kernel_low - 0x6000;
180
181 if (kernel_cmdline) {
182 pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
183 }
184
185 if (initrd_filename) {
186 long initrd_base;
187 int64_t initrd_size;
188
189 initrd_size = get_image_size(initrd_filename);
190 if (initrd_size < 0) {
191 error_report("could not load initial ram disk '%s'",
192 initrd_filename);
193 exit(1);
194 }
195
196
197 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
198 load_image_targphys(initrd_filename, initrd_base,
199 ram_size - initrd_base);
200
201 address_space_stq(&address_space_memory, param_offset + 0x100,
202 initrd_base + 0xfffffc0000000000ULL,
203 MEMTXATTRS_UNSPECIFIED,
204 NULL);
205 address_space_stq(&address_space_memory, param_offset + 0x108,
206 initrd_size, MEMTXATTRS_UNSPECIFIED, NULL);
207 }
208 }
209}
210
211static void clipper_machine_init(MachineClass *mc)
212{
213 mc->desc = "Alpha DP264/CLIPPER";
214 mc->init = clipper_init;
215 mc->block_default_type = IF_IDE;
216 mc->max_cpus = 4;
217 mc->is_default = true;
218 mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67");
219 mc->default_ram_id = "ram";
220}
221
222DEFINE_MACHINE("clipper", clipper_machine_init)
223