Statistics
| Branch: | Revision:

root / hw / sun4m.c @ 5fafdf24

History | View | Annotate | Download (19.3 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 "vl.h"
25
//#define DEBUG_IRQ
26

    
27
/*
28
 * Sun4m architecture was used in the following machines:
29
 *
30
 * SPARCserver 6xxMP/xx
31
 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
32
 * SPARCstation LX/ZX (4/30)
33
 * SPARCstation Voyager
34
 * SPARCstation 10/xx, SPARCserver 10/xx
35
 * SPARCstation 5, SPARCserver 5
36
 * SPARCstation 20/xx, SPARCserver 20
37
 * SPARCstation 4
38
 *
39
 * See for example: http://www.sunhelp.org/faq/sunref1.html
40
 */
41

    
42
#ifdef DEBUG_IRQ
43
#define DPRINTF(fmt, args...)                           \
44
    do { printf("CPUIRQ: " fmt , ##args); } while (0)
45
#else
46
#define DPRINTF(fmt, args...)
47
#endif
48

    
49
#define KERNEL_LOAD_ADDR     0x00004000
50
#define CMDLINE_ADDR         0x007ff000
51
#define INITRD_LOAD_ADDR     0x00800000
52
#define PROM_SIZE_MAX        (256 * 1024)
53
#define PROM_ADDR             0xffd00000
54
#define PROM_FILENAME             "openbios-sparc32"
55

    
56
#define MAX_CPUS 16
57
#define MAX_PILS 16
58

    
59
struct hwdef {
60
    target_phys_addr_t iommu_base, slavio_base;
61
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
62
    target_phys_addr_t serial_base, fd_base;
63
    target_phys_addr_t dma_base, esp_base, le_base;
64
    target_phys_addr_t tcx_base, cs_base, power_base;
65
    long vram_size, nvram_size;
66
    // IRQ numbers are not PIL ones, but master interrupt controller register
67
    // bit numbers
68
    int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
69
    int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
70
    int machine_id; // For NVRAM
71
    uint32_t intbit_to_level[32];
72
};
73

    
74
/* TSC handling */
75

    
76
uint64_t cpu_get_tsc()
77
{
78
    return qemu_get_clock(vm_clock);
79
}
80

    
81
int DMA_get_channel_mode (int nchan)
82
{
83
    return 0;
84
}
85
int DMA_read_memory (int nchan, void *buf, int pos, int size)
86
{
87
    return 0;
88
}
89
int DMA_write_memory (int nchan, void *buf, int pos, int size)
90
{
91
    return 0;
92
}
93
void DMA_hold_DREQ (int nchan) {}
94
void DMA_release_DREQ (int nchan) {}
95
void DMA_schedule(int nchan) {}
96
void DMA_run (void) {}
97
void DMA_init (int high_page_enable) {}
98
void DMA_register_channel (int nchan,
99
                           DMA_transfer_handler transfer_handler,
100
                           void *opaque)
101
{
102
}
103

    
104
static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
105
{
106
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
107
    m48t59_write(nvram, addr++, value & 0xff);
108
}
109

    
110
static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
111
{
112
    m48t59_write(nvram, addr++, value >> 24);
113
    m48t59_write(nvram, addr++, (value >> 16) & 0xff);
114
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
115
    m48t59_write(nvram, addr++, value & 0xff);
116
}
117

    
118
static void nvram_set_string (m48t59_t *nvram, uint32_t addr,
119
                       const unsigned char *str, uint32_t max)
120
{
121
    unsigned int i;
122

    
123
    for (i = 0; i < max && str[i] != '\0'; i++) {
124
        m48t59_write(nvram, addr + i, str[i]);
125
    }
126
    m48t59_write(nvram, addr + max - 1, '\0');
127
}
128

    
129
static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr,
130
                                const unsigned char *str)
131
{
132
    uint32_t len;
133

    
134
    len = strlen(str) + 1;
135
    nvram_set_string(nvram, addr, str, len);
136

    
137
    return addr + len;
138
}
139

    
140
static void nvram_finish_partition (m48t59_t *nvram, uint32_t start,
141
                                    uint32_t end)
142
{
143
    unsigned int i, sum;
144

    
145
    // Length divided by 16
146
    m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff);
147
    m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff);
148
    // Checksum
149
    sum = m48t59_read(nvram, start);
150
    for (i = 0; i < 14; i++) {
151
        sum += m48t59_read(nvram, start + 2 + i);
152
        sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
153
    }
154
    m48t59_write(nvram, start + 1, sum & 0xff);
155
}
156

    
157
extern int nographic;
158

    
159
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
160
                       int boot_device, uint32_t RAM_size,
