]> Git Repo - qemu.git/blob - hw/alpha_dp264.c
scsi-disk: support DVD profile in GET CONFIGURATION
[qemu.git] / hw / alpha_dp264.c
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
20 static 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
35 static 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
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)
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 + 0xfffffc0000000000ULL);
159             stq_phys(param_offset + 0x108, initrd_size);
160         }
161     }
162 }
163
164 static 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
172 static void clipper_machine_init(void)
173 {
174     qemu_register_machine(&clipper_machine);
175 }
176
177 machine_init(clipper_machine_init);
This page took 0.041301 seconds and 4 git commands to generate.