Statistics
| Branch: | Revision:

root / hw / sun4m.c @ f930d07e

History | View | Annotate | Download (19.6 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        (512 * 1024)
53
#define PROM_PADDR           0xff0000000ULL
54
#define PROM_VADDR           0xffd00000
55
#define PROM_FILENAME        "openbios-sparc32"
56

    
57
#define MAX_CPUS 16
58
#define MAX_PILS 16
59

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

    
75
/* TSC handling */
76

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

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

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

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

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

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

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

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

    
138
    return addr + len;
139
}
140

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

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

    
158
extern int nographic;
159

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

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

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

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

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

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

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

    
213
    // Sun4m specific use
214
    start = i = 0x1fd8;
215
    m48t59_write(nvram, i++, 0x01);
216
    m48t59_write(nvram, i++, machine_id);
217
    j = 0;
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
    m48t59_write(nvram, i, macaddr[j]);
224

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

    
232
static void *slavio_intctl;
233

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

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

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

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

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

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

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

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

    
286
static void *slavio_misc;
287

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
381
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
382
                        hwdef->nvram_size, 8);
383

    
384
    slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
385
                          slavio_cpu_irq);
386

    
387
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
388
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
389
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
390
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
391
                       serial_hds[1], serial_hds[0]);
392
    fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
393

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

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

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

    
408
    return nvram;
409
}
410

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

    
423
    linux_boot = (kernel_filename != NULL);
424

    
425
    prom_offset = RAM_size + vram_size;
426
    cpu_register_physical_memory(PROM_PADDR,
427
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
428
                                 prom_offset | IO_MEM_ROM);
429

    
430
    if (bios_name == NULL)
431
        bios_name = PROM_FILENAME;
432
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
433
    ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
434
    if (ret < 0 || ret > PROM_SIZE_MAX)
435
        ret = load_image(buf, phys_ram_base + prom_offset);
436
    if (ret < 0 || ret > PROM_SIZE_MAX) {
437
        fprintf(stderr, "qemu: could not load prom '%s'\n",
438
                buf);
439
        exit(1);
440
    }
441

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

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

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

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

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

    
566
    sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
567
                      kernel_filename, kernel_cmdline, initrd_filename,
568
                      hwdefs[machine].machine_id, nvram);
569
}
570

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

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

    
597
QEMUMachine ss5_machine = {
598
    "SS-5",
599
    "Sun4m platform, SPARCstation 5",
600
    ss5_init,
601
};
602

    
603
QEMUMachine ss10_machine = {
604
    "SS-10",
605
    "Sun4m platform, SPARCstation 10",
606
    ss10_init,
607
};