Statistics
| Branch: | Revision:

root / hw / sun4m.c @ ae40972f

History | View | Annotate | Download (23 kB)

1
/*
2
 * QEMU Sun4m System Emulator
3
 *
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "hw.h"
25
#include "qemu-timer.h"
26
#include "sun4m.h"
27
#include "nvram.h"
28
#include "sparc32_dma.h"
29
#include "fdc.h"
30
#include "sysemu.h"
31
#include "net.h"
32
#include "boards.h"
33
#include "firmware_abi.h"
34

    
35
//#define DEBUG_IRQ
36

    
37
/*
38
 * Sun4m architecture was used in the following machines:
39
 *
40
 * SPARCserver 6xxMP/xx
41
 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
42
 * SPARCstation LX/ZX (4/30)
43
 * SPARCstation Voyager
44
 * SPARCstation 10/xx, SPARCserver 10/xx
45
 * SPARCstation 5, SPARCserver 5
46
 * SPARCstation 20/xx, SPARCserver 20
47
 * SPARCstation 4
48
 *
49
 * See for example: http://www.sunhelp.org/faq/sunref1.html
50
 */
51

    
52
#ifdef DEBUG_IRQ
53
#define DPRINTF(fmt, args...)                           \
54
    do { printf("CPUIRQ: " fmt , ##args); } while (0)
55
#else
56
#define DPRINTF(fmt, args...)
57
#endif
58

    
59
#define KERNEL_LOAD_ADDR     0x00004000
60
#define CMDLINE_ADDR         0x007ff000
61
#define INITRD_LOAD_ADDR     0x00800000
62
#define PROM_SIZE_MAX        (512 * 1024)
63
#define PROM_VADDR           0xffd00000
64
#define PROM_FILENAME        "openbios-sparc32"
65

    
66
#define MAX_CPUS 16
67
#define MAX_PILS 16
68

    
69
struct hwdef {
70
    target_phys_addr_t iommu_base, slavio_base;
71
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
72
    target_phys_addr_t serial_base, fd_base;
73
    target_phys_addr_t dma_base, esp_base, le_base;
74
    target_phys_addr_t tcx_base, cs_base, power_base;
75
    target_phys_addr_t ecc_base;
76
    uint32_t ecc_version;
77
    long vram_size, nvram_size;
78
    // IRQ numbers are not PIL ones, but master interrupt controller register
79
    // bit numbers
80
    int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
81
    int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
82
    int machine_id; // For NVRAM
83
    uint32_t iommu_version;
84
    uint32_t intbit_to_level[32];
85
    uint64_t max_mem;
86
    const char * const default_cpu_model;
87
};
88

    
89
/* TSC handling */
90

    
91
uint64_t cpu_get_tsc()
92
{
93
    return qemu_get_clock(vm_clock);
94
}
95

    
96
int DMA_get_channel_mode (int nchan)
97
{
98
    return 0;
99
}
100
int DMA_read_memory (int nchan, void *buf, int pos, int size)
101
{
102
    return 0;
103
}
104
int DMA_write_memory (int nchan, void *buf, int pos, int size)
105
{
106
    return 0;
107
}
108
void DMA_hold_DREQ (int nchan) {}
109
void DMA_release_DREQ (int nchan) {}
110
void DMA_schedule(int nchan) {}
111
void DMA_run (void) {}
112
void DMA_init (int high_page_enable) {}
113
void DMA_register_channel (int nchan,
114
                           DMA_transfer_handler transfer_handler,
115
                           void *opaque)
116
{
117
}
118

    
119
extern int nographic;
120

    
121
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
122
                       const char *boot_devices, uint32_t RAM_size,
123
                       uint32_t kernel_size,
124
                       int width, int height, int depth,
125
                       int machine_id)
126
{
127
    unsigned int i;
128
    uint32_t start, end;
129
    uint8_t image[0x1ff0];
130
    ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ
131
    struct sparc_arch_cfg *sparc_header;
132
    struct OpenBIOS_nvpart_v1 *part_header;
133

    
134
    memset(image, '\0', sizeof(image));
135

    
136
    // Try to match PPC NVRAM
137
    strcpy(header->struct_ident, "QEMU_BIOS");
138
    header->struct_version = cpu_to_be32(3); /* structure v3 */
139

    
140
    header->nvram_size = cpu_to_be16(0x2000);
141
    header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t));
