Statistics
| Branch: | Revision:

root / hw / sun4m.c @ 327ac2e7

History | View | Annotate | Download (19.2 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

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

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

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

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

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

    
354
    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
355
                              iommu, &espdma_irq);
356
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
357
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq);
358

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

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

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

    
394
    for (i = 0; i < MAX_DISKS; i++) {
395
        if (bs_table[i]) {
396
            esp_scsi_attach(main_esp, bs_table[i], i);
397
        }
398
    }
399

    
400
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
401
                                   slavio_irq[hwdef->me_irq]);
402
    if (hwdef->cs_base != (target_phys_addr_t)-1)
403
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
404

    
405
    return nvram;
406
}
407

    
408
static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device,
409
                              const char *kernel_filename,
410
                              const char *kernel_cmdline,
411
                              const char *initrd_filename,
412
                              int machine_id,
413
                              void *nvram)
414
{
415
    int ret, linux_boot;
416
    char buf[1024];
417
    unsigned int i;
418
    long prom_offset, initrd_size, kernel_size;
419

    
420
    linux_boot = (kernel_filename != NULL);
421

    
422
    prom_offset = RAM_size + vram_size;
423
    cpu_register_physical_memory(PROM_ADDR, 
424
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, 
425
                                 prom_offset | IO_MEM_ROM);
426

    
427
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
428
    ret = load_elf(buf, 0, NULL, NULL, NULL);
429
    if (ret < 0) {
430
        fprintf(stderr, "qemu: could not load prom '%s'\n", 
431
                buf);
432
        exit(1);
433
    }
434

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

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

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

    
543
static void sun4m_common_init(int RAM_size, int boot_device, DisplayState *ds,
544
                              const char *kernel_filename, const char *kernel_cmdline,
545
                              const char *initrd_filename, const char *cpu_model,
546
                              unsigned int machine, int max_ram)
547
{
548
    void *nvram;
549

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

    
558
    sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
559
                      kernel_filename, kernel_cmdline, initrd_filename,
560
                      hwdefs[machine].machine_id, nvram);
561
}
562

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

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

    
589
QEMUMachine ss5_machine = {
590
    "SS-5",
591
    "Sun4m platform, SPARCstation 5",
592
    ss5_init,
593
};
594

    
595
QEMUMachine ss10_machine = {
596
    "SS-10",
597
    "Sun4m platform, SPARCstation 10",
598
    ss10_init,
599
};