]> git.proxmox.com Git - mirror_qemu.git/blame - hw/alpha/dp264.c
Replaced get_tick_per_sec() by NANOSECONDS_PER_SECOND
[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
PB
21#include "hw/timer/i8254.h"
22#include "hw/char/serial.h"
80bb2ff7
RH
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/* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
35 (0) The dev_irq_n lines into the cpu, which we totally ignore,
36 (1) The DRIR lines in the typhoon chipset,
37 (2) The "vector" aka mangled interrupt number reported by SRM PALcode,
38 (3) The interrupt number assigned by the kernel.
39 The following function is concerned with (1) only. */
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
3ef96221 50static void clipper_init(MachineState *machine)
80bb2ff7 51{
3ef96221
MA
52 ram_addr_t ram_size = machine->ram_size;
53 const char *cpu_model = machine->cpu_model;
54 const char *kernel_filename = machine->kernel_filename;
55 const char *kernel_cmdline = machine->kernel_cmdline;
56 const char *initrd_filename = machine->initrd_filename;
ad601177 57 AlphaCPU *cpus[4];
80bb2ff7 58 PCIBus *pci_bus;
48a18b3c 59 ISABus *isa_bus;
80bb2ff7
RH
60 qemu_irq rtc_irq;
61 long size, i;
c18f8556 62 char *palcode_filename;
80bb2ff7
RH
63 uint64_t palcode_entry, palcode_low, palcode_high;
64 uint64_t kernel_entry, kernel_low, kernel_high;
65
66 /* Create up to 4 cpus. */
67 memset(cpus, 0, sizeof(cpus));
68 for (i = 0; i < smp_cpus; ++i) {
ad601177 69 cpus[i] = cpu_alpha_init(cpu_model ? cpu_model : "ev67");
80bb2ff7
RH
70 }
71
ad601177
AF
72 cpus[0]->env.trap_arg0 = ram_size;
73 cpus[0]->env.trap_arg1 = 0;
74 cpus[0]->env.trap_arg2 = smp_cpus;
80bb2ff7
RH
75
76 /* Init the chipset. */
71baa303
HP
77 pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus,
78 clipper_pci_map_irq);
80bb2ff7 79
e605e969
RH
80 /* Since we have an SRM-compatible PALcode, use the SRM epoch. */
81 rtc_init(isa_bus, 1900, rtc_irq);
82
319ba9f5 83 pit_init(isa_bus, 0x40, 0, NULL);
48a18b3c 84 isa_create_simple(isa_bus, "i8042");
80bb2ff7
RH
85
86 /* VGA setup. Don't bother loading the bios. */
606f90cc 87 pci_vga_init(pci_bus);
80bb2ff7
RH
88
89 /* Serial code setup. */
b6607a1a 90 serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS);
80bb2ff7
RH
91
92 /* Network setup. e1000 is good enough, failing Tulip support. */
93 for (i = 0; i < nb_nics; i++) {
29b358f9 94 pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL);
80bb2ff7
RH
95 }
96
97 /* IDE disk setup. */
98 {
99 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
d8f94e1b 100 ide_drive_get(hd, ARRAY_SIZE(hd));
80bb2ff7
RH
101
102 pci_cmd646_ide_init(pci_bus, hd, 0);
103 }
104
105 /* Load PALcode. Given that this is not "real" cpu palcode,
106 but one explicitly written for the emulation, we might as
107 well load it directly from and ELF image. */
c18f8556
SZ
108 palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
109 bios_name ? bios_name : "palcode-clipper");
80bb2ff7 110 if (palcode_filename == NULL) {
c525436e 111 error_report("no palcode provided");
80bb2ff7
RH
112 exit(1);
113 }
114 size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,
115 NULL, &palcode_entry, &palcode_low, &palcode_high,
7ef295ea 116 0, EM_ALPHA, 0, 0);
80bb2ff7 117 if (size < 0) {
c525436e 118 error_report("could not load palcode '%s'", palcode_filename);
80bb2ff7
RH
119 exit(1);
120 }
c18f8556 121 g_free(palcode_filename);
80bb2ff7
RH
122
123 /* Start all cpus at the PALcode RESET entry point. */
124 for (i = 0; i < smp_cpus; ++i) {
ad601177
AF
125 cpus[i]->env.pal_mode = 1;
126 cpus[i]->env.pc = palcode_entry;
127 cpus[i]->env.palbr = palcode_entry;
80bb2ff7
RH
128 }
129
130 /* Load a kernel. */
131 if (kernel_filename) {
132 uint64_t param_offset;
133
134 size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys,
135 NULL, &kernel_entry, &kernel_low, &kernel_high,
7ef295ea 136 0, EM_ALPHA, 0, 0);
80bb2ff7 137 if (size < 0) {
c525436e 138 error_report("could not load kernel '%s'", kernel_filename);
80bb2ff7
RH
139 exit(1);
140 }
141
ad601177 142 cpus[0]->env.trap_arg1 = kernel_entry;
80bb2ff7
RH
143
144 param_offset = kernel_low - 0x6000;
145
146 if (kernel_cmdline) {
147 pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
148 }
149
150 if (initrd_filename) {
151 long initrd_base, initrd_size;
152
153 initrd_size = get_image_size(initrd_filename);
154 if (initrd_size < 0) {
c525436e
MA
155 error_report("could not load initial ram disk '%s'",
156 initrd_filename);
80bb2ff7
RH
157 exit(1);
158 }
159
160 /* Put the initrd image as high in memory as possible. */
161 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
162 load_image_targphys(initrd_filename, initrd_base,
163 ram_size - initrd_base);
164
42874d3a
PM
165 address_space_stq(&address_space_memory, param_offset + 0x100,
166 initrd_base + 0xfffffc0000000000ULL,
167 MEMTXATTRS_UNSPECIFIED,
168 NULL);
169 address_space_stq(&address_space_memory, param_offset + 0x108,
170 initrd_size, MEMTXATTRS_UNSPECIFIED, NULL);
80bb2ff7
RH
171 }
172 }
173}
174
e264d29d 175static void clipper_machine_init(MachineClass *mc)
80bb2ff7 176{
e264d29d
EH
177 mc->desc = "Alpha DP264/CLIPPER";
178 mc->init = clipper_init;
179 mc->max_cpus = 4;
180 mc->is_default = 1;
80bb2ff7
RH
181}
182
e264d29d 183DEFINE_MACHINE("clipper", clipper_machine_init)