142
    header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg));
143
    strcpy(header->arch, "sun4m");
144
    header->nb_cpus = smp_cpus & 0xff;
145
    header->RAM0_base = 0;
146
    header->RAM0_size = cpu_to_be64((uint64_t)RAM_size);
147
    strcpy(header->boot_devices, boot_devices);
148
    header->nboot_devices = strlen(boot_devices) & 0xff;
149
    header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR);
150
    header->kernel_size = cpu_to_be64((uint64_t)kernel_size);
151
    if (cmdline) {
152
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
153
        header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR);
154
        header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline));
155
    }
156
    // XXX add initrd_image, initrd_size
157
    header->width = cpu_to_be16(width);
158
    header->height = cpu_to_be16(height);
159
    header->depth = cpu_to_be16(depth);
160
    if (nographic)
161
        header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
162

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

    
165
    // Architecture specific header
166
    start = sizeof(ohwcfg_v3_t);
167
    sparc_header = (struct sparc_arch_cfg *)&image[start];
168
    sparc_header->valid = 0;
169
    start += sizeof(struct sparc_arch_cfg);
170

    
171
    // OpenBIOS nvram variables
172
    // Variable partition
173
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
174
    part_header->signature = OPENBIOS_PART_SYSTEM;
175
    strcpy(part_header->name, "system");
176

    
177
    end = start + sizeof(struct OpenBIOS_nvpart_v1);
178
    for (i = 0; i < nb_prom_envs; i++)
179
        end = OpenBIOS_set_var(image, end, prom_envs[i]);
180

    
181
    // End marker
182
    image[end++] = '\0';
183

    
184
    end = start + ((end - start + 15) & ~15);
185
    OpenBIOS_finish_partition(part_header, end - start);
186

    
187
    // free partition
188
    start = end;
189
    part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
190
    part_header->signature = OPENBIOS_PART_FREE;
191
    strcpy(part_header->name, "free");
192

    
193
    end = 0x1fd0;
194
    OpenBIOS_finish_partition(part_header, end - start);
195

    
196
    Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, machine_id);
197

    
198
    for (i = 0; i < sizeof(image); i++)
199
        m48t59_write(nvram, i, image[i]);
200
}
201

    
202
static void *slavio_intctl;
203

    
204
void pic_info()
205
{
206
    slavio_pic_info(slavio_intctl);
207
}
208

    
209
void irq_info()
210
{
211
    slavio_irq_info(slavio_intctl);
212
}
213

    
214
void cpu_check_irqs(CPUState *env)
215
{
216
    if (env->pil_in && (env->interrupt_index == 0 ||
217
                        (env->interrupt_index & ~15) == TT_EXTINT)) {
218
        unsigned int i;
219

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

    
224
                env->interrupt_index = TT_EXTINT | i;
225
                if (old_interrupt != env->interrupt_index)
226
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
227
                break;
228
            }
229
        }
230
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
231
        env->interrupt_index = 0;
232
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
233
    }
