Use qemu_irqs between CPUs and interrupt controller
[qemu/qemu_0_9_1_stable.git] / hw / sun4m.c
blobc69d732f91b296a6e94484160389f26542be5a1d
1 /*
2 * QEMU Sun4m System Emulator
3 *
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
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
22 * THE SOFTWARE.
24 #include "vl.h"
25 //#define DEBUG_IRQ
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
37 * SPARCstation 4
39 * See for example: http://www.sunhelp.org/faq/sunref1.html
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
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"
56 #define MAX_CPUS 16
57 #define MAX_PILS 16
59 struct hwdef {
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
67 // bit numbers
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];
74 /* TSC handling */
76 uint64_t cpu_get_tsc()
78 return qemu_get_clock(vm_clock);
81 int DMA_get_channel_mode (int nchan)
83 return 0;
85 int DMA_read_memory (int nchan, void *buf, int pos, int size)
87 return 0;
89 int DMA_write_memory (int nchan, void *buf, int pos, int size)
91 return 0;
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,
100 void *opaque)
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)
121 unsigned int i;
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)
132 uint32_t len;
134 len = strlen(str) + 1;
135 nvram_set_string(nvram, addr, str, len);
137 return addr + len;
140 static void nvram_finish_partition (m48t59_t *nvram, uint32_t start,
141 uint32_t end)
143 unsigned int i, sum;
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;
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,
165 int machine_id)
167 unsigned char tmp = 0;
168 unsigned int i, j;
169 uint32_t start, end;
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);
182 if (cmdline) {
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
194 start = 252;
195 m48t59_write(nvram, start, 0x70);
196 nvram_set_string(nvram, start + 4, "system", 12);
198 end = start + 16;
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);
206 // free partition
207 start = end;
208 m48t59_write(nvram, start, 0x7f);
209 nvram_set_string(nvram, start + 4, "free", 12);
211 end = 0x1fd0;
212 nvram_finish_partition(nvram, start, end);
214 // Sun4m specific use
215 start = i = 0x1fd8;
216 m48t59_write(nvram, i++, 0x01);
217 m48t59_write(nvram, i++, machine_id);
218 j = 0;
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;
235 void pic_info()
237 slavio_pic_info(slavio_intctl);
240 void irq_info()
242 slavio_irq_info(slavio_intctl);
245 static void cpu_set_irq(void *opaque, int irq, int level)
247 CPUState *env = opaque;
249 if (level) {
250 DPRINTF("Raise CPU IRQ %d\n", irq);
252 env->halted = 0;
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);
259 } else {
260 DPRINTF("Not triggered, pending exception %d\n",
261 env->interrupt_index);
263 } else {
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;
283 cpu_reset(env);
284 env->halted = 0;
287 static void secondary_cpu_reset(void *opaque)
289 CPUState *env = opaque;
291 cpu_reset(env);
292 env->halted = 1;
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];
300 unsigned int i;
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;
306 /* init CPUs */
307 sparc_find_by_name(cpu_model, &def);
308 if (def == NULL) {
309 fprintf(stderr, "Unable to find Sparc CPU definition\n");
310 exit(1);
313 for(i = 0; i < smp_cpus; i++) {
314 env = cpu_init();
315 cpu_sparc_register(env, def);
316 envs[i] = env;
317 if (i == 0) {
318 qemu_register_reset(main_cpu_reset, env);
319 } else {
320 qemu_register_reset(secondary_cpu_reset, env);
321 env->halted = 1;
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);
330 /* allocate RAM */
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,
338 cpu_irqs,
339 hwdef->clock_irq);
341 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
342 iommu, &espdma_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);
348 exit (1);
350 tcx_init(ds, hwdef->tcx_base, phys_ram_base + ram_size, ram_size,
351 hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
352 if (nd_table[0].vlan) {
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 {
357 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
358 exit (1);
361 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
362 hwdef->nvram_size, 8);
363 for (i = 0; i < MAX_CPUS; i++) {
364 slavio_timer_init(hwdef->counter_base +
365 (target_phys_addr_t)(i * TARGET_PAGE_SIZE),
366 slavio_cpu_irq[i], 0);
368 slavio_timer_init(hwdef->counter_base + 0x10000ULL,
369 slavio_irq[hwdef->clock1_irq], 2);
370 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
371 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
372 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
373 slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
374 serial_hds[1], serial_hds[0]);
375 fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
376 main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq);
378 for (i = 0; i < MAX_DISKS; i++) {
379 if (bs_table[i]) {
380 esp_scsi_attach(main_esp, bs_table[i], i);
384 slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base,
385 slavio_irq[hwdef->me_irq]);
386 if (hwdef->cs_base != (target_phys_addr_t)-1)
387 cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
390 static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device,
391 const char *kernel_filename,
392 const char *kernel_cmdline,
393 const char *initrd_filename,
394 int machine_id)
396 int ret, linux_boot;
397 char buf[1024];
398 unsigned int i;
399 long prom_offset, initrd_size, kernel_size;
401 linux_boot = (kernel_filename != NULL);
403 prom_offset = ram_size + vram_size;
404 cpu_register_physical_memory(PROM_ADDR,
405 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
406 prom_offset | IO_MEM_ROM);
408 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
409 ret = load_elf(buf, 0, NULL, NULL, NULL);
410 if (ret < 0) {
411 fprintf(stderr, "qemu: could not load prom '%s'\n",
412 buf);
413 exit(1);
416 kernel_size = 0;
417 if (linux_boot) {
418 kernel_size = load_elf(kernel_filename, -0xf0000000, NULL, NULL, NULL);
419 if (kernel_size < 0)
420 kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
421 if (kernel_size < 0)
422 kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
423 if (kernel_size < 0) {
424 fprintf(stderr, "qemu: could not load kernel '%s'\n",
425 kernel_filename);
426 exit(1);
429 /* load initrd */
430 initrd_size = 0;
431 if (initrd_filename) {
432 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
433 if (initrd_size < 0) {
434 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
435 initrd_filename);
436 exit(1);
439 if (initrd_size > 0) {
440 for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
441 if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
442 == 0x48647253) { // HdrS
443 stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
444 stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
445 break;
450 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
451 boot_device, ram_size, kernel_size, graphic_width,
452 graphic_height, graphic_depth, machine_id);
455 static const struct hwdef hwdefs[] = {
456 /* SS-5 */
458 .iommu_base = 0x10000000,
459 .tcx_base = 0x50000000,
460 .cs_base = 0x6c000000,
461 .slavio_base = 0x70000000,
462 .ms_kb_base = 0x71000000,
463 .serial_base = 0x71100000,
464 .nvram_base = 0x71200000,
465 .fd_base = 0x71400000,
466 .counter_base = 0x71d00000,
467 .intctl_base = 0x71e00000,
468 .dma_base = 0x78400000,
469 .esp_base = 0x78800000,
470 .le_base = 0x78c00000,
471 .power_base = 0x7a000000,
472 .vram_size = 0x00100000,
473 .nvram_size = 0x2000,
474 .esp_irq = 18,
475 .le_irq = 16,
476 .clock_irq = 7,
477 .clock1_irq = 19,
478 .ms_kb_irq = 14,
479 .ser_irq = 15,
480 .fd_irq = 22,
481 .me_irq = 30,
482 .cs_irq = 5,
483 .machine_id = 0x80,
484 .intbit_to_level = {
485 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
486 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
489 /* SS-10 */
491 .iommu_base = 0xfe0000000ULL,
492 .tcx_base = 0xe20000000ULL,
493 .cs_base = -1,
494 .slavio_base = 0xff0000000ULL,
495 .ms_kb_base = 0xff1000000ULL,
496 .serial_base = 0xff1100000ULL,
497 .nvram_base = 0xff1200000ULL,
498 .fd_base = 0xff1700000ULL,
499 .counter_base = 0xff1300000ULL,
500 .intctl_base = 0xff1400000ULL,
501 .dma_base = 0xef0400000ULL,
502 .esp_base = 0xef0800000ULL,
503 .le_base = 0xef0c00000ULL,
504 .power_base = 0xefa000000ULL,
505 .vram_size = 0x00100000,
506 .nvram_size = 0x2000,
507 .esp_irq = 18,
508 .le_irq = 16,
509 .clock_irq = 7,
510 .clock1_irq = 19,
511 .ms_kb_irq = 14,
512 .ser_irq = 15,
513 .fd_irq = 22,
514 .me_irq = 30,
515 .cs_irq = -1,
516 .machine_id = 0x72,
517 .intbit_to_level = {
518 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
519 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
524 static void sun4m_common_init(int ram_size, int boot_device, DisplayState *ds,
525 const char *kernel_filename, const char *kernel_cmdline,
526 const char *initrd_filename, const char *cpu_model,
527 unsigned int machine, int max_ram)
529 if ((unsigned int)ram_size > (unsigned int)max_ram) {
530 fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
531 (unsigned int)ram_size / (1024 * 1024),
532 (unsigned int)max_ram / (1024 * 1024));
533 exit(1);
535 sun4m_hw_init(&hwdefs[machine], ram_size, ds, cpu_model);
537 sun4m_load_kernel(hwdefs[machine].vram_size, ram_size, boot_device,
538 kernel_filename, kernel_cmdline, initrd_filename,
539 hwdefs[machine].machine_id);
542 /* SPARCstation 5 hardware initialisation */
543 static void ss5_init(int ram_size, int vga_ram_size, int boot_device,
544 DisplayState *ds, const char **fd_filename, int snapshot,
545 const char *kernel_filename, const char *kernel_cmdline,
546 const char *initrd_filename, const char *cpu_model)
548 if (cpu_model == NULL)
549 cpu_model = "Fujitsu MB86904";
550 sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
551 kernel_cmdline, initrd_filename, cpu_model,
552 0, 0x10000000);
555 /* SPARCstation 10 hardware initialisation */
556 static void ss10_init(int ram_size, int vga_ram_size, int boot_device,
557 DisplayState *ds, const char **fd_filename, int snapshot,
558 const char *kernel_filename, const char *kernel_cmdline,
559 const char *initrd_filename, const char *cpu_model)
561 if (cpu_model == NULL)
562 cpu_model = "TI SuperSparc II";
563 sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
564 kernel_cmdline, initrd_filename, cpu_model,
565 1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
568 QEMUMachine ss5_machine = {
569 "SS-5",
570 "Sun4m platform, SPARCstation 5",
571 ss5_init,
574 QEMUMachine ss10_machine = {
575 "SS-10",
576 "Sun4m platform, SPARCstation 10",
577 ss10_init,