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