234
}
235

    
236
static void cpu_set_irq(void *opaque, int irq, int level)
237
{
238
    CPUState *env = opaque;
239

    
240
    if (level) {
241
        DPRINTF("Raise CPU IRQ %d\n", irq);
242
        env->halted = 0;
243
        env->pil_in |= 1 << irq;
244
        cpu_check_irqs(env);
245
    } else {
246
        DPRINTF("Lower CPU IRQ %d\n", irq);
247
        env->pil_in &= ~(1 << irq);
248
        cpu_check_irqs(env);
249
    }
250
}
251

    
252
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
253
{
254
}
255

    
256
static void *slavio_misc;
257

    
258
void qemu_system_powerdown(void)
259
{
260
    slavio_set_power_fail(slavio_misc, 1);
261
}
262

    
263
static void main_cpu_reset(void *opaque)
264
{
265
    CPUState *env = opaque;
266

    
267
    cpu_reset(env);
268
    env->halted = 0;
269
}
270

    
271
static void secondary_cpu_reset(void *opaque)
272
{
273
    CPUState *env = opaque;
274

    
275
    cpu_reset(env);
276
    env->halted = 1;
277
}
278

    
279
static unsigned long sun4m_load_kernel(const char *kernel_filename,
280
                                       const char *kernel_cmdline,
281
                                       const char *initrd_filename)
282
{
283
    int linux_boot;
284
    unsigned int i;
285
    long initrd_size, kernel_size;
286

    
287
    linux_boot = (kernel_filename != NULL);
288

    
289
    kernel_size = 0;
290
    if (linux_boot) {
291
        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
292
                               NULL);
293
        if (kernel_size < 0)
294
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
295
        if (kernel_size < 0)
296
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
297
        if (kernel_size < 0) {
298
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
299
                    kernel_filename);
300
            exit(1);
301
        }
302

    
303
        /* load initrd */
304
        initrd_size = 0;
305
        if (initrd_filename) {
306
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
307
            if (initrd_size < 0) {
308
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
309
                        initrd_filename);
310
                exit(1);
311
            }
312
        }
313
        if (initrd_size > 0) {
314
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
315
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
316
                    == 0x48647253) { // HdrS
317
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
318
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
319
                    break;
320
                }
321
            }
322
        }
323
    }
324
    return kernel_size;
325
}
326

    
327
static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
328
                          const char *boot_device,
329
                          DisplayState *ds, const char *kernel_filename,
330
                          const char *kernel_cmdline,
331
                          const char *initrd_filename, const char *cpu_model)
332

    
333
{
334
    CPUState *env, *envs[MAX_CPUS];
335
    unsigned int i;
336
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
337
    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
338
        *espdma_irq, *ledma_irq;
339
    qemu_irq *esp_reset, *le_reset;
340
    unsigned long prom_offset, kernel_size;
341
    int ret;
342
    char buf[1024];
343
    BlockDriverState *fd[MAX_FD];
344
    int index;
345

    
346
    /* init CPUs */
347
    if (!cpu_model)
348
        cpu_model = hwdef->default_cpu_model;
349

    
350
    for(i = 0; i < smp_cpus; i++) {
351
        env = cpu_init(cpu_model);
352
        if (!env) {
353
            fprintf(stderr, "Unable to find Sparc CPU definition\n");
354
            exit(1);
355
        }
356
        cpu_sparc_set_id(env, i);
357
        envs[i] = env;
358
        if (i == 0) {
359
            qemu_register_reset(main_cpu_reset, env);
360
        } else {
361
            qemu_register_reset(secondary_cpu_reset, env);
362
            env->halted = 1;
363
        }
364
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
365
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
366
        env->prom_addr = hwdef->slavio_base;
367
    }
368

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

    
372

    
373
    /* allocate RAM */
374
    if ((uint64_t)RAM_size > hwdef->max_mem) {
375
        fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
376
                (unsigned int)RAM_size / (1024 * 1024),
377
                (unsigned int)(hwdef->max_mem / (1024 * 1024)));
378
        exit(1);
379
    }
380
    cpu_register_physical_memory(0, RAM_size, 0);
381

    
382
    /* load boot prom */
383
    prom_offset = RAM_size + hwdef->vram_size;
384
    cpu_register_physical_memory(hwdef->slavio_base,
385
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
386
                                 TARGET_PAGE_MASK,
387
                                 prom_offset | IO_MEM_ROM);
388

    
389
    if (bios_name == NULL)
390
        bios_name = PROM_FILENAME;
391
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
392
    ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
393
    if (ret < 0 || ret > PROM_SIZE_MAX)
