Blame view

hw/sun4m.c 53.5 KB
1
/*
2
 * QEMU Sun4m & Sun4d & Sun4c System Emulator
3
 *
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5
 *
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
pbrook authored
24
25
26
27
28
29
30
31
32
#include "hw.h"
#include "qemu-timer.h"
#include "sun4m.h"
#include "nvram.h"
#include "sparc32_dma.h"
#include "fdc.h"
#include "sysemu.h"
#include "net.h"
#include "boards.h"
33
#include "firmware_abi.h"
34
#include "scsi.h"
blueswir1 authored
35
36
#include "pc.h"
#include "isa.h"
37
#include "fw_cfg.h"
38
#include "escc.h"
39
40
//#define DEBUG_IRQ
41
42
43
44
45
/*
 * Sun4m architecture was used in the following machines:
 *
 * SPARCserver 6xxMP/xx
blueswir1 authored
46
47
 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15),
 * SPARCclassic X (4/10)
48
49
50
51
52
53
54
 * SPARCstation LX/ZX (4/30)
 * SPARCstation Voyager
 * SPARCstation 10/xx, SPARCserver 10/xx
 * SPARCstation 5, SPARCserver 5
 * SPARCstation 20/xx, SPARCserver 20
 * SPARCstation 4
 *
55
56
57
58
59
 * Sun4d architecture was used in the following machines:
 *
 * SPARCcenter 2000
 * SPARCserver 1000
 *
60
61
62
63
64
65
66
 * Sun4c architecture was used in the following machines:
 * SPARCstation 1/1+, SPARCserver 1/1+
 * SPARCstation SLC
 * SPARCstation IPC
 * SPARCstation ELC
 * SPARCstation IPX
 *
67
68
69
 * See for example: http://www.sunhelp.org/faq/sunref1.html
 */
70
71
72
73
74
75
76
#ifdef DEBUG_IRQ
#define DPRINTF(fmt, args...)                           \
    do { printf("CPUIRQ: " fmt , ##args); } while (0)
#else
#define DPRINTF(fmt, args...)
#endif
77
#define KERNEL_LOAD_ADDR     0x00004000
bellard authored
78
#define CMDLINE_ADDR         0x007ff000
bellard authored
79
#define INITRD_LOAD_ADDR     0x00800000
80
#define PROM_SIZE_MAX        (1024 * 1024)
blueswir1 authored
81
#define PROM_VADDR           0xffd00000
blueswir1 authored
82
#define PROM_FILENAME        "openbios-sparc32"
83
#define CFG_ADDR             0xd00000510ULL
84
#define FW_CFG_SUN4M_DEPTH   (FW_CFG_ARCH_LOCAL + 0x00)
85
86
87
88
// Control plane, 8-bit and 24-bit planes
#define TCX_SIZE             (9 * 1024 * 1024)
89
#define MAX_CPUS 16
90
#define MAX_PILS 16
91
92
93
#define ESCC_CLOCK 4915200
94
struct sun4m_hwdef {
95
96
97
    target_phys_addr_t iommu_base, slavio_base;
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
    target_phys_addr_t serial_base, fd_base;
blueswir1 authored
98
    target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
99
    target_phys_addr_t tcx_base, cs_base, apc_base, aux1_base, aux2_base;
100
101
    target_phys_addr_t ecc_base;
    uint32_t ecc_version;
102
    long vram_size, nvram_size;
blueswir1 authored
103
    // IRQ numbers are not PIL ones, but master interrupt controller
104
    // register bit numbers
105
    int esp_irq, le_irq, clock_irq, clock1_irq;
106
    int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq, ecc_irq;
107
108
    uint8_t nvram_machine_id;
    uint16_t machine_id;
109
    uint32_t iommu_version;
110
    uint32_t intbit_to_level[32];
111
112
    uint64_t max_mem;
    const char * const default_cpu_model;
113
114
};
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#define MAX_IOUNITS 5

struct sun4d_hwdef {
    target_phys_addr_t iounit_bases[MAX_IOUNITS], slavio_base;
    target_phys_addr_t counter_base, nvram_base, ms_kb_base;
    target_phys_addr_t serial_base;
    target_phys_addr_t espdma_base, esp_base;
    target_phys_addr_t ledma_base, le_base;
    target_phys_addr_t tcx_base;
    target_phys_addr_t sbi_base;
    unsigned long vram_size, nvram_size;
    // IRQ numbers are not PIL ones, but SBI register bit numbers
    int esp_irq, le_irq, clock_irq, clock1_irq;
    int ser_irq, ms_kb_irq, me_irq;
129
130
    uint8_t nvram_machine_id;
    uint16_t machine_id;
131
132
133
134
135
    uint32_t iounit_version;
    uint64_t max_mem;
    const char * const default_cpu_model;
};
136
137
138
139
140
struct sun4c_hwdef {
    target_phys_addr_t iommu_base, slavio_base;
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
    target_phys_addr_t serial_base, fd_base;
    target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
141
    target_phys_addr_t tcx_base, aux1_base;
142
143
144
    long vram_size, nvram_size;
    // IRQ numbers are not PIL ones, but master interrupt controller
    // register bit numbers
145
146
    int esp_irq, le_irq, clock_irq, clock1_irq;
    int ser_irq, ms_kb_irq, fd_irq, me_irq;
147
148
149
150
151
152
153
154
    uint8_t nvram_machine_id;
    uint16_t machine_id;
    uint32_t iommu_version;
    uint32_t intbit_to_level[32];
    uint64_t max_mem;
    const char * const default_cpu_model;
};
bellard authored
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
int DMA_get_channel_mode (int nchan)
{
    return 0;
}
int DMA_read_memory (int nchan, void *buf, int pos, int size)
{
    return 0;
}
int DMA_write_memory (int nchan, void *buf, int pos, int size)
{
    return 0;
}
void DMA_hold_DREQ (int nchan) {}
void DMA_release_DREQ (int nchan) {}
void DMA_schedule(int nchan) {}
void DMA_init (int high_page_enable) {}
void DMA_register_channel (int nchan,
                           DMA_transfer_handler transfer_handler,
                           void *opaque)
{
}
177
178
179
180
181
182
183
184
185
186
static int nvram_boot_set(void *opaque, const char *boot_device)
{
    unsigned int i;
    uint8_t image[sizeof(ohwcfg_v3_t)];
    ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ
    m48t59_t *nvram = (m48t59_t *)opaque;

    for (i = 0; i < sizeof(image); i++)
        image[i] = m48t59_read(nvram, i) & 0xff;
187
188
    pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
            boot_device);
189
190
191
192
193
194
195
196
197
    header->nboot_devices = strlen(boot_device) & 0xff;
    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));

    for (i = 0; i < sizeof(image); i++)
        m48t59_write(nvram, i, image[i]);

    return 0;
}
198
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
199
                       const char *boot_devices, ram_addr_t RAM_size,
