]> git.proxmox.com Git - mirror_qemu.git/blame - hw/sun4m.c
Update OHW interface to version 3.
[mirror_qemu.git] / hw / sun4m.c
CommitLineData
420557e8
FB
1/*
2 * QEMU Sun4m 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 */
24#include "vl.h"
d2c63fc1
BS
25#include "m48t59.h"
26#include "firmware_abi.h"
27
b3a23197 28//#define DEBUG_IRQ
420557e8 29
36cd9210
BS
30/*
31 * Sun4m architecture was used in the following machines:
32 *
33 * SPARCserver 6xxMP/xx
34 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
35 * SPARCstation LX/ZX (4/30)
36 * SPARCstation Voyager
37 * SPARCstation 10/xx, SPARCserver 10/xx
38 * SPARCstation 5, SPARCserver 5
39 * SPARCstation 20/xx, SPARCserver 20
40 * SPARCstation 4
41 *
42 * See for example: http://www.sunhelp.org/faq/sunref1.html
43 */
44
b3a23197
BS
45#ifdef DEBUG_IRQ
46#define DPRINTF(fmt, args...) \
47 do { printf("CPUIRQ: " fmt , ##args); } while (0)
48#else
49#define DPRINTF(fmt, args...)
50#endif
51
420557e8 52#define KERNEL_LOAD_ADDR 0x00004000
b6f479d3 53#define CMDLINE_ADDR 0x007ff000
713c45fa 54#define INITRD_LOAD_ADDR 0x00800000
aa6ad6fe 55#define PROM_SIZE_MAX (512 * 1024)
40ce0a9a
BS
56#define PROM_PADDR 0xff0000000ULL
57#define PROM_VADDR 0xffd00000
f930d07e 58#define PROM_FILENAME "openbios-sparc32"
b8174937 59
ba3c64fb 60#define MAX_CPUS 16
b3a23197 61#define MAX_PILS 16
420557e8 62
36cd9210 63struct hwdef {
5dcb6b91
BS
64 target_phys_addr_t iommu_base, slavio_base;
65 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
66 target_phys_addr_t serial_base, fd_base;
67 target_phys_addr_t dma_base, esp_base, le_base;
68 target_phys_addr_t tcx_base, cs_base, power_base;
36cd9210
BS
69 long vram_size, nvram_size;
70 // IRQ numbers are not PIL ones, but master interrupt controller register
71 // bit numbers
d7edfd27 72 int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
36cd9210
BS
73 int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
74 int machine_id; // For NVRAM
e0353fe2 75 uint32_t intbit_to_level[32];
36cd9210
BS
76};
77
420557e8
FB
78/* TSC handling */
79
80uint64_t cpu_get_tsc()
81{
82 return qemu_get_clock(vm_clock);
83}
84
6f7e9aec
FB
85int DMA_get_channel_mode (int nchan)
86{
87 return 0;
88}
89int DMA_read_memory (int nchan, void *buf, int pos, int size)
90{
91 return 0;
92}
93int DMA_write_memory (int nchan, void *buf, int pos, int size)
94{
95 return 0;
96}
97void DMA_hold_DREQ (int nchan) {}
98void DMA_release_DREQ (int nchan) {}
99void DMA_schedule(int nchan) {}
100void DMA_run (void) {}
101void DMA_init (int high_page_enable) {}
102void DMA_register_channel (int nchan,
103 DMA_transfer_handler transfer_handler,
104 void *opaque)
105{
106}
107
6f7e9aec
FB
108extern int nographic;
109
819385c5 110static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
d2c63fc1 111 const char *boot_devices, uint32_t RAM_size,
f930d07e
BS
112 uint32_t kernel_size,
113 int width, int height, int depth,
36cd9210 114 int machine_id)
e80cfcfc 115{
d2c63fc1 116 unsigned int i;
66508601 117 uint32_t start, end;
d2c63fc1
BS
118 uint8_t image[0x1ff0];
119 ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ
120 struct sparc_arch_cfg *sparc_header;
121 struct OpenBIOS_nvpart_v1 *part_header;
122
123 memset(image, '\0', sizeof(image));
e80cfcfc 124
6f7e9aec 125 // Try to match PPC NVRAM
d2c63fc1
BS
126 strcpy(header->struct_ident, "QEMU_BIOS");
127 header->struct_version = cpu_to_be32(3); /* structure v3 */
128
129 header->nvram_size = cpu_to_be16(0x2000);
130 header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t));
131 header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg));
132 strcpy(header->arch, "sun4m");
133 header->nb_cpus = smp_cpus & 0xff;
134 header->RAM0_base = 0;
135 header->RAM0_size = cpu_to_be64((uint64_t)RAM_size);
136 strcpy(header->boot_devices, boot_devices);
137 header->nboot_devices = strlen(boot_devices) & 0xff;
138 header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR);
139 header->kernel_size = cpu_to_be64((uint64_t)kernel_size);
b6f479d3 140 if (cmdline) {
f930d07e 141 strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
d2c63fc1
BS
142 header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR);
143 header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline));
b6f479d3 144 }
d2c63fc1
BS
145 // XXX add initrd_image, initrd_size
146 header->width = cpu_to_be16(width);
147 header->height = cpu_to_be16(height);
148 header->depth = cpu_to_be16(depth);
149 if (nographic)
150 header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
151
152 header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
153
154 // Architecture specific header
155 start = sizeof(ohwcfg_v3_t);
156 sparc_header = (struct sparc_arch_cfg *)&image[start];
157 sparc_header->valid = 0;
158 start += sizeof(struct sparc_arch_cfg);
b6f479d3 159
66508601
BS
160 // OpenBIOS nvram variables
161 // Variable partition
d2c63fc1
BS
162 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
163 part_header->signature = OPENBIOS_PART_SYSTEM;
164 strcpy(part_header->name, "system");
66508601 165
d2c63fc1 166 end = start + sizeof(struct OpenBIOS_nvpart_v1);
66508601 167 for (i = 0; i < nb_prom_envs; i++)
d2c63fc1
BS
168 end = OpenBIOS_set_var(image, end, prom_envs[i]);
169
170 // End marker
171 image[end++] = '\0';
66508601 172
66508601 173 end = start + ((end - start + 15) & ~15);
d2c63fc1 174 OpenBIOS_finish_partition(part_header, end - start);
66508601
BS
175
176 // free partition
177 start = end;
d2c63fc1
BS
178 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
179 part_header->signature = OPENBIOS_PART_FREE;
180 strcpy(part_header->name, "free");
66508601
BS
181
182 end = 0x1fd0;
d2c63fc1
BS
183 OpenBIOS_finish_partition(part_header, end - start);
184
185 Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, machine_id);
186
187 for (i = 0; i < sizeof(image); i++)
188 m48t59_write(nvram, i, image[i]);
e80cfcfc
FB
189}
190
191static void *slavio_intctl;
192
193void pic_info()
194{
195 slavio_pic_info(slavio_intctl);
196}
197
198void irq_info()
199{
200 slavio_irq_info(slavio_intctl);
201}
202
327ac2e7
BS
203void cpu_check_irqs(CPUState *env)
204{
205 if (env->pil_in && (env->interrupt_index == 0 ||
206 (env->interrupt_index & ~15) == TT_EXTINT)) {
207 unsigned int i;
208
209 for (i = 15; i > 0; i--) {
210 if (env->pil_in & (1 << i)) {
211 int old_interrupt = env->interrupt_index;
212
213 env->interrupt_index = TT_EXTINT | i;
214 if (old_interrupt != env->interrupt_index)
215 cpu_interrupt(env, CPU_INTERRUPT_HARD);
216 break;
217 }
218 }
219 } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
220 env->interrupt_index = 0;
221 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
222 }
223}
224
b3a23197
BS
225static void cpu_set_irq(void *opaque, int irq, int level)
226{
227 CPUState *env = opaque;
228
229 if (level) {
230 DPRINTF("Raise CPU IRQ %d\n", irq);
b3a23197 231 env->halted = 0;
327ac2e7
BS
232 env->pil_in |= 1 << irq;
233 cpu_check_irqs(env);
b3a23197
BS
234 } else {
235 DPRINTF("Lower CPU IRQ %d\n", irq);
327ac2e7
BS
236 env->pil_in &= ~(1 << irq);
237 cpu_check_irqs(env);
b3a23197
BS
238 }
239}
240
241static void dummy_cpu_set_irq(void *opaque, int irq, int level)
242{
243}
244
3475187d
FB
245static void *slavio_misc;
246
247void qemu_system_powerdown(void)
248{
249 slavio_set_power_fail(slavio_misc, 1);
250}
251
c68ea704
FB
252static void main_cpu_reset(void *opaque)
253{
254 CPUState *env = opaque;
3d29fbef
BS
255
256 cpu_reset(env);
257 env->halted = 0;
258}
259
260static void secondary_cpu_reset(void *opaque)
261{
262 CPUState *env = opaque;
263
c68ea704 264 cpu_reset(env);
3d29fbef 265 env->halted = 1;
c68ea704
FB
266}
267
b3ceef24
BS
268static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
269 DisplayState *ds, const char *cpu_model)
36cd9210 270
420557e8 271{
ba3c64fb 272 CPUState *env, *envs[MAX_CPUS];
713c45fa 273 unsigned int i;
b3ceef24 274 void *iommu, *espdma, *ledma, *main_esp, *nvram;
b3a23197 275 qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
d7edfd27 276 *espdma_irq, *ledma_irq;
2d069bab 277 qemu_irq *esp_reset, *le_reset;
420557e8 278
ba3c64fb 279 /* init CPUs */
b3a23197 280
ba3c64fb 281 for(i = 0; i < smp_cpus; i++) {
aaed909a
FB
282 env = cpu_init(cpu_model);
283 if (!env) {
284 fprintf(stderr, "Unable to find Sparc CPU definition\n");
285 exit(1);
286 }
287 cpu_sparc_set_id(env, i);
ba3c64fb 288 envs[i] = env;
3d29fbef
BS
289 if (i == 0) {
290 qemu_register_reset(main_cpu_reset, env);
291 } else {
292 qemu_register_reset(secondary_cpu_reset, env);
ba3c64fb 293 env->halted = 1;
3d29fbef 294 }
ba3c64fb 295 register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
b3a23197 296 cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
ba3c64fb 297 }
b3a23197
BS
298
299 for (i = smp_cpus; i < MAX_CPUS; i++)
300 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
301
420557e8 302 /* allocate RAM */
b3ceef24 303 cpu_register_physical_memory(0, RAM_size, 0);
420557e8 304
36cd9210
BS
305 iommu = iommu_init(hwdef->iommu_base);
306 slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
5dcb6b91 307 hwdef->intctl_base + 0x10000ULL,
d537cf6c 308 &hwdef->intbit_to_level[0],
d7edfd27 309 &slavio_irq, &slavio_cpu_irq,
b3a23197 310 cpu_irqs,
d7edfd27 311 hwdef->clock_irq);
b3a23197 312
5aca8c3b 313 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
2d069bab
BS
314 iommu, &espdma_irq, &esp_reset);
315
5aca8c3b 316 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
2d069bab
BS
317 slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
318 &le_reset);
ba3c64fb 319
eee0b836
BS
320 if (graphic_depth != 8 && graphic_depth != 24) {
321 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
322 exit (1);
323 }
b3ceef24 324 tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
eee0b836 325 hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
dbe06e18
BS
326
327 if (nd_table[0].model == NULL
328 || strcmp(nd_table[0].model, "lance") == 0) {
2d069bab 329 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
c4a7060c
BS
330 } else if (strcmp(nd_table[0].model, "?") == 0) {
331 fprintf(stderr, "qemu: Supported NICs: lance\n");
332 exit (1);
dbe06e18
BS
333 } else {
334 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
335 exit (1);
a41b2ff2 336 }
dbe06e18 337
d537cf6c
PB
338 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
339 hwdef->nvram_size, 8);
81732d19
BS
340
341 slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
342 slavio_cpu_irq);
343
d537cf6c 344 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
b81b3b10
FB
345 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
346 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
d537cf6c
PB
347 slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
348 serial_hds[1], serial_hds[0]);
741402f9 349
6a3b9cc9
BS
350 if (hwdef->fd_base != (target_phys_addr_t)-1)
351 sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd_table);
2d069bab
BS
352
353 main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq,
354 esp_reset);
f1587550
TS
355
356 for (i = 0; i < MAX_DISKS; i++) {
357 if (bs_table[i]) {
358 esp_scsi_attach(main_esp, bs_table[i], i);
359 }
360 }
361
5dcb6b91 362 slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
d537cf6c 363 slavio_irq[hwdef->me_irq]);
5dcb6b91 364 if (hwdef->cs_base != (target_phys_addr_t)-1)
803b3c7b 365 cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
b3ceef24
BS
366
367 return nvram;
36cd9210
BS
368}
369
6ac0e82d
AZ
370static void sun4m_load_kernel(long vram_size, int RAM_size,
371 const char *boot_device,
36cd9210
BS
372 const char *kernel_filename,
373 const char *kernel_cmdline,
374 const char *initrd_filename,
b3ceef24
BS
375 int machine_id,
376 void *nvram)
36cd9210
BS
377{
378 int ret, linux_boot;
379 char buf[1024];
380 unsigned int i;
381 long prom_offset, initrd_size, kernel_size;
382
383 linux_boot = (kernel_filename != NULL);
420557e8 384
b3ceef24 385 prom_offset = RAM_size + vram_size;
40ce0a9a 386 cpu_register_physical_memory(PROM_PADDR,
5fafdf24 387 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
b3783731 388 prom_offset | IO_MEM_ROM);
e80cfcfc 389
1192dad8
JM
390 if (bios_name == NULL)
391 bios_name = PROM_FILENAME;
392 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
40ce0a9a 393 ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
aa6ad6fe
BS
394 if (ret < 0 || ret > PROM_SIZE_MAX)
395 ret = load_image(buf, phys_ram_base + prom_offset);
396 if (ret < 0 || ret > PROM_SIZE_MAX) {
397 fprintf(stderr, "qemu: could not load prom '%s'\n",
398 buf);
399 exit(1);
e80cfcfc 400 }
e80cfcfc 401
6f7e9aec 402 kernel_size = 0;
e80cfcfc 403 if (linux_boot) {
0bd5f4ce
BS
404 kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
405 NULL);
6f7e9aec 406 if (kernel_size < 0)
f930d07e
BS
407 kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
408 if (kernel_size < 0)
409 kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
6f7e9aec 410 if (kernel_size < 0) {
5fafdf24 411 fprintf(stderr, "qemu: could not load kernel '%s'\n",
e80cfcfc 412 kernel_filename);
f930d07e 413 exit(1);
420557e8 414 }
713c45fa
FB
415
416 /* load initrd */
417 initrd_size = 0;
418 if (initrd_filename) {
419 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
420 if (initrd_size < 0) {
5fafdf24 421 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
713c45fa
FB
422 initrd_filename);
423 exit(1);
424 }
425 }
426 if (initrd_size > 0) {
f930d07e
BS
427 for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
428 if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
429 == 0x48647253) { // HdrS
430 stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
431 stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
432 break;
433 }
434 }
713c45fa 435 }
420557e8 436 }
36cd9210 437 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
b3ceef24 438 boot_device, RAM_size, kernel_size, graphic_width,
36cd9210
BS
439 graphic_height, graphic_depth, machine_id);
440}
441
442static const struct hwdef hwdefs[] = {
443 /* SS-5 */
444 {
445 .iommu_base = 0x10000000,
446 .tcx_base = 0x50000000,
447 .cs_base = 0x6c000000,
384ccb5d 448 .slavio_base = 0x70000000,
36cd9210
BS
449 .ms_kb_base = 0x71000000,
450 .serial_base = 0x71100000,
451 .nvram_base = 0x71200000,
452 .fd_base = 0x71400000,
453 .counter_base = 0x71d00000,
454 .intctl_base = 0x71e00000,
455 .dma_base = 0x78400000,
456 .esp_base = 0x78800000,
457 .le_base = 0x78c00000,
5dcb6b91 458 .power_base = 0x7a000000,
36cd9210
BS
459 .vram_size = 0x00100000,
460 .nvram_size = 0x2000,
461 .esp_irq = 18,
462 .le_irq = 16,
463 .clock_irq = 7,
464 .clock1_irq = 19,
465 .ms_kb_irq = 14,
466 .ser_irq = 15,
467 .fd_irq = 22,
468 .me_irq = 30,
469 .cs_irq = 5,
470 .machine_id = 0x80,
e0353fe2 471 .intbit_to_level = {
f930d07e
BS
472 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
473 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
e0353fe2
BS
474 },
475 },
476 /* SS-10 */
e0353fe2 477 {
5dcb6b91
BS
478 .iommu_base = 0xfe0000000ULL,
479 .tcx_base = 0xe20000000ULL,
803b3c7b 480 .cs_base = -1,
5dcb6b91
BS
481 .slavio_base = 0xff0000000ULL,
482 .ms_kb_base = 0xff1000000ULL,
483 .serial_base = 0xff1100000ULL,
484 .nvram_base = 0xff1200000ULL,
485 .fd_base = 0xff1700000ULL,
486 .counter_base = 0xff1300000ULL,
487 .intctl_base = 0xff1400000ULL,
488 .dma_base = 0xef0400000ULL,
489 .esp_base = 0xef0800000ULL,
490 .le_base = 0xef0c00000ULL,
491 .power_base = 0xefa000000ULL,
e0353fe2
BS
492 .vram_size = 0x00100000,
493 .nvram_size = 0x2000,
494 .esp_irq = 18,
495 .le_irq = 16,
496 .clock_irq = 7,
497 .clock1_irq = 19,
498 .ms_kb_irq = 14,
499 .ser_irq = 15,
500 .fd_irq = 22,
501 .me_irq = 30,
803b3c7b
BS
502 .cs_irq = -1,
503 .machine_id = 0x72,
e0353fe2 504 .intbit_to_level = {
f930d07e
BS
505 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
506 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
e0353fe2 507 },
36cd9210 508 },
6a3b9cc9
BS
509 /* SS-600MP */
510 {
511 .iommu_base = 0xfe0000000ULL,
512 .tcx_base = 0xe20000000ULL,
513 .cs_base = -1,
514 .slavio_base = 0xff0000000ULL,
515 .ms_kb_base = 0xff1000000ULL,
516 .serial_base = 0xff1100000ULL,
517 .nvram_base = 0xff1200000ULL,
518 .fd_base = -1,
519 .counter_base = 0xff1300000ULL,
520 .intctl_base = 0xff1400000ULL,
521 .dma_base = 0xef0081000ULL,
522 .esp_base = 0xef0080000ULL,
523 .le_base = 0xef0060000ULL,
524 .power_base = 0xefa000000ULL,
525 .vram_size = 0x00100000,
526 .nvram_size = 0x2000,
527 .esp_irq = 18,
528 .le_irq = 16,
529 .clock_irq = 7,
530 .clock1_irq = 19,
531 .ms_kb_irq = 14,
532 .ser_irq = 15,
533 .fd_irq = 22,
534 .me_irq = 30,
535 .cs_irq = -1,
536 .machine_id = 0x71,
537 .intbit_to_level = {
538 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
539 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
540 },
541 },
36cd9210
BS
542};
543
6ac0e82d 544static void sun4m_common_init(int RAM_size, const char *boot_device, DisplayState *ds,
36cd9210
BS
545 const char *kernel_filename, const char *kernel_cmdline,
546 const char *initrd_filename, const char *cpu_model,
4edebb0e 547 unsigned int machine, int max_ram)
36cd9210 548{
b3ceef24
BS
549 void *nvram;
550
551 if ((unsigned int)RAM_size > (unsigned int)max_ram) {
4edebb0e 552 fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
b3ceef24 553 (unsigned int)RAM_size / (1024 * 1024),
5dcb6b91 554 (unsigned int)max_ram / (1024 * 1024));
4edebb0e
BS
555 exit(1);
556 }
b3ceef24 557 nvram = sun4m_hw_init(&hwdefs[machine], RAM_size, ds, cpu_model);
36cd9210 558
b3ceef24 559 sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
36cd9210 560 kernel_filename, kernel_cmdline, initrd_filename,
b3ceef24 561 hwdefs[machine].machine_id, nvram);
36cd9210
BS
562}
563
564/* SPARCstation 5 hardware initialisation */
6ac0e82d 565static void ss5_init(int RAM_size, int vga_ram_size, const char *boot_device,
36cd9210
BS
566 DisplayState *ds, const char **fd_filename, int snapshot,
567 const char *kernel_filename, const char *kernel_cmdline,
568 const char *initrd_filename, const char *cpu_model)
569{
570 if (cpu_model == NULL)
571 cpu_model = "Fujitsu MB86904";
b3ceef24 572 sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
36cd9210 573 kernel_cmdline, initrd_filename, cpu_model,
4edebb0e 574 0, 0x10000000);
420557e8 575}
c0e564d5 576
e0353fe2 577/* SPARCstation 10 hardware initialisation */
6ac0e82d 578static void ss10_init(int RAM_size, int vga_ram_size, const char *boot_device,
e0353fe2
BS
579 DisplayState *ds, const char **fd_filename, int snapshot,
580 const char *kernel_filename, const char *kernel_cmdline,
581 const char *initrd_filename, const char *cpu_model)
582{
583 if (cpu_model == NULL)
584 cpu_model = "TI SuperSparc II";
b3ceef24 585 sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
e0353fe2 586 kernel_cmdline, initrd_filename, cpu_model,
40ce0a9a 587 1, 0xffffffff); // XXX actually first 62GB ok
e0353fe2
BS
588}
589
6a3b9cc9
BS
590/* SPARCserver 600MP hardware initialisation */
591static void ss600mp_init(int RAM_size, int vga_ram_size, const char *boot_device,
592 DisplayState *ds, const char **fd_filename, int snapshot,
593 const char *kernel_filename, const char *kernel_cmdline,
594 const char *initrd_filename, const char *cpu_model)
595{
596 if (cpu_model == NULL)
597 cpu_model = "TI SuperSparc II";
598 sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
599 kernel_cmdline, initrd_filename, cpu_model,
600 2, 0xffffffff); // XXX actually first 62GB ok
601}
602
36cd9210
BS
603QEMUMachine ss5_machine = {
604 "SS-5",
605 "Sun4m platform, SPARCstation 5",
606 ss5_init,
c0e564d5 607};
e0353fe2
BS
608
609QEMUMachine ss10_machine = {
610 "SS-10",
611 "Sun4m platform, SPARCstation 10",
612 ss10_init,
613};
6a3b9cc9
BS
614
615QEMUMachine ss600mp_machine = {
616 "SS-600MP",
617 "Sun4m platform, SPARCserver 600MP",
618 ss600mp_init,
619};