]> git.proxmox.com Git - mirror_qemu.git/blame - hw/alpha/dp264.c
hw: Move MC146818 device from hw/timer/ to hw/rtc/ subdirectory
[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"
80bb2ff7 12#include "elf.h"
83c9f4ca 13#include "hw/loader.h"
47b43a1f 14#include "alpha_sys.h"
c525436e 15#include "qemu/error-report.h"
9c17d615 16#include "sysemu/sysemu.h"
bcdb9064 17#include "hw/rtc/mc146818rtc.h"
83c9f4ca 18#include "hw/ide.h"
0d09e41a 19#include "hw/timer/i8254.h"
a4cb7739 20#include "hw/isa/superio.h"
f4564fc0 21#include "hw/dma/i8257.h"
f348b6d1 22#include "qemu/cutils.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 52 ram_addr_t ram_size = machine->ram_size;
3ef96221
MA
53 const char *kernel_filename = machine->kernel_filename;
54 const char *kernel_cmdline = machine->kernel_cmdline;
55 const char *initrd_filename = machine->initrd_filename;
ad601177 56 AlphaCPU *cpus[4];
80bb2ff7 57 PCIBus *pci_bus;
48a18b3c 58 ISABus *isa_bus;
80bb2ff7
RH
59 qemu_irq rtc_irq;
60 long size, i;
c18f8556 61 char *palcode_filename;
80bb2ff7
RH
62 uint64_t palcode_entry, palcode_low, palcode_high;
63 uint64_t kernel_entry, kernel_low, kernel_high;
33decbd2 64 unsigned int smp_cpus = machine->smp.cpus;
80bb2ff7
RH
65
66 /* Create up to 4 cpus. */
67 memset(cpus, 0, sizeof(cpus));
68 for (i = 0; i < smp_cpus; ++i) {
fb92da84 69 cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
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 80 /* Since we have an SRM-compatible PALcode, use the SRM epoch. */
6c646a11 81 mc146818_rtc_init(isa_bus, 1900, rtc_irq);
e605e969 82
acf695ec 83 i8254_pit_init(isa_bus, 0x40, 0, NULL);
80bb2ff7
RH
84
85 /* VGA setup. Don't bother loading the bios. */
606f90cc 86 pci_vga_init(pci_bus);
80bb2ff7 87
80bb2ff7
RH
88 /* Network setup. e1000 is good enough, failing Tulip support. */
89 for (i = 0; i < nb_nics; i++) {
29b358f9 90 pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL);
80bb2ff7
RH
91 }
92
f4564fc0
PMD
93 /* 2 82C37 (dma) */
94 isa_create_simple(isa_bus, "i82374");
95
a4cb7739
PMD
96 /* Super I/O */
97 isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO);
98
80bb2ff7
RH
99 /* IDE disk setup. */
100 {
101 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
d8f94e1b 102 ide_drive_get(hd, ARRAY_SIZE(hd));
80bb2ff7
RH
103
104 pci_cmd646_ide_init(pci_bus, hd, 0);
105 }
106
107 /* Load PALcode. Given that this is not "real" cpu palcode,
108 but one explicitly written for the emulation, we might as
109 well load it directly from and ELF image. */
c18f8556
SZ
110 palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
111 bios_name ? bios_name : "palcode-clipper");
80bb2ff7 112 if (palcode_filename == NULL) {
c525436e 113 error_report("no palcode provided");
80bb2ff7
RH
114 exit(1);
115 }
4366e1db 116 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
80bb2ff7 117 NULL, &palcode_entry, &palcode_low, &palcode_high,
7ef295ea 118 0, EM_ALPHA, 0, 0);
80bb2ff7 119 if (size < 0) {
c525436e 120 error_report("could not load palcode '%s'", palcode_filename);
80bb2ff7
RH
121 exit(1);
122 }
c18f8556 123 g_free(palcode_filename);
80bb2ff7
RH
124
125 /* Start all cpus at the PALcode RESET entry point. */
126 for (i = 0; i < smp_cpus; ++i) {
ad601177
AF
127 cpus[i]->env.pc = palcode_entry;
128 cpus[i]->env.palbr = palcode_entry;
80bb2ff7
RH
129 }
130
131 /* Load a kernel. */
132 if (kernel_filename) {
133 uint64_t param_offset;
134
4366e1db 135 size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
80bb2ff7 136 NULL, &kernel_entry, &kernel_low, &kernel_high,
7ef295ea 137 0, EM_ALPHA, 0, 0);
80bb2ff7 138 if (size < 0) {
c525436e 139 error_report("could not load kernel '%s'", kernel_filename);
80bb2ff7
RH
140 exit(1);
141 }
142
ad601177 143 cpus[0]->env.trap_arg1 = kernel_entry;
80bb2ff7
RH
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) {
f3839fda
LZ
152 long initrd_base;
153 int64_t initrd_size;
80bb2ff7
RH
154
155 initrd_size = get_image_size(initrd_filename);
156 if (initrd_size < 0) {
c525436e
MA
157 error_report("could not load initial ram disk '%s'",
158 initrd_filename);
80bb2ff7
RH
159 exit(1);
160 }
161
162 /* Put the initrd image as high in memory as possible. */
163 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
164 load_image_targphys(initrd_filename, initrd_base,
165 ram_size - initrd_base);
166
42874d3a
PM
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);
80bb2ff7
RH
173 }
174 }
175}
176
e264d29d 177static void clipper_machine_init(MachineClass *mc)
80bb2ff7 178{
e264d29d
EH
179 mc->desc = "Alpha DP264/CLIPPER";
180 mc->init = clipper_init;
2059839b 181 mc->block_default_type = IF_IDE;
e264d29d
EH
182 mc->max_cpus = 4;
183 mc->is_default = 1;
fb92da84 184 mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67");
80bb2ff7
RH
185}
186
e264d29d 187DEFINE_MACHINE("clipper", clipper_machine_init)