1
2
3
4
5
6
7
8
9#include "qemu/osdep.h"
10#include "qemu-common.h"
11#include "cpu.h"
12#include "hw/hw.h"
13#include "elf.h"
14#include "hw/loader.h"
15#include "hw/boards.h"
16#include "alpha_sys.h"
17#include "qemu/error-report.h"
18#include "sysemu/sysemu.h"
19#include "hw/timer/mc146818rtc.h"
20#include "hw/ide.h"
21#include "hw/timer/i8254.h"
22#include "hw/isa/superio.h"
23#include "hw/dma/i8257.h"
24#include "qemu/cutils.h"
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
37
38
39
40
41
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
52static void clipper_init(MachineState *machine)
53{
54 ram_addr_t ram_size = machine->ram_size;
55 const char *kernel_filename = machine->kernel_filename;
56 const char *kernel_cmdline = machine->kernel_cmdline;
57 const char *initrd_filename = machine->initrd_filename;
58 AlphaCPU *cpus[4];
59 PCIBus *pci_bus;
60 ISABus *isa_bus;
61 qemu_irq rtc_irq;
62 long size, i;
63 char *palcode_filename;
64 uint64_t palcode_entry, palcode_low, palcode_high;
65 uint64_t kernel_entry, kernel_low, kernel_high;
66 unsigned int smp_cpus = machine->smp.cpus;
67
68
69 memset(cpus, 0, sizeof(cpus));
70 for (i = 0; i < smp_cpus; ++i) {
71 cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
72 }
73
74 cpus[0]->env.trap_arg0 = ram_size;
75 cpus[0]->env.trap_arg1 = 0;
76 cpus[0]->env.trap_arg2 = smp_cpus;
77
78
79 pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus,
80 clipper_pci_map_irq);
81
82
83 mc146818_rtc_init(isa_bus, 1900, rtc_irq);
84
85 i8254_pit_init(isa_bus, 0x40, 0, NULL);
86
87
88 pci_vga_init(pci_bus);
89
90
91 for (i = 0; i < nb_nics; i++) {
92 pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL);
93 }
94
95
96 isa_create_simple(isa_bus, "i82374");
97
98
99 isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO);
100
101
102 {
103 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
104 ide_drive_get(hd, ARRAY_SIZE(hd));
105
106 pci_cmd646_ide_init(pci_bus, hd, 0);
107 }
108
109
110
111
112 palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
113 bios_name ? bios_name : "palcode-clipper");
114 if (palcode_filename == NULL) {
115 error_report("no palcode provided");
116 exit(1);
117 }
118 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
119 NULL, &palcode_entry, &palcode_low, &palcode_high,
120 0, EM_ALPHA, 0, 0);
121 if (size < 0) {
122 error_report("could not load palcode '%s'", palcode_filename);
123 exit(1);
124 }
125 g_free(palcode_filename);
126
127
128 for (i = 0; i < smp_cpus; ++i) {
129 cpus[i]->env.pc = palcode_entry;
130 cpus[i]->env.palbr = palcode_entry;
131 }
132
133
134 if (kernel_filename) {
135 uint64_t param_offset;
136
137 size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
138 NULL, &kernel_entry, &kernel_low, &kernel_high,
139 0, EM_ALPHA, 0, 0);
140 if (size < 0) {
141 error_report("could not load kernel '%s'", kernel_filename);
142 exit(1);
143 }
144
145 cpus[0]->env.trap_arg1 = kernel_entry;
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) {
154 long initrd_base;
155 int64_t initrd_size;
156
157 initrd_size = get_image_size(initrd_filename);
158 if (initrd_size < 0) {
159 error_report("could not load initial ram disk '%s'",
160 initrd_filename);
161 exit(1);
162 }
163
164
165 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
166 load_image_targphys(initrd_filename, initrd_base,
167 ram_size - initrd_base);
168
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);
175 }
176 }
177}
178
179static void clipper_machine_init(MachineClass *mc)
180{
181 mc->desc = "Alpha DP264/CLIPPER";
182 mc->init = clipper_init;
183 mc->block_default_type = IF_IDE;
184 mc->max_cpus = 4;
185 mc->is_default = 1;
186 mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67");
187}
188
189DEFINE_MACHINE("clipper", clipper_machine_init)
190