Blame view

hw/sun4m.c 19.6 KB
1
2
/*
 * QEMU Sun4m System Emulator
3
 *
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5
 *
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"
25
//#define DEBUG_IRQ
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
 * Sun4m architecture was used in the following machines:
 *
 * SPARCserver 6xxMP/xx
 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
 * SPARCstation LX/ZX (4/30)
 * SPARCstation Voyager
 * SPARCstation 10/xx, SPARCserver 10/xx
 * SPARCstation 5, SPARCserver 5
 * SPARCstation 20/xx, SPARCserver 20
 * SPARCstation 4
 *
 * See for example: http://www.sunhelp.org/faq/sunref1.html
 */
42
43
44
45
46
47
48
#ifdef DEBUG_IRQ
#define DPRINTF(fmt, args...)                           \
    do { printf("CPUIRQ: " fmt , ##args); } while (0)
#else
#define DPRINTF(fmt, args...)
#endif
49
#define KERNEL_LOAD_ADDR     0x00004000
bellard authored
50
#define CMDLINE_ADDR         0x007ff000
bellard authored
51
#define INITRD_LOAD_ADDR     0x00800000
52
#define PROM_SIZE_MAX        (512 * 1024)
blueswir1 authored
53
54
#define PROM_PADDR           0xff0000000ULL
#define PROM_VADDR           0xffd00000
blueswir1 authored
55
#define PROM_FILENAME        "openbios-sparc32"
56
57
#define MAX_CPUS 16
58
#define MAX_PILS 16
59
60
struct hwdef {
61
62
63
64
65
    target_phys_addr_t iommu_base, slavio_base;
    target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
    target_phys_addr_t serial_base, fd_base;
    target_phys_addr_t dma_base, esp_base, le_base;
    target_phys_addr_t tcx_base, cs_base, power_base;
66
67
68
    long vram_size, nvram_size;
    // IRQ numbers are not PIL ones, but master interrupt controller register
    // bit numbers
69
    int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
70
71
    int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
    int machine_id; // For NVRAM
72
    uint32_t intbit_to_level[32];
73
74
};
75
76
77
78
79
80
81
/* TSC handling */

uint64_t cpu_get_tsc()
{
    return qemu_get_clock(vm_clock);
}
bellard authored
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
int DMA_get_channel_mode (int nchan)
{
    return 0;
}
int DMA_read_memory (int nchan, void *buf, int pos, int size)
{
    return 0;
}
int DMA_write_memory (int nchan, void *buf, int pos, int size)
{
    return 0;
}
void DMA_hold_DREQ (int nchan) {}
void DMA_release_DREQ (int nchan) {}
void DMA_schedule(int nchan) {}
void DMA_run (void) {}
void DMA_init (int high_page_enable) {}
void DMA_register_channel (int nchan,
                           DMA_transfer_handler transfer_handler,
                           void *opaque)
{
}
105
static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
bellard authored
106
{
107
108
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
    m48t59_write(nvram, addr++, value & 0xff);
bellard authored
109
110
}
111
static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
bellard authored
112
{
113
114
115
116
    m48t59_write(nvram, addr++, value >> 24);
    m48t59_write(nvram, addr++, (value >> 16) & 0xff);
    m48t59_write(nvram, addr++, (value >> 8) & 0xff);
    m48t59_write(nvram, addr++, value & 0xff);
bellard authored
117
118
}
119
static void nvram_set_string (m48t59_t *nvram, uint32_t addr,
bellard authored
120
121
122
123
124
                       const unsigned char *str, uint32_t max)
{
    unsigned int i;

    for (i = 0; i < max && str[i] != '\0'; i++) {
125
        m48t59_write(nvram, addr + i, str[i]);
bellard authored
126
    }
127
    m48t59_write(nvram, addr + max - 1, '\0');
bellard authored
128
}
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr,
                                const unsigned char *str)
{
    uint32_t len;

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

    return addr + len;
}

static void nvram_finish_partition (m48t59_t *nvram, uint32_t start,
                                    uint32_t end)
{
    unsigned int i, sum;

    // Length divided by 16
    m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff);
    m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff);
    // Checksum
    sum = m48t59_read(nvram, start);
    for (i = 0; i < 14; i++) {
        sum += m48t59_read(nvram, start + 2 + i);
        sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
    }
    m48t59_write(nvram, start + 1, sum & 0xff);
}
bellard authored
158
159
extern int nographic;
160
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
blueswir1 authored
161
162
163
                       int boot_device, uint32_t RAM_size,
                       uint32_t kernel_size,
                       int width, int height, int depth,