161
                       uint32_t kernel_size,
162
                       int width, int height, int depth,
163
                       int machine_id)
164
{
165
    unsigned char tmp = 0;
166
    unsigned int i, j;
167
    uint32_t start, end;
168

    
169
    // Try to match PPC NVRAM
170
    nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
171
    nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */
172
    // NVRAM_size, arch not applicable
173
    m48t59_write(nvram, 0x2D, smp_cpus & 0xff);
174
    m48t59_write(nvram, 0x2E, 0);
175
    m48t59_write(nvram, 0x2F, nographic & 0xff);
176
    nvram_set_lword(nvram,  0x30, RAM_size);
177
    m48t59_write(nvram, 0x34, boot_device & 0xff);
178
    nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
179
    nvram_set_lword(nvram,  0x3C, kernel_size);
180
    if (cmdline) {
181
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
182
        nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
183
        nvram_set_lword(nvram,  0x44, strlen(cmdline));
184
    }
185
    // initrd_image, initrd_size passed differently
186
    nvram_set_word(nvram,   0x54, width);
187
    nvram_set_word(nvram,   0x56, height);
188
    nvram_set_word(nvram,   0x58, depth);
189

    
190
    // OpenBIOS nvram variables
191
    // Variable partition
192
    start = 252;
193
    m48t59_write(nvram, start, 0x70);
194
    nvram_set_string(nvram, start + 4, "system", 12);
195

    
196
    end = start + 16;
197
    for (i = 0; i < nb_prom_envs; i++)
198
        end = nvram_set_var(nvram, end, prom_envs[i]);
199

    
200
    m48t59_write(nvram, end++ , 0);
201
    end = start + ((end - start + 15) & ~15);
202
    nvram_finish_partition(nvram, start, end);
203

    
204
    // free partition
205
    start = end;
206
    m48t59_write(nvram, start, 0x7f);
207
    nvram_set_string(nvram, start + 4, "free", 12);
208

    
209
    end = 0x1fd0;
210
    nvram_finish_partition(nvram, start, end);
211

    
212
    // Sun4m specific use
213
    start = i = 0x1fd8;
214
    m48t59_write(nvram, i++, 0x01);
215
    m48t59_write(nvram, i++, machine_id);
216
    j = 0;
217
    m48t59_write(nvram, i++, macaddr[j++]);
218
    m48t59_write(nvram, i++, macaddr[j++]);
219
    m48t59_write(nvram, i++, macaddr[j++]);
220
    m48t59_write(nvram, i++, macaddr[j++]);
221
    m48t59_write(nvram, i++, macaddr[j++]);
222
    m48t59_write(nvram, i, macaddr[j]);
223

    
224
    /* Calculate checksum */
225
    for (i = start; i < start + 15; i++) {
226
        tmp ^= m48t59_read(nvram, i);
227
    }
228
    m48t59_write(nvram, start + 15, tmp);
229
}
230

    
231
static void *slavio_intctl;
232

    
233
void pic_info()
234
{
235
    slavio_pic_info(slavio_intctl);
236
}
237

    
238
void irq_info()
239
{
240
    slavio_irq_info(slavio_intctl);
241
}
242

    
243
void cpu_check_irqs(CPUState *env)
244
{
245
    if (env->pil_in && (env->interrupt_index == 0 ||
246
                        (env->interrupt_index & ~15) == TT_EXTINT)) {
247
        unsigned int i;
248

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

    
253
                env->interrupt_index = TT_EXTINT | i;
254
                if (old_interrupt != env->interrupt_index)
255
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
256
                break;
257
            }
258
        }