394
        ret = load_image(buf, phys_ram_base + prom_offset);
395
    if (ret < 0 || ret > PROM_SIZE_MAX) {
396
        fprintf(stderr, "qemu: could not load prom '%s'\n",
397
                buf);
398
        exit(1);
399
    }
400

    
401
    /* set up devices */
402
    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version);
403
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
404
                                       hwdef->intctl_base + 0x10000ULL,
405
                                       &hwdef->intbit_to_level[0],
406
                                       &slavio_irq, &slavio_cpu_irq,
407
                                       cpu_irqs,
408
                                       hwdef->clock_irq);
409

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

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

    
417
    if (graphic_depth != 8 && graphic_depth != 24) {
418
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
419
        exit (1);
420
    }
421
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
422
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
423

    
424
    if (nd_table[0].model == NULL
425
        || strcmp(nd_table[0].model, "lance") == 0) {
426
        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
427
    } else if (strcmp(nd_table[0].model, "?") == 0) {
428
        fprintf(stderr, "qemu: Supported NICs: lance\n");
429
        exit (1);
430
    } else {
431
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
432
        exit (1);
433
    }
434

    
435
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
436
                        hwdef->nvram_size, 8);
437

    
438
    slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
439
                          slavio_cpu_irq);
440

    
441
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
442
                              nographic);
443
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
444
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
445
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
446
                       serial_hds[1], serial_hds[0]);
447

    
448
    if (hwdef->fd_base != (target_phys_addr_t)-1) {
449
        /* there is zero or one floppy drive */
450
        fd[1] = fd[0] = NULL;
451
        index = drive_get_index(IF_FLOPPY, 0, 0);
452
        if (index != -1)
453
            fd[0] = drives_table[index].bdrv;
454

    
455
        sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd);
456
    }
457

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

    
463
    main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq,
464
                        esp_reset);
465

    
466
    for (i = 0; i < ESP_MAX_DEVS; i++) {
467
        index = drive_get_index(IF_SCSI, 0, i);
468
        if (index == -1)
469
            continue;
470
        esp_scsi_attach(main_esp, drives_table[index].bdrv, i);
471
    }
472

    
473
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
474
                                   slavio_irq[hwdef->me_irq]);
475
    if (hwdef->cs_base != (target_phys_addr_t)-1)
476
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
477

    
478
    kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline,
479
                                    initrd_filename);
480

    
481
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
482
               boot_device, RAM_size, kernel_size, graphic_width,
483
               graphic_height, graphic_depth, hwdef->machine_id);
484

    
485
    if (hwdef->ecc_base != (target_phys_addr_t)-1)
486
        ecc_init(hwdef->ecc_base, hwdef->ecc_version);
