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