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