qemu

Форк
0
/
dp264.c 
218 строк · 7.1 Кб
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 controller
6
 * that we need to emulate as well.
7
 */
8

9
#include "qemu/osdep.h"
10
#include "cpu.h"
11
#include "elf.h"
12
#include "hw/loader.h"
13
#include "alpha_sys.h"
14
#include "qemu/error-report.h"
15
#include "hw/rtc/mc146818rtc.h"
16
#include "hw/ide/pci.h"
17
#include "hw/isa/superio.h"
18
#include "net/net.h"
19
#include "qemu/cutils.h"
20
#include "qemu/datadir.h"
21

22
static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
23
{
24
    if (((addr >> 41) & 3) == 2) {
25
        addr &= 0xffffffffffull;
26
    }
27
    return addr;
28
}
29

30
/* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
31
    (0) The dev_irq_n lines into the cpu, which we totally ignore,
32
    (1) The DRIR lines in the typhoon chipset,
33
    (2) The "vector" aka mangled interrupt number reported by SRM PALcode,
34
    (3) The interrupt number assigned by the kernel.
35
   The following function is concerned with (1) only.  */
36

37
static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
38
{
39
    int slot = d->devfn >> 3;
40

41
    assert(irq_num >= 0 && irq_num <= 3);
42

43
    return (slot + 1) * 4 + irq_num;
44
}
45

46
static void clipper_init(MachineState *machine)
47
{
48
    ram_addr_t ram_size = machine->ram_size;
49
    const char *kernel_filename = machine->kernel_filename;
50
    const char *kernel_cmdline = machine->kernel_cmdline;
51
    const char *initrd_filename = machine->initrd_filename;
52
    MachineClass *mc = MACHINE_GET_CLASS(machine);
53
    AlphaCPU *cpus[4];
54
    PCIBus *pci_bus;
55
    PCIDevice *pci_dev;
56
    DeviceState *i82378_dev;
57
    ISABus *isa_bus;
58
    qemu_irq rtc_irq;
59
    qemu_irq isa_irq;
60
    long size, i;
61
    char *palcode_filename;
62
    uint64_t palcode_entry;
63
    uint64_t kernel_entry, kernel_low;
64
    unsigned int smp_cpus = machine->smp.cpus;
65

66
    /* Create up to 4 cpus.  */
67
    memset(cpus, 0, sizeof(cpus));
68
    for (i = 0; i < smp_cpus; ++i) {
69
        cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
70
    }
71

72
    /*
73
     * arg0 -> memory size
74
     * arg1 -> kernel entry point
75
     * arg2 -> config word
76
     *
77
     * Config word: bits 0-5 -> ncpus
78
     *              bit  6   -> nographics option (for HWRPB CTB)
79
     *
80
     * See init_hwrpb() in the PALcode.
81
     */
82
    cpus[0]->env.trap_arg0 = ram_size;
83
    cpus[0]->env.trap_arg1 = 0;
84
    cpus[0]->env.trap_arg2 = smp_cpus | (!machine->enable_graphics << 6);
85

86
    /*
87
     * Init the chipset.  Because we're using CLIPPER IRQ mappings,
88
     * the minimum PCI device IdSel is 1.
89
     */
90
    pci_bus = typhoon_init(machine->ram, &isa_irq, &rtc_irq, cpus,
91
                           clipper_pci_map_irq, PCI_DEVFN(1, 0));
92

93
    /*
94
     * Init the PCI -> ISA bridge.
95
     *
96
     * Technically, PCI-based Alphas shipped with one of three different
97
     * PCI-ISA bridges:
98
     *
99
     * - Intel i82378 SIO
100
     * - Cypress CY82c693UB
101
     * - ALI M1533
102
     *
103
     * (An Intel i82375 PCI-EISA bridge was also used on some models.)
104
     *
105
     * For simplicity, we model an i82378 here, even though it wouldn't
106
     * have been on any Tsunami/Typhoon systems; it's close enough, and
107
     * we don't want to deal with modelling the CY82c693UB (which has
108
     * incompatible edge/level control registers, plus other peripherals
109
     * like IDE and USB) or the M1533 (which also has IDE and USB).
110
     *
111
     * Importantly, we need to provide a PCI device node for it, otherwise
112
     * some operating systems won't notice there's an ISA bus to configure.
113
     */
114
    i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(7, 0), "i82378"));