blueswir1 authored
200
201
                       uint32_t kernel_size,
                       int width, int height, int depth,
202
                       int nvram_machine_id, const char *arch)
bellard authored
203
{
204
    unsigned int i;
205
    uint32_t start, end;
206
207
208
209
210
211
    uint8_t image[0x1ff0];
    ohwcfg_v3_t *header = (ohwcfg_v3_t *)&image;
    struct sparc_arch_cfg *sparc_header;
    struct OpenBIOS_nvpart_v1 *part_header;

    memset(image, '\0', sizeof(image));
bellard authored
212
bellard authored
213
    // Try to match PPC NVRAM
214
215
    pstrcpy((char *)header->struct_ident, sizeof(header->struct_ident),
            "QEMU_BIOS");
216
217
218
219
220
    header->struct_version = cpu_to_be32(3); /* structure v3 */

    header->nvram_size = cpu_to_be16(0x2000);
    header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t));
    header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg));
221
    pstrcpy((char *)header->arch, sizeof(header->arch), arch);
222
223
224
    header->nb_cpus = smp_cpus & 0xff;
    header->RAM0_base = 0;
    header->RAM0_size = cpu_to_be64((uint64_t)RAM_size);
225
226
    pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
            boot_devices);
227
228
229
    header->nboot_devices = strlen(boot_devices) & 0xff;
    header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR);
    header->kernel_size = cpu_to_be64((uint64_t)kernel_size);
bellard authored
230
    if (cmdline) {
231
        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline);
232
233
        header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR);
        header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline));
bellard authored
234
    }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    // XXX add initrd_image, initrd_size
    header->width = cpu_to_be16(width);
    header->height = cpu_to_be16(height);
    header->depth = cpu_to_be16(depth);
    if (nographic)
        header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);

    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));

    // Architecture specific header
    start = sizeof(ohwcfg_v3_t);
    sparc_header = (struct sparc_arch_cfg *)&image[start];
    sparc_header->valid = 0;
    start += sizeof(struct sparc_arch_cfg);
bellard authored
249
250
251
    // OpenBIOS nvram variables
    // Variable partition
252
253
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
    part_header->signature = OPENBIOS_PART_SYSTEM;
254
    pstrcpy(part_header->name, sizeof(part_header->name), "system");
255
256
    end = start + sizeof(struct OpenBIOS_nvpart_v1);
257
    for (i = 0; i < nb_prom_envs; i++)
258
259
260
261
        end = OpenBIOS_set_var(image, end, prom_envs[i]);

    // End marker
    image[end++] = '\0';
262
263

    end = start + ((end - start + 15) & ~15);
264
    OpenBIOS_finish_partition(part_header, end - start);
265
266
267

    // free partition
    start = end;
268
269
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
    part_header->signature = OPENBIOS_PART_FREE;
270
    pstrcpy(part_header->name, sizeof(part_header->name), "free");
271
272

    end = 0x1fd0;
273
274
    OpenBIOS_finish_partition(part_header, end - start);
275
276
    Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr,
                    nvram_machine_id);
277
278
279

    for (i = 0; i < sizeof(image); i++)
        m48t59_write(nvram, i, image[i]);
280
281

    qemu_register_boot_set(nvram_boot_set, nvram);
bellard authored
282
283
284
285
}

static void *slavio_intctl;
blueswir1 authored
286
void pic_info(void)
bellard authored
287
{
288
289
    if (slavio_intctl)
        slavio_pic_info(slavio_intctl);
bellard authored
290
291
}
blueswir1 authored
292
void irq_info(void)
bellard authored
293
{
294
295
    if (slavio_intctl)
        slavio_irq_info(slavio_intctl);
bellard authored
296
297
}
298
299
300
301
302
303
304
305
306
307
308
void cpu_check_irqs(CPUState *env)
{
    if (env->pil_in && (env->interrupt_index == 0 ||
                        (env->interrupt_index & ~15) == TT_EXTINT)) {
        unsigned int i;

        for (i = 15; i > 0; i--) {
            if (env->pil_in & (1 << i)) {
                int old_interrupt = env->interrupt_index;

                env->interrupt_index = TT_EXTINT | i;
309
310
                if (old_interrupt != env->interrupt_index) {
                    DPRINTF("Set CPU IRQ %d\n", i);
311
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
312
                }
313
314
315
316
                break;
            }
        }
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
317
        DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
318
319
320
321
322
        env->interrupt_index = 0;
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
    }
}
323
324
325
326
327
328
329
static void cpu_set_irq(void *opaque, int irq, int level)
{
    CPUState *env = opaque;

    if (level) {
        DPRINTF("Raise CPU IRQ %d\n", irq);
        env->halted = 0;
330
331
        env->pil_in |= 1 << irq;
        cpu_check_irqs(env);
332
333
    } else {
        DPRINTF("Lower CPU IRQ %d\n", irq);
334
335
        env->pil_in &= ~(1 << irq);
        cpu_check_irqs(env);
336
337
338
339
340
341
342
    }
}

static void dummy_cpu_set_irq(void *opaque, int irq, int level)
{
}
bellard authored
343
344
345
346
347
348
349
static void *slavio_misc;

void qemu_system_powerdown(void)
{
    slavio_set_power_fail(slavio_misc, 1);
}
bellard authored
350
351
352
static void main_cpu_reset(void *opaque)
{
    CPUState *env = opaque;
353
354
355
356
357
358
359
360
361

    cpu_reset(env);
    env->halted = 0;
}

static void secondary_cpu_reset(void *opaque)
{
    CPUState *env = opaque;
bellard authored
362
    cpu_reset(env);
363
    env->halted = 1;
bellard authored
364
365
}
366
367
368
369
370
371
static void cpu_halt_signal(void *opaque, int irq, int level)
{
    if (level && cpu_single_env)
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
}
372
static unsigned long sun4m_load_kernel(const char *kernel_filename,
373
374
                                       const char *initrd_filename,
                                       ram_addr_t RAM_size)
375
376
377
378
379
380
381
382
383
384
385
386
{
    int linux_boot;
    unsigned int i;
    long initrd_size, kernel_size;

    linux_boot = (kernel_filename != NULL);

    kernel_size = 0;
    if (linux_boot) {
        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
                               NULL);
        if (kernel_size < 0)
387
388
            kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
                                    RAM_size - KERNEL_LOAD_ADDR);
389
        if (kernel_size < 0)
390
391
392
            kernel_size = load_image_targphys(kernel_filename,
                                              KERNEL_LOAD_ADDR,
                                              RAM_size - KERNEL_LOAD_ADDR);
