2 * QEMU Sun4m System Emulator
4 * Copyright (c) 2003-2005 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
28 * Sun4m architecture was used in the following machines:
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
39 * See for example: http://www.sunhelp.org/faq/sunref1.html
43 #define DPRINTF(fmt, args...) \
44 do { printf("CPUIRQ: " fmt , ##args); } while (0)
46 #define DPRINTF(fmt, args...)
49 #define KERNEL_LOAD_ADDR 0x00004000
50 #define CMDLINE_ADDR 0x007ff000
51 #define INITRD_LOAD_ADDR 0x00800000
52 #define PROM_SIZE_MAX (256 * 1024)
53 #define PROM_ADDR 0xffd00000
54 #define PROM_FILENAME "openbios-sparc32"
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
;
65 long vram_size
, nvram_size
;
66 // IRQ numbers are not PIL ones, but master interrupt controller register
68 int intctl_g_intr
, esp_irq
, le_irq
, clock_irq
, clock1_irq
;
69 int ser_irq
, ms_kb_irq
, fd_irq
, me_irq
, cs_irq
;
70 int machine_id
; // For NVRAM
71 uint32_t intbit_to_level
[32];
76 uint64_t cpu_get_tsc()
78 return qemu_get_clock(vm_clock
);
81 int DMA_get_channel_mode (int nchan
)
85 int DMA_read_memory (int nchan
, void *buf
, int pos
, int size
)
89 int DMA_write_memory (int nchan
, void *buf
, int pos
, int size
)
93 void DMA_hold_DREQ (int nchan
) {}
94 void DMA_release_DREQ (int nchan
) {}
95 void DMA_schedule(int nchan
) {}
96 void DMA_run (void) {}
97 void DMA_init (int high_page_enable
) {}
98 void DMA_register_channel (int nchan
,
99 DMA_transfer_handler transfer_handler
,
104 static void nvram_set_word (m48t59_t
*nvram
, uint32_t addr
, uint16_t value
)
106 m48t59_write(nvram
, addr
++, (value
>> 8) & 0xff);
107 m48t59_write(nvram
, addr
++, value
& 0xff);
110 static void nvram_set_lword (m48t59_t
*nvram
, uint32_t addr
, uint32_t value
)
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);
118 static void nvram_set_string (m48t59_t
*nvram
, uint32_t addr
,
119 const unsigned char *str
, uint32_t max
)
123 for (i
= 0; i
< max
&& str
[i
] != '\0'; i
++) {
124 m48t59_write(nvram
, addr
+ i
, str
[i
]);
126 m48t59_write(nvram
, addr
+ max
- 1, '\0');
129 static uint32_t nvram_set_var (m48t59_t
*nvram
, uint32_t addr
,
130 const unsigned char *str
)
134 len
= strlen(str
) + 1;
135 nvram_set_string(nvram
, addr
, str
, len
);
140 static void nvram_finish_partition (m48t59_t
*nvram
, uint32_t start
,
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);
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;
154 m48t59_write(nvram
, start
+ 1, sum
& 0xff);
157 static m48t59_t
*nvram
;
159 extern int nographic
;
161 static void nvram_init(m48t59_t
*nvram
, uint8_t *macaddr
, const char *cmdline
,
162 int boot_device
, uint32_t RAM_size
,
163 uint32_t kernel_size
,
164 int width
, int height
, int depth
,
167 unsigned char tmp
= 0;
171 // Try to match PPC NVRAM
172 nvram_set_string(nvram
, 0x00, "QEMU_BIOS", 16);
173 nvram_set_lword(nvram
, 0x10, 0x00000001); /* structure v1 */
174 // NVRAM_size, arch not applicable
175 m48t59_write(nvram
, 0x2D, smp_cpus
& 0xff);
176 m48t59_write(nvram
, 0x2E, 0);
177 m48t59_write(nvram
, 0x2F, nographic
& 0xff);
178 nvram_set_lword(nvram
, 0x30, RAM_size
);
179 m48t59_write(nvram
, 0x34, boot_device
& 0xff);
180 nvram_set_lword(nvram
, 0x38, KERNEL_LOAD_ADDR
);
181 nvram_set_lword(nvram
, 0x3C, kernel_size
);
183 strcpy(phys_ram_base
+ CMDLINE_ADDR
, cmdline
);
184 nvram_set_lword(nvram
, 0x40, CMDLINE_ADDR
);
185 nvram_set_lword(nvram
, 0x44, strlen(cmdline
));
187 // initrd_image, initrd_size passed differently
188 nvram_set_word(nvram
, 0x54, width
);
189 nvram_set_word(nvram
, 0x56, height
);
190 nvram_set_word(nvram
, 0x58, depth
);
192 // OpenBIOS nvram variables
193 // Variable partition
195 m48t59_write(nvram
, start
, 0x70);
196 nvram_set_string(nvram
, start
+ 4, "system", 12);
199 for (i
= 0; i
< nb_prom_envs
; i
++)
200 end
= nvram_set_var(nvram
, end
, prom_envs
[i
]);
202 m48t59_write(nvram
, end
++ , 0);
203 end
= start
+ ((end
- start
+ 15) & ~15);
204 nvram_finish_partition(nvram
, start
, end
);
208 m48t59_write(nvram
, start
, 0x7f);
209 nvram_set_string(nvram
, start
+ 4, "free", 12);
212 nvram_finish_partition(nvram
, start
, end
);
214 // Sun4m specific use
216 m48t59_write(nvram
, i
++, 0x01);
217 m48t59_write(nvram
, i
++, machine_id
);
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
++]);
223 m48t59_write(nvram
, i
++, macaddr
[j
++]);
224 m48t59_write(nvram
, i
, macaddr
[j
]);
226 /* Calculate checksum */
227 for (i
= start
; i
< start
+ 15; i
++) {
228 tmp
^= m48t59_read(nvram
, i
);
230 m48t59_write(nvram
, start
+ 15, tmp
);
233 static void *slavio_intctl
;
237 slavio_pic_info(slavio_intctl
);
242 slavio_irq_info(slavio_intctl
);
245 static void cpu_set_irq(void *opaque
, int irq
, int level
)
247 CPUState
*env
= opaque
;
250 DPRINTF("Raise CPU IRQ %d\n", irq
);
254 if (env
->interrupt_index
== 0 ||
255 ((env
->interrupt_index
& ~15) == TT_EXTINT
&&
256 (env
->interrupt_index
& 15) < irq
)) {
257 env
->interrupt_index
= TT_EXTINT
| irq
;
258 cpu_interrupt(env
, CPU_INTERRUPT_HARD
);
260 DPRINTF("Not triggered, pending exception %d\n",
261 env
->interrupt_index
);
264 DPRINTF("Lower CPU IRQ %d\n", irq
);
268 static void dummy_cpu_set_irq(void *opaque
, int irq
, int level
)
272 static void *slavio_misc
;
274 void qemu_system_powerdown(void)
276 slavio_set_power_fail(slavio_misc
, 1);
279 static void main_cpu_reset(void *opaque
)
281 CPUState
*env
= opaque
;
287 static void secondary_cpu_reset(void *opaque
)
289 CPUState
*env
= opaque
;
295 static void sun4m_hw_init(const struct hwdef
*hwdef
, int ram_size
,
296 DisplayState
*ds
, const char *cpu_model
)
299 CPUState
*env
, *envs
[MAX_CPUS
];
301 void *iommu
, *espdma
, *ledma
, *main_esp
;
302 const sparc_def_t
*def
;
303 qemu_irq
*cpu_irqs
[MAX_CPUS
], *slavio_irq
, *slavio_cpu_irq
,
304 *espdma_irq
, *ledma_irq
;
307 sparc_find_by_name(cpu_model
, &def
);
309 fprintf(stderr
, "Unable to find Sparc CPU definition\n");
313 for(i
= 0; i
< smp_cpus
; i
++) {
315 cpu_sparc_register(env
, def
);
318 qemu_register_reset(main_cpu_reset
, env
);
320 qemu_register_reset(secondary_cpu_reset
, env
);
323 register_savevm("cpu", i
, 3, cpu_save
, cpu_load
, env
);
324 cpu_irqs
[i
] = qemu_allocate_irqs(cpu_set_irq
, envs
[i
], MAX_PILS
);
327 for (i
= smp_cpus
; i
< MAX_CPUS
; i
++)
328 cpu_irqs
[i
] = qemu_allocate_irqs(dummy_cpu_set_irq
, NULL
, MAX_PILS
);
331 cpu_register_physical_memory(0, ram_size
, 0);
333 iommu
= iommu_init(hwdef
->iommu_base
);
334 slavio_intctl
= slavio_intctl_init(hwdef
->intctl_base
,
335 hwdef
->intctl_base
+ 0x10000ULL
,
336 &hwdef
->intbit_to_level
[0],
337 &slavio_irq
, &slavio_cpu_irq
,
341 espdma
= sparc32_dma_init(hwdef
->dma_base
, slavio_irq
[hwdef
->esp_irq
],
343 ledma
= sparc32_dma_init(hwdef
->dma_base
+ 16ULL,
344 slavio_irq
[hwdef
->le_irq
], iommu
, &ledma_irq
);
346 if (graphic_depth
!= 8 && graphic_depth
!= 24) {
347 fprintf(stderr
, "qemu: Unsupported depth: %d\n", graphic_depth
);
350 tcx_init(ds
, hwdef
->tcx_base
, phys_ram_base
+ ram_size
, ram_size
,
351 hwdef
->vram_size
, graphic_width
, graphic_height
, graphic_depth
);
353 if (nd_table
[0].model
== NULL
354 || strcmp(nd_table
[0].model
, "lance") == 0) {
355 lance_init(&nd_table
[0], hwdef
->le_base
, ledma
, *ledma_irq
);
356 } else if (strcmp(nd_table
[0].model
, "?") == 0) {
357 fprintf(stderr
, "qemu: Supported NICs: lance\n");
360 fprintf(stderr
, "qemu: Unsupported NIC: %s\n", nd_table
[0].model
);
364 nvram
= m48t59_init(slavio_irq
[0], hwdef
->nvram_base
, 0,
365 hwdef
->nvram_size
, 8);
366 for (i
= 0; i
< MAX_CPUS
; i
++) {
367 slavio_timer_init(hwdef
->counter_base
+
368 (target_phys_addr_t
)(i
* TARGET_PAGE_SIZE
),
369 slavio_cpu_irq
[i
], 0);
371 slavio_timer_init(hwdef
->counter_base
+ 0x10000ULL
,
372 slavio_irq
[hwdef
->clock1_irq
], 2);
373 slavio_serial_ms_kbd_init(hwdef
->ms_kb_base
, slavio_irq
[hwdef
->ms_kb_irq
]);
374 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
375 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
376 slavio_serial_init(hwdef
->serial_base
, slavio_irq
[hwdef
->ser_irq
],
377 serial_hds
[1], serial_hds
[0]);
378 fdctrl_init(slavio_irq
[hwdef
->fd_irq
], 0, 1, hwdef
->fd_base
, fd_table
);
379 main_esp
= esp_init(bs_table
, hwdef
->esp_base
, espdma
, *espdma_irq
);
381 for (i
= 0; i
< MAX_DISKS
; i
++) {
383 esp_scsi_attach(main_esp
, bs_table
[i
], i
);
387 slavio_misc
= slavio_misc_init(hwdef
->slavio_base
, hwdef
->power_base
,
388 slavio_irq
[hwdef
->me_irq
]);
389 if (hwdef
->cs_base
!= (target_phys_addr_t
)-1)
390 cs_init(hwdef
->cs_base
, hwdef
->cs_irq
, slavio_intctl
);
393 static void sun4m_load_kernel(long vram_size
, int ram_size
, int boot_device
,
394 const char *kernel_filename
,
395 const char *kernel_cmdline
,
396 const char *initrd_filename
,
402 long prom_offset
, initrd_size
, kernel_size
;
404 linux_boot
= (kernel_filename
!= NULL
);
406 prom_offset
= ram_size
+ vram_size
;
407 cpu_register_physical_memory(PROM_ADDR
,
408 (PROM_SIZE_MAX
+ TARGET_PAGE_SIZE
- 1) & TARGET_PAGE_MASK
,
409 prom_offset
| IO_MEM_ROM
);
411 snprintf(buf
, sizeof(buf
), "%s/%s", bios_dir
, PROM_FILENAME
);
412 ret
= load_elf(buf
, 0, NULL
, NULL
, NULL
);
414 fprintf(stderr
, "qemu: could not load prom '%s'\n",
421 kernel_size
= load_elf(kernel_filename
, -0xf0000000, NULL
, NULL
, NULL
);
423 kernel_size
= load_aout(kernel_filename
, phys_ram_base
+ KERNEL_LOAD_ADDR
);
425 kernel_size
= load_image(kernel_filename
, phys_ram_base
+ KERNEL_LOAD_ADDR
);
426 if (kernel_size
< 0) {
427 fprintf(stderr
, "qemu: could not load kernel '%s'\n",
434 if (initrd_filename
) {
435 initrd_size
= load_image(initrd_filename
, phys_ram_base
+ INITRD_LOAD_ADDR
);
436 if (initrd_size
< 0) {
437 fprintf(stderr
, "qemu: could not load initial ram disk '%s'\n",
442 if (initrd_size
> 0) {
443 for (i
= 0; i
< 64 * TARGET_PAGE_SIZE
; i
+= TARGET_PAGE_SIZE
) {
444 if (ldl_raw(phys_ram_base
+ KERNEL_LOAD_ADDR
+ i
)
445 == 0x48647253) { // HdrS
446 stl_raw(phys_ram_base
+ KERNEL_LOAD_ADDR
+ i
+ 16, INITRD_LOAD_ADDR
);
447 stl_raw(phys_ram_base
+ KERNEL_LOAD_ADDR
+ i
+ 20, initrd_size
);
453 nvram_init(nvram
, (uint8_t *)&nd_table
[0].macaddr
, kernel_cmdline
,
454 boot_device
, ram_size
, kernel_size
, graphic_width
,
455 graphic_height
, graphic_depth
, machine_id
);
458 static const struct hwdef hwdefs
[] = {
461 .iommu_base
= 0x10000000,
462 .tcx_base
= 0x50000000,
463 .cs_base
= 0x6c000000,
464 .slavio_base
= 0x70000000,
465 .ms_kb_base
= 0x71000000,
466 .serial_base
= 0x71100000,
467 .nvram_base
= 0x71200000,
468 .fd_base
= 0x71400000,
469 .counter_base
= 0x71d00000,
470 .intctl_base
= 0x71e00000,
471 .dma_base
= 0x78400000,
472 .esp_base
= 0x78800000,
473 .le_base
= 0x78c00000,
474 .power_base
= 0x7a000000,
475 .vram_size
= 0x00100000,
476 .nvram_size
= 0x2000,
488 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
489 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
494 .iommu_base
= 0xfe0000000ULL
,
495 .tcx_base
= 0xe20000000ULL
,
497 .slavio_base
= 0xff0000000ULL
,
498 .ms_kb_base
= 0xff1000000ULL
,
499 .serial_base
= 0xff1100000ULL
,
500 .nvram_base
= 0xff1200000ULL
,
501 .fd_base
= 0xff1700000ULL
,
502 .counter_base
= 0xff1300000ULL
,
503 .intctl_base
= 0xff1400000ULL
,
504 .dma_base
= 0xef0400000ULL
,
505 .esp_base
= 0xef0800000ULL
,
506 .le_base
= 0xef0c00000ULL
,
507 .power_base
= 0xefa000000ULL
,
508 .vram_size
= 0x00100000,
509 .nvram_size
= 0x2000,
521 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
522 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
527 static void sun4m_common_init(int ram_size
, int boot_device
, DisplayState
*ds
,
528 const char *kernel_filename
, const char *kernel_cmdline
,
529 const char *initrd_filename
, const char *cpu_model
,
530 unsigned int machine
, int max_ram
)
532 if ((unsigned int)ram_size
> (unsigned int)max_ram
) {
533 fprintf(stderr
, "qemu: Too much memory for this machine: %d, maximum %d\n",
534 (unsigned int)ram_size
/ (1024 * 1024),
535 (unsigned int)max_ram
/ (1024 * 1024));
538 sun4m_hw_init(&hwdefs
[machine
], ram_size
, ds
, cpu_model
);
540 sun4m_load_kernel(hwdefs
[machine
].vram_size
, ram_size
, boot_device
,
541 kernel_filename
, kernel_cmdline
, initrd_filename
,
542 hwdefs
[machine
].machine_id
);
545 /* SPARCstation 5 hardware initialisation */
546 static void ss5_init(int ram_size
, int vga_ram_size
, int boot_device
,
547 DisplayState
*ds
, const char **fd_filename
, int snapshot
,
548 const char *kernel_filename
, const char *kernel_cmdline
,
549 const char *initrd_filename
, const char *cpu_model
)
551 if (cpu_model
== NULL
)
552 cpu_model
= "Fujitsu MB86904";
553 sun4m_common_init(ram_size
, boot_device
, ds
, kernel_filename
,
554 kernel_cmdline
, initrd_filename
, cpu_model
,
558 /* SPARCstation 10 hardware initialisation */
559 static void ss10_init(int ram_size
, int vga_ram_size
, int boot_device
,
560 DisplayState
*ds
, const char **fd_filename
, int snapshot
,
561 const char *kernel_filename
, const char *kernel_cmdline
,
562 const char *initrd_filename
, const char *cpu_model
)
564 if (cpu_model
== NULL
)
565 cpu_model
= "TI SuperSparc II";
566 sun4m_common_init(ram_size
, boot_device
, ds
, kernel_filename
,
567 kernel_cmdline
, initrd_filename
, cpu_model
,
568 1, PROM_ADDR
); // XXX prom overlap, actually first 4GB ok
571 QEMUMachine ss5_machine
= {
573 "Sun4m platform, SPARCstation 5",
577 QEMUMachine ss10_machine
= {
579 "Sun4m platform, SPARCstation 10",