164
                       int machine_id)
bellard authored
165
166
{
    unsigned char tmp = 0;
167
168
    unsigned int i, j;
    uint32_t start, end;
bellard authored
169
bellard authored
170
171
172
173
    // Try to match PPC NVRAM
    nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
    nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */
    // NVRAM_size, arch not applicable
174
175
    m48t59_write(nvram, 0x2D, smp_cpus & 0xff);
    m48t59_write(nvram, 0x2E, 0);
176
    m48t59_write(nvram, 0x2F, nographic & 0xff);
bellard authored
177
    nvram_set_lword(nvram,  0x30, RAM_size);
178
    m48t59_write(nvram, 0x34, boot_device & 0xff);
bellard authored
179
180
    nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
    nvram_set_lword(nvram,  0x3C, kernel_size);
bellard authored
181
    if (cmdline) {
blueswir1 authored
182
183
        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
        nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
bellard authored
184
        nvram_set_lword(nvram,  0x44, strlen(cmdline));
bellard authored
185
    }
bellard authored
186
187
188
189
    // initrd_image, initrd_size passed differently
    nvram_set_word(nvram,   0x54, width);
    nvram_set_word(nvram,   0x56, height);
    nvram_set_word(nvram,   0x58, depth);
bellard authored
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
    // OpenBIOS nvram variables
    // Variable partition
    start = 252;
    m48t59_write(nvram, start, 0x70);
    nvram_set_string(nvram, start + 4, "system", 12);

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

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

    // free partition
    start = end;
    m48t59_write(nvram, start, 0x7f);
    nvram_set_string(nvram, start + 4, "free", 12);

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

    /* Calculate checksum */
226
227
    for (i = start; i < start + 15; i++) {
        tmp ^= m48t59_read(nvram, i);
bellard authored
228
    }
229
    m48t59_write(nvram, start + 15, tmp);
bellard authored
230
231
232
233
234
235
236
237
238
239
240
241
242
243
}

static void *slavio_intctl;

void pic_info()
{
    slavio_pic_info(slavio_intctl);
}

void irq_info()
{
    slavio_irq_info(slavio_intctl);
}
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
void cpu_check_irqs(CPUState *env)
{
    if (env->pil_in && (env->interrupt_index == 0 ||
                        (env->interrupt_index & ~15) == TT_EXTINT)) {
        unsigned int i;

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

                env->interrupt_index = TT_EXTINT | i;
                if (old_interrupt != env->interrupt_index)
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
                break;
            }
        }
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
        env->interrupt_index = 0;
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
    }
}
266
267
268
269
270
271
272
static void cpu_set_irq(void *opaque, int irq, int level)
{
    CPUState *env = opaque;

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

static void dummy_cpu_set_irq(void *opaque, int irq, int level)
{
}
bellard authored
286
287
288
289
290
291
292
static void *slavio_misc;

void qemu_system_powerdown(void)
{
    slavio_set_power_fail(slavio_misc, 1);
}
bellard authored
293
294
295
static void main_cpu_reset(void *opaque)
{
    CPUState *env = opaque;
296
297
298
299
300
301
302
303
304

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

static void secondary_cpu_reset(void *opaque)
{
    CPUState *env = opaque;
bellard authored
305
    cpu_reset(env);
306
    env->halted = 1;
bellard authored
307
308
}
309
310
static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
                           DisplayState *ds, const char *cpu_model)
311
312
{
313
    CPUState *env, *envs[MAX_CPUS];
bellard authored
314
    unsigned int i;
315
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
blueswir1 authored
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 */
blueswir1 authored
322
323
324
325
326
    sparc_find_by_name(cpu_model, &def);
    if (def == NULL) {
        fprintf(stderr, "Unable to find Sparc CPU definition\n");
        exit(1);
    }
327
328
329
    for(i = 0; i < smp_cpus; i++) {
        env = cpu_init();
330
        cpu_sparc_register(env, def, i);
331
        envs[i] = env;
332
333
334
335
        if (i == 0) {
            qemu_register_reset(main_cpu_reset, env);
        } else {
            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
343
344

    for (i = smp_cpus; i < MAX_CPUS; i++)
        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
345
    /* allocate RAM */
346
    cpu_register_physical_memory(0, RAM_size, 0);
347
348
349
    iommu = iommu_init(hwdef->iommu_base);
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
350
                                       hwdef->intctl_base + 0x10000ULL,
pbrook authored
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
358
                              iommu, &espdma_irq, &esp_reset);
359
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
360
361
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
                             &le_reset);
362
blueswir1 authored
363
364
365
366
    if (graphic_depth != 8 && graphic_depth != 24) {
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
        exit (1);
    }
367
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
blueswir1 authored
368
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
369
370
371

    if (nd_table[0].model == NULL
        || strcmp(nd_table[0].model, "lance") == 0) {
372
        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
373
374
375
    } else if (strcmp(nd_table[0].model, "?") == 0) {
        fprintf(stderr, "qemu: Supported NICs: lance\n");
        exit (1);
376
377
378
    } else {
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
        exit (1);
379
    }
380
pbrook authored
381
382
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
                        hwdef->nvram_size, 8);
383
384
385
386

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

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

    for (i = 0; i < MAX_DISKS; i++) {
        if (bs_table[i]) {
            esp_scsi_attach(main_esp, bs_table[i], i);
        }
    }
403
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
pbrook authored
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
413
414
                              const char *kernel_filename,
                              const char *kernel_cmdline,
                              const char *initrd_filename,
415
416
                              int machine_id,
                              void *nvram)