487
}
488

    
489
static const struct hwdef hwdefs[] = {
490
    /* SS-5 */
491
    {
492
        .iommu_base   = 0x10000000,
493
        .tcx_base     = 0x50000000,
494
        .cs_base      = 0x6c000000,
495
        .slavio_base  = 0x70000000,
496
        .ms_kb_base   = 0x71000000,
497
        .serial_base  = 0x71100000,
498
        .nvram_base   = 0x71200000,
499
        .fd_base      = 0x71400000,
500
        .counter_base = 0x71d00000,
501
        .intctl_base  = 0x71e00000,
502
        .dma_base     = 0x78400000,
503
        .esp_base     = 0x78800000,
504
        .le_base      = 0x78c00000,
505
        .power_base   = 0x7a000000,
506
        .ecc_base     = -1,
507
        .vram_size    = 0x00100000,
508
        .nvram_size   = 0x2000,
509
        .esp_irq = 18,
510
        .le_irq = 16,
511
        .clock_irq = 7,
512
        .clock1_irq = 19,
513
        .ms_kb_irq = 14,
514
        .ser_irq = 15,
515
        .fd_irq = 22,
516
        .me_irq = 30,
517
        .cs_irq = 5,
518
        .machine_id = 0x80,
519
        .iommu_version = 0x04000000,
520
        .intbit_to_level = {
521
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
522
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
523
        },
524
        .max_mem = 0x10000000,
525
        .default_cpu_model = "Fujitsu MB86904",
526
    },
527
    /* SS-10 */
528
    {
529
        .iommu_base   = 0xfe0000000ULL,
530
        .tcx_base     = 0xe20000000ULL,
531
        .cs_base      = -1,
532
        .slavio_base  = 0xff0000000ULL,
533
        .ms_kb_base   = 0xff1000000ULL,
534
        .serial_base  = 0xff1100000ULL,
535
        .nvram_base   = 0xff1200000ULL,
536
        .fd_base      = 0xff1700000ULL,
537
        .counter_base = 0xff1300000ULL,
538
        .intctl_base  = 0xff1400000ULL,
539
        .dma_base     = 0xef0400000ULL,
540
        .esp_base     = 0xef0800000ULL,
541
        .le_base      = 0xef0c00000ULL,
542
        .power_base   = 0xefa000000ULL,
543
        .ecc_base     = 0xf00000000ULL,
544
        .ecc_version  = 0x10000000, // version 0, implementation 1
545
        .vram_size    = 0x00100000,
546
        .nvram_size   = 0x2000,
547
        .esp_irq = 18,
548
        .le_irq = 16,
549
        .clock_irq = 7,
550
        .clock1_irq = 19,
551
        .ms_kb_irq = 14,
552
        .ser_irq = 15,
553
        .fd_irq = 22,
554
        .me_irq = 30,
555
        .cs_irq = -1,
556
        .machine_id = 0x72,
557
        .iommu_version = 0x03000000,
558
        .intbit_to_level = {
559
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
560
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
561
        },
562
        .max_mem = 0xffffffff, // XXX actually first 62GB ok
563
        .default_cpu_model = "TI SuperSparc II",
564
    },
565
    /* SS-600MP */
566
    {
567
        .iommu_base   = 0xfe0000000ULL,
568
        .tcx_base     = 0xe20000000ULL,
569
        .cs_base      = -1,
570
        .slavio_base  = 0xff0000000ULL,
571
        .ms_kb_base   = 0xff1000000ULL,
572
        .serial_base  = 0xff1100000ULL,
573
        .nvram_base   = 0xff1200000ULL,
574
        .fd_base      = -1,
575
        .counter_base = 0xff1300000ULL,
576
        .intctl_base  = 0xff1400000ULL,
577
        .dma_base     = 0xef0081000ULL,
578
        .esp_base     = 0xef0080000ULL,
579
        .le_base      = 0xef0060000ULL,
580
        .power_base   = 0xefa000000ULL,
581
        .ecc_base     = 0xf00000000ULL,
582
        .ecc_version  = 0x00000000, // version 0, implementation 0
583
        .vram_size    = 0x00100000,
584
        .nvram_size   = 0x2000,
585
        .esp_irq = 18,
586
        .le_irq = 16,
587
        .clock_irq = 7,
588
        .clock1_irq = 19,
589
        .ms_kb_irq = 14,
590
        .ser_irq = 15,
591
        .fd_irq = 22,
592
        .me_irq = 30,
593
        .cs_irq = -1,
594
        .machine_id = 0x71,
595
        .iommu_version = 0x01000000,
596
        .intbit_to_level = {
597
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
598
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
599
        },
600
        .max_mem = 0xffffffff, // XXX actually first 62GB ok
601
        .default_cpu_model = "TI SuperSparc II",
602
    },
603
    /* SS-20 */
604
    {
605
        .iommu_base   = 0xfe0000000ULL,
606
        .tcx_base     = 0xe20000000ULL,
607
        .cs_base      = -1,
608
        .slavio_base  = 0xff0000000ULL,
609
        .ms_kb_base   = 0xff1000000ULL,
610
        .serial_base  = 0xff1100000ULL,
611
        .nvram_base   = 0xff1200000ULL,
612
        .fd_base      = 0xff1700000ULL,
613
        .counter_base = 0xff1300000ULL,
614
        .intctl_base  = 0xff1400000ULL,
615
        .dma_base     = 0xef0400000ULL,
616
        .esp_base     = 0xef0800000ULL,
617
        .le_base      = 0xef0c00000ULL,
618
        .power_base   = 0xefa000000ULL,
619
        .ecc_base     = 0xf00000000ULL,
620
        .ecc_version  = 0x20000000, // version 0, implementation 2
621
        .vram_size    = 0x00100000,
622
        .nvram_size   = 0x2000,
623
        .esp_irq = 18,
624
        .le_irq = 16,
625
        .clock_irq = 7,
626
        .clock1_irq = 19,
627
        .ms_kb_irq = 14,
628
        .ser_irq = 15,
629
        .fd_irq = 22,
630
        .me_irq = 30,
631
        .cs_irq = -1,
632
        .machine_id = 0x72,
633
        .iommu_version = 0x13000000,
634
        .intbit_to_level = {
635
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
636
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
637
        },
638
        .max_mem = 0xffffffff, // XXX actually first 62GB ok
639
        .default_cpu_model = "TI SuperSparc II",
640
    },
641
};
642

    
643
/* SPARCstation 5 hardware initialisation */
644
static void ss5_init(int RAM_size, int vga_ram_size,
645
                     const char *boot_device, DisplayState *ds,
646
                     const char *kernel_filename, const char *kernel_cmdline,
647
                     const char *initrd_filename, const char *cpu_model)