259
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
260
        env->interrupt_index = 0;
261
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
262
    }
263
}
264

    
265
static void cpu_set_irq(void *opaque, int irq, int level)
266
{
267
    CPUState *env = opaque;
268

    
269
    if (level) {
270
        DPRINTF("Raise CPU IRQ %d\n", irq);
271
        env->halted = 0;
272
        env->pil_in |= 1 << irq;
273
        cpu_check_irqs(env);
274
    } else {
275
        DPRINTF("Lower CPU IRQ %d\n", irq);
276
        env->pil_in &= ~(1 << irq);
277
        cpu_check_irqs(env);
278
    }
279
}
280

    
281
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
282
{
283
}
284

    
285
static void *slavio_misc;
286

    
287
void qemu_system_powerdown(void)
288
{
289
    slavio_set_power_fail(slavio_misc, 1);
290
}
291

    
292
static void main_cpu_reset(void *opaque)
293
{
294
    CPUState *env = opaque;
295

    
296
    cpu_reset(env);
297
    env->halted = 0;
298
}
299

    
300
static void secondary_cpu_reset(void *opaque)
301
{
302
    CPUState *env = opaque;
303

    
304
    cpu_reset(env);
305
    env->halted = 1;
306
}
307

    
308
static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
309
                           DisplayState *ds, const char *cpu_model)
310

    
311
{
312
    CPUState *env, *envs[MAX_CPUS];
313
    unsigned int i;
314
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
315
    const sparc_def_t *def;
316
    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
317
        *espdma_irq, *ledma_irq;
318
    qemu_irq *esp_reset, *le_reset;
319

    
320
    /* init CPUs */
321
    sparc_find_by_name(cpu_model, &def);
322
    if (def == NULL) {
323
        fprintf(stderr, "Unable to find Sparc CPU definition\n");
324
        exit(1);
325
    }
326

    
327
    for(i = 0; i < smp_cpus; i++) {
328
        env = cpu_init();
329
        cpu_sparc_register(env, def);
330
        envs[i] = env;
331
        if (i == 0) {
332
            qemu_register_reset(main_cpu_reset, env);
333
        } else {
334
            qemu_register_reset(secondary_cpu_reset, env);
335
            env->halted = 1;
336
        }
337
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
338
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
339
    }
340

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

    
344
    /* allocate RAM */
345
    cpu_register_physical_memory(0, RAM_size, 0);
346

    
347
    iommu = iommu_init(hwdef->iommu_base);
348
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
349
                                       hwdef->intctl_base + 0x10000ULL,
350
                                       &hwdef->intbit_to_level[0],
351
                                       &slavio_irq, &slavio_cpu_irq,
352
                                       cpu_irqs,
353
                                       hwdef->clock_irq);
354

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

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

    
362
    if (graphic_depth != 8 && graphic_depth != 24) {
363
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
364
        exit (1);
365
    }
366
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
367
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
368

    
369
    if (nd_table[0].model == NULL
370
        || strcmp(nd_table[0].model, "lance") == 0) {
371
        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
372
    } else if (strcmp(nd_table[0].model, "?") == 0) {
373
        fprintf(stderr, "qemu: Supported NICs: lance\n");
374
        exit (1);
375
    } else {
376
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
377
        exit (1);
378
    }
379

    
380
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
381
                        hwdef->nvram_size, 8);
382
    for (i = 0; i < MAX_CPUS; i++) {
383
        slavio_timer_init(hwdef->counter_base +
384
                          (target_phys_addr_t)(i * TARGET_PAGE_SIZE),
385
                           slavio_cpu_irq[i], 0);
386
    }
387
    slavio_timer_init(hwdef->counter_base + 0x10000ULL,
388
                      slavio_irq[hwdef->clock1_irq], 2);