393
394
395
396
397
398
399
400
401
        if (kernel_size < 0) {
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
                    kernel_filename);
            exit(1);
        }

        /* load initrd */
        initrd_size = 0;
        if (initrd_filename) {
402
403
404
            initrd_size = load_image_targphys(initrd_filename,
                                              INITRD_LOAD_ADDR,
                                              RAM_size - INITRD_LOAD_ADDR);
405
406
407
408
409
410
411
412
            if (initrd_size < 0) {
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
                        initrd_filename);
                exit(1);
            }
        }
        if (initrd_size > 0) {
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
413
414
415
                if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
                    stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
                    stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size);
416
417
418
419
420
421
422
423
                    break;
                }
            }
        }
    }
    return kernel_size;
}
424
static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
425
                          const char *boot_device,
426
                          const char *kernel_filename,
427
428
                          const char *kernel_cmdline,
                          const char *initrd_filename, const char *cpu_model)
429
430
{
431
    CPUState *env, *envs[MAX_CPUS];
bellard authored
432
    unsigned int i;
433
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
434
    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
435
        *espdma_irq, *ledma_irq;
436
    qemu_irq *esp_reset, *le_reset;
437
    qemu_irq *fdc_tc;
438
    qemu_irq *cpu_halt;
blueswir1 authored
439
440
    ram_addr_t ram_offset, prom_offset, tcx_offset, idreg_offset;
    unsigned long kernel_size;
441
442
    int ret;
    char buf[1024];
443
    BlockDriverState *fd[MAX_FD];
blueswir1 authored
444
    int drive_index;
445
    void *fw_cfg;
446
447
    /* init CPUs */
448
449
    if (!cpu_model)
        cpu_model = hwdef->default_cpu_model;
450
451
    for(i = 0; i < smp_cpus; i++) {
452
453
        env = cpu_init(cpu_model);
        if (!env) {
454
            fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
455
456
457
            exit(1);
        }
        cpu_sparc_set_id(env, i);
458
        envs[i] = env;
459
460
461
462
        if (i == 0) {
            qemu_register_reset(main_cpu_reset, env);
        } else {
            qemu_register_reset(secondary_cpu_reset, env);
463
            env->halted = 1;
464
        }
465
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
466
        env->prom_addr = hwdef->slavio_base;
467
    }
468
469
470
471

    for (i = smp_cpus; i < MAX_CPUS; i++)
        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
472
473
    /* allocate RAM */
474
    if ((uint64_t)RAM_size > hwdef->max_mem) {
blueswir1 authored
475
476
        fprintf(stderr,
                "qemu: Too much memory for this machine: %d, maximum %d\n",
477
                (unsigned int)(RAM_size / (1024 * 1024)),
478
479
480
                (unsigned int)(hwdef->max_mem / (1024 * 1024)));
        exit(1);
    }
blueswir1 authored
481
482
    ram_offset = qemu_ram_alloc(RAM_size);
    cpu_register_physical_memory(0, RAM_size, ram_offset);
483
484
    /* load boot prom */
blueswir1 authored
485
    prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
486
487
488
489
490
491
492
493
494
495
    cpu_register_physical_memory(hwdef->slavio_base,
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
                                 TARGET_PAGE_MASK,
                                 prom_offset | IO_MEM_ROM);

    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
    ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
    if (ret < 0 || ret > PROM_SIZE_MAX)
blueswir1 authored
496
        ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX);
497
498
499
500
501
502
503
    if (ret < 0 || ret > PROM_SIZE_MAX) {
        fprintf(stderr, "qemu: could not load prom '%s'\n",
                buf);
        exit(1);
    }

    /* set up devices */
504
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
505
                                       hwdef->intctl_base + 0x10000ULL,
pbrook authored
506
                                       &hwdef->intbit_to_level[0],
507
                                       &slavio_irq, &slavio_cpu_irq,
508
                                       cpu_irqs,
509
                                       hwdef->clock_irq);
510
511
    if (hwdef->idreg_base) {
512
        static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 };
blueswir1 authored
513
blueswir1 authored
514
        idreg_offset = qemu_ram_alloc(sizeof(idreg_data));
515
        cpu_register_physical_memory(hwdef->idreg_base, sizeof(idreg_data),
blueswir1 authored
516
                                     idreg_offset | IO_MEM_ROM);
517
518
        cpu_physical_memory_write_rom(hwdef->idreg_base, idreg_data,
                                      sizeof(idreg_data));
blueswir1 authored
519
520
    }
521
522
523
    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
                       slavio_irq[hwdef->me_irq]);
524
    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
525
526
                              iommu, &espdma_irq, &esp_reset);
527
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
528
529
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
                             &le_reset);
530
blueswir1 authored
531
532
533
534
    if (graphic_depth != 8 && graphic_depth != 24) {
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
        exit (1);
    }
blueswir1 authored
535
    tcx_offset = qemu_ram_alloc(hwdef->vram_size);
536
    tcx_init(hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset,
blueswir1 authored
537
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
538
539
    lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
540
pbrook authored
541
542
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
                        hwdef->nvram_size, 8);
543
544

    slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
545
                          slavio_cpu_irq, smp_cpus);
546
547
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
548
                              nographic, ESCC_CLOCK, 1);
549
550
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
551
552
    escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], slavio_irq[hwdef->ser_irq],
              serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
553
554
    cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1);
555
556
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->apc_base,
                                   hwdef->aux1_base, hwdef->aux2_base,
557
                                   slavio_irq[hwdef->me_irq], cpu_halt[0],
558
559
                                   &fdc_tc);
560
    if (hwdef->fd_base) {
561
        /* there is zero or one floppy drive */
562
        memset(fd, 0, sizeof(fd));
blueswir1 authored
563
564
565
        drive_index = drive_get_index(IF_FLOPPY, 0, 0);
        if (drive_index != -1)
            fd[0] = drives_table[drive_index].bdrv;
566
567
568
        sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
                          fdc_tc);
569
570
571
572
573
574
575
    }

    if (drive_get_max_bus(IF_SCSI) > 0) {
        fprintf(stderr, "qemu: too many SCSI bus\n");
        exit(1);
    }
576
    main_esp = esp_init(hwdef->esp_base, 2,
577
578
                        espdma_memory_read, espdma_memory_write,
                        espdma, *espdma_irq, esp_reset);
579
580
    for (i = 0; i < ESP_MAX_DEVS; i++) {
blueswir1 authored
581
582
        drive_index = drive_get_index(IF_SCSI, 0, i);
        if (drive_index == -1)
583
            continue;
blueswir1 authored
584
        esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i);
585
586
    }
587
    if (hwdef->cs_base)
588
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
589
590
591
    kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
                                    RAM_size);
592
593

    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
594
               boot_device, RAM_size, kernel_size, graphic_width,
595
596
               graphic_height, graphic_depth, hwdef->nvram_machine_id,
               "Sun4m");
597
598
    if (hwdef->ecc_base)
599
600
        ecc_init(hwdef->ecc_base, slavio_irq[hwdef->ecc_irq],
                 hwdef->ecc_version);
601
602
603

    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
604
605
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
606
    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
