]> Git Repo - qemu.git/blame - hw/sun4m.c
MIPS disassembler update.
[qemu.git] / hw / sun4m.c
CommitLineData
420557e8
FB
1/*
2 * QEMU Sun4m System Emulator
3 *
b81b3b10 4 * Copyright (c) 2003-2005 Fabrice Bellard
420557e8
FB
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "vl.h"
b3a23197 25//#define DEBUG_IRQ
420557e8 26
36cd9210
BS
27/*
28 * Sun4m architecture was used in the following machines:
29 *
30 * SPARCserver 6xxMP/xx
31 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10)
32 * SPARCstation LX/ZX (4/30)
33 * SPARCstation Voyager
34 * SPARCstation 10/xx, SPARCserver 10/xx
35 * SPARCstation 5, SPARCserver 5
36 * SPARCstation 20/xx, SPARCserver 20
37 * SPARCstation 4
38 *
39 * See for example: http://www.sunhelp.org/faq/sunref1.html
40 */
41
b3a23197
BS
42#ifdef DEBUG_IRQ
43#define DPRINTF(fmt, args...) \
44 do { printf("CPUIRQ: " fmt , ##args); } while (0)
45#else
46#define DPRINTF(fmt, args...)
47#endif
48
420557e8 49#define KERNEL_LOAD_ADDR 0x00004000
b6f479d3 50#define CMDLINE_ADDR 0x007ff000
713c45fa 51#define INITRD_LOAD_ADDR 0x00800000
b3783731 52#define PROM_SIZE_MAX (256 * 1024)
e80cfcfc 53#define PROM_ADDR 0xffd00000
0986ac3b 54#define PROM_FILENAME "openbios-sparc32"
b8174937 55
ba3c64fb 56#define MAX_CPUS 16
b3a23197 57#define MAX_PILS 16
420557e8 58
36cd9210 59struct hwdef {
5dcb6b91
BS
60 target_phys_addr_t iommu_base, slavio_base;
61 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
62 target_phys_addr_t serial_base, fd_base;
63 target_phys_addr_t dma_base, esp_base, le_base;
64 target_phys_addr_t tcx_base, cs_base, power_base;
36cd9210
BS
65 long vram_size, nvram_size;
66 // IRQ numbers are not PIL ones, but master interrupt controller register
67 // bit numbers
d7edfd27 68 int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
36cd9210
BS
69 int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
70 int machine_id; // For NVRAM
e0353fe2 71 uint32_t intbit_to_level[32];
36cd9210
BS
72};
73
420557e8
FB
74/* TSC handling */
75
76uint64_t cpu_get_tsc()
77{
78 return qemu_get_clock(vm_clock);
79}
80
6f7e9aec
FB
81int DMA_get_channel_mode (int nchan)
82{
83 return 0;
84}
85int DMA_read_memory (int nchan, void *buf, int pos, int size)
86{
87 return 0;
88}
89int DMA_write_memory (int nchan, void *buf, int pos, int size)
90{
91 return 0;
92}
93void DMA_hold_DREQ (int nchan) {}
94void DMA_release_DREQ (int nchan) {}
95void DMA_schedule(int nchan) {}
96void DMA_run (void) {}
97void DMA_init (int high_page_enable) {}
98void DMA_register_channel (int nchan,
99 DMA_transfer_handler transfer_handler,
100 void *opaque)
101{
102}
103
819385c5 104static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
6f7e9aec 105{
819385c5
FB
106 m48t59_write(nvram, addr++, (value >> 8) & 0xff);
107 m48t59_write(nvram, addr++, value & 0xff);
6f7e9aec
FB
108}
109
819385c5 110static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
6f7e9aec 111{
819385c5
FB
112 m48t59_write(nvram, addr++, value >> 24);
113 m48t59_write(nvram, addr++, (value >> 16) & 0xff);
114 m48t59_write(nvram, addr++, (value >> 8) & 0xff);
115 m48t59_write(nvram, addr++, value & 0xff);
6f7e9aec
FB
116}
117
819385c5 118static void nvram_set_string (m48t59_t *nvram, uint32_t addr,
6f7e9aec
FB
119 const unsigned char *str, uint32_t max)
120{
121 unsigned int i;
122
123 for (i = 0; i < max && str[i] != '\0'; i++) {
819385c5 124 m48t59_write(nvram, addr + i, str[i]);
6f7e9aec 125 }
819385c5 126 m48t59_write(nvram, addr + max - 1, '\0');
6f7e9aec 127}
420557e8 128
66508601
BS
129static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr,
130 const unsigned char *str)
131{
132 uint32_t len;
133
134 len = strlen(str) + 1;
135 nvram_set_string(nvram, addr, str, len);
136
137 return addr + len;
138}
139
140static void nvram_finish_partition (m48t59_t *nvram, uint32_t start,
141 uint32_t end)
142{
143 unsigned int i, sum;
144
145 // Length divided by 16
146 m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff);
147 m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff);
148 // Checksum
149 sum = m48t59_read(nvram, start);
150 for (i = 0; i < 14; i++) {
151 sum += m48t59_read(nvram, start + 2 + i);
152 sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
153 }
154 m48t59_write(nvram, start + 1, sum & 0xff);
155}
156
6f7e9aec
FB
157extern int nographic;
158
819385c5 159static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
6f7e9aec
FB
160 int boot_device, uint32_t RAM_size,
161 uint32_t kernel_size,
36cd9210
BS
162 int width, int height, int depth,
163 int machine_id)
e80cfcfc
FB
164{
165 unsigned char tmp = 0;
66508601
BS
166 unsigned int i, j;
167 uint32_t start, end;
e80cfcfc 168
6f7e9aec
FB
169 // Try to match PPC NVRAM
170 nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
171 nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */
172 // NVRAM_size, arch not applicable
ba3c64fb
FB
173 m48t59_write(nvram, 0x2D, smp_cpus & 0xff);
174 m48t59_write(nvram, 0x2E, 0);
819385c5 175 m48t59_write(nvram, 0x2F, nographic & 0xff);
6f7e9aec 176 nvram_set_lword(nvram, 0x30, RAM_size);
819385c5 177 m48t59_write(nvram, 0x34, boot_device & 0xff);
6f7e9aec
FB
178 nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR);
179 nvram_set_lword(nvram, 0x3C, kernel_size);
b6f479d3 180 if (cmdline) {
b6f479d3 181 strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
6f7e9aec
FB
182 nvram_set_lword(nvram, 0x40, CMDLINE_ADDR);
183 nvram_set_lword(nvram, 0x44, strlen(cmdline));
b6f479d3 184 }
6f7e9aec
FB
185 // initrd_image, initrd_size passed differently
186 nvram_set_word(nvram, 0x54, width);
187 nvram_set_word(nvram, 0x56, height);
188 nvram_set_word(nvram, 0x58, depth);
b6f479d3 189
66508601
BS
190 // OpenBIOS nvram variables
191 // Variable partition
192 start = 252;
193 m48t59_write(nvram, start, 0x70);
194 nvram_set_string(nvram, start + 4, "system", 12);
195
196 end = start + 16;
197 for (i = 0; i < nb_prom_envs; i++)
198 end = nvram_set_var(nvram, end, prom_envs[i]);
199
200 m48t59_write(nvram, end++ , 0);
201 end = start + ((end - start + 15) & ~15);
202 nvram_finish_partition(nvram, start, end);
203
204 // free partition
205 start = end;
206 m48t59_write(nvram, start, 0x7f);
207 nvram_set_string(nvram, start + 4, "free", 12);
208
209 end = 0x1fd0;
210 nvram_finish_partition(nvram, start, end);
211
6f7e9aec 212 // Sun4m specific use
66508601 213 start = i = 0x1fd8;
819385c5 214 m48t59_write(nvram, i++, 0x01);
36cd9210 215 m48t59_write(nvram, i++, machine_id);
e80cfcfc 216 j = 0;
819385c5
FB
217 m48t59_write(nvram, i++, macaddr[j++]);
218 m48t59_write(nvram, i++, macaddr[j++]);
219 m48t59_write(nvram, i++, macaddr[j++]);
220 m48t59_write(nvram, i++, macaddr[j++]);
221 m48t59_write(nvram, i++, macaddr[j++]);
222 m48t59_write(nvram, i, macaddr[j]);
e80cfcfc
FB
223
224 /* Calculate checksum */
66508601
BS
225 for (i = start; i < start + 15; i++) {
226 tmp ^= m48t59_read(nvram, i);
e80cfcfc 227 }
66508601 228 m48t59_write(nvram, start + 15, tmp);
e80cfcfc
FB
229}
230
231static void *slavio_intctl;
232
233void pic_info()
234{
235 slavio_pic_info(slavio_intctl);
236}
237
238void irq_info()
239{
240 slavio_irq_info(slavio_intctl);
241}
242
327ac2e7
BS
243void cpu_check_irqs(CPUState *env)
244{
245 if (env->pil_in && (env->interrupt_index == 0 ||
246 (env->interrupt_index & ~15) == TT_EXTINT)) {
247 unsigned int i;
248
249 for (i = 15; i > 0; i--) {
250 if (env->pil_in & (1 << i)) {
251 int old_interrupt = env->interrupt_index;
252
253 env->interrupt_index = TT_EXTINT | i;
254 if (old_interrupt != env->interrupt_index)
255 cpu_interrupt(env, CPU_INTERRUPT_HARD);
256 break;
257 }
258 }
259 } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
260 env->interrupt_index = 0;
261 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
262 }
263}
264
b3a23197
BS
265static void cpu_set_irq(void *opaque, int irq, int level)
266{
267 CPUState *env = opaque;
268
269 if (level) {
270 DPRINTF("Raise CPU IRQ %d\n", irq);
b3a23197 271 env->halted = 0;
327ac2e7
BS
272 env->pil_in |= 1 << irq;
273 cpu_check_irqs(env);
b3a23197
BS
274 } else {
275 DPRINTF("Lower CPU IRQ %d\n", irq);
327ac2e7
BS
276 env->pil_in &= ~(1 << irq);
277 cpu_check_irqs(env);
b3a23197
BS
278 }
279}
280
281static void dummy_cpu_set_irq(void *opaque, int irq, int level)
282{
283}
284
3475187d
FB
285static void *slavio_misc;
286
287void qemu_system_powerdown(void)
288{
289 slavio_set_power_fail(slavio_misc, 1);
290}
291
c68ea704
FB
292static void main_cpu_reset(void *opaque)
293{
294 CPUState *env = opaque;
3d29fbef
BS
295
296 cpu_reset(env);
297 env->halted = 0;
298}
299
300static void secondary_cpu_reset(void *opaque)
301{
302 CPUState *env = opaque;
303
c68ea704 304 cpu_reset(env);
3d29fbef 305 env->halted = 1;
c68ea704
FB
306}
307
b3ceef24
BS
308static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
309 DisplayState *ds, const char *cpu_model)
36cd9210 310
420557e8 311{
ba3c64fb 312 CPUState *env, *envs[MAX_CPUS];
713c45fa 313 unsigned int i;
b3ceef24 314 void *iommu, *espdma, *ledma, *main_esp, *nvram;
62724a37 315 const sparc_def_t *def;
b3a23197 316 qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
d7edfd27 317 *espdma_irq, *ledma_irq;
420557e8 318
ba3c64fb 319 /* init CPUs */
62724a37
BS
320 sparc_find_by_name(cpu_model, &def);
321 if (def == NULL) {
322 fprintf(stderr, "Unable to find Sparc CPU definition\n");
323 exit(1);
324 }
b3a23197 325
ba3c64fb
FB
326 for(i = 0; i < smp_cpus; i++) {
327 env = cpu_init();
62724a37 328 cpu_sparc_register(env, def);
ba3c64fb 329 envs[i] = env;
3d29fbef
BS
330 if (i == 0) {
331 qemu_register_reset(main_cpu_reset, env);
332 } else {
333 qemu_register_reset(secondary_cpu_reset, env);
ba3c64fb 334 env->halted = 1;
3d29fbef 335 }
ba3c64fb 336 register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
b3a23197 337 cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
ba3c64fb 338 }
b3a23197
BS
339
340 for (i = smp_cpus; i < MAX_CPUS; i++)
341 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
342
420557e8 343 /* allocate RAM */
b3ceef24 344 cpu_register_physical_memory(0, RAM_size, 0);
420557e8 345
36cd9210
BS
346 iommu = iommu_init(hwdef->iommu_base);
347 slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
5dcb6b91 348 hwdef->intctl_base + 0x10000ULL,
d537cf6c 349 &hwdef->intbit_to_level[0],
d7edfd27 350 &slavio_irq, &slavio_cpu_irq,
b3a23197 351 cpu_irqs,
d7edfd27 352 hwdef->clock_irq);
b3a23197 353
5aca8c3b 354 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
70c0de96 355 iommu, &espdma_irq);
5aca8c3b 356 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
70c0de96 357 slavio_irq[hwdef->le_irq], iommu, &ledma_irq);
ba3c64fb 358
eee0b836
BS
359 if (graphic_depth != 8 && graphic_depth != 24) {
360 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
361 exit (1);
362 }
b3ceef24 363 tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
eee0b836 364 hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
dbe06e18
BS
365
366 if (nd_table[0].model == NULL
367 || strcmp(nd_table[0].model, "lance") == 0) {
368 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq);
c4a7060c
BS
369 } else if (strcmp(nd_table[0].model, "?") == 0) {
370 fprintf(stderr, "qemu: Supported NICs: lance\n");
371 exit (1);
dbe06e18
BS
372 } else {
373 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
374 exit (1);
a41b2ff2 375 }
dbe06e18 376
d537cf6c
PB
377 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
378 hwdef->nvram_size, 8);
ba3c64fb 379 for (i = 0; i < MAX_CPUS; i++) {
5dcb6b91
BS
380 slavio_timer_init(hwdef->counter_base +
381 (target_phys_addr_t)(i * TARGET_PAGE_SIZE),
d7edfd27 382 slavio_cpu_irq[i], 0);
ba3c64fb 383 }
d7edfd27
BS
384 slavio_timer_init(hwdef->counter_base + 0x10000ULL,
385 slavio_irq[hwdef->clock1_irq], 2);
d537cf6c 386 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
b81b3b10
FB
387 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
388 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
d537cf6c
PB
389 slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
390 serial_hds[1], serial_hds[0]);
391 fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
70c0de96 392 main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq);
f1587550
TS
393
394 for (i = 0; i < MAX_DISKS; i++) {
395 if (bs_table[i]) {
396 esp_scsi_attach(main_esp, bs_table[i], i);
397 }
398 }
399
5dcb6b91 400 slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
d537cf6c 401 slavio_irq[hwdef->me_irq]);
5dcb6b91 402 if (hwdef->cs_base != (target_phys_addr_t)-1)
803b3c7b 403 cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
b3ceef24
BS
404
405 return nvram;
36cd9210
BS
406}
407
b3ceef24 408static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device,
36cd9210
BS
409 const char *kernel_filename,
410 const char *kernel_cmdline,
411 const char *initrd_filename,
b3ceef24
BS
412 int machine_id,
413 void *nvram)
36cd9210
BS
414{
415 int ret, linux_boot;
416 char buf[1024];
417 unsigned int i;
418 long prom_offset, initrd_size, kernel_size;
419
420 linux_boot = (kernel_filename != NULL);
420557e8 421
b3ceef24 422 prom_offset = RAM_size + vram_size;
b3783731
FB
423 cpu_register_physical_memory(PROM_ADDR,
424 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
425 prom_offset | IO_MEM_ROM);
e80cfcfc 426
0986ac3b 427 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
74287114 428 ret = load_elf(buf, 0, NULL, NULL, NULL);
e80cfcfc
FB
429 if (ret < 0) {
430 fprintf(stderr, "qemu: could not load prom '%s'\n",
431 buf);
432 exit(1);
433 }
e80cfcfc 434
6f7e9aec 435 kernel_size = 0;
e80cfcfc 436 if (linux_boot) {
74287114 437 kernel_size = load_elf(kernel_filename, -0xf0000000, NULL, NULL, NULL);
6f7e9aec
FB
438 if (kernel_size < 0)
439 kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
440 if (kernel_size < 0)
441 kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
442 if (kernel_size < 0) {
420557e8 443 fprintf(stderr, "qemu: could not load kernel '%s'\n",
e80cfcfc
FB
444 kernel_filename);
445 exit(1);
420557e8 446 }
713c45fa
FB
447
448 /* load initrd */
449 initrd_size = 0;
450 if (initrd_filename) {
451 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
452 if (initrd_size < 0) {
453 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
454 initrd_filename);
455 exit(1);
456 }
457 }
458 if (initrd_size > 0) {
459 for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
460 if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
461 == 0x48647253) { // HdrS
462 stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
463 stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
464 break;
465 }
466 }
467 }
420557e8 468 }
36cd9210 469 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
b3ceef24 470 boot_device, RAM_size, kernel_size, graphic_width,
36cd9210
BS
471 graphic_height, graphic_depth, machine_id);
472}
473
474static const struct hwdef hwdefs[] = {
475 /* SS-5 */
476 {
477 .iommu_base = 0x10000000,
478 .tcx_base = 0x50000000,
479 .cs_base = 0x6c000000,
384ccb5d 480 .slavio_base = 0x70000000,
36cd9210
BS
481 .ms_kb_base = 0x71000000,
482 .serial_base = 0x71100000,
483 .nvram_base = 0x71200000,
484 .fd_base = 0x71400000,
485 .counter_base = 0x71d00000,
486 .intctl_base = 0x71e00000,
487 .dma_base = 0x78400000,
488 .esp_base = 0x78800000,
489 .le_base = 0x78c00000,
5dcb6b91 490 .power_base = 0x7a000000,
36cd9210
BS
491 .vram_size = 0x00100000,
492 .nvram_size = 0x2000,
493 .esp_irq = 18,
494 .le_irq = 16,
495 .clock_irq = 7,
496 .clock1_irq = 19,
497 .ms_kb_irq = 14,
498 .ser_irq = 15,
499 .fd_irq = 22,
500 .me_irq = 30,
501 .cs_irq = 5,
502 .machine_id = 0x80,
e0353fe2
BS
503 .intbit_to_level = {
504 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
505 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
506 },
507 },
508 /* SS-10 */
e0353fe2 509 {
5dcb6b91
BS
510 .iommu_base = 0xfe0000000ULL,
511 .tcx_base = 0xe20000000ULL,
803b3c7b 512 .cs_base = -1,
5dcb6b91
BS
513 .slavio_base = 0xff0000000ULL,
514 .ms_kb_base = 0xff1000000ULL,
515 .serial_base = 0xff1100000ULL,
516 .nvram_base = 0xff1200000ULL,
517 .fd_base = 0xff1700000ULL,
518 .counter_base = 0xff1300000ULL,
519 .intctl_base = 0xff1400000ULL,
520 .dma_base = 0xef0400000ULL,
521 .esp_base = 0xef0800000ULL,
522 .le_base = 0xef0c00000ULL,
523 .power_base = 0xefa000000ULL,
e0353fe2
BS
524 .vram_size = 0x00100000,
525 .nvram_size = 0x2000,
526 .esp_irq = 18,
527 .le_irq = 16,
528 .clock_irq = 7,
529 .clock1_irq = 19,
530 .ms_kb_irq = 14,
531 .ser_irq = 15,
532 .fd_irq = 22,
533 .me_irq = 30,
803b3c7b
BS
534 .cs_irq = -1,
535 .machine_id = 0x72,
e0353fe2
BS
536 .intbit_to_level = {
537 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
538 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
539 },
36cd9210
BS
540 },
541};
542
b3ceef24 543static void sun4m_common_init(int RAM_size, int boot_device, DisplayState *ds,
36cd9210
BS
544 const char *kernel_filename, const char *kernel_cmdline,
545 const char *initrd_filename, const char *cpu_model,
4edebb0e 546 unsigned int machine, int max_ram)
36cd9210 547{
b3ceef24
BS
548 void *nvram;
549
550 if ((unsigned int)RAM_size > (unsigned int)max_ram) {
4edebb0e 551 fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
b3ceef24 552 (unsigned int)RAM_size / (1024 * 1024),
5dcb6b91 553 (unsigned int)max_ram / (1024 * 1024));
4edebb0e
BS
554 exit(1);
555 }
b3ceef24 556 nvram = sun4m_hw_init(&hwdefs[machine], RAM_size, ds, cpu_model);
36cd9210 557
b3ceef24 558 sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
36cd9210 559 kernel_filename, kernel_cmdline, initrd_filename,
b3ceef24 560 hwdefs[machine].machine_id, nvram);
36cd9210
BS
561}
562
563/* SPARCstation 5 hardware initialisation */
b3ceef24 564static void ss5_init(int RAM_size, int vga_ram_size, int boot_device,
36cd9210
BS
565 DisplayState *ds, const char **fd_filename, int snapshot,
566 const char *kernel_filename, const char *kernel_cmdline,
567 const char *initrd_filename, const char *cpu_model)
568{
569 if (cpu_model == NULL)
570 cpu_model = "Fujitsu MB86904";
b3ceef24 571 sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
36cd9210 572 kernel_cmdline, initrd_filename, cpu_model,
4edebb0e 573 0, 0x10000000);
420557e8 574}
c0e564d5 575
e0353fe2 576/* SPARCstation 10 hardware initialisation */
b3ceef24 577static void ss10_init(int RAM_size, int vga_ram_size, int boot_device,
e0353fe2
BS
578 DisplayState *ds, const char **fd_filename, int snapshot,
579 const char *kernel_filename, const char *kernel_cmdline,
580 const char *initrd_filename, const char *cpu_model)
581{
582 if (cpu_model == NULL)
583 cpu_model = "TI SuperSparc II";
b3ceef24 584 sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
e0353fe2 585 kernel_cmdline, initrd_filename, cpu_model,
5dcb6b91 586 1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
e0353fe2
BS
587}
588
36cd9210
BS
589QEMUMachine ss5_machine = {
590 "SS-5",
591 "Sun4m platform, SPARCstation 5",
592 ss5_init,
c0e564d5 593};
e0353fe2
BS
594
595QEMUMachine ss10_machine = {
596 "SS-10",
597 "Sun4m platform, SPARCstation 10",
598 ss10_init,
599};
This page took 0.203797 seconds and 4 git commands to generate.