2 * QEMU Alpha DP264/CLIPPER hardware system emulator.
4 * Choose CLIPPER IRQ mappings over, say, DP264, MONET, or WEBBRICK
5 * variants because CLIPPER doesn't have an SMC669 SuperIO controller
6 * that we need to emulate as well.
13 #include "alpha_sys.h"
15 #include "mc146818rtc.h"
20 static uint64_t cpu_alpha_superpage_to_phys(void *opaque
, uint64_t addr
)
22 if (((addr
>> 41) & 3) == 2) {
23 addr
&= 0xffffffffffull
;
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. */
35 static int clipper_pci_map_irq(PCIDevice
*d
, int irq_num
)
37 int slot
= d
->devfn
>> 3;
39 assert(irq_num
>= 0 && irq_num
<= 3);
41 return (slot
+ 1) * 4 + irq_num
;
44 static 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
)
55 const char *palcode_filename
;
56 uint64_t palcode_entry
, palcode_low
, palcode_high
;
57 uint64_t kernel_entry
, kernel_low
, kernel_high
;
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");
65 cpus
[0]->trap_arg0
= ram_size
;
66 cpus
[0]->trap_arg1
= 0;
67 cpus
[0]->trap_arg2
= smp_cpus
;
69 /* Init the chipset. */
70 pci_bus
= typhoon_init(ram_size
, &rtc_irq
, cpus
, clipper_pci_map_irq
);
72 rtc_init(1980, rtc_irq
);
74 isa_create_simple("i8042");
76 /* VGA setup. Don't bother loading the bios. */
77 alpha_pci_vga_setup(pci_bus
);
79 /* Serial code setup. */
80 for (i
= 0; i
< MAX_SERIAL_PORTS
; ++i
) {
82 serial_isa_init(i
, serial_hds
[i
]);
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
);
93 DriveInfo
*hd
[MAX_IDE_BUS
* MAX_IDE_DEVS
];
94 ide_drive_get(hd
, MAX_IDE_BUS
);
96 pci_cmd646_ide_init(pci_bus
, hd
, 0);
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");
108 size
= load_elf(palcode_filename
, cpu_alpha_superpage_to_phys
,
109 NULL
, &palcode_entry
, &palcode_low
, &palcode_high
,
112 hw_error("could not load palcode '%s'\n", palcode_filename
);
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
;
124 if (kernel_filename
) {
125 uint64_t param_offset
;
127 size
= load_elf(kernel_filename
, cpu_alpha_superpage_to_phys
,
128 NULL
, &kernel_entry
, &kernel_low
, &kernel_high
,
131 hw_error("could not load kernel '%s'\n", kernel_filename
);
135 cpus
[0]->trap_arg1
= kernel_entry
;
137 param_offset
= kernel_low
- 0x6000;
139 if (kernel_cmdline
) {
140 pstrcpy_targphys("cmdline", param_offset
, 0x100, kernel_cmdline
);
143 if (initrd_filename
) {
144 long initrd_base
, initrd_size
;
146 initrd_size
= get_image_size(initrd_filename
);
147 if (initrd_size
< 0) {
148 hw_error("could not load initial ram disk '%s'\n",
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
);
158 stq_phys(param_offset
+ 0x100, initrd_base
+ 0xfffffc0000000000ULL
);
159 stq_phys(param_offset
+ 0x108, initrd_size
);
164 static QEMUMachine clipper_machine
= {
166 .desc
= "Alpha DP264/CLIPPER",
167 .init
= clipper_init
,
172 static void clipper_machine_init(void)
174 qemu_register_machine(&clipper_machine
);
177 machine_init(clipper_machine_init
);