417
418
419
420
421
422
423
{
    int ret, linux_boot;
    char buf[1024];
    unsigned int i;
    long prom_offset, initrd_size, kernel_size;

    linux_boot = (kernel_filename != NULL);
424
425
    prom_offset = RAM_size + vram_size;
blueswir1 authored
426
    cpu_register_physical_memory(PROM_PADDR,
427
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
bellard authored
428
                                 prom_offset | IO_MEM_ROM);
bellard authored
429
430
431
432
    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
blueswir1 authored
433
    ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
434
435
436
437
438
439
    if (ret < 0 || ret > PROM_SIZE_MAX)
        ret = load_image(buf, phys_ram_base + prom_offset);
    if (ret < 0 || ret > PROM_SIZE_MAX) {
        fprintf(stderr, "qemu: could not load prom '%s'\n",
                buf);
        exit(1);
bellard authored
440
441
    }
bellard authored
442
    kernel_size = 0;
bellard authored
443
    if (linux_boot) {
blueswir1 authored
444
445
        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
                               NULL);
bellard authored
446
        if (kernel_size < 0)
blueswir1 authored
447
448
449
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
        if (kernel_size < 0)
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
bellard authored
450
        if (kernel_size < 0) {
451
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
bellard authored
452
                    kernel_filename);
blueswir1 authored
453
            exit(1);
454
        }
bellard authored
455
456
457
458
459
460

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

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

    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
563
        exit(1);
    }
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
574
575
576
577
578
                       DisplayState *ds, const char **fd_filename, int snapshot,
                       const char *kernel_filename, const char *kernel_cmdline,
                       const char *initrd_filename, const char *cpu_model)
{
    if (cpu_model == NULL)
        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
}
bellard authored
583
584
/* SPARCstation 10 hardware initialisation */
585
static void ss10_init(int RAM_size, int vga_ram_size, int boot_device,
586
587
588
589
590
591
                            DisplayState *ds, const char **fd_filename, int snapshot,
                            const char *kernel_filename, const char *kernel_cmdline,
                            const char *initrd_filename, const char *cpu_model)
{
    if (cpu_model == NULL)
        cpu_model = "TI SuperSparc II";
592
    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
593
                      kernel_cmdline, initrd_filename, cpu_model,
blueswir1 authored
594
                      1, 0xffffffff); // XXX actually first 62GB ok
595
596
}
597
598
599
600
QEMUMachine ss5_machine = {
    "SS-5",
    "Sun4m platform, SPARCstation 5",
    ss5_init,
bellard authored
601
};
602
603
604
605
606
607

QEMUMachine ss10_machine = {
    "SS-10",
    "Sun4m platform, SPARCstation 10",
    ss10_init,
};