607
608
}
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
enum {
    ss2_id = 0,
    ss5_id = 32,
    vger_id,
    lx_id,
    ss4_id,
    scls_id,
    sbook_id,
    ss10_id = 64,
    ss20_id,
    ss600mp_id,
    ss1000_id = 96,
    ss2000_id,
};
624
static const struct sun4m_hwdef sun4m_hwdefs[] = {
625
626
627
628
629
    /* SS-5 */
    {
        .iommu_base   = 0x10000000,
        .tcx_base     = 0x50000000,
        .cs_base      = 0x6c000000,
blueswir1 authored
630
        .slavio_base  = 0x70000000,
631
632
633
634
635
636
        .ms_kb_base   = 0x71000000,
        .serial_base  = 0x71100000,
        .nvram_base   = 0x71200000,
        .fd_base      = 0x71400000,
        .counter_base = 0x71d00000,
        .intctl_base  = 0x71e00000,
blueswir1 authored
637
        .idreg_base   = 0x78000000,
638
639
640
        .dma_base     = 0x78400000,
        .esp_base     = 0x78800000,
        .le_base      = 0x78c00000,
641
        .apc_base     = 0x6a000000,
642
643
        .aux1_base    = 0x71900000,
        .aux2_base    = 0x71910000,
644
645
646
647
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
648
        .clock_irq = 7,
649
650
651
652
653
654
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
        .cs_irq = 5,
655
656
        .nvram_machine_id = 0x80,
        .machine_id = ss5_id,
657
        .iommu_version = 0x05000000,
658
        .intbit_to_level = {
blueswir1 authored
659
660
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
661
        },
662
663
        .max_mem = 0x10000000,
        .default_cpu_model = "Fujitsu MB86904",
664
665
666
    },
    /* SS-10 */
    {
667
668
669
670
671
672
673
674
675
        .iommu_base   = 0xfe0000000ULL,
        .tcx_base     = 0xe20000000ULL,
        .slavio_base  = 0xff0000000ULL,
        .ms_kb_base   = 0xff1000000ULL,
        .serial_base  = 0xff1100000ULL,
        .nvram_base   = 0xff1200000ULL,
        .fd_base      = 0xff1700000ULL,
        .counter_base = 0xff1300000ULL,
        .intctl_base  = 0xff1400000ULL,
blueswir1 authored
676
        .idreg_base   = 0xef0000000ULL,
677
678
679
        .dma_base     = 0xef0400000ULL,
        .esp_base     = 0xef0800000ULL,
        .le_base      = 0xef0c00000ULL,
680
        .apc_base     = 0xefa000000ULL, // XXX should not exist
681
682
        .aux1_base    = 0xff1800000ULL,
        .aux2_base    = 0xff1a01000ULL,
683
684
        .ecc_base     = 0xf00000000ULL,
        .ecc_version  = 0x10000000, // version 0, implementation 1
685
686
687
688
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
689
        .clock_irq = 7,
690
691
692
693
694
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
695
        .ecc_irq = 28,
696
697
        .nvram_machine_id = 0x72,
        .machine_id = ss10_id,
698
        .iommu_version = 0x03000000,
699
        .intbit_to_level = {
blueswir1 authored
700
701
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
702
        },
703
        .max_mem = 0xf00000000ULL,
704
        .default_cpu_model = "TI SuperSparc II",
705
    },
706
707
708
709
710
711
712
713
714
715
716
717
718
    /* SS-600MP */
    {
        .iommu_base   = 0xfe0000000ULL,
        .tcx_base     = 0xe20000000ULL,
        .slavio_base  = 0xff0000000ULL,
        .ms_kb_base   = 0xff1000000ULL,
        .serial_base  = 0xff1100000ULL,
        .nvram_base   = 0xff1200000ULL,
        .counter_base = 0xff1300000ULL,
        .intctl_base  = 0xff1400000ULL,
        .dma_base     = 0xef0081000ULL,
        .esp_base     = 0xef0080000ULL,
        .le_base      = 0xef0060000ULL,
719
        .apc_base     = 0xefa000000ULL, // XXX should not exist
720
721
        .aux1_base    = 0xff1800000ULL,
        .aux2_base    = 0xff1a01000ULL, // XXX should not exist
722
723
        .ecc_base     = 0xf00000000ULL,
        .ecc_version  = 0x00000000, // version 0, implementation 0
724
725
726
727
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
728
        .clock_irq = 7,
729
730
731
732
733
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
734
        .ecc_irq = 28,
735
736
        .nvram_machine_id = 0x71,
        .machine_id = ss600mp_id,
737
        .iommu_version = 0x01000000,
738
739
740
741
        .intbit_to_level = {
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
        },
742
        .max_mem = 0xf00000000ULL,
743
        .default_cpu_model = "TI SuperSparc II",
744
    },
745
746
747
748
749
750
751
752
753
754
755
    /* SS-20 */
    {
        .iommu_base   = 0xfe0000000ULL,
        .tcx_base     = 0xe20000000ULL,
        .slavio_base  = 0xff0000000ULL,
        .ms_kb_base   = 0xff1000000ULL,
        .serial_base  = 0xff1100000ULL,
        .nvram_base   = 0xff1200000ULL,
        .fd_base      = 0xff1700000ULL,
        .counter_base = 0xff1300000ULL,
        .intctl_base  = 0xff1400000ULL,
blueswir1 authored
756
        .idreg_base   = 0xef0000000ULL,
757
758
759
        .dma_base     = 0xef0400000ULL,
        .esp_base     = 0xef0800000ULL,
        .le_base      = 0xef0c00000ULL,
760
        .apc_base     = 0xefa000000ULL, // XXX should not exist
761
762
        .aux1_base    = 0xff1800000ULL,
        .aux2_base    = 0xff1a01000ULL,
763
764
765
766
767
768
        .ecc_base     = 0xf00000000ULL,
        .ecc_version  = 0x20000000, // version 0, implementation 2
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
769
        .clock_irq = 7,
770
771
772
773
774
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
775
        .ecc_irq = 28,
776
777
        .nvram_machine_id = 0x72,
        .machine_id = ss20_id,
778
779
780
781
782
        .iommu_version = 0x13000000,
        .intbit_to_level = {
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
        },
783
        .max_mem = 0xf00000000ULL,
784
785
        .default_cpu_model = "TI SuperSparc II",
    },
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
    /* Voyager */
    {
        .iommu_base   = 0x10000000,
        .tcx_base     = 0x50000000,
        .slavio_base  = 0x70000000,
        .ms_kb_base   = 0x71000000,
        .serial_base  = 0x71100000,
        .nvram_base   = 0x71200000,
        .fd_base      = 0x71400000,
        .counter_base = 0x71d00000,
        .intctl_base  = 0x71e00000,
        .idreg_base   = 0x78000000,
        .dma_base     = 0x78400000,
        .esp_base     = 0x78800000,
        .le_base      = 0x78c00000,
        .apc_base     = 0x71300000, // pmc
        .aux1_base    = 0x71900000,
        .aux2_base    = 0x71910000,
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
        .clock_irq = 7,
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
814
815
        .nvram_machine_id = 0x80,
        .machine_id = vger_id,
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
        .iommu_version = 0x05000000,
        .intbit_to_level = {
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
        },
        .max_mem = 0x10000000,
        .default_cpu_model = "Fujitsu MB86904",
    },
    /* LX */
    {
        .iommu_base   = 0x10000000,
        .tcx_base     = 0x50000000,
        .slavio_base  = 0x70000000,
        .ms_kb_base   = 0x71000000,
        .serial_base  = 0x71100000,
        .nvram_base   = 0x71200000,
        .fd_base      = 0x71400000,
        .counter_base = 0x71d00000,
        .intctl_base  = 0x71e00000,
        .idreg_base   = 0x78000000,
        .dma_base     = 0x78400000,
        .esp_base     = 0x78800000,
        .le_base      = 0x78c00000,
        .aux1_base    = 0x71900000,
        .aux2_base    = 0x71910000,
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
        .clock_irq = 7,
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
851
852
        .nvram_machine_id = 0x80,
        .machine_id = lx_id,
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
        .iommu_version = 0x04000000,
        .intbit_to_level = {
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
        },
        .max_mem = 0x10000000,
        .default_cpu_model = "TI MicroSparc I",
    },
    /* SS-4 */
    {
        .iommu_base   = 0x10000000,
        .tcx_base     = 0x50000000,
        .cs_base      = 0x6c000000,
        .slavio_base  = 0x70000000,
        .ms_kb_base   = 0x71000000,
        .serial_base  = 0x71100000,
        .nvram_base   = 0x71200000,
        .fd_base      = 0x71400000,
        .counter_base = 0x71d00000,
        .intctl_base  = 0x71e00000,
        .idreg_base   = 0x78000000,
        .dma_base     = 0x78400000,
        .esp_base     = 0x78800000,
        .le_base      = 0x78c00000,
        .apc_base     = 0x6a000000,
        .aux1_base    = 0x71900000,
        .aux2_base    = 0x71910000,
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
        .clock_irq = 7,
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
        .cs_irq = 5,
891
892
        .nvram_machine_id = 0x80,
        .machine_id = ss4_id,
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
        .iommu_version = 0x05000000,
        .intbit_to_level = {
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
        },
        .max_mem = 0x10000000,
        .default_cpu_model = "Fujitsu MB86904",
    },
    /* SPARCClassic */
    {
        .iommu_base   = 0x10000000,
        .tcx_base     = 0x50000000,
        .slavio_base  = 0x70000000,
        .ms_kb_base   = 0x71000000,
        .serial_base  = 0x71100000,
        .nvram_base   = 0x71200000,
        .fd_base      = 0x71400000,
        .counter_base = 0x71d00000,
        .intctl_base  = 0x71e00000,
        .idreg_base   = 0x78000000,
        .dma_base     = 0x78400000,
        .esp_base     = 0x78800000,
        .le_base      = 0x78c00000,
        .apc_base     = 0x6a000000,
        .aux1_base    = 0x71900000,
        .aux2_base    = 0x71910000,
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
        .clock_irq = 7,
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
929
930
        .nvram_machine_id = 0x80,
        .machine_id = scls_id,
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
        .iommu_version = 0x05000000,
        .intbit_to_level = {
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
        },
        .max_mem = 0x10000000,
        .default_cpu_model = "TI MicroSparc I",
    },
    /* SPARCbook */
    {
        .iommu_base   = 0x10000000,
        .tcx_base     = 0x50000000, // XXX
        .slavio_base  = 0x70000000,
        .ms_kb_base   = 0x71000000,
        .serial_base  = 0x71100000,
        .nvram_base   = 0x71200000,
        .fd_base      = 0x71400000,
        .counter_base = 0x71d00000,
        .intctl_base  = 0x71e00000,
        .idreg_base   = 0x78000000,
        .dma_base     = 0x78400000,
        .esp_base     = 0x78800000,
        .le_base      = 0x78c00000,
        .apc_base     = 0x6a000000,
        .aux1_base    = 0x71900000,
        .aux2_base    = 0x71910000,
        .vram_size    = 0x00100000,
        .nvram_size   = 0x2000,
        .esp_irq = 18,
        .le_irq = 16,
        .clock_irq = 7,
        .clock1_irq = 19,
        .ms_kb_irq = 14,
        .ser_irq = 15,
        .fd_irq = 22,
        .me_irq = 30,
967
968
        .nvram_machine_id = 0x80,
        .machine_id = sbook_id,
969
970
971
972
973
974
975
976
        .iommu_version = 0x05000000,
        .intbit_to_level = {
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
        },
        .max_mem = 0x10000000,
        .default_cpu_model = "TI MicroSparc I",
    },
977
978
979
};