115
    isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0"));
116

117
    /* Connect the ISA PIC to the Typhoon IRQ used for ISA interrupts. */
118
    qdev_connect_gpio_out(i82378_dev, 0, isa_irq);
119

120
    /* Since we have an SRM-compatible PALcode, use the SRM epoch.  */
121
    mc146818_rtc_init(isa_bus, 1900, rtc_irq);
122

123
    /* VGA setup.  Don't bother loading the bios.  */
124
    pci_vga_init(pci_bus);
125

126
    /* Network setup.  e1000 is good enough, failing Tulip support.  */
127
    pci_init_nic_devices(pci_bus, mc->default_nic);
128

129
    /* Super I/O */
130
    isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO);
131

132
    /* IDE disk setup.  */
133
    pci_dev = pci_create_simple(pci_bus, -1, "cmd646-ide");
134
    pci_ide_create_devs(pci_dev);
135

136
    /* Load PALcode.  Given that this is not "real" cpu palcode,
137
       but one explicitly written for the emulation, we might as
138
       well load it directly from and ELF image.  */
139
    palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
140
                                      machine->firmware ?: "palcode-clipper");
141
    if (palcode_filename == NULL) {
142
        error_report("no palcode provided");
143
        exit(1);
144
    }
145
    size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
146
                    NULL, &palcode_entry, NULL, NULL, NULL,
147
                    0, EM_ALPHA, 0, 0);
148
    if (size < 0) {
149
        error_report("could not load palcode '%s'", palcode_filename);
150
        exit(1);
151
    }
152
    g_free(palcode_filename);
153

154
    /* Start all cpus at the PALcode RESET entry point.  */
155
    for (i = 0; i < smp_cpus; ++i) {
156
        cpus[i]->env.pc = palcode_entry;
157
        cpus[i]->env.palbr = palcode_entry;
158
    }
159

160
    /* Load a kernel.  */
161
    if (kernel_filename) {
162
        uint64_t param_offset;
163

164
        size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
165
                        NULL, &kernel_entry, &kernel_low, NULL, NULL,
166
                        0, EM_ALPHA, 0, 0);
167
        if (size < 0) {
168
            error_report("could not load kernel '%s'", kernel_filename);
169
            exit(1);
170
        }
171

172
        cpus[0]->env.trap_arg1 = kernel_entry;
173

174
        param_offset = kernel_low - 0x6000;
175

176
        if (kernel_cmdline) {
177
            pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
178
        }
179

180
        if (initrd_filename) {
181
            long initrd_base;
182
            int64_t initrd_size;
183

184
            initrd_size = get_image_size(initrd_filename);
185
            if (initrd_size < 0) {
186
                error_report("could not load initial ram disk '%s'",
187
                             initrd_filename);
188
                exit(1);
189
            }
190

191
            /* Put the initrd image as high in memory as possible.  */
192
            initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
193
            load_image_targphys(initrd_filename, initrd_base,
194
                                ram_size - initrd_base);
195

196
            address_space_stq(&address_space_memory, param_offset + 0x100,
197
                              initrd_base + 0xfffffc0000000000ULL,
198
                              MEMTXATTRS_UNSPECIFIED,
199
                              NULL);
200
            address_space_stq(&address_space_memory, param_offset + 0x108,
201
                              initrd_size, MEMTXATTRS_UNSPECIFIED, NULL);
202
        }
203
    }
204
}
205

206
static void clipper_machine_init(MachineClass *mc)
207
{
208
    mc->desc = "Alpha DP264/CLIPPER";
209
    mc->init = clipper_init;
210
    mc->block_default_type = IF_IDE;
211
    mc->max_cpus = 4;
212
    mc->is_default = true;
213
    mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67");
214
    mc->default_ram_id = "ram";
215
    mc->default_nic = "e1000";
216
}
217

218
DEFINE_MACHINE("clipper", clipper_machine_init)
219

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.