389
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
390
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
391
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
392
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
393
                       serial_hds[1], serial_hds[0]);
394
    fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
395

    
396
    main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq,
397
                        esp_reset);
398

    
399
    for (i = 0; i < MAX_DISKS; i++) {
400
        if (bs_table[i]) {
401
            esp_scsi_attach(main_esp, bs_table[i], i);
402
        }
403
    }
404

    
405
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
406
                                   slavio_irq[hwdef->me_irq]);
407
    if (hwdef->cs_base != (target_phys_addr_t)-1)
408
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
409

    
410
    return nvram;
411
}
412

    
413
static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device,
414
                              const char *kernel_filename,
415
                              const char *kernel_cmdline,
416
                              const char *initrd_filename,
417
                              int machine_id,
418
                              void *nvram)
419
{
420
    int ret, linux_boot;
421
    char buf[1024];
422
    unsigned int i;
423
    long prom_offset, initrd_size, kernel_size;
424

    
425
    linux_boot = (kernel_filename != NULL);
426

    
427
    prom_offset = RAM_size + vram_size;
428
    cpu_register_physical_memory(PROM_ADDR,
429
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
430
                                 prom_offset | IO_MEM_ROM);
431

    
432
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
433
    ret = load_elf(buf, 0, NULL, NULL, NULL);
434
    if (ret < 0) {
435
        fprintf(stderr, "qemu: could not load prom '%s'\n",
436
                buf);
437
        exit(1);
438
    }
439

    
440
    kernel_size = 0;
441
    if (linux_boot) {
442
        kernel_size = load_elf(kernel_filename, -0xf0000000, NULL, NULL, NULL);
443
        if (kernel_size < 0)
444
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
445
        if (kernel_size < 0)
446
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
447
        if (kernel_size < 0) {
448
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
449
                    kernel_filename);
450
            exit(1);
451
        }
452

    
453
        /* load initrd */
454
        initrd_size = 0;
455
        if (initrd_filename) {
456
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
457
            if (initrd_size < 0) {
458
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
459
                        initrd_filename);
460
                exit(1);
461
            }
462
        }
463
        if (initrd_size > 0) {
464
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
465
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
466
                    == 0x48647253) { // HdrS
467
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
468
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
469
                    break;
470
                }
471
            }
472
        }
473
    }
474
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
475
               boot_device, RAM_size, kernel_size, graphic_width,
476
               graphic_height, graphic_depth, machine_id);