/* SPARCstation 5 hardware initialisation */
980
static void ss5_init(ram_addr_t RAM_size, int vga_ram_size,
981
                     const char *boot_device,
982
983
                     const char *kernel_filename, const char *kernel_cmdline,
                     const char *initrd_filename, const char *cpu_model)
984
{
985
    sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
986
                  kernel_cmdline, initrd_filename, cpu_model);
987
}
bellard authored
988
989
/* SPARCstation 10 hardware initialisation */
990
static void ss10_init(ram_addr_t RAM_size, int vga_ram_size,
991
                      const char *boot_device,
992
993
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename, const char *cpu_model)
994
{
995
    sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
996
                  kernel_cmdline, initrd_filename, cpu_model);
997
998
}
999
/* SPARCserver 600MP hardware initialisation */
1000
static void ss600mp_init(ram_addr_t RAM_size, int vga_ram_size,
1001
                         const char *boot_device,
blueswir1 authored
1002
1003
                         const char *kernel_filename,
                         const char *kernel_cmdline,
1004
1005
                         const char *initrd_filename, const char *cpu_model)
{
1006
    sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
1007
                  kernel_cmdline, initrd_filename, cpu_model);
1008
1009
}
1010
/* SPARCstation 20 hardware initialisation */
1011
static void ss20_init(ram_addr_t RAM_size, int vga_ram_size,
1012
                      const char *boot_device,
1013
1014
1015
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename, const char *cpu_model)
{
1016
    sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
1017
1018
1019
                  kernel_cmdline, initrd_filename, cpu_model);
}
1020
/* SPARCstation Voyager hardware initialisation */
1021
static void vger_init(ram_addr_t RAM_size, int vga_ram_size,
1022
                      const char *boot_device,
1023
1024
1025
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename, const char *cpu_model)
{
1026
    sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
1027
1028
1029
1030
                  kernel_cmdline, initrd_filename, cpu_model);
}

