]> git.proxmox.com Git - mirror_qemu.git/blame - hw/alpha_dp264.c
Merge branch 'axp-system-7' of git://repo.or.cz/qemu/rth
[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
5 * variants because CLIPPER doesn't have an SMC669 SuperIO controler
6 * that we need to emulate as well.
7 */
8
9#include "hw.h"
10#include "elf.h"
11#include "loader.h"
12#include "boards.h"
13#include "alpha_sys.h"
14#include "sysemu.h"
15#include "mc146818rtc.h"
16#include "ide.h"
17
18#define MAX_IDE_BUS 2
19
20static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
21{
22 if (((addr >> 41) & 3) == 2) {
23 addr &= 0xffffffffffull;
24 }
25 return addr;
26}
27
28/* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
29 (0) The dev_irq_n lines into the cpu, which we totally ignore,
30 (1) The DRIR lines in the typhoon chipset,
31 (2) The "vector" aka mangled interrupt number reported by SRM PALcode,
32 (3) The interrupt number assigned by the kernel.
33 The following function is concerned with (1) only. */
34
35static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
36{
37 int slot = d->devfn >> 3;
38
39 assert(irq_num >= 0 && irq_num <= 3);
40
41 return (slot + 1) * 4 + irq_num;
42}
43
44static void clipper_init(ram_addr_t ram_size,
45 const char *boot_device,
46 const char *kernel_filename,
47 const char *kernel_cmdline,
48 const char *initrd_filename,
49 const char *cpu_model)
50{
51 CPUState *cpus[4];
52 PCIBus *pci_bus;
53 qemu_irq rtc_irq;
54 long size, i;
55 const char *palcode_filename;
56 uint64_t palcode_entry, palcode_low, palcode_high;
57 uint64_t kernel_entry, kernel_low, kernel_high;
58
59 /* Create up to 4 cpus. */
60 memset(cpus, 0, sizeof(cpus));
61 for (i = 0; i < smp_cpus; ++i) {
62 cpus[i] = cpu_init(cpu_model ? cpu_model : "ev67");
63 }
64
65 cpus[0]->trap_arg0 = ram_size;
66 cpus[0]->trap_arg1 = 0;
67 cpus[0]->trap_arg2 = smp_cpus;
68
69 /* Init the chipset. */
70 pci_bus = typhoon_init(ram_size, &rtc_irq, cpus, clipper_pci_map_irq);
71
72 rtc_init(1980, rtc_irq);
73 pit_init(0x40, 0);
74 isa_create_simple("i8042");
75
76 /* VGA setup. Don't bother loading the bios. */
77 alpha_pci_vga_setup(pci_bus);
78
79 /* Serial code setup. */
80 for (i = 0; i < MAX_SERIAL_PORTS; ++i) {
81 if (serial_hds[i]) {
82 serial_isa_init(i, serial_hds[i]);
83 }
84 }
85
86 /* Network setup. e1000 is good enough, failing Tulip support. */
87 for (i = 0; i < nb_nics; i++) {
88 pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
89 }
90
91 /* IDE disk setup. */
92 {
93 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
94 ide_drive_get(hd, MAX_IDE_BUS);
95
96 pci_cmd646_ide_init(pci_bus, hd, 0);
97 }
98
99 /* Load PALcode. Given that this is not "real" cpu palcode,
100 but one explicitly written for the emulation, we might as
101 well load it directly from and ELF image. */
102 palcode_filename = (bios_name ? bios_name : "palcode-clipper");
103 palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, palcode_filename);
104 if (palcode_filename == NULL) {
105 hw_error("no palcode provided\n");
106 exit(1);
107 }
108 size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,
109 NULL, &palcode_entry, &palcode_low, &palcode_high,
110 0, EM_ALPHA, 0);
111 if (size < 0) {
112 hw_error("could not load palcode '%s'\n", palcode_filename);
113 exit(1);
114 }
115
116 /* Start all cpus at the PALcode RESET entry point. */
117 for (i = 0; i < smp_cpus; ++i) {
118 cpus[i]->pal_mode = 1;
119 cpus[i]->pc = palcode_entry;
120 cpus[i]->palbr = palcode_entry;
121 }
122
123 /* Load a kernel. */
124 if (kernel_filename) {
125 uint64_t param_offset;
126
127 size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys,
128 NULL, &kernel_entry, &kernel_low, &kernel_high,
129 0, EM_ALPHA, 0);
130 if (size < 0) {
131 hw_error("could not load kernel '%s'\n", kernel_filename);
132 exit(1);
133 }
134
135 cpus[0]->trap_arg1 = kernel_entry;
136
137 param_offset = kernel_low - 0x6000;
138
139 if (kernel_cmdline) {
140 pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
141 }
142
143 if (initrd_filename) {
144 long initrd_base, initrd_size;
145
146 initrd_size = get_image_size(initrd_filename);
147 if (initrd_size < 0) {
148 hw_error("could not load initial ram disk '%s'\n",
149 initrd_filename);
150 exit(1);
151 }
152
153 /* Put the initrd image as high in memory as possible. */
154 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
155 load_image_targphys(initrd_filename, initrd_base,
156 ram_size - initrd_base);
157
158 stq_phys(param_offset + 0x100, initrd_base + 0xfffffc0000000000UL);
159 stq_phys(param_offset + 0x108, initrd_size);
160 }
161 }
162}
163
164static QEMUMachine clipper_machine = {
165 .name = "clipper",
166 .desc = "Alpha DP264/CLIPPER",
167 .init = clipper_init,
168 .max_cpus = 4,
169 .is_default = 1,
170};
171
172static void clipper_machine_init(void)
173{
174 qemu_register_machine(&clipper_machine);
175}
176
177machine_init(clipper_machine_init);