]> git.proxmox.com Git - mirror_qemu.git/blame - hw/sun4m.c
kill drives_table
[mirror_qemu.git] / hw / sun4m.c
CommitLineData
420557e8 1/*
ee76f82e 2 * QEMU Sun4m & Sun4d & Sun4c System Emulator
5fafdf24 3 *
b81b3b10 4 * Copyright (c) 2003-2005 Fabrice Bellard
5fafdf24 5 *
420557e8
FB
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 */
9d07d757 24#include "sysbus.h"
87ecb68b
PB
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"
d2c63fc1 33#include "firmware_abi.h"
8b17de88 34#include "scsi.h"
22548760
BS
35#include "pc.h"
36#include "isa.h"
3cce6243 37#include "fw_cfg.h"
b4ed08e0 38#include "escc.h"
d2c63fc1 39
b3a23197 40//#define DEBUG_IRQ
420557e8 41
36cd9210
BS
42/*
43 * Sun4m architecture was used in the following machines:
44 *
45 * SPARCserver 6xxMP/xx
77f193da
BS
46 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15),
47 * SPARCclassic X (4/10)
36cd9210
BS
48 * SPARCstation LX/ZX (4/30)
49 * SPARCstation Voyager
50 * SPARCstation 10/xx, SPARCserver 10/xx
51 * SPARCstation 5, SPARCserver 5
52 * SPARCstation 20/xx, SPARCserver 20
53 * SPARCstation 4
54 *
7d85892b
BS
55 * Sun4d architecture was used in the following machines:
56 *
57 * SPARCcenter 2000
58 * SPARCserver 1000
59 *
ee76f82e
BS
60 * Sun4c architecture was used in the following machines:
61 * SPARCstation 1/1+, SPARCserver 1/1+
62 * SPARCstation SLC
63 * SPARCstation IPC
64 * SPARCstation ELC
65 * SPARCstation IPX
66 *
36cd9210
BS
67 * See for example: http://www.sunhelp.org/faq/sunref1.html
68 */
69
b3a23197 70#ifdef DEBUG_IRQ
001faf32
BS
71#define DPRINTF(fmt, ...) \
72 do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
b3a23197 73#else
001faf32 74#define DPRINTF(fmt, ...)
b3a23197
BS
75#endif
76
420557e8 77#define KERNEL_LOAD_ADDR 0x00004000
b6f479d3 78#define CMDLINE_ADDR 0x007ff000
713c45fa 79#define INITRD_LOAD_ADDR 0x00800000
a7227727 80#define PROM_SIZE_MAX (1024 * 1024)
40ce0a9a 81#define PROM_VADDR 0xffd00000
f930d07e 82#define PROM_FILENAME "openbios-sparc32"
3cce6243 83#define CFG_ADDR 0xd00000510ULL
fbfcf955 84#define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
b8174937 85
ba3c64fb 86#define MAX_CPUS 16
b3a23197 87#define MAX_PILS 16
420557e8 88
b4ed08e0
BS
89#define ESCC_CLOCK 4915200
90
8137cde8 91struct sun4m_hwdef {
5dcb6b91
BS
92 target_phys_addr_t iommu_base, slavio_base;
93 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
94 target_phys_addr_t serial_base, fd_base;
4c2485de 95 target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
0019ad53 96 target_phys_addr_t tcx_base, cs_base, apc_base, aux1_base, aux2_base;
7eb0c8e8
BS
97 target_phys_addr_t ecc_base;
98 uint32_t ecc_version;
36cd9210 99 long vram_size, nvram_size;
6341fdcb 100 // IRQ numbers are not PIL ones, but master interrupt controller
e3a79bca 101 // register bit numbers
1572a18c 102 int esp_irq, le_irq, clock_irq, clock1_irq;
e42c20b4 103 int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq, ecc_irq;
905fdcb5
BS
104 uint8_t nvram_machine_id;
105 uint16_t machine_id;
7fbfb139 106 uint32_t iommu_version;
e0353fe2 107 uint32_t intbit_to_level[32];
3ebf5aaf
BS
108 uint64_t max_mem;
109 const char * const default_cpu_model;
36cd9210
BS
110};
111
7d85892b
BS
112#define MAX_IOUNITS 5
113
114struct sun4d_hwdef {
115 target_phys_addr_t iounit_bases[MAX_IOUNITS], slavio_base;
116 target_phys_addr_t counter_base, nvram_base, ms_kb_base;
117 target_phys_addr_t serial_base;
118 target_phys_addr_t espdma_base, esp_base;
119 target_phys_addr_t ledma_base, le_base;
120 target_phys_addr_t tcx_base;
121 target_phys_addr_t sbi_base;
122 unsigned long vram_size, nvram_size;
123 // IRQ numbers are not PIL ones, but SBI register bit numbers
124 int esp_irq, le_irq, clock_irq, clock1_irq;
125 int ser_irq, ms_kb_irq, me_irq;
905fdcb5
BS
126 uint8_t nvram_machine_id;
127 uint16_t machine_id;
7d85892b
BS
128 uint32_t iounit_version;
129 uint64_t max_mem;
130 const char * const default_cpu_model;
131};
132
8137cde8
BS
133struct sun4c_hwdef {
134 target_phys_addr_t iommu_base, slavio_base;
135 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
136 target_phys_addr_t serial_base, fd_base;
137 target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
1572a18c 138 target_phys_addr_t tcx_base, aux1_base;
8137cde8
BS
139 long vram_size, nvram_size;
140 // IRQ numbers are not PIL ones, but master interrupt controller
141 // register bit numbers
1572a18c
BS
142 int esp_irq, le_irq, clock_irq, clock1_irq;
143 int ser_irq, ms_kb_irq, fd_irq, me_irq;
8137cde8
BS
144 uint8_t nvram_machine_id;
145 uint16_t machine_id;
146 uint32_t iommu_version;
147 uint32_t intbit_to_level[32];
148 uint64_t max_mem;
149 const char * const default_cpu_model;
150};
151
6f7e9aec
FB
152int DMA_get_channel_mode (int nchan)
153{
154 return 0;
155}
156int DMA_read_memory (int nchan, void *buf, int pos, int size)
157{
158 return 0;
159}
160int DMA_write_memory (int nchan, void *buf, int pos, int size)
161{
162 return 0;
163}
164void DMA_hold_DREQ (int nchan) {}
165void DMA_release_DREQ (int nchan) {}
166void DMA_schedule(int nchan) {}
6f7e9aec
FB
167void DMA_init (int high_page_enable) {}
168void DMA_register_channel (int nchan,
169 DMA_transfer_handler transfer_handler,
170 void *opaque)
171{
172}
173
513f789f 174static int fw_cfg_boot_set(void *opaque, const char *boot_device)
81864572 175{
513f789f 176 fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
81864572
BS
177 return 0;
178}
179
819385c5 180static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
6ef05b95 181 const char *boot_devices, ram_addr_t RAM_size,
f930d07e
BS
182 uint32_t kernel_size,
183 int width, int height, int depth,
905fdcb5 184 int nvram_machine_id, const char *arch)
e80cfcfc 185{
d2c63fc1 186 unsigned int i;
66508601 187 uint32_t start, end;
d2c63fc1 188 uint8_t image[0x1ff0];
d2c63fc1
BS
189 struct OpenBIOS_nvpart_v1 *part_header;
190
191 memset(image, '\0', sizeof(image));
e80cfcfc 192
513f789f 193 start = 0;
b6f479d3 194
66508601
BS
195 // OpenBIOS nvram variables
196 // Variable partition
d2c63fc1
BS
197 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
198 part_header->signature = OPENBIOS_PART_SYSTEM;
363a37d5 199 pstrcpy(part_header->name, sizeof(part_header->name), "system");
66508601 200
d2c63fc1 201 end = start + sizeof(struct OpenBIOS_nvpart_v1);
66508601 202 for (i = 0; i < nb_prom_envs; i++)
d2c63fc1
BS
203 end = OpenBIOS_set_var(image, end, prom_envs[i]);
204
205 // End marker
206 image[end++] = '\0';
66508601 207
66508601 208 end = start + ((end - start + 15) & ~15);
d2c63fc1 209 OpenBIOS_finish_partition(part_header, end - start);
66508601
BS
210
211 // free partition
212 start = end;
d2c63fc1
BS
213 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
214 part_header->signature = OPENBIOS_PART_FREE;
363a37d5 215 pstrcpy(part_header->name, sizeof(part_header->name), "free");
66508601
BS
216
217 end = 0x1fd0;
d2c63fc1
BS
218 OpenBIOS_finish_partition(part_header, end - start);
219
905fdcb5
BS
220 Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr,
221 nvram_machine_id);
d2c63fc1
BS
222
223 for (i = 0; i < sizeof(image); i++)
224 m48t59_write(nvram, i, image[i]);
e80cfcfc
FB
225}
226
227static void *slavio_intctl;
228
376253ec 229void pic_info(Monitor *mon)
e80cfcfc 230{
7d85892b 231 if (slavio_intctl)
376253ec 232 slavio_pic_info(mon, slavio_intctl);
e80cfcfc
FB
233}
234
376253ec 235void irq_info(Monitor *mon)
e80cfcfc 236{
7d85892b 237 if (slavio_intctl)
376253ec 238 slavio_irq_info(mon, slavio_intctl);
e80cfcfc
FB
239}
240
327ac2e7
BS
241void cpu_check_irqs(CPUState *env)
242{
243 if (env->pil_in && (env->interrupt_index == 0 ||
244 (env->interrupt_index & ~15) == TT_EXTINT)) {
245 unsigned int i;
246
247 for (i = 15; i > 0; i--) {
248 if (env->pil_in & (1 << i)) {
249 int old_interrupt = env->interrupt_index;
250
251 env->interrupt_index = TT_EXTINT | i;
f32d7ec5
BS
252 if (old_interrupt != env->interrupt_index) {
253 DPRINTF("Set CPU IRQ %d\n", i);
327ac2e7 254 cpu_interrupt(env, CPU_INTERRUPT_HARD);
f32d7ec5 255 }
327ac2e7
BS
256 break;
257 }
258 }
259 } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
f32d7ec5 260 DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
327ac2e7
BS
261 env->interrupt_index = 0;
262 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
263 }
264}
265
b3a23197
BS
266static 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);
b3a23197 272 env->halted = 0;
327ac2e7
BS
273 env->pil_in |= 1 << irq;
274 cpu_check_irqs(env);
b3a23197
BS
275 } else {
276 DPRINTF("Lower CPU IRQ %d\n", irq);
327ac2e7
BS
277 env->pil_in &= ~(1 << irq);
278 cpu_check_irqs(env);
b3a23197
BS
279 }
280}
281
282static void dummy_cpu_set_irq(void *opaque, int irq, int level)
283{
284}
285
3475187d
FB
286static void *slavio_misc;
287
288void qemu_system_powerdown(void)
289{
290 slavio_set_power_fail(slavio_misc, 1);
291}
292
c68ea704
FB
293static void main_cpu_reset(void *opaque)
294{
295 CPUState *env = opaque;
3d29fbef
BS
296
297 cpu_reset(env);
298 env->halted = 0;
299}
300
301static void secondary_cpu_reset(void *opaque)
302{
303 CPUState *env = opaque;
304
c68ea704 305 cpu_reset(env);
3d29fbef 306 env->halted = 1;
c68ea704
FB
307}
308
6d0c293d
BS
309static void cpu_halt_signal(void *opaque, int irq, int level)
310{
311 if (level && cpu_single_env)
312 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
313}
314
3ebf5aaf 315static unsigned long sun4m_load_kernel(const char *kernel_filename,
293f78bc
BS
316 const char *initrd_filename,
317 ram_addr_t RAM_size)
3ebf5aaf
BS
318{
319 int linux_boot;
320 unsigned int i;
321 long initrd_size, kernel_size;
322
323 linux_boot = (kernel_filename != NULL);
324
325 kernel_size = 0;
326 if (linux_boot) {
327 kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
328 NULL);
329 if (kernel_size < 0)
293f78bc
BS
330 kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
331 RAM_size - KERNEL_LOAD_ADDR);
3ebf5aaf 332 if (kernel_size < 0)
293f78bc
BS
333 kernel_size = load_image_targphys(kernel_filename,
334 KERNEL_LOAD_ADDR,
335 RAM_size - KERNEL_LOAD_ADDR);
3ebf5aaf
BS
336 if (kernel_size < 0) {
337 fprintf(stderr, "qemu: could not load kernel '%s'\n",
338 kernel_filename);
339 exit(1);
340 }
341
342 /* load initrd */
343 initrd_size = 0;
344 if (initrd_filename) {
293f78bc
BS
345 initrd_size = load_image_targphys(initrd_filename,
346 INITRD_LOAD_ADDR,
347 RAM_size - INITRD_LOAD_ADDR);
3ebf5aaf
BS
348 if (initrd_size < 0) {
349 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
350 initrd_filename);
351 exit(1);
352 }
353 }
354 if (initrd_size > 0) {
355 for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
293f78bc
BS
356 if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
357 stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
358 stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size);
3ebf5aaf
BS
359 break;
360 }
361 }
362 }
363 }
364 return kernel_size;
365}
366
9d07d757
PB
367static void lance_init(NICInfo *nd, target_phys_addr_t leaddr,
368 void *dma_opaque, qemu_irq irq, qemu_irq *reset)
369{
370 DeviceState *dev;
371 SysBusDevice *s;
372
373 qemu_check_nic_model(&nd_table[0], "lance");
374
375 dev = qdev_create(NULL, "lance");
ee6847d1 376 dev->nd = nd;
daa65491 377 qdev_prop_set_ptr(dev, "dma", dma_opaque);
9d07d757
PB
378 qdev_init(dev);
379 s = sysbus_from_qdev(dev);
380 sysbus_mmio_map(s, 0, leaddr);
381 sysbus_connect_irq(s, 0, irq);
067a3ddc 382 *reset = qdev_get_gpio_in(dev, 0);
9d07d757
PB
383}
384
325f2747
BS
385/* NCR89C100/MACIO Internal ID register */
386static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 };
387
388static void idreg_init(target_phys_addr_t addr)
389{
390 DeviceState *dev;
391 SysBusDevice *s;
392
393 dev = qdev_create(NULL, "macio_idreg");
394 qdev_init(dev);
395 s = sysbus_from_qdev(dev);
396
397 sysbus_mmio_map(s, 0, addr);
398 cpu_physical_memory_write_rom(addr, idreg_data, sizeof(idreg_data));
399}
400
401static void idreg_init1(SysBusDevice *dev)
402{
403 ram_addr_t idreg_offset;
404
405 idreg_offset = qemu_ram_alloc(sizeof(idreg_data));
406 sysbus_init_mmio(dev, sizeof(idreg_data), idreg_offset | IO_MEM_ROM);
407}
408
409static SysBusDeviceInfo idreg_info = {
410 .init = idreg_init1,
411 .qdev.name = "macio_idreg",
412 .qdev.size = sizeof(SysBusDevice),
325f2747
BS
413};
414
415static void idreg_register_devices(void)
416{
417 sysbus_register_withprop(&idreg_info);
418}
419
420device_init(idreg_register_devices);
421
f48f6569
BS
422/* Boot PROM (OpenBIOS) */
423static void prom_init(target_phys_addr_t addr, const char *bios_name)
424{
425 DeviceState *dev;
426 SysBusDevice *s;
427 char *filename;
428 int ret;
429
430 dev = qdev_create(NULL, "openprom");
431 qdev_init(dev);
432 s = sysbus_from_qdev(dev);
433
434 sysbus_mmio_map(s, 0, addr);
435
436 /* load boot prom */
437 if (bios_name == NULL) {
438 bios_name = PROM_FILENAME;
439 }
440 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
441 if (filename) {
442 ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL);
443 if (ret < 0 || ret > PROM_SIZE_MAX) {
444 ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
445 }
446 qemu_free(filename);
447 } else {
448 ret = -1;
449 }
450 if (ret < 0 || ret > PROM_SIZE_MAX) {
451 fprintf(stderr, "qemu: could not load prom '%s'\n", bios_name);
452 exit(1);
453 }
454}
455
456static void prom_init1(SysBusDevice *dev)
457{
458 ram_addr_t prom_offset;
459
460 prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
461 sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM);
462}
463
464static SysBusDeviceInfo prom_info = {
465 .init = prom_init1,
466 .qdev.name = "openprom",
467 .qdev.size = sizeof(SysBusDevice),
ee6847d1
GH
468 .qdev.props = (Property[]) {
469 {/* end of property list */}
f48f6569
BS
470 }
471};
472
473static void prom_register_devices(void)
474{
475 sysbus_register_withprop(&prom_info);
476}
477
478device_init(prom_register_devices);
479
ee6847d1
GH
480typedef struct RamDevice
481{
482 SysBusDevice busdev;
04843626 483 uint64_t size;
ee6847d1
GH
484} RamDevice;
485
a350db85
BS
486/* System RAM */
487static void ram_init1(SysBusDevice *dev)
488{
489 ram_addr_t RAM_size, ram_offset;
ee6847d1 490 RamDevice *d = FROM_SYSBUS(RamDevice, dev);
a350db85 491
ee6847d1 492 RAM_size = d->size;
a350db85
BS
493
494 ram_offset = qemu_ram_alloc(RAM_size);
495 sysbus_init_mmio(dev, RAM_size, ram_offset);
496}
497
498static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size,
499 uint64_t max_mem)
500{
501 DeviceState *dev;
502 SysBusDevice *s;
ee6847d1 503 RamDevice *d;
a350db85
BS
504
505 /* allocate RAM */
506 if ((uint64_t)RAM_size > max_mem) {
507 fprintf(stderr,
508 "qemu: Too much memory for this machine: %d, maximum %d\n",
509 (unsigned int)(RAM_size / (1024 * 1024)),
510 (unsigned int)(max_mem / (1024 * 1024)));
511 exit(1);
512 }
513 dev = qdev_create(NULL, "memory");
a350db85
BS
514 s = sysbus_from_qdev(dev);
515
ee6847d1
GH
516 d = FROM_SYSBUS(RamDevice, s);
517 d->size = RAM_size;
f6e097e7 518 qdev_init(dev);
ee6847d1 519
a350db85
BS
520 sysbus_mmio_map(s, 0, addr);
521}
522
523static SysBusDeviceInfo ram_info = {
524 .init = ram_init1,
525 .qdev.name = "memory",
ee6847d1
GH
526 .qdev.size = sizeof(RamDevice),
527 .qdev.props = (Property[]) {
528 {
529 .name = "size",
04843626 530 .info = &qdev_prop_uint64,
ee6847d1
GH
531 .offset = offsetof(RamDevice, size),
532 },
533 {/* end of property list */}
a350db85
BS
534 }
535};
536
537static void ram_register_devices(void)
538{
539 sysbus_register_withprop(&ram_info);
540}
541
542device_init(ram_register_devices);
543
666713c0
BS
544static CPUState *cpu_devinit(const char *cpu_model, unsigned int id,
545 uint64_t prom_addr, qemu_irq **cpu_irqs)
546{
547 CPUState *env;
548
549 env = cpu_init(cpu_model);
550 if (!env) {
551 fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
552 exit(1);
553 }
554
555 cpu_sparc_set_id(env, id);
556 if (id == 0) {
557 qemu_register_reset(main_cpu_reset, env);
558 } else {
559 qemu_register_reset(secondary_cpu_reset, env);
560 env->halted = 1;
561 }
562 *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
563 env->prom_addr = prom_addr;
564
565 return env;
566}
567
8137cde8 568static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
3ebf5aaf 569 const char *boot_device,
3023f332 570 const char *kernel_filename,
3ebf5aaf
BS
571 const char *kernel_cmdline,
572 const char *initrd_filename, const char *cpu_model)
420557e8 573{
666713c0 574 CPUState *envs[MAX_CPUS];
713c45fa 575 unsigned int i;
cfb9de9c 576 void *iommu, *espdma, *ledma, *nvram;
a1961a4b 577 qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
6f6260c7 578 espdma_irq, ledma_irq;
2d069bab 579 qemu_irq *esp_reset, *le_reset;
2582cfa0 580 qemu_irq fdc_tc;
6d0c293d 581 qemu_irq *cpu_halt;
5c6602c5 582 unsigned long kernel_size;
e4bcb14c 583 BlockDriverState *fd[MAX_FD];
3cce6243 584 void *fw_cfg;
a1961a4b 585 DeviceState *dev;
751c6a17 586 DriveInfo *dinfo;
420557e8 587
ba3c64fb 588 /* init CPUs */
3ebf5aaf
BS
589 if (!cpu_model)
590 cpu_model = hwdef->default_cpu_model;
b3a23197 591
ba3c64fb 592 for(i = 0; i < smp_cpus; i++) {
666713c0 593 envs[i] = cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
ba3c64fb 594 }
b3a23197
BS
595
596 for (i = smp_cpus; i < MAX_CPUS; i++)
597 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
598
3ebf5aaf 599
3ebf5aaf 600 /* set up devices */
a350db85
BS
601 ram_init(0, RAM_size, hwdef->max_mem);
602
f48f6569
BS
603 prom_init(hwdef->slavio_base, bios_name);
604
a1961a4b
BS
605 dev = slavio_intctl_init(hwdef->intctl_base,
606 hwdef->intctl_base + 0x10000ULL,
607 &hwdef->intbit_to_level[0],
608 cpu_irqs,
609 hwdef->clock_irq);
610
611 for (i = 0; i < 32; i++) {
612 slavio_irq[i] = qdev_get_gpio_in(dev, i);
613 }
614 for (i = 0; i < MAX_CPUS; i++) {
615 slavio_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
616 }
b3a23197 617
fe096129 618 if (hwdef->idreg_base) {
325f2747 619 idreg_init(hwdef->idreg_base);
4c2485de
BS
620 }
621
ff403da6
BS
622 iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
623 slavio_irq[hwdef->me_irq]);
624
5aca8c3b 625 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
2d069bab
BS
626 iommu, &espdma_irq, &esp_reset);
627
5aca8c3b 628 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
2d069bab
BS
629 slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
630 &le_reset);
ba3c64fb 631
eee0b836
BS
632 if (graphic_depth != 8 && graphic_depth != 24) {
633 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
634 exit (1);
635 }
dc828ca1
PB
636 tcx_init(hwdef->tcx_base, hwdef->vram_size, graphic_width, graphic_height,
637 graphic_depth);
dbe06e18 638
6f6260c7 639 lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq, le_reset);
dbe06e18 640
d537cf6c
PB
641 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
642 hwdef->nvram_size, 8);
81732d19
BS
643
644 slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
19f8e5dd 645 slavio_cpu_irq, smp_cpus);
81732d19 646
577390ff 647 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
993fbfdb 648 display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
b81b3b10
FB
649 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
650 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
aeeb69c7
AJ
651 escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], slavio_irq[hwdef->ser_irq],
652 serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
741402f9 653
6d0c293d 654 cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1);
2582cfa0 655 slavio_misc = slavio_misc_init(hwdef->slavio_base,
2be17ebd 656 hwdef->aux1_base, hwdef->aux2_base,
2582cfa0
BS
657 slavio_irq[hwdef->me_irq], fdc_tc);
658 if (hwdef->apc_base) {
659 apc_init(hwdef->apc_base, cpu_halt[0]);
660 }
2be17ebd 661
fe096129 662 if (hwdef->fd_base) {
e4bcb14c 663 /* there is zero or one floppy drive */
309e60bd 664 memset(fd, 0, sizeof(fd));
751c6a17
GH
665 dinfo = drive_get(IF_FLOPPY, 0, 0);
666 if (dinfo)
667 fd[0] = dinfo->bdrv;
2d069bab 668
2be17ebd 669 sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
2582cfa0 670 &fdc_tc);
e4bcb14c
TS
671 }
672
673 if (drive_get_max_bus(IF_SCSI) > 0) {
674 fprintf(stderr, "qemu: too many SCSI bus\n");
675 exit(1);
676 }
677
cfb9de9c
PB
678 esp_init(hwdef->esp_base, 2,
679 espdma_memory_read, espdma_memory_write,
6f6260c7 680 espdma, espdma_irq, esp_reset);
f1587550 681
fa28ec52
BS
682 if (hwdef->cs_base) {
683 sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,
684 slavio_irq[hwdef->cs_irq]);
685 }
b3ceef24 686
293f78bc
BS
687 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
688 RAM_size);
36cd9210 689
36cd9210 690 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
b3ceef24 691 boot_device, RAM_size, kernel_size, graphic_width,
905fdcb5
BS
692 graphic_height, graphic_depth, hwdef->nvram_machine_id,
693 "Sun4m");
7eb0c8e8 694
fe096129 695 if (hwdef->ecc_base)
e42c20b4
BS
696 ecc_init(hwdef->ecc_base, slavio_irq[hwdef->ecc_irq],
697 hwdef->ecc_version);
3cce6243
BS
698
699 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
700 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
905fdcb5
BS
701 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
702 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
fbfcf955 703 fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
513f789f
BS
704 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
705 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
706 if (kernel_cmdline) {
707 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
708 pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
709 } else {
710 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
711 }
712 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
713 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
714 fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
715 qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
36cd9210
BS
716}
717
905fdcb5
BS
718enum {
719 ss2_id = 0,
720 ss5_id = 32,
721 vger_id,
722 lx_id,
723 ss4_id,
724 scls_id,
725 sbook_id,
726 ss10_id = 64,
727 ss20_id,
728 ss600mp_id,
729 ss1000_id = 96,
730 ss2000_id,
731};
732
8137cde8 733static const struct sun4m_hwdef sun4m_hwdefs[] = {
36cd9210
BS
734 /* SS-5 */
735 {
736 .iommu_base = 0x10000000,
737 .tcx_base = 0x50000000,
738 .cs_base = 0x6c000000,
384ccb5d 739 .slavio_base = 0x70000000,
36cd9210
BS
740 .ms_kb_base = 0x71000000,
741 .serial_base = 0x71100000,
742 .nvram_base = 0x71200000,
743 .fd_base = 0x71400000,
744 .counter_base = 0x71d00000,
745 .intctl_base = 0x71e00000,
4c2485de 746 .idreg_base = 0x78000000,
36cd9210
BS
747 .dma_base = 0x78400000,
748 .esp_base = 0x78800000,
749 .le_base = 0x78c00000,
127fc407 750 .apc_base = 0x6a000000,
0019ad53
BS
751 .aux1_base = 0x71900000,
752 .aux2_base = 0x71910000,
36cd9210
BS
753 .vram_size = 0x00100000,
754 .nvram_size = 0x2000,
755 .esp_irq = 18,
756 .le_irq = 16,
e3a79bca 757 .clock_irq = 7,
36cd9210
BS
758 .clock1_irq = 19,
759 .ms_kb_irq = 14,
760 .ser_irq = 15,
761 .fd_irq = 22,
762 .me_irq = 30,
763 .cs_irq = 5,
905fdcb5
BS
764 .nvram_machine_id = 0x80,
765 .machine_id = ss5_id,
cf3102ac 766 .iommu_version = 0x05000000,
e0353fe2 767 .intbit_to_level = {
f930d07e
BS
768 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
769 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
e0353fe2 770 },
3ebf5aaf
BS
771 .max_mem = 0x10000000,
772 .default_cpu_model = "Fujitsu MB86904",
e0353fe2
BS
773 },
774 /* SS-10 */
e0353fe2 775 {
5dcb6b91
BS
776 .iommu_base = 0xfe0000000ULL,
777 .tcx_base = 0xe20000000ULL,
5dcb6b91
BS
778 .slavio_base = 0xff0000000ULL,
779 .ms_kb_base = 0xff1000000ULL,
780 .serial_base = 0xff1100000ULL,
781 .nvram_base = 0xff1200000ULL,
782 .fd_base = 0xff1700000ULL,
783 .counter_base = 0xff1300000ULL,
784 .intctl_base = 0xff1400000ULL,
4c2485de 785 .idreg_base = 0xef0000000ULL,
5dcb6b91
BS
786 .dma_base = 0xef0400000ULL,
787 .esp_base = 0xef0800000ULL,
788 .le_base = 0xef0c00000ULL,
0019ad53 789 .apc_base = 0xefa000000ULL, // XXX should not exist
127fc407
BS
790 .aux1_base = 0xff1800000ULL,
791 .aux2_base = 0xff1a01000ULL,
7eb0c8e8
BS
792 .ecc_base = 0xf00000000ULL,
793 .ecc_version = 0x10000000, // version 0, implementation 1
e0353fe2
BS
794 .vram_size = 0x00100000,
795 .nvram_size = 0x2000,
796 .esp_irq = 18,
797 .le_irq = 16,
e3a79bca 798 .clock_irq = 7,
e0353fe2
BS
799 .clock1_irq = 19,
800 .ms_kb_irq = 14,
801 .ser_irq = 15,
802 .fd_irq = 22,
803 .me_irq = 30,
e42c20b4 804 .ecc_irq = 28,
905fdcb5
BS
805 .nvram_machine_id = 0x72,
806 .machine_id = ss10_id,
7fbfb139 807 .iommu_version = 0x03000000,
e0353fe2 808 .intbit_to_level = {
f930d07e
BS
809 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
810 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
e0353fe2 811 },
6ef05b95 812 .max_mem = 0xf00000000ULL,
3ebf5aaf 813 .default_cpu_model = "TI SuperSparc II",
36cd9210 814 },
6a3b9cc9
BS
815 /* SS-600MP */
816 {
817 .iommu_base = 0xfe0000000ULL,
818 .tcx_base = 0xe20000000ULL,
6a3b9cc9
BS
819 .slavio_base = 0xff0000000ULL,
820 .ms_kb_base = 0xff1000000ULL,
821 .serial_base = 0xff1100000ULL,
822 .nvram_base = 0xff1200000ULL,
6a3b9cc9
BS
823 .counter_base = 0xff1300000ULL,
824 .intctl_base = 0xff1400000ULL,
825 .dma_base = 0xef0081000ULL,
826 .esp_base = 0xef0080000ULL,
827 .le_base = 0xef0060000ULL,
0019ad53 828 .apc_base = 0xefa000000ULL, // XXX should not exist
127fc407
BS
829 .aux1_base = 0xff1800000ULL,
830 .aux2_base = 0xff1a01000ULL, // XXX should not exist
7eb0c8e8
BS
831 .ecc_base = 0xf00000000ULL,
832 .ecc_version = 0x00000000, // version 0, implementation 0
6a3b9cc9
BS
833 .vram_size = 0x00100000,
834 .nvram_size = 0x2000,
835 .esp_irq = 18,
836 .le_irq = 16,
e3a79bca 837 .clock_irq = 7,
6a3b9cc9
BS
838 .clock1_irq = 19,
839 .ms_kb_irq = 14,
840 .ser_irq = 15,
841 .fd_irq = 22,
842 .me_irq = 30,
e42c20b4 843 .ecc_irq = 28,
905fdcb5
BS
844 .nvram_machine_id = 0x71,
845 .machine_id = ss600mp_id,
7fbfb139 846 .iommu_version = 0x01000000,
6a3b9cc9
BS
847 .intbit_to_level = {
848 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
849 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
850 },
6ef05b95 851 .max_mem = 0xf00000000ULL,
3ebf5aaf 852 .default_cpu_model = "TI SuperSparc II",
6a3b9cc9 853 },
ae40972f
BS
854 /* SS-20 */
855 {
856 .iommu_base = 0xfe0000000ULL,
857 .tcx_base = 0xe20000000ULL,
ae40972f
BS
858 .slavio_base = 0xff0000000ULL,
859 .ms_kb_base = 0xff1000000ULL,
860 .serial_base = 0xff1100000ULL,
861 .nvram_base = 0xff1200000ULL,
862 .fd_base = 0xff1700000ULL,
863 .counter_base = 0xff1300000ULL,
864 .intctl_base = 0xff1400000ULL,
4c2485de 865 .idreg_base = 0xef0000000ULL,
ae40972f
BS
866 .dma_base = 0xef0400000ULL,
867 .esp_base = 0xef0800000ULL,
868 .le_base = 0xef0c00000ULL,
0019ad53 869 .apc_base = 0xefa000000ULL, // XXX should not exist
577d8dd4
BS
870 .aux1_base = 0xff1800000ULL,
871 .aux2_base = 0xff1a01000ULL,
ae40972f
BS
872 .ecc_base = 0xf00000000ULL,
873 .ecc_version = 0x20000000, // version 0, implementation 2
874 .vram_size = 0x00100000,
875 .nvram_size = 0x2000,
876 .esp_irq = 18,
877 .le_irq = 16,
e3a79bca 878 .clock_irq = 7,
ae40972f
BS
879 .clock1_irq = 19,
880 .ms_kb_irq = 14,
881 .ser_irq = 15,
882 .fd_irq = 22,
883 .me_irq = 30,
e42c20b4 884 .ecc_irq = 28,
905fdcb5
BS
885 .nvram_machine_id = 0x72,
886 .machine_id = ss20_id,
ae40972f
BS
887 .iommu_version = 0x13000000,
888 .intbit_to_level = {
889 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
890 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
891 },
6ef05b95 892 .max_mem = 0xf00000000ULL,
ae40972f
BS
893 .default_cpu_model = "TI SuperSparc II",
894 },
a526a31c
BS
895 /* Voyager */
896 {
897 .iommu_base = 0x10000000,
898 .tcx_base = 0x50000000,
a526a31c
BS
899 .slavio_base = 0x70000000,
900 .ms_kb_base = 0x71000000,
901 .serial_base = 0x71100000,
902 .nvram_base = 0x71200000,
903 .fd_base = 0x71400000,
904 .counter_base = 0x71d00000,
905 .intctl_base = 0x71e00000,
906 .idreg_base = 0x78000000,
907 .dma_base = 0x78400000,
908 .esp_base = 0x78800000,
909 .le_base = 0x78c00000,
910 .apc_base = 0x71300000, // pmc
911 .aux1_base = 0x71900000,
912 .aux2_base = 0x71910000,
a526a31c
BS
913 .vram_size = 0x00100000,
914 .nvram_size = 0x2000,
915 .esp_irq = 18,
916 .le_irq = 16,
917 .clock_irq = 7,
918 .clock1_irq = 19,
919 .ms_kb_irq = 14,
920 .ser_irq = 15,
921 .fd_irq = 22,
922 .me_irq = 30,
905fdcb5
BS
923 .nvram_machine_id = 0x80,
924 .machine_id = vger_id,
a526a31c
BS
925 .iommu_version = 0x05000000,
926 .intbit_to_level = {
927 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
928 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
929 },
930 .max_mem = 0x10000000,
931 .default_cpu_model = "Fujitsu MB86904",
932 },
933 /* LX */
934 {
935 .iommu_base = 0x10000000,
936 .tcx_base = 0x50000000,
a526a31c
BS
937 .slavio_base = 0x70000000,
938 .ms_kb_base = 0x71000000,
939 .serial_base = 0x71100000,
940 .nvram_base = 0x71200000,
941 .fd_base = 0x71400000,
942 .counter_base = 0x71d00000,
943 .intctl_base = 0x71e00000,
944 .idreg_base = 0x78000000,
945 .dma_base = 0x78400000,
946 .esp_base = 0x78800000,
947 .le_base = 0x78c00000,
a526a31c
BS
948 .aux1_base = 0x71900000,
949 .aux2_base = 0x71910000,
a526a31c
BS
950 .vram_size = 0x00100000,
951 .nvram_size = 0x2000,
952 .esp_irq = 18,
953 .le_irq = 16,
954 .clock_irq = 7,
955 .clock1_irq = 19,
956 .ms_kb_irq = 14,
957 .ser_irq = 15,
958 .fd_irq = 22,
959 .me_irq = 30,
905fdcb5
BS
960 .nvram_machine_id = 0x80,
961 .machine_id = lx_id,
a526a31c
BS
962 .iommu_version = 0x04000000,
963 .intbit_to_level = {
964 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
965 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
966 },
967 .max_mem = 0x10000000,
968 .default_cpu_model = "TI MicroSparc I",
969 },
970 /* SS-4 */
971 {
972 .iommu_base = 0x10000000,
973 .tcx_base = 0x50000000,
974 .cs_base = 0x6c000000,
975 .slavio_base = 0x70000000,
976 .ms_kb_base = 0x71000000,
977 .serial_base = 0x71100000,
978 .nvram_base = 0x71200000,
979 .fd_base = 0x71400000,
980 .counter_base = 0x71d00000,
981 .intctl_base = 0x71e00000,
982 .idreg_base = 0x78000000,
983 .dma_base = 0x78400000,
984 .esp_base = 0x78800000,
985 .le_base = 0x78c00000,
986 .apc_base = 0x6a000000,
987 .aux1_base = 0x71900000,
988 .aux2_base = 0x71910000,
a526a31c
BS
989 .vram_size = 0x00100000,
990 .nvram_size = 0x2000,
991 .esp_irq = 18,
992 .le_irq = 16,
993 .clock_irq = 7,
994 .clock1_irq = 19,
995 .ms_kb_irq = 14,
996 .ser_irq = 15,
997 .fd_irq = 22,
998 .me_irq = 30,
999 .cs_irq = 5,
905fdcb5
BS
1000 .nvram_machine_id = 0x80,
1001 .machine_id = ss4_id,
a526a31c
BS
1002 .iommu_version = 0x05000000,
1003 .intbit_to_level = {
1004 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
1005 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
1006 },
1007 .max_mem = 0x10000000,
1008 .default_cpu_model = "Fujitsu MB86904",
1009 },
1010 /* SPARCClassic */
1011 {
1012 .iommu_base = 0x10000000,
1013 .tcx_base = 0x50000000,
a526a31c
BS
1014 .slavio_base = 0x70000000,
1015 .ms_kb_base = 0x71000000,
1016 .serial_base = 0x71100000,
1017 .nvram_base = 0x71200000,
1018 .fd_base = 0x71400000,
1019 .counter_base = 0x71d00000,
1020 .intctl_base = 0x71e00000,
1021 .idreg_base = 0x78000000,
1022 .dma_base = 0x78400000,
1023 .esp_base = 0x78800000,
1024 .le_base = 0x78c00000,
1025 .apc_base = 0x6a000000,
1026 .aux1_base = 0x71900000,
1027 .aux2_base = 0x71910000,
a526a31c
BS
1028 .vram_size = 0x00100000,
1029 .nvram_size = 0x2000,
1030 .esp_irq = 18,
1031 .le_irq = 16,
1032 .clock_irq = 7,
1033 .clock1_irq = 19,
1034 .ms_kb_irq = 14,
1035 .ser_irq = 15,
1036 .fd_irq = 22,
1037 .me_irq = 30,
905fdcb5
BS
1038 .nvram_machine_id = 0x80,
1039 .machine_id = scls_id,
a526a31c
BS
1040 .iommu_version = 0x05000000,
1041 .intbit_to_level = {
1042 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
1043 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
1044 },
1045 .max_mem = 0x10000000,
1046 .default_cpu_model = "TI MicroSparc I",
1047 },
1048 /* SPARCbook */
1049 {
1050 .iommu_base = 0x10000000,
1051 .tcx_base = 0x50000000, // XXX
a526a31c
BS
1052 .slavio_base = 0x70000000,
1053 .ms_kb_base = 0x71000000,
1054 .serial_base = 0x71100000,
1055 .nvram_base = 0x71200000,
1056 .fd_base = 0x71400000,
1057 .counter_base = 0x71d00000,
1058 .intctl_base = 0x71e00000,
1059 .idreg_base = 0x78000000,
1060 .dma_base = 0x78400000,
1061 .esp_base = 0x78800000,
1062 .le_base = 0x78c00000,
1063 .apc_base = 0x6a000000,
1064 .aux1_base = 0x71900000,
1065 .aux2_base = 0x71910000,
a526a31c
BS
1066 .vram_size = 0x00100000,
1067 .nvram_size = 0x2000,
1068 .esp_irq = 18,
1069 .le_irq = 16,
1070 .clock_irq = 7,
1071 .clock1_irq = 19,
1072 .ms_kb_irq = 14,
1073 .ser_irq = 15,
1074 .fd_irq = 22,
1075 .me_irq = 30,
905fdcb5
BS
1076 .nvram_machine_id = 0x80,
1077 .machine_id = sbook_id,
a526a31c
BS
1078 .iommu_version = 0x05000000,
1079 .intbit_to_level = {
1080 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
1081 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
1082 },
1083 .max_mem = 0x10000000,
1084 .default_cpu_model = "TI MicroSparc I",
1085 },
36cd9210
BS
1086};
1087
36cd9210 1088/* SPARCstation 5 hardware initialisation */
fbe1b595 1089static void ss5_init(ram_addr_t RAM_size,
3023f332 1090 const char *boot_device,
b881c2c6
BS
1091 const char *kernel_filename, const char *kernel_cmdline,
1092 const char *initrd_filename, const char *cpu_model)
36cd9210 1093{
3023f332 1094 sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
3ebf5aaf 1095 kernel_cmdline, initrd_filename, cpu_model);
420557e8 1096}
c0e564d5 1097
e0353fe2 1098/* SPARCstation 10 hardware initialisation */
fbe1b595 1099static void ss10_init(ram_addr_t RAM_size,
3023f332 1100 const char *boot_device,
b881c2c6
BS
1101 const char *kernel_filename, const char *kernel_cmdline,
1102 const char *initrd_filename, const char *cpu_model)
e0353fe2 1103{
3023f332 1104 sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
3ebf5aaf 1105 kernel_cmdline, initrd_filename, cpu_model);
e0353fe2
BS
1106}
1107
6a3b9cc9 1108/* SPARCserver 600MP hardware initialisation */
fbe1b595 1109static void ss600mp_init(ram_addr_t RAM_size,
3023f332 1110 const char *boot_device,
77f193da
BS
1111 const char *kernel_filename,
1112 const char *kernel_cmdline,
6a3b9cc9
BS
1113 const char *initrd_filename, const char *cpu_model)
1114{
3023f332 1115 sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
3ebf5aaf 1116 kernel_cmdline, initrd_filename, cpu_model);
6a3b9cc9
BS
1117}
1118
ae40972f 1119/* SPARCstation 20 hardware initialisation */
fbe1b595 1120static void ss20_init(ram_addr_t RAM_size,
3023f332 1121 const char *boot_device,
ae40972f
BS
1122 const char *kernel_filename, const char *kernel_cmdline,
1123 const char *initrd_filename, const char *cpu_model)
1124{
3023f332 1125 sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
ee76f82e
BS
1126 kernel_cmdline, initrd_filename, cpu_model);
1127}
1128
a526a31c 1129/* SPARCstation Voyager hardware initialisation */
fbe1b595 1130static void vger_init(ram_addr_t RAM_size,
3023f332 1131 const char *boot_device,
a526a31c
BS
1132 const char *kernel_filename, const char *kernel_cmdline,
1133 const char *initrd_filename, const char *cpu_model)
1134{
3023f332 1135 sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
a526a31c
BS
1136 kernel_cmdline, initrd_filename, cpu_model);
1137}
1138
1139/* SPARCstation LX hardware initialisation */
fbe1b595 1140static void ss_lx_init(ram_addr_t RAM_size,
3023f332 1141 const char *boot_device,
a526a31c
BS
1142 const char *kernel_filename, const char *kernel_cmdline,
1143 const char *initrd_filename, const char *cpu_model)
1144{
3023f332 1145 sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
a526a31c
BS
1146 kernel_cmdline, initrd_filename, cpu_model);
1147}
1148
1149/* SPARCstation 4 hardware initialisation */
fbe1b595 1150static void ss4_init(ram_addr_t RAM_size,
3023f332 1151 const char *boot_device,
a526a31c
BS
1152 const char *kernel_filename, const char *kernel_cmdline,
1153 const char *initrd_filename, const char *cpu_model)
1154{
3023f332 1155 sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
a526a31c
BS
1156 kernel_cmdline, initrd_filename, cpu_model);
1157}
1158
1159/* SPARCClassic hardware initialisation */
fbe1b595 1160static void scls_init(ram_addr_t RAM_size,
3023f332 1161 const char *boot_device,
a526a31c
BS
1162 const char *kernel_filename, const char *kernel_cmdline,
1163 const char *initrd_filename, const char *cpu_model)
1164{
3023f332 1165 sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
a526a31c
BS
1166 kernel_cmdline, initrd_filename, cpu_model);
1167}
1168
1169/* SPARCbook hardware initialisation */
fbe1b595 1170static void sbook_init(ram_addr_t RAM_size,
3023f332 1171 const char *boot_device,
a526a31c
BS
1172 const char *kernel_filename, const char *kernel_cmdline,
1173 const char *initrd_filename, const char *cpu_model)
1174{
3023f332 1175 sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
a526a31c
BS
1176 kernel_cmdline, initrd_filename, cpu_model);
1177}
1178
f80f9ec9 1179static QEMUMachine ss5_machine = {
66de733b
BS
1180 .name = "SS-5",
1181 .desc = "Sun4m platform, SPARCstation 5",
1182 .init = ss5_init,
c9b1ae2c 1183 .use_scsi = 1,
0c257437 1184 .is_default = 1,
c0e564d5 1185};
e0353fe2 1186
f80f9ec9 1187static QEMUMachine ss10_machine = {
66de733b
BS
1188 .name = "SS-10",
1189 .desc = "Sun4m platform, SPARCstation 10",
1190 .init = ss10_init,
c9b1ae2c 1191 .use_scsi = 1,
1bcee014 1192 .max_cpus = 4,
e0353fe2 1193};
6a3b9cc9 1194
f80f9ec9 1195static QEMUMachine ss600mp_machine = {
66de733b
BS
1196 .name = "SS-600MP",
1197 .desc = "Sun4m platform, SPARCserver 600MP",
1198 .init = ss600mp_init,
c9b1ae2c 1199 .use_scsi = 1,
1bcee014 1200 .max_cpus = 4,
6a3b9cc9 1201};
ae40972f 1202
f80f9ec9 1203static QEMUMachine ss20_machine = {
66de733b
BS
1204 .name = "SS-20",
1205 .desc = "Sun4m platform, SPARCstation 20",
1206 .init = ss20_init,
c9b1ae2c 1207 .use_scsi = 1,
1bcee014 1208 .max_cpus = 4,
ae40972f
BS
1209};
1210
f80f9ec9 1211static QEMUMachine voyager_machine = {
66de733b
BS
1212 .name = "Voyager",
1213 .desc = "Sun4m platform, SPARCstation Voyager",
1214 .init = vger_init,
c9b1ae2c 1215 .use_scsi = 1,
a526a31c
BS
1216};
1217
f80f9ec9 1218static QEMUMachine ss_lx_machine = {
66de733b
BS
1219 .name = "LX",
1220 .desc = "Sun4m platform, SPARCstation LX",
1221 .init = ss_lx_init,
c9b1ae2c 1222 .use_scsi = 1,
a526a31c
BS
1223};
1224
f80f9ec9 1225static QEMUMachine ss4_machine = {
66de733b
BS
1226 .name = "SS-4",
1227 .desc = "Sun4m platform, SPARCstation 4",
1228 .init = ss4_init,
c9b1ae2c 1229 .use_scsi = 1,
a526a31c
BS
1230};
1231
f80f9ec9 1232static QEMUMachine scls_machine = {
66de733b
BS
1233 .name = "SPARCClassic",
1234 .desc = "Sun4m platform, SPARCClassic",
1235 .init = scls_init,
c9b1ae2c 1236 .use_scsi = 1,
a526a31c
BS
1237};
1238
f80f9ec9 1239static QEMUMachine sbook_machine = {
66de733b
BS
1240 .name = "SPARCbook",
1241 .desc = "Sun4m platform, SPARCbook",
1242 .init = sbook_init,
c9b1ae2c 1243 .use_scsi = 1,
a526a31c
BS
1244};
1245
7d85892b
BS
1246static const struct sun4d_hwdef sun4d_hwdefs[] = {
1247 /* SS-1000 */
1248 {
1249 .iounit_bases = {
1250 0xfe0200000ULL,
1251 0xfe1200000ULL,
1252 0xfe2200000ULL,
1253 0xfe3200000ULL,
1254 -1,
1255 },
1256 .tcx_base = 0x820000000ULL,
1257 .slavio_base = 0xf00000000ULL,
1258 .ms_kb_base = 0xf00240000ULL,
1259 .serial_base = 0xf00200000ULL,
1260 .nvram_base = 0xf00280000ULL,
1261 .counter_base = 0xf00300000ULL,
1262 .espdma_base = 0x800081000ULL,
1263 .esp_base = 0x800080000ULL,
1264 .ledma_base = 0x800040000ULL,
1265 .le_base = 0x800060000ULL,
1266 .sbi_base = 0xf02800000ULL,
c1d00dc0 1267 .vram_size = 0x00100000,
7d85892b
BS
1268 .nvram_size = 0x2000,
1269 .esp_irq = 3,
1270 .le_irq = 4,
1271 .clock_irq = 14,
1272 .clock1_irq = 10,
1273 .ms_kb_irq = 12,
1274 .ser_irq = 12,
905fdcb5
BS
1275 .nvram_machine_id = 0x80,
1276 .machine_id = ss1000_id,
7d85892b 1277 .iounit_version = 0x03000000,
6ef05b95 1278 .max_mem = 0xf00000000ULL,
7d85892b
BS
1279 .default_cpu_model = "TI SuperSparc II",
1280 },
1281 /* SS-2000 */
1282 {
1283 .iounit_bases = {
1284 0xfe0200000ULL,
1285 0xfe1200000ULL,
1286 0xfe2200000ULL,
1287 0xfe3200000ULL,
1288 0xfe4200000ULL,
1289 },
1290 .tcx_base = 0x820000000ULL,
1291 .slavio_base = 0xf00000000ULL,
1292 .ms_kb_base = 0xf00240000ULL,
1293 .serial_base = 0xf00200000ULL,
1294 .nvram_base = 0xf00280000ULL,
1295 .counter_base = 0xf00300000ULL,
1296 .espdma_base = 0x800081000ULL,
1297 .esp_base = 0x800080000ULL,
1298 .ledma_base = 0x800040000ULL,
1299 .le_base = 0x800060000ULL,
1300 .sbi_base = 0xf02800000ULL,
c1d00dc0 1301 .vram_size = 0x00100000,
7d85892b
BS
1302 .nvram_size = 0x2000,
1303 .esp_irq = 3,
1304 .le_irq = 4,
1305 .clock_irq = 14,
1306 .clock1_irq = 10,
1307 .ms_kb_irq = 12,
1308 .ser_irq = 12,
905fdcb5
BS
1309 .nvram_machine_id = 0x80,
1310 .machine_id = ss2000_id,
7d85892b 1311 .iounit_version = 0x03000000,
6ef05b95 1312 .max_mem = 0xf00000000ULL,
7d85892b
BS
1313 .default_cpu_model = "TI SuperSparc II",
1314 },
1315};
1316
6ef05b95 1317static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
7d85892b 1318 const char *boot_device,
3023f332 1319 const char *kernel_filename,
7d85892b
BS
1320 const char *kernel_cmdline,
1321 const char *initrd_filename, const char *cpu_model)
1322{
666713c0 1323 CPUState *envs[MAX_CPUS];
7d85892b 1324 unsigned int i;
7fc06735
BS
1325 void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram;
1326 qemu_irq *cpu_irqs[MAX_CPUS], sbi_irq[32], sbi_cpu_irq[MAX_CPUS],
6f6260c7 1327 espdma_irq, ledma_irq;
7d85892b 1328 qemu_irq *esp_reset, *le_reset;
5c6602c5 1329 unsigned long kernel_size;
3cce6243 1330 void *fw_cfg;
7fc06735 1331 DeviceState *dev;
7d85892b
BS
1332
1333 /* init CPUs */
1334 if (!cpu_model)
1335 cpu_model = hwdef->default_cpu_model;
1336
666713c0
BS
1337 for(i = 0; i < smp_cpus; i++) {
1338 envs[i] = cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
7d85892b
BS
1339 }
1340
1341 for (i = smp_cpus; i < MAX_CPUS; i++)
1342 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
1343
7d85892b 1344 /* set up devices */
a350db85
BS
1345 ram_init(0, RAM_size, hwdef->max_mem);
1346
f48f6569
BS
1347 prom_init(hwdef->slavio_base, bios_name);
1348
7fc06735
BS
1349 dev = sbi_init(hwdef->sbi_base, cpu_irqs);
1350
1351 for (i = 0; i < 32; i++) {
1352 sbi_irq[i] = qdev_get_gpio_in(dev, i);
1353 }
1354 for (i = 0; i < MAX_CPUS; i++) {
1355 sbi_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
1356 }
7d85892b
BS
1357
1358 for (i = 0; i < MAX_IOUNITS; i++)
1359 if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1)
ff403da6
BS
1360 iounits[i] = iommu_init(hwdef->iounit_bases[i],
1361 hwdef->iounit_version,
1362 sbi_irq[hwdef->me_irq]);
7d85892b
BS
1363
1364 espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[hwdef->esp_irq],
1365 iounits[0], &espdma_irq, &esp_reset);
1366
1367 ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[hwdef->le_irq],
1368 iounits[0], &ledma_irq, &le_reset);
1369
1370 if (graphic_depth != 8 && graphic_depth != 24) {
1371 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
1372 exit (1);
1373 }
dc828ca1
PB
1374 tcx_init(hwdef->tcx_base, hwdef->vram_size, graphic_width, graphic_height,
1375 graphic_depth);
7d85892b 1376
6f6260c7 1377 lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq, le_reset);
7d85892b
BS
1378
1379 nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0,
1380 hwdef->nvram_size, 8);
1381
1382 slavio_timer_init_all(hwdef->counter_base, sbi_irq[hwdef->clock1_irq],
1383 sbi_cpu_irq, smp_cpus);
1384
1385 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[hwdef->ms_kb_irq],
993fbfdb 1386 display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
7d85892b
BS
1387 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
1388 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
aeeb69c7
AJ
1389 escc_init(hwdef->serial_base, sbi_irq[hwdef->ser_irq], sbi_irq[hwdef->ser_irq],
1390 serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
7d85892b
BS
1391
1392 if (drive_get_max_bus(IF_SCSI) > 0) {
1393 fprintf(stderr, "qemu: too many SCSI bus\n");
1394 exit(1);
1395 }
1396
cfb9de9c
PB
1397 esp_init(hwdef->esp_base, 2,
1398 espdma_memory_read, espdma_memory_write,
6f6260c7 1399 espdma, espdma_irq, esp_reset);
7d85892b 1400
293f78bc
BS
1401 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
1402 RAM_size);
7d85892b
BS
1403
1404 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
1405 boot_device, RAM_size, kernel_size, graphic_width,
905fdcb5
BS
1406 graphic_height, graphic_depth, hwdef->nvram_machine_id,
1407 "Sun4d");
3cce6243
BS
1408
1409 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
1410 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
905fdcb5
BS
1411 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
1412 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
513f789f
BS
1413 fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
1414 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
1415 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
1416 if (kernel_cmdline) {
1417 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
1418 pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
1419 } else {
1420 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
1421 }
1422 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
1423 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
1424 fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
1425 qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
7d85892b
BS
1426}
1427
1428/* SPARCserver 1000 hardware initialisation */
fbe1b595 1429static void ss1000_init(ram_addr_t RAM_size,
3023f332 1430 const char *boot_device,
7d85892b
BS
1431 const char *kernel_filename, const char *kernel_cmdline,
1432 const char *initrd_filename, const char *cpu_model)
1433{
3023f332 1434 sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
7d85892b
BS
1435 kernel_cmdline, initrd_filename, cpu_model);
1436}
1437
1438/* SPARCcenter 2000 hardware initialisation */
fbe1b595 1439static void ss2000_init(ram_addr_t RAM_size,
3023f332 1440 const char *boot_device,
7d85892b
BS
1441 const char *kernel_filename, const char *kernel_cmdline,
1442 const char *initrd_filename, const char *cpu_model)
1443{
3023f332 1444 sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
7d85892b
BS
1445 kernel_cmdline, initrd_filename, cpu_model);
1446}
1447
f80f9ec9 1448static QEMUMachine ss1000_machine = {
66de733b
BS
1449 .name = "SS-1000",
1450 .desc = "Sun4d platform, SPARCserver 1000",
1451 .init = ss1000_init,
c9b1ae2c 1452 .use_scsi = 1,
1bcee014 1453 .max_cpus = 8,
7d85892b
BS
1454};
1455
f80f9ec9 1456static QEMUMachine ss2000_machine = {
66de733b
BS
1457 .name = "SS-2000",
1458 .desc = "Sun4d platform, SPARCcenter 2000",
1459 .init = ss2000_init,
c9b1ae2c 1460 .use_scsi = 1,
1bcee014 1461 .max_cpus = 20,
7d85892b 1462};
8137cde8
BS
1463
1464static const struct sun4c_hwdef sun4c_hwdefs[] = {
1465 /* SS-2 */
1466 {
1467 .iommu_base = 0xf8000000,
1468 .tcx_base = 0xfe000000,
8137cde8
BS
1469 .slavio_base = 0xf6000000,
1470 .intctl_base = 0xf5000000,
1471 .counter_base = 0xf3000000,
1472 .ms_kb_base = 0xf0000000,
1473 .serial_base = 0xf1000000,
1474 .nvram_base = 0xf2000000,
1475 .fd_base = 0xf7200000,
1476 .dma_base = 0xf8400000,
1477 .esp_base = 0xf8800000,
1478 .le_base = 0xf8c00000,
8137cde8 1479 .aux1_base = 0xf7400003,
8137cde8
BS
1480 .vram_size = 0x00100000,
1481 .nvram_size = 0x800,
1482 .esp_irq = 2,
1483 .le_irq = 3,
1484 .clock_irq = 5,
1485 .clock1_irq = 7,
1486 .ms_kb_irq = 1,
1487 .ser_irq = 1,
1488 .fd_irq = 1,
1489 .me_irq = 1,
8137cde8
BS
1490 .nvram_machine_id = 0x55,
1491 .machine_id = ss2_id,
1492 .max_mem = 0x10000000,
1493 .default_cpu_model = "Cypress CY7C601",
1494 },
1495};
1496
1497static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
1498 const char *boot_device,
3023f332 1499 const char *kernel_filename,
8137cde8
BS
1500 const char *kernel_cmdline,
1501 const char *initrd_filename, const char *cpu_model)
1502{
1503 CPUState *env;
cfb9de9c 1504 void *iommu, *espdma, *ledma, *nvram;
e32cba29 1505 qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq;
8137cde8 1506 qemu_irq *esp_reset, *le_reset;
2582cfa0 1507 qemu_irq fdc_tc;
5c6602c5 1508 unsigned long kernel_size;
8137cde8 1509 BlockDriverState *fd[MAX_FD];
8137cde8 1510 void *fw_cfg;
e32cba29
BS
1511 DeviceState *dev;
1512 unsigned int i;
751c6a17 1513 DriveInfo *dinfo;
8137cde8
BS
1514
1515 /* init CPU */
1516 if (!cpu_model)
1517 cpu_model = hwdef->default_cpu_model;
1518
666713c0 1519 env = cpu_devinit(cpu_model, 0, hwdef->slavio_base, &cpu_irqs);
8137cde8 1520
8137cde8 1521 /* set up devices */
a350db85
BS
1522 ram_init(0, RAM_size, hwdef->max_mem);
1523
f48f6569
BS
1524 prom_init(hwdef->slavio_base, bios_name);
1525
e32cba29
BS
1526 dev = sun4c_intctl_init(hwdef->intctl_base, cpu_irqs);
1527
1528 for (i = 0; i < 8; i++) {
1529 slavio_irq[i] = qdev_get_gpio_in(dev, i);
1530 }
8137cde8
BS
1531
1532 iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
1533 slavio_irq[hwdef->me_irq]);
1534
1535 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
1536 iommu, &espdma_irq, &esp_reset);
1537
1538 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
1539 slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
1540 &le_reset);
1541
1542 if (graphic_depth != 8 && graphic_depth != 24) {
1543 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
1544 exit (1);
1545 }
dc828ca1
PB
1546 tcx_init(hwdef->tcx_base, hwdef->vram_size, graphic_width, graphic_height,
1547 graphic_depth);
8137cde8 1548
6f6260c7 1549 lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq, le_reset);
8137cde8
BS
1550
1551 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
1552 hwdef->nvram_size, 2);
1553
1554 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
993fbfdb 1555 display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
8137cde8
BS
1556 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
1557 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
aeeb69c7
AJ
1558 escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
1559 slavio_irq[hwdef->ser_irq], serial_hds[0], serial_hds[1],
1560 ESCC_CLOCK, 1);
8137cde8 1561
2582cfa0
BS
1562 slavio_misc = slavio_misc_init(0, hwdef->aux1_base, 0,
1563 slavio_irq[hwdef->me_irq], fdc_tc);
8137cde8
BS
1564
1565 if (hwdef->fd_base != (target_phys_addr_t)-1) {
1566 /* there is zero or one floppy drive */
ce802585 1567 memset(fd, 0, sizeof(fd));
751c6a17
GH
1568 dinfo = drive_get(IF_FLOPPY, 0, 0);
1569 if (dinfo)
1570 fd[0] = dinfo->bdrv;
8137cde8
BS
1571
1572 sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
2582cfa0 1573 &fdc_tc);
8137cde8
BS
1574 }
1575
1576 if (drive_get_max_bus(IF_SCSI) > 0) {
1577 fprintf(stderr, "qemu: too many SCSI bus\n");
1578 exit(1);
1579 }
1580
cfb9de9c
PB
1581 esp_init(hwdef->esp_base, 2,
1582 espdma_memory_read, espdma_memory_write,
6f6260c7 1583 espdma, espdma_irq, esp_reset);
8137cde8
BS
1584
1585 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
1586 RAM_size);
1587
1588 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
1589 boot_device, RAM_size, kernel_size, graphic_width,
1590 graphic_height, graphic_depth, hwdef->nvram_machine_id,
1591 "Sun4c");
1592
1593 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
1594 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
1595 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
1596 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
513f789f
BS
1597 fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
1598 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
1599 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
1600 if (kernel_cmdline) {
1601 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
1602 pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
1603 } else {
1604 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
1605 }
1606 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
1607 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
1608 fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
1609 qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
8137cde8
BS
1610}
1611
1612/* SPARCstation 2 hardware initialisation */
fbe1b595 1613static void ss2_init(ram_addr_t RAM_size,
3023f332 1614 const char *boot_device,
8137cde8
BS
1615 const char *kernel_filename, const char *kernel_cmdline,
1616 const char *initrd_filename, const char *cpu_model)
1617{
3023f332 1618 sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
8137cde8
BS
1619 kernel_cmdline, initrd_filename, cpu_model);
1620}
1621
f80f9ec9 1622static QEMUMachine ss2_machine = {
8137cde8
BS
1623 .name = "SS-2",
1624 .desc = "Sun4c platform, SPARCstation 2",
1625 .init = ss2_init,
8137cde8 1626 .use_scsi = 1,
8137cde8 1627};
f80f9ec9
AL
1628
1629static void ss2_machine_init(void)
1630{
1631 qemu_register_machine(&ss5_machine);
1632 qemu_register_machine(&ss10_machine);
1633 qemu_register_machine(&ss600mp_machine);
1634 qemu_register_machine(&ss20_machine);
1635 qemu_register_machine(&voyager_machine);
1636 qemu_register_machine(&ss_lx_machine);
1637 qemu_register_machine(&ss4_machine);
1638 qemu_register_machine(&scls_machine);
1639 qemu_register_machine(&sbook_machine);
1640 qemu_register_machine(&ss1000_machine);
1641 qemu_register_machine(&ss2000_machine);
1642 qemu_register_machine(&ss2_machine);
1643}
1644
1645machine_init(ss2_machine_init);