/* SPARCstation LX hardware initialisation */
1031
static void ss_lx_init(ram_addr_t RAM_size, int vga_ram_size,
1032
                       const char *boot_device,
1033
1034
1035
                       const char *kernel_filename, const char *kernel_cmdline,
                       const char *initrd_filename, const char *cpu_model)
{
1036
    sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
1037
1038
1039
1040
                  kernel_cmdline, initrd_filename, cpu_model);
}

/* SPARCstation 4 hardware initialisation */
1041
static void ss4_init(ram_addr_t RAM_size, int vga_ram_size,
1042
                     const char *boot_device,
1043
1044
1045
                     const char *kernel_filename, const char *kernel_cmdline,
                     const char *initrd_filename, const char *cpu_model)
{
1046
    sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
1047
1048
1049
1050
                  kernel_cmdline, initrd_filename, cpu_model);
}

/* SPARCClassic hardware initialisation */
1051
static void scls_init(ram_addr_t RAM_size, int vga_ram_size,
1052
                      const char *boot_device,
1053
1054
1055
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename, const char *cpu_model)
{
1056
    sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
1057
1058
1059
1060
                  kernel_cmdline, initrd_filename, cpu_model);
}

/* SPARCbook hardware initialisation */
1061
static void sbook_init(ram_addr_t RAM_size, int vga_ram_size,
1062
                       const char *boot_device,
1063
1064
1065
                       const char *kernel_filename, const char *kernel_cmdline,
                       const char *initrd_filename, const char *cpu_model)
{
1066
    sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
1067
1068
1069
                  kernel_cmdline, initrd_filename, cpu_model);
}
1070
QEMUMachine ss5_machine = {
blueswir1 authored
1071
1072
1073
1074
    .name = "SS-5",
    .desc = "Sun4m platform, SPARCstation 5",
    .init = ss5_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1075
    .nodisk_ok = 1,
1076
    .use_scsi = 1,
bellard authored
1077
};
1078
1079

QEMUMachine ss10_machine = {
blueswir1 authored
1080
1081
1082
1083
    .name = "SS-10",
    .desc = "Sun4m platform, SPARCstation 10",
    .init = ss10_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1084
    .nodisk_ok = 1,
1085
    .use_scsi = 1,
blueswir1 authored
1086
    .max_cpus = 4,
1087
};
1088
1089

QEMUMachine ss600mp_machine = {
blueswir1 authored
1090
1091
1092
1093
    .name = "SS-600MP",
    .desc = "Sun4m platform, SPARCserver 600MP",
    .init = ss600mp_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1094
    .nodisk_ok = 1,
1095
    .use_scsi = 1,
blueswir1 authored
1096
    .max_cpus = 4,
1097
};
1098
1099

QEMUMachine ss20_machine = {
blueswir1 authored
1100
1101
1102
1103
    .name = "SS-20",
    .desc = "Sun4m platform, SPARCstation 20",
    .init = ss20_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1104
    .nodisk_ok = 1,
1105
    .use_scsi = 1,
blueswir1 authored
1106
    .max_cpus = 4,
1107
1108
};
1109
QEMUMachine voyager_machine = {
blueswir1 authored
1110
1111
1112
1113
    .name = "Voyager",
    .desc = "Sun4m platform, SPARCstation Voyager",
    .init = vger_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1114
    .nodisk_ok = 1,
1115
    .use_scsi = 1,
1116
1117
1118
};

QEMUMachine ss_lx_machine = {
blueswir1 authored
1119
1120
1121
1122
    .name = "LX",
    .desc = "Sun4m platform, SPARCstation LX",
    .init = ss_lx_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1123
    .nodisk_ok = 1,
1124
    .use_scsi = 1,
1125
1126
1127
};

QEMUMachine ss4_machine = {
blueswir1 authored
1128
1129
1130
1131
    .name = "SS-4",
    .desc = "Sun4m platform, SPARCstation 4",
    .init = ss4_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1132
    .nodisk_ok = 1,
1133
    .use_scsi = 1,
1134
1135
1136
};

QEMUMachine scls_machine = {
blueswir1 authored
1137
1138
1139
1140
    .name = "SPARCClassic",
    .desc = "Sun4m platform, SPARCClassic",
    .init = scls_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1141
    .nodisk_ok = 1,
1142
    .use_scsi = 1,
1143
1144
1145
};

QEMUMachine sbook_machine = {
blueswir1 authored
1146
1147
1148
1149
    .name = "SPARCbook",
    .desc = "Sun4m platform, SPARCbook",
    .init = sbook_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1150
    .nodisk_ok = 1,
1151
    .use_scsi = 1,
1152
1153
};
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
static const struct sun4d_hwdef sun4d_hwdefs[] = {
    /* SS-1000 */
    {
        .iounit_bases   = {
            0xfe0200000ULL,
            0xfe1200000ULL,
            0xfe2200000ULL,
            0xfe3200000ULL,
            -1,
        },
        .tcx_base     = 0x820000000ULL,
        .slavio_base  = 0xf00000000ULL,
        .ms_kb_base   = 0xf00240000ULL,
        .serial_base  = 0xf00200000ULL,
        .nvram_base   = 0xf00280000ULL,
        .counter_base = 0xf00300000ULL,
        .espdma_base  = 0x800081000ULL,
        .esp_base     = 0x800080000ULL,
        .ledma_base   = 0x800040000ULL,
        .le_base      = 0x800060000ULL,
        .sbi_base     = 0xf02800000ULL,
blueswir1 authored
1175
        .vram_size    = 0x00100000,
1176
1177
1178
1179
1180
1181
1182
        .nvram_size   = 0x2000,
        .esp_irq = 3,
        .le_irq = 4,
        .clock_irq = 14,
        .clock1_irq = 10,
        .ms_kb_irq = 12,
        .ser_irq = 12,
1183
1184
        .nvram_machine_id = 0x80,
        .machine_id = ss1000_id,
1185
        .iounit_version = 0x03000000,
1186
        .max_mem = 0xf00000000ULL,
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
        .default_cpu_model = "TI SuperSparc II",
    },
    /* SS-2000 */
    {
        .iounit_bases   = {
            0xfe0200000ULL,
            0xfe1200000ULL,
            0xfe2200000ULL,
            0xfe3200000ULL,
            0xfe4200000ULL,
        },
        .tcx_base     = 0x820000000ULL,
        .slavio_base  = 0xf00000000ULL,
        .ms_kb_base   = 0xf00240000ULL,
        .serial_base  = 0xf00200000ULL,
        .nvram_base   = 0xf00280000ULL,
        .counter_base = 0xf00300000ULL,
        .espdma_base  = 0x800081000ULL,
        .esp_base     = 0x800080000ULL,
        .ledma_base   = 0x800040000ULL,
        .le_base      = 0x800060000ULL,
        .sbi_base     = 0xf02800000ULL,
blueswir1 authored
1209
        .vram_size    = 0x00100000,
1210
1211
1212
1213
1214
1215
1216
        .nvram_size   = 0x2000,
        .esp_irq = 3,
        .le_irq = 4,
        .clock_irq = 14,
        .clock1_irq = 10,
        .ms_kb_irq = 12,
        .ser_irq = 12,
1217
1218
        .nvram_machine_id = 0x80,
        .machine_id = ss2000_id,
1219
        .iounit_version = 0x03000000,
1220
        .max_mem = 0xf00000000ULL,
1221
1222
1223
1224
        .default_cpu_model = "TI SuperSparc II",
    },
};
1225
static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
1226
                          const char *boot_device,
