Statistics
| Branch: | Revision:

root / hw / sun4m.c @ 87ecb68b

History | View | Annotate | Download (20.7 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_PADDR           0xff0000000ULL
64
#define PROM_VADDR           0xffd00000
65
#define PROM_FILENAME        "openbios-sparc32"
66

    
67
#define MAX_CPUS 16
68
#define MAX_PILS 16
69

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

    
86
/* TSC handling */
87

    
88
uint64_t cpu_get_tsc()
89
{
90
    return qemu_get_clock(vm_clock);
91
}
92

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

    
116
extern int nographic;
117

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

    
131
    memset(image, '\0', sizeof(image));
132

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

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

    
160
    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
161

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

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

    
174
    end = start + sizeof(struct OpenBIOS_nvpart_v1);
175
    for (i = 0; i < nb_prom_envs; i++)
176
        end = OpenBIOS_set_var(image, end, prom_envs[i]);
177

    
178
    // End marker
179
    image[end++] = '\0';
180

    
181
    end = start + ((end - start + 15) & ~15);
182
    OpenBIOS_finish_partition(part_header, end - start);
183

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

    
190
    end = 0x1fd0;
191
    OpenBIOS_finish_partition(part_header, end - start);
192

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

    
195
    for (i = 0; i < sizeof(image); i++)
196
        m48t59_write(nvram, i, image[i]);
197
}
198

    
199
static void *slavio_intctl;
200

    
201
void pic_info()
202
{
203
    slavio_pic_info(slavio_intctl);
204
}
205

    
206
void irq_info()
207
{
208
    slavio_irq_info(slavio_intctl);
209
}
210

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

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

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

    
233
static void cpu_set_irq(void *opaque, int irq, int level)
234
{
235
    CPUState *env = opaque;
236

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

    
249
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
250
{
251
}
252

    
253
static void *slavio_misc;
254

    
255
void qemu_system_powerdown(void)
256
{
257
    slavio_set_power_fail(slavio_misc, 1);
258
}
259

    
260
static void main_cpu_reset(void *opaque)
261
{
262
    CPUState *env = opaque;
263

    
264
    cpu_reset(env);
265
    env->halted = 0;
266
}
267

    
268
static void secondary_cpu_reset(void *opaque)
269
{
270
    CPUState *env = opaque;
271

    
272
    cpu_reset(env);
273
    env->halted = 1;
274
}
275

    
276
static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
277
                           DisplayState *ds, const char *cpu_model)
278

    
279
{
280
    CPUState *env, *envs[MAX_CPUS];
281
    unsigned int i;
282
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
283
    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
284
        *espdma_irq, *ledma_irq;
285
    qemu_irq *esp_reset, *le_reset;
286

    
287
    /* init CPUs */
288

    
289
    for(i = 0; i < smp_cpus; i++) {
290
        env = cpu_init(cpu_model);
291
        if (!env) {
292
            fprintf(stderr, "Unable to find Sparc CPU definition\n");
293
            exit(1);
294
        }
295
        cpu_sparc_set_id(env, i);
296
        envs[i] = env;
297
        if (i == 0) {
298
            qemu_register_reset(main_cpu_reset, env);
299
        } else {
300
            qemu_register_reset(secondary_cpu_reset, env);
301
            env->halted = 1;
302
        }
303
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
304
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
305
    }
306

    
307
    for (i = smp_cpus; i < MAX_CPUS; i++)
308
        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
309

    
310
    /* allocate RAM */
311
    cpu_register_physical_memory(0, RAM_size, 0);
312

    
313
    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version);
314
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
315
                                       hwdef->intctl_base + 0x10000ULL,
316
                                       &hwdef->intbit_to_level[0],
317
                                       &slavio_irq, &slavio_cpu_irq,
318
                                       cpu_irqs,
319
                                       hwdef->clock_irq);
320

    
321
    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
322
                              iommu, &espdma_irq, &esp_reset);
323

    
324
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
325
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
326
                             &le_reset);
327

    
328
    if (graphic_depth != 8 && graphic_depth != 24) {
329
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
330
        exit (1);
331
    }
332
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
333
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
334

    
335
    if (nd_table[0].model == NULL
336
        || strcmp(nd_table[0].model, "lance") == 0) {
337
        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
338
    } else if (strcmp(nd_table[0].model, "?") == 0) {
339
        fprintf(stderr, "qemu: Supported NICs: lance\n");
340
        exit (1);
341
    } else {
342
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
343
        exit (1);
344
    }