648
{
649
    sun4m_hw_init(&hwdefs[0], RAM_size, boot_device, ds, kernel_filename,
650
                  kernel_cmdline, initrd_filename, cpu_model);
651
}
652

    
653
/* SPARCstation 10 hardware initialisation */
654
static void ss10_init(int RAM_size, int vga_ram_size,
655
                      const char *boot_device, DisplayState *ds,
656
                      const char *kernel_filename, const char *kernel_cmdline,
657
                      const char *initrd_filename, const char *cpu_model)
658
{
659
    sun4m_hw_init(&hwdefs[1], RAM_size, boot_device, ds, kernel_filename,
660
                  kernel_cmdline, initrd_filename, cpu_model);
661
}
662

    
663
/* SPARCserver 600MP hardware initialisation */
664
static void ss600mp_init(int RAM_size, int vga_ram_size,
665
                         const char *boot_device, DisplayState *ds,
666
                         const char *kernel_filename, const char *kernel_cmdline,
667
                         const char *initrd_filename, const char *cpu_model)
668
{
669
    sun4m_hw_init(&hwdefs[2], RAM_size, boot_device, ds, kernel_filename,
670
                  kernel_cmdline, initrd_filename, cpu_model);
671
}
672

    
673
/* SPARCstation 20 hardware initialisation */
674
static void ss20_init(int RAM_size, int vga_ram_size,
675
                      const char *boot_device, DisplayState *ds,
676
                      const char *kernel_filename, const char *kernel_cmdline,
677
                      const char *initrd_filename, const char *cpu_model)
678
{
679
    sun4m_hw_init(&hwdefs[3], RAM_size, boot_device, ds, kernel_filename,
680
                  kernel_cmdline, initrd_filename, cpu_model);
681
}
682

    
683
QEMUMachine ss5_machine = {
684
    "SS-5",
685
    "Sun4m platform, SPARCstation 5",
686
    ss5_init,
687
};
688

    
689
QEMUMachine ss10_machine = {
690
    "SS-10",
691
    "Sun4m platform, SPARCstation 10",
692
    ss10_init,
693
};
694

    
695
QEMUMachine ss600mp_machine = {
696
    "SS-600MP",
697
    "Sun4m platform, SPARCserver 600MP",
698
    ss600mp_init,
699
};
700

    
701
QEMUMachine ss20_machine = {
702
    "SS-20",
703
    "Sun4m platform, SPARCstation 20",
704
    ss20_init,
705
};
706