1227
                          const char *kernel_filename,
1228
1229
1230
1231
1232
1233
1234
1235
1236
                          const char *kernel_cmdline,
                          const char *initrd_filename, const char *cpu_model)
{
    CPUState *env, *envs[MAX_CPUS];
    unsigned int i;
    void *iounits[MAX_IOUNITS], *espdma, *ledma, *main_esp, *nvram, *sbi;
    qemu_irq *cpu_irqs[MAX_CPUS], *sbi_irq, *sbi_cpu_irq,
        *espdma_irq, *ledma_irq;
    qemu_irq *esp_reset, *le_reset;
blueswir1 authored
1237
1238
    ram_addr_t ram_offset, prom_offset, tcx_offset;
    unsigned long kernel_size;
1239
1240
    int ret;
    char buf[1024];
blueswir1 authored
1241
    int drive_index;
1242
    void *fw_cfg;
1243
1244
1245
1246
1247
1248
1249
1250

    /* init CPUs */
    if (!cpu_model)
        cpu_model = hwdef->default_cpu_model;

    for (i = 0; i < smp_cpus; i++) {
        env = cpu_init(cpu_model);
        if (!env) {
1251
            fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
            exit(1);
        }
        cpu_sparc_set_id(env, i);
        envs[i] = env;
        if (i == 0) {
            qemu_register_reset(main_cpu_reset, env);
        } else {
            qemu_register_reset(secondary_cpu_reset, env);
            env->halted = 1;
        }
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
        env->prom_addr = hwdef->slavio_base;
    }

    for (i = smp_cpus; i < MAX_CPUS; i++)
        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);

    /* allocate RAM */
    if ((uint64_t)RAM_size > hwdef->max_mem) {
blueswir1 authored
1271
1272
        fprintf(stderr,
                "qemu: Too much memory for this machine: %d, maximum %d\n",
1273
                (unsigned int)(RAM_size / (1024 * 1024)),
1274
1275
1276
                (unsigned int)(hwdef->max_mem / (1024 * 1024)));
        exit(1);
    }
blueswir1 authored
1277
1278
    ram_offset = qemu_ram_alloc(RAM_size);
    cpu_register_physical_memory(0, RAM_size, ram_offset);
1279
1280

    /* load boot prom */
blueswir1 authored
1281
    prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
    cpu_register_physical_memory(hwdef->slavio_base,
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
                                 TARGET_PAGE_MASK,
                                 prom_offset | IO_MEM_ROM);

    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
    ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
    if (ret < 0 || ret > PROM_SIZE_MAX)
blueswir1 authored
1292
        ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX);
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
    if (ret < 0 || ret > PROM_SIZE_MAX) {
        fprintf(stderr, "qemu: could not load prom '%s'\n",
                buf);
        exit(1);
    }

    /* set up devices */
    sbi = sbi_init(hwdef->sbi_base, &sbi_irq, &sbi_cpu_irq, cpu_irqs);

    for (i = 0; i < MAX_IOUNITS; i++)
        if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1)
1304
1305
1306
            iounits[i] = iommu_init(hwdef->iounit_bases[i],
                                    hwdef->iounit_version,
                                    sbi_irq[hwdef->me_irq]);
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317

    espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[hwdef->esp_irq],
                              iounits[0], &espdma_irq, &esp_reset);

    ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[hwdef->le_irq],
                             iounits[0], &ledma_irq, &le_reset);

    if (graphic_depth != 8 && graphic_depth != 24) {
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
        exit (1);
    }
blueswir1 authored
1318
    tcx_offset = qemu_ram_alloc(hwdef->vram_size);
1319
    tcx_init(hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset,
1320
1321
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
1322
    lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
1323
1324
1325
1326
1327
1328
1329
1330

    nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0,
                        hwdef->nvram_size, 8);

    slavio_timer_init_all(hwdef->counter_base, sbi_irq[hwdef->clock1_irq],
                          sbi_cpu_irq, smp_cpus);

    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[hwdef->ms_kb_irq],
1331
                              nographic, ESCC_CLOCK, 1);
1332
1333
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
1334
1335
    escc_init(hwdef->serial_base, sbi_irq[hwdef->ser_irq], sbi_irq[hwdef->ser_irq],
              serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
1336
1337
1338
1339
1340
1341

    if (drive_get_max_bus(IF_SCSI) > 0) {
        fprintf(stderr, "qemu: too many SCSI bus\n");
        exit(1);
    }
1342
    main_esp = esp_init(hwdef->esp_base, 2,
1343
1344
                        espdma_memory_read, espdma_memory_write,
                        espdma, *espdma_irq, esp_reset);
1345
1346

    for (i = 0; i < ESP_MAX_DEVS; i++) {
blueswir1 authored
1347
1348
        drive_index = drive_get_index(IF_SCSI, 0, i);
        if (drive_index == -1)
1349
            continue;
blueswir1 authored
1350
        esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i);
1351
1352
    }
1353
1354
    kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
                                    RAM_size);
1355
1356
1357

    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
               boot_device, RAM_size, kernel_size, graphic_width,
1358
1359
               graphic_height, graphic_depth, hwdef->nvram_machine_id,
               "Sun4d");
1360
1361
1362

    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
1363
1364
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
1365
1366
1367
}

/* SPARCserver 1000 hardware initialisation */
1368
static void ss1000_init(ram_addr_t RAM_size, int vga_ram_size,
1369
                        const char *boot_device,
1370
1371
1372
                        const char *kernel_filename, const char *kernel_cmdline,
                        const char *initrd_filename, const char *cpu_model)
{
1373
    sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
1374
1375
1376
1377
                  kernel_cmdline, initrd_filename, cpu_model);
}

/* SPARCcenter 2000 hardware initialisation */
1378
static void ss2000_init(ram_addr_t RAM_size, int vga_ram_size,
1379
                        const char *boot_device,
1380
1381
1382
                        const char *kernel_filename, const char *kernel_cmdline,
                        const char *initrd_filename, const char *cpu_model)
{
1383
    sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
1384
1385
1386
1387
                  kernel_cmdline, initrd_filename, cpu_model);
}

