Statistics
| Branch: | Revision:

root / hw / alpha_dp264.c @ 83e94fb8

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