477
}
478

    
479
static const struct hwdef hwdefs[] = {
480
    /* SS-5 */
481
    {
482
        .iommu_base   = 0x10000000,
483
        .tcx_base     = 0x50000000,
484
        .cs_base      = 0x6c000000,
485
        .slavio_base  = 0x70000000,
486
        .ms_kb_base   = 0x71000000,
487
        .serial_base  = 0x71100000,
488
        .nvram_base   = 0x71200000,
489
        .fd_base      = 0x71400000,
490
        .counter_base = 0x71d00000,
491
        .intctl_base  = 0x71e00000,
492
        .dma_base     = 0x78400000,
493
        .esp_base     = 0x78800000,
494
        .le_base      = 0x78c00000,
495
        .power_base   = 0x7a000000,
496
        .vram_size    = 0x00100000,
497
        .nvram_size   = 0x2000,
498
        .esp_irq = 18,
499
        .le_irq = 16,
500
        .clock_irq = 7,
501
        .clock1_irq = 19,
502
        .ms_kb_irq = 14,
503
        .ser_irq = 15,
504
        .fd_irq = 22,
505
        .me_irq = 30,
506
        .cs_irq = 5,
507
        .machine_id = 0x80,
508
        .intbit_to_level = {
509
            2, 3, 5, 7, 9, 11, 0, 14,        3, 5, 7, 9, 11, 13, 12, 12,
510
            6, 0, 4, 10, 8, 0, 11, 0,        0, 0, 0, 0, 15, 0, 15, 0,
511
        },
512
    },
513
    /* SS-10 */
514
    {
515
        .iommu_base   = 0xfe0000000ULL,
516
        .tcx_base     = 0xe20000000ULL,
517
        .cs_base      = -1,
518
        .slavio_base  = 0xff0000000ULL,
519
        .ms_kb_base   = 0xff1000000ULL,
520
        .serial_base  = 0xff1100000ULL,
521
        .nvram_base   = 0xff1200000ULL,
522
        .fd_base      = 0xff1700000ULL,
523
        .counter_base = 0xff1300000ULL,
524
        .intctl_base  = 0xff1400000ULL,
525
        .dma_base     = 0xef0400000ULL,
526
        .esp_base     = 0xef0800000ULL,
527
        .le_base      = 0xef0c00000ULL,
528
        .power_base   = 0xefa000000ULL,
529
        .vram_size    = 0x00100000,
530
        .nvram_size   = 0x2000,
531
        .esp_irq = 18,
532
        .le_irq = 16,
533
        .clock_irq = 7,
534
        .clock1_irq = 19,
535
        .ms_kb_irq = 14,
536
        .ser_irq = 15,
537
        .fd_irq = 22,
538
        .me_irq = 30,
539
        .cs_irq = -1,
540
        .machine_id = 0x72,
541
        .intbit_to_level = {
542
            2, 3, 5, 7, 9, 11, 0, 14,        3, 5, 7, 9, 11, 13, 12, 12,
543
            6, 0, 4, 10, 8, 0, 11, 0,        0, 0, 0, 0, 15, 0, 15, 0,
544
        },
545
    },
546
};
547

    
548
static void sun4m_common_init(int RAM_size, int boot_device, DisplayState *ds,
549
                              const char *kernel_filename, const char *kernel_cmdline,
550
                              const char *initrd_filename, const char *cpu_model,
551
                              unsigned int machine, int max_ram)
552
{
553
    void *nvram;
554

    
555
    if ((unsigned int)RAM_size > (unsigned int)max_ram) {
556
        fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
557
                (unsigned int)RAM_size / (1024 * 1024),
558
                (unsigned int)max_ram / (1024 * 1024));
559
        exit(1);
560
    }
561
    nvram = sun4m_hw_init(&hwdefs[machine], RAM_size, ds, cpu_model);
562

    
563
    sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
564
                      kernel_filename, kernel_cmdline, initrd_filename,
565
                      hwdefs[machine].machine_id, nvram);
566
}
567

    
568
/* SPARCstation 5 hardware initialisation */
569
static void ss5_init(int RAM_size, int vga_ram_size, int boot_device,
570
                       DisplayState *ds, const char **fd_filename, int snapshot,
571
                       const char *kernel_filename, const char *kernel_cmdline,
572
                       const char *initrd_filename, const char *cpu_model)
573
{
574
    if (cpu_model == NULL)
575
        cpu_model = "Fujitsu MB86904";
576
    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
577
                      kernel_cmdline, initrd_filename, cpu_model,
578
                      0, 0x10000000);
579
}
580

    
581
/* SPARCstation 10 hardware initialisation */
582
static void ss10_init(int RAM_size, int vga_ram_size, int boot_device,
583
                            DisplayState *ds, const char **fd_filename, int snapshot,
584
                            const char *kernel_filename, const char *kernel_cmdline,
585
                            const char *initrd_filename, const char *cpu_model)
586
{
587
    if (cpu_model == NULL)
588
        cpu_model = "TI SuperSparc II";
589
    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
590
                      kernel_cmdline, initrd_filename, cpu_model,
591
                      1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
592
}
593

    
594
QEMUMachine ss5_machine = {
595
    "SS-5",
596
    "Sun4m platform, SPARCstation 5",
597
    ss5_init,
598
};
599

    
600
QEMUMachine ss10_machine = {
601
    "SS-10",
602
    "Sun4m platform, SPARCstation 10",
603
    ss10_init,
604
};