QEMUMachine ss1000_machine = {
blueswir1 authored
1388
1389
1390
1391
    .name = "SS-1000",
    .desc = "Sun4d platform, SPARCserver 1000",
    .init = ss1000_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1392
    .nodisk_ok = 1,
1393
    .use_scsi = 1,
blueswir1 authored
1394
    .max_cpus = 8,
1395
1396
1397
};

QEMUMachine ss2000_machine = {
blueswir1 authored
1398
1399
1400
1401
    .name = "SS-2000",
    .desc = "Sun4d platform, SPARCcenter 2000",
    .init = ss2000_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
1402
    .nodisk_ok = 1,
1403
    .use_scsi = 1,
blueswir1 authored
1404
    .max_cpus = 20,
1405
};
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441

static const struct sun4c_hwdef sun4c_hwdefs[] = {
    /* SS-2 */
    {
        .iommu_base   = 0xf8000000,
        .tcx_base     = 0xfe000000,
        .slavio_base  = 0xf6000000,
        .intctl_base  = 0xf5000000,
        .counter_base = 0xf3000000,
        .ms_kb_base   = 0xf0000000,
        .serial_base  = 0xf1000000,
        .nvram_base   = 0xf2000000,
        .fd_base      = 0xf7200000,
        .dma_base     = 0xf8400000,
        .esp_base     = 0xf8800000,
        .le_base      = 0xf8c00000,
        .aux1_base    = 0xf7400003,
        .vram_size    = 0x00100000,
        .nvram_size   = 0x800,
        .esp_irq = 2,
        .le_irq = 3,
        .clock_irq = 5,
        .clock1_irq = 7,
        .ms_kb_irq = 1,
        .ser_irq = 1,
        .fd_irq = 1,
        .me_irq = 1,
        .nvram_machine_id = 0x55,
        .machine_id = ss2_id,
        .max_mem = 0x10000000,
        .default_cpu_model = "Cypress CY7C601",
    },
};

static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
                          const char *boot_device,
1442
                          const char *kernel_filename,
1443
1444
1445
1446
1447
1448
1449
1450
1451
                          const char *kernel_cmdline,
                          const char *initrd_filename, const char *cpu_model)
{
    CPUState *env;
    unsigned int i;
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
    qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq;
    qemu_irq *esp_reset, *le_reset;
    qemu_irq *fdc_tc;
blueswir1 authored
1452
1453
    ram_addr_t ram_offset, prom_offset, tcx_offset;
    unsigned long kernel_size;
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
    int ret;
    char buf[1024];
    BlockDriverState *fd[MAX_FD];
    int drive_index;
    void *fw_cfg;

    /* init CPU */
    if (!cpu_model)
        cpu_model = hwdef->default_cpu_model;

    env = cpu_init(cpu_model);
    if (!env) {
        fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
        exit(1);
    }

    cpu_sparc_set_id(env, 0);

    qemu_register_reset(main_cpu_reset, env);
    cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
    env->prom_addr = hwdef->slavio_base;

    /* allocate RAM */
    if ((uint64_t)RAM_size > hwdef->max_mem) {
        fprintf(stderr,
                "qemu: Too much memory for this machine: %d, maximum %d\n",
                (unsigned int)(RAM_size / (1024 * 1024)),
                (unsigned int)(hwdef->max_mem / (1024 * 1024)));
        exit(1);
    }
blueswir1 authored
1484
1485
    ram_offset = qemu_ram_alloc(RAM_size);
    cpu_register_physical_memory(0, RAM_size, ram_offset);
1486
1487

    /* load boot prom */
blueswir1 authored
1488
    prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
    cpu_register_physical_memory(hwdef->slavio_base,
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
                                 TARGET_PAGE_MASK,
                                 prom_offset | IO_MEM_ROM);

    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
    ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
    if (ret < 0 || ret > PROM_SIZE_MAX)
        ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX);
    if (ret < 0 || ret > PROM_SIZE_MAX) {
        fprintf(stderr, "qemu: could not load prom '%s'\n",
                buf);
        exit(1);
    }

    /* set up devices */
    slavio_intctl = sun4c_intctl_init(hwdef->intctl_base,
                                      &slavio_irq, cpu_irqs);

    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
                       slavio_irq[hwdef->me_irq]);

    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
                              iommu, &espdma_irq, &esp_reset);

    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
                             &le_reset);

    if (graphic_depth != 8 && graphic_depth != 24) {
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
        exit (1);
    }
blueswir1 authored
1524
    tcx_offset = qemu_ram_alloc(hwdef->vram_size);
1525
    tcx_init(hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset,
1526
1527
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
1528
    lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
1529
1530
1531
1532
1533

    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
                        hwdef->nvram_size, 2);

    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
1534
                              nographic, ESCC_CLOCK, 1);
1535
1536
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
1537
1538
1539
    escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
              slavio_irq[hwdef->ser_irq], serial_hds[0], serial_hds[1],
              ESCC_CLOCK, 1);
1540
1541
    slavio_misc = slavio_misc_init(0, 0, hwdef->aux1_base, 0,
1542
                                   slavio_irq[hwdef->me_irq], NULL, &fdc_tc);
1543
1544
1545

    if (hwdef->fd_base != (target_phys_addr_t)-1) {
        /* there is zero or one floppy drive */
1546
        memset(fd, 0, sizeof(fd));
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
        drive_index = drive_get_index(IF_FLOPPY, 0, 0);
        if (drive_index != -1)
            fd[0] = drives_table[drive_index].bdrv;

        sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
                          fdc_tc);
    }

    if (drive_get_max_bus(IF_SCSI) > 0) {
        fprintf(stderr, "qemu: too many SCSI bus\n");
        exit(1);
    }

    main_esp = esp_init(hwdef->esp_base, 2,
                        espdma_memory_read, espdma_memory_write,
                        espdma, *espdma_irq, esp_reset);

    for (i = 0; i < ESP_MAX_DEVS; i++) {
        drive_index = drive_get_index(IF_SCSI, 0, i);
        if (drive_index == -1)
            continue;
        esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i);
    }

    kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
                                    RAM_size);

    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
               boot_device, RAM_size, kernel_size, graphic_width,
               graphic_height, graphic_depth, hwdef->nvram_machine_id,
               "Sun4c");

    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
}

/* SPARCstation 2 hardware initialisation */
static void ss2_init(ram_addr_t RAM_size, int vga_ram_size,
1587
                     const char *boot_device,
1588
1589
1590
                     const char *kernel_filename, const char *kernel_cmdline,
                     const char *initrd_filename, const char *cpu_model)
{
1591
    sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
                  kernel_cmdline, initrd_filename, cpu_model);
}

QEMUMachine ss2_machine = {
    .name = "SS-2",
    .desc = "Sun4c platform, SPARCstation 2",
    .init = ss2_init,
    .ram_require = PROM_SIZE_MAX + TCX_SIZE,
    .nodisk_ok = 1,
    .use_scsi = 1,
};