Statistics
| Branch: | Revision:

root / hw / alpha_dp264.c @ c48c6522

History | View | Annotate | Download (5.3 kB)

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