345

    
346
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
347
                        hwdef->nvram_size, 8);
348

    
349
    slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
350
                          slavio_cpu_irq);
351

    
352
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
353
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
354
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
355
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
356
                       serial_hds[1], serial_hds[0]);
357

    
358
    if (hwdef->fd_base != (target_phys_addr_t)-1)
359
        sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd_table);
360

    
361
    main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq,
362
                        esp_reset);
363

    
364
    for (i = 0; i < MAX_DISKS; i++) {
365
        if (bs_table[i]) {
366
            esp_scsi_attach(main_esp, bs_table[i], i);
367
        }
368
    }
369

    
370
    slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
371
                                   slavio_irq[hwdef->me_irq]);
372
    if (hwdef->cs_base != (target_phys_addr_t)-1)
373
        cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
374

    
375
    return nvram;
376
}
377

    
378
static void sun4m_load_kernel(long vram_size, int RAM_size,
379
                              const char *boot_device,
380
                              const char *kernel_filename,
381
                              const char *kernel_cmdline,
382
                              const char *initrd_filename,
383
                              int machine_id,
384
                              void *nvram)
385
{
386
    int ret, linux_boot;
387
    char buf[1024];
388
    unsigned int i;
389
    long prom_offset, initrd_size, kernel_size;
390

    
391
    linux_boot = (kernel_filename != NULL);
392

    
393
    prom_offset = RAM_size + vram_size;
394
    cpu_register_physical_memory(PROM_PADDR,
395
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
396
                                 prom_offset | IO_MEM_ROM);
397

    
398
    if (bios_name == NULL)
399
        bios_name = PROM_FILENAME;
400
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
401
    ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
402
    if (ret < 0 || ret > PROM_SIZE_MAX)
403
        ret = load_image(buf, phys_ram_base + prom_offset);
404
    if (ret < 0 || ret > PROM_SIZE_MAX) {
405
        fprintf(stderr, "qemu: could not load prom '%s'\n",
406
                buf);
407
        exit(1);
408
    }
409

    
410
    kernel_size = 0;
411
    if (linux_boot) {
412
        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
413
                               NULL);
414
        if (kernel_size < 0)
415
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
416
        if (kernel_size < 0)
417
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
418
        if (kernel_size < 0) {
419
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
420
                    kernel_filename);
421
            exit(1);
422
        }
423

    
424
        /* load initrd */
425
        initrd_size = 0;
426
        if (initrd_filename) {
427
            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
428
            if (initrd_size < 0) {
429
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
430
                        initrd_filename);
431
                exit(1);
432
            }
433
        }
434
        if (initrd_size > 0) {
435
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
436
                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
437
                    == 0x48647253) { // HdrS
438
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
439
                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
440
                    break;
441
                }
442
            }
443
        }
444
    }
445
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
446
               boot_device, RAM_size, kernel_size, graphic_width,
447
               graphic_height, graphic_depth, machine_id);
448
}
449

    
450
static const struct hwdef hwdefs[] = {
451
    /* SS-5 */
452
    {
453
        .iommu_base   = 0x10000000,
454
        .tcx_base     = 0x50000000,
455
        .cs_base      = 0x6c000000,
456
        .slavio_base  = 0x70000000,
457
        .ms_kb_base   = 0x71000000,
458
        .serial_base  = 0x71100000,
459
        .nvram_base   = 0x71200000,
460
        .fd_base      = 0x71400000,
461
        .counter_base = 0x71d00000,
462
        .intctl_base  = 0x71e00000,
463
        .dma_base     = 0x78400000,
464
        .esp_base     = 0x78800000,
465
        .le_base      = 0x78c00000,
466
        .power_base   = 0x7a000000,
467
        .vram_size    = 0x00100000,
468
        .nvram_size   = 0x2000,
469
        .esp_irq = 18,
470
        .le_irq = 16,
471
        .clock_irq = 7,
472
        .clock1_irq = 19,
473
        .ms_kb_irq = 14,
474
        .ser_irq = 15,
475
        .fd_irq = 22,
476
        .me_irq = 30,
477
        .cs_irq = 5,
478
        .machine_id = 0x80,
479
        .iommu_version = 0x04000000,
480
        .intbit_to_level = {
481
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
482
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
483
        },
484
    },
485
    /* SS-10 */
486
    {
487
        .iommu_base   = 0xfe0000000ULL,
488
        .tcx_base     = 0xe20000000ULL,
489
        .cs_base      = -1,
490
        .slavio_base  = 0xff0000000ULL,
491
        .ms_kb_base   = 0xff1000000ULL,
492
        .serial_base  = 0xff1100000ULL,
493
        .nvram_base   = 0xff1200000ULL,
494
        .fd_base      = 0xff1700000ULL,
495
        .counter_base = 0xff1300000ULL,
496
        .intctl_base  = 0xff1400000ULL,
497
        .dma_base     = 0xef0400000ULL,
498
        .esp_base     = 0xef0800000ULL,
499
        .le_base      = 0xef0c00000ULL,
500
        .power_base   = 0xefa000000ULL,
501
        .vram_size    = 0x00100000,
502
        .nvram_size   = 0x2000,
503
        .esp_irq = 18,
504
        .le_irq = 16,
505
        .clock_irq = 7,
506
        .clock1_irq = 19,
507
        .ms_kb_irq = 14,
508
        .ser_irq = 15,
509
        .fd_irq = 22,
510
        .me_irq = 30,
511
        .cs_irq = -1,
512
        .machine_id = 0x72,
513
        .iommu_version = 0x03000000,
514
        .intbit_to_level = {
515
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
516
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
517
        },
518
    },
519
    /* SS-600MP */
520
    {
521
        .iommu_base   = 0xfe0000000ULL,
522
        .tcx_base     = 0xe20000000ULL,
523
        .cs_base      = -1,
524
        .slavio_base  = 0xff0000000ULL,
525
        .ms_kb_base   = 0xff1000000ULL,
526
        .serial_base  = 0xff1100000ULL,
527
        .nvram_base   = 0xff1200000ULL,
528
        .fd_base      = -1,
529
        .counter_base = 0xff1300000ULL,
530
        .intctl_base  = 0xff1400000ULL,
531
        .dma_base     = 0xef0081000ULL,
532
        .esp_base     = 0xef0080000ULL,
533
        .le_base      = 0xef0060000ULL,
534
        .power_base   = 0xefa000000ULL,
535
        .vram_size    = 0x00100000,
536
        .nvram_size   = 0x2000,
537
        .esp_irq = 18,
538
        .le_irq = 16,
539
        .clock_irq = 7,
540
        .clock1_irq = 19,
541
        .ms_kb_irq = 14,
542
        .ser_irq = 15,
543
        .fd_irq = 22,
544
        .me_irq = 30,
545
        .cs_irq = -1,
546
        .machine_id = 0x71,
547
        .iommu_version = 0x01000000,
548
        .intbit_to_level = {
549
            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
550
            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
551
        },
552
    },
553
};
554

    
555
static void sun4m_common_init(int RAM_size, const char *boot_device, DisplayState *ds,
556
                              const char *kernel_filename, const char *kernel_cmdline,
557
                              const char *initrd_filename, const char *cpu_model,
558
                              unsigned int machine, int max_ram)
559
{
560
    void *nvram;
561

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

    
570
    sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
571
                      kernel_filename, kernel_cmdline, initrd_filename,
572
                      hwdefs[machine].machine_id, nvram);
573
}
574

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

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

    
601
/* SPARCserver 600MP hardware initialisation */
602
static void ss600mp_init(int RAM_size, int vga_ram_size, const char *boot_device,
603
                         DisplayState *ds, const char **fd_filename, int snapshot,
604
                         const char *kernel_filename, const char *kernel_cmdline,
605
                         const char *initrd_filename, const char *cpu_model)
606
{
607
    if (cpu_model == NULL)
608
        cpu_model = "TI SuperSparc II";
609
    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
610
                      kernel_cmdline, initrd_filename, cpu_model,
611
                      2, 0xffffffff); // XXX actually first 62GB ok
612
}
613

    
614
QEMUMachine ss5_machine = {
615
    "SS-5",
616
    "Sun4m platform, SPARCstation 5",
617
    ss5_init,
618
};
619

    
620
QEMUMachine ss10_machine = {
621
    "SS-10",
622
    "Sun4m platform, SPARCstation 10",
623
    ss10_init,
624
};
625

    
626
QEMUMachine ss600mp_machine = {
627
    "SS-600MP",
628
    "Sun4m platform, SPARCserver 600MP",
629
    ss600mp_init,
630
};