|
|
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.8 root 24: #include "sysbus.h"
1.1.1.6 root 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.10 root 34: #include "esp.h"
1.1.1.7 root 35: #include "pc.h"
36: #include "isa.h"
37: #include "fw_cfg.h"
38: #include "escc.h"
1.1.1.11! root 39: #include "empty_slot.h"
1.1.1.10 root 40: #include "qdev-addr.h"
41: #include "loader.h"
42: #include "elf.h"
1.1.1.6 root 43:
44: //#define DEBUG_IRQ
45:
46: /*
47: * Sun4m architecture was used in the following machines:
48: *
49: * SPARCserver 6xxMP/xx
1.1.1.7 root 50: * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15),
51: * SPARCclassic X (4/10)
1.1.1.6 root 52: * SPARCstation LX/ZX (4/30)
53: * SPARCstation Voyager
54: * SPARCstation 10/xx, SPARCserver 10/xx
55: * SPARCstation 5, SPARCserver 5
56: * SPARCstation 20/xx, SPARCserver 20
57: * SPARCstation 4
58: *
59: * Sun4d architecture was used in the following machines:
60: *
61: * SPARCcenter 2000
62: * SPARCserver 1000
63: *
64: * Sun4c architecture was used in the following machines:
65: * SPARCstation 1/1+, SPARCserver 1/1+
66: * SPARCstation SLC
67: * SPARCstation IPC
68: * SPARCstation ELC
69: * SPARCstation IPX
70: *
71: * See for example: http://www.sunhelp.org/faq/sunref1.html
72: */
73:
74: #ifdef DEBUG_IRQ
1.1.1.8 root 75: #define DPRINTF(fmt, ...) \
76: do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
1.1.1.6 root 77: #else
1.1.1.8 root 78: #define DPRINTF(fmt, ...)
1.1.1.6 root 79: #endif
1.1 root 80:
81: #define KERNEL_LOAD_ADDR 0x00004000
82: #define CMDLINE_ADDR 0x007ff000
83: #define INITRD_LOAD_ADDR 0x00800000
1.1.1.7 root 84: #define PROM_SIZE_MAX (1024 * 1024)
1.1.1.6 root 85: #define PROM_VADDR 0xffd00000
86: #define PROM_FILENAME "openbios-sparc32"
1.1.1.7 root 87: #define CFG_ADDR 0xd00000510ULL
88: #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
89:
1.1.1.2 root 90: #define MAX_CPUS 16
1.1.1.6 root 91: #define MAX_PILS 16
1.1.1.11! root 92: #define MAX_VSIMMS 4
1.1.1.6 root 93:
1.1.1.7 root 94: #define ESCC_CLOCK 4915200
95:
96: struct sun4m_hwdef {
1.1.1.11! root 97: target_phys_addr_t iommu_base, iommu_pad_base, iommu_pad_len, slavio_base;
1.1.1.6 root 98: target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
99: target_phys_addr_t serial_base, fd_base;
1.1.1.11! root 100: target_phys_addr_t afx_base, idreg_base, dma_base, esp_base, le_base;
1.1.1.7 root 101: target_phys_addr_t tcx_base, cs_base, apc_base, aux1_base, aux2_base;
1.1.1.11! root 102: target_phys_addr_t bpp_base, dbri_base, sx_base;
! 103: struct {
! 104: target_phys_addr_t reg_base, vram_base;
! 105: } vsimm[MAX_VSIMMS];
1.1.1.6 root 106: target_phys_addr_t ecc_base;
107: uint32_t ecc_version;
1.1.1.7 root 108: uint8_t nvram_machine_id;
109: uint16_t machine_id;
1.1.1.6 root 110: uint32_t iommu_version;
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;
1.1.1.7 root 125: uint8_t nvram_machine_id;
126: uint16_t machine_id;
1.1.1.6 root 127: uint32_t iounit_version;
128: uint64_t max_mem;
129: const char * const default_cpu_model;
130: };
1.1 root 131:
1.1.1.7 root 132: struct sun4c_hwdef {
133: target_phys_addr_t iommu_base, slavio_base;
134: target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base;
135: target_phys_addr_t serial_base, fd_base;
136: target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
137: target_phys_addr_t tcx_base, aux1_base;
138: uint8_t nvram_machine_id;
139: uint16_t machine_id;
140: uint32_t iommu_version;
141: uint64_t max_mem;
142: const char * const default_cpu_model;
143: };
1.1 root 144:
145: int DMA_get_channel_mode (int nchan)
146: {
147: return 0;
148: }
149: int DMA_read_memory (int nchan, void *buf, int pos, int size)
150: {
151: return 0;
152: }
153: int DMA_write_memory (int nchan, void *buf, int pos, int size)
154: {
155: return 0;
156: }
157: void DMA_hold_DREQ (int nchan) {}
158: void DMA_release_DREQ (int nchan) {}
159: void DMA_schedule(int nchan) {}
1.1.1.11! root 160:
! 161: void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit)
! 162: {
! 163: }
! 164:
1.1 root 165: void DMA_register_channel (int nchan,
166: DMA_transfer_handler transfer_handler,
167: void *opaque)
168: {
169: }
170:
1.1.1.8 root 171: static int fw_cfg_boot_set(void *opaque, const char *boot_device)
1.1.1.7 root 172: {
1.1.1.8 root 173: fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
1.1.1.7 root 174: return 0;
175: }
1.1 root 176:
1.1.1.11! root 177: static void nvram_init(M48t59State *nvram, uint8_t *macaddr,
! 178: const char *cmdline, const char *boot_devices,
! 179: ram_addr_t RAM_size, uint32_t kernel_size,
1.1.1.6 root 180: int width, int height, int depth,
1.1.1.7 root 181: int nvram_machine_id, const char *arch)
1.1 root 182: {
1.1.1.6 root 183: unsigned int i;
184: uint32_t start, end;
185: uint8_t image[0x1ff0];
186: struct OpenBIOS_nvpart_v1 *part_header;
187:
188: memset(image, '\0', sizeof(image));
1.1 root 189:
1.1.1.8 root 190: start = 0;
1.1.1.6 root 191:
192: // OpenBIOS nvram variables
193: // Variable partition
194: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
195: part_header->signature = OPENBIOS_PART_SYSTEM;
1.1.1.7 root 196: pstrcpy(part_header->name, sizeof(part_header->name), "system");
1.1.1.6 root 197:
198: end = start + sizeof(struct OpenBIOS_nvpart_v1);
199: for (i = 0; i < nb_prom_envs; i++)
200: end = OpenBIOS_set_var(image, end, prom_envs[i]);
201:
202: // End marker
203: image[end++] = '\0';
204:
205: end = start + ((end - start + 15) & ~15);
206: OpenBIOS_finish_partition(part_header, end - start);
207:
208: // free partition
209: start = end;
210: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
211: part_header->signature = OPENBIOS_PART_FREE;
1.1.1.7 root 212: pstrcpy(part_header->name, sizeof(part_header->name), "free");
1.1.1.6 root 213:
214: end = 0x1fd0;
215: OpenBIOS_finish_partition(part_header, end - start);
216:
1.1.1.7 root 217: Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr,
218: nvram_machine_id);
1.1.1.6 root 219:
220: for (i = 0; i < sizeof(image); i++)
221: m48t59_write(nvram, i, image[i]);
1.1 root 222: }
223:
1.1.1.10 root 224: static DeviceState *slavio_intctl;
1.1 root 225:
1.1.1.8 root 226: void pic_info(Monitor *mon)
1.1 root 227: {
1.1.1.6 root 228: if (slavio_intctl)
1.1.1.8 root 229: slavio_pic_info(mon, slavio_intctl);
1.1 root 230: }
231:
1.1.1.8 root 232: void irq_info(Monitor *mon)
1.1 root 233: {
1.1.1.6 root 234: if (slavio_intctl)
1.1.1.8 root 235: slavio_irq_info(mon, slavio_intctl);
1.1 root 236: }
237:
1.1.1.6 root 238: void cpu_check_irqs(CPUState *env)
1.1 root 239: {
1.1.1.6 root 240: if (env->pil_in && (env->interrupt_index == 0 ||
241: (env->interrupt_index & ~15) == TT_EXTINT)) {
242: unsigned int i;
243:
244: for (i = 15; i > 0; i--) {
245: if (env->pil_in & (1 << i)) {
246: int old_interrupt = env->interrupt_index;
247:
248: env->interrupt_index = TT_EXTINT | i;
1.1.1.7 root 249: if (old_interrupt != env->interrupt_index) {
250: DPRINTF("Set CPU IRQ %d\n", i);
1.1.1.6 root 251: cpu_interrupt(env, CPU_INTERRUPT_HARD);
1.1.1.7 root 252: }
1.1.1.6 root 253: break;
254: }
255: }
256: } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
1.1.1.7 root 257: DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
1.1.1.6 root 258: env->interrupt_index = 0;
259: cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
260: }
1.1 root 261: }
262:
1.1.1.6 root 263: static void cpu_set_irq(void *opaque, int irq, int level)
1.1.1.4 root 264: {
1.1.1.6 root 265: CPUState *env = opaque;
266:
267: if (level) {
268: DPRINTF("Raise CPU IRQ %d\n", irq);
269: env->halted = 0;
270: env->pil_in |= 1 << irq;
271: cpu_check_irqs(env);
272: } else {
273: DPRINTF("Lower CPU IRQ %d\n", irq);
274: env->pil_in &= ~(1 << irq);
275: cpu_check_irqs(env);
276: }
1.1.1.4 root 277: }
278:
1.1.1.6 root 279: static void dummy_cpu_set_irq(void *opaque, int irq, int level)
1.1.1.2 root 280: {
281: }
282:
283: static void main_cpu_reset(void *opaque)
284: {
285: CPUState *env = opaque;
1.1.1.6 root 286:
1.1.1.2 root 287: cpu_reset(env);
1.1.1.6 root 288: env->halted = 0;
1.1.1.2 root 289: }
290:
1.1.1.6 root 291: static void secondary_cpu_reset(void *opaque)
1.1 root 292: {
1.1.1.6 root 293: CPUState *env = opaque;
294:
295: cpu_reset(env);
296: env->halted = 1;
297: }
298:
1.1.1.7 root 299: static void cpu_halt_signal(void *opaque, int irq, int level)
300: {
301: if (level && cpu_single_env)
302: cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
303: }
304:
1.1.1.11! root 305: static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
! 306: {
! 307: return addr - 0xf0000000ULL;
! 308: }
! 309:
1.1.1.6 root 310: static unsigned long sun4m_load_kernel(const char *kernel_filename,
1.1.1.7 root 311: const char *initrd_filename,
312: ram_addr_t RAM_size)
1.1.1.6 root 313: {
314: int linux_boot;
1.1 root 315: unsigned int i;
1.1.1.6 root 316: long initrd_size, kernel_size;
1.1.1.10 root 317: uint8_t *ptr;
1.1 root 318:
319: linux_boot = (kernel_filename != NULL);
320:
1.1.1.6 root 321: kernel_size = 0;
322: if (linux_boot) {
1.1.1.10 root 323: int bswap_needed;
324:
325: #ifdef BSWAP_NEEDED
326: bswap_needed = 1;
327: #else
328: bswap_needed = 0;
329: #endif
1.1.1.11! root 330: kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
! 331: NULL, NULL, NULL, 1, ELF_MACHINE, 0);
1.1.1.6 root 332: if (kernel_size < 0)
1.1.1.7 root 333: kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
1.1.1.10 root 334: RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
335: TARGET_PAGE_SIZE);
1.1.1.6 root 336: if (kernel_size < 0)
1.1.1.7 root 337: kernel_size = load_image_targphys(kernel_filename,
338: KERNEL_LOAD_ADDR,
339: RAM_size - KERNEL_LOAD_ADDR);
1.1.1.6 root 340: if (kernel_size < 0) {
341: fprintf(stderr, "qemu: could not load kernel '%s'\n",
342: kernel_filename);
343: exit(1);
344: }
345:
346: /* load initrd */
347: initrd_size = 0;
348: if (initrd_filename) {
1.1.1.7 root 349: initrd_size = load_image_targphys(initrd_filename,
350: INITRD_LOAD_ADDR,
351: RAM_size - INITRD_LOAD_ADDR);
1.1.1.6 root 352: if (initrd_size < 0) {
353: fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
354: initrd_filename);
355: exit(1);
356: }
357: }
358: if (initrd_size > 0) {
359: for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
1.1.1.10 root 360: ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
361: if (ldl_p(ptr) == 0x48647253) { // HdrS
362: stl_p(ptr + 16, INITRD_LOAD_ADDR);
363: stl_p(ptr + 20, initrd_size);
1.1.1.6 root 364: break;
365: }
366: }
367: }
368: }
369: return kernel_size;
370: }
371:
1.1.1.10 root 372: static void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq)
373: {
374: DeviceState *dev;
375: SysBusDevice *s;
376:
377: dev = qdev_create(NULL, "iommu");
378: qdev_prop_set_uint32(dev, "version", version);
379: qdev_init_nofail(dev);
380: s = sysbus_from_qdev(dev);
381: sysbus_connect_irq(s, 0, irq);
382: sysbus_mmio_map(s, 0, addr);
383:
384: return s;
385: }
386:
387: static void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq,
388: void *iommu, qemu_irq *dev_irq)
389: {
390: DeviceState *dev;
391: SysBusDevice *s;
392:
393: dev = qdev_create(NULL, "sparc32_dma");
394: qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
395: qdev_init_nofail(dev);
396: s = sysbus_from_qdev(dev);
397: sysbus_connect_irq(s, 0, parent_irq);
398: *dev_irq = qdev_get_gpio_in(dev, 0);
399: sysbus_mmio_map(s, 0, daddr);
400:
401: return s;
402: }
403:
1.1.1.8 root 404: static void lance_init(NICInfo *nd, target_phys_addr_t leaddr,
1.1.1.10 root 405: void *dma_opaque, qemu_irq irq)
1.1.1.8 root 406: {
407: DeviceState *dev;
408: SysBusDevice *s;
1.1.1.10 root 409: qemu_irq reset;
1.1.1.8 root 410:
411: qemu_check_nic_model(&nd_table[0], "lance");
412:
413: dev = qdev_create(NULL, "lance");
1.1.1.10 root 414: qdev_set_nic_properties(dev, nd);
1.1.1.9 root 415: qdev_prop_set_ptr(dev, "dma", dma_opaque);
1.1.1.10 root 416: qdev_init_nofail(dev);
1.1.1.8 root 417: s = sysbus_from_qdev(dev);
418: sysbus_mmio_map(s, 0, leaddr);
419: sysbus_connect_irq(s, 0, irq);
1.1.1.10 root 420: reset = qdev_get_gpio_in(dev, 0);
421: qdev_connect_gpio_out(dma_opaque, 0, reset);
422: }
423:
424: static DeviceState *slavio_intctl_init(target_phys_addr_t addr,
425: target_phys_addr_t addrg,
426: qemu_irq **parent_irq)
427: {
428: DeviceState *dev;
429: SysBusDevice *s;
430: unsigned int i, j;
431:
432: dev = qdev_create(NULL, "slavio_intctl");
433: qdev_init_nofail(dev);
434:
435: s = sysbus_from_qdev(dev);
436:
437: for (i = 0; i < MAX_CPUS; i++) {
438: for (j = 0; j < MAX_PILS; j++) {
439: sysbus_connect_irq(s, i * MAX_PILS + j, parent_irq[i][j]);
440: }
441: }
442: sysbus_mmio_map(s, 0, addrg);
443: for (i = 0; i < MAX_CPUS; i++) {
444: sysbus_mmio_map(s, i + 1, addr + i * TARGET_PAGE_SIZE);
445: }
446:
447: return dev;
448: }
449:
450: #define SYS_TIMER_OFFSET 0x10000ULL
451: #define CPU_TIMER_OFFSET(cpu) (0x1000ULL * cpu)
452:
453: static void slavio_timer_init_all(target_phys_addr_t addr, qemu_irq master_irq,
454: qemu_irq *cpu_irqs, unsigned int num_cpus)
455: {
456: DeviceState *dev;
457: SysBusDevice *s;
458: unsigned int i;
459:
460: dev = qdev_create(NULL, "slavio_timer");
461: qdev_prop_set_uint32(dev, "num_cpus", num_cpus);
462: qdev_init_nofail(dev);
463: s = sysbus_from_qdev(dev);
464: sysbus_connect_irq(s, 0, master_irq);
465: sysbus_mmio_map(s, 0, addr + SYS_TIMER_OFFSET);
466:
467: for (i = 0; i < MAX_CPUS; i++) {
468: sysbus_mmio_map(s, i + 1, addr + (target_phys_addr_t)CPU_TIMER_OFFSET(i));
469: sysbus_connect_irq(s, i + 1, cpu_irqs[i]);
470: }
471: }
472:
473: #define MISC_LEDS 0x01600000
474: #define MISC_CFG 0x01800000
475: #define MISC_DIAG 0x01a00000
476: #define MISC_MDM 0x01b00000
477: #define MISC_SYS 0x01f00000
478:
479: static void slavio_misc_init(target_phys_addr_t base,
480: target_phys_addr_t aux1_base,
481: target_phys_addr_t aux2_base, qemu_irq irq,
482: qemu_irq fdc_tc)
483: {
484: DeviceState *dev;
485: SysBusDevice *s;
486:
487: dev = qdev_create(NULL, "slavio_misc");
488: qdev_init_nofail(dev);
489: s = sysbus_from_qdev(dev);
490: if (base) {
491: /* 8 bit registers */
492: /* Slavio control */
493: sysbus_mmio_map(s, 0, base + MISC_CFG);
494: /* Diagnostics */
495: sysbus_mmio_map(s, 1, base + MISC_DIAG);
496: /* Modem control */
497: sysbus_mmio_map(s, 2, base + MISC_MDM);
498: /* 16 bit registers */
499: /* ss600mp diag LEDs */
500: sysbus_mmio_map(s, 3, base + MISC_LEDS);
501: /* 32 bit registers */
502: /* System control */
503: sysbus_mmio_map(s, 4, base + MISC_SYS);
504: }
505: if (aux1_base) {
506: /* AUX 1 (Misc System Functions) */
507: sysbus_mmio_map(s, 5, aux1_base);
508: }
509: if (aux2_base) {
510: /* AUX 2 (Software Powerdown Control) */
511: sysbus_mmio_map(s, 6, aux2_base);
512: }
513: sysbus_connect_irq(s, 0, irq);
514: sysbus_connect_irq(s, 1, fdc_tc);
515: qemu_system_powerdown = qdev_get_gpio_in(dev, 0);
516: }
517:
518: static void ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version)
519: {
520: DeviceState *dev;
521: SysBusDevice *s;
522:
523: dev = qdev_create(NULL, "eccmemctl");
524: qdev_prop_set_uint32(dev, "version", version);
525: qdev_init_nofail(dev);
526: s = sysbus_from_qdev(dev);
527: sysbus_connect_irq(s, 0, irq);
528: sysbus_mmio_map(s, 0, base);
529: if (version == 0) { // SS-600MP only
530: sysbus_mmio_map(s, 1, base + 0x1000);
531: }
532: }
533:
534: static void apc_init(target_phys_addr_t power_base, qemu_irq cpu_halt)
535: {
536: DeviceState *dev;
537: SysBusDevice *s;
538:
539: dev = qdev_create(NULL, "apc");
540: qdev_init_nofail(dev);
541: s = sysbus_from_qdev(dev);
542: /* Power management (APC) XXX: not a Slavio device */
543: sysbus_mmio_map(s, 0, power_base);
544: sysbus_connect_irq(s, 0, cpu_halt);
545: }
546:
547: static void tcx_init(target_phys_addr_t addr, int vram_size, int width,
548: int height, int depth)
549: {
550: DeviceState *dev;
551: SysBusDevice *s;
552:
553: dev = qdev_create(NULL, "SUNW,tcx");
554: qdev_prop_set_taddr(dev, "addr", addr);
555: qdev_prop_set_uint32(dev, "vram_size", vram_size);
556: qdev_prop_set_uint16(dev, "width", width);
557: qdev_prop_set_uint16(dev, "height", height);
558: qdev_prop_set_uint16(dev, "depth", depth);
559: qdev_init_nofail(dev);
560: s = sysbus_from_qdev(dev);
561: /* 8-bit plane */
562: sysbus_mmio_map(s, 0, addr + 0x00800000ULL);
563: /* DAC */
564: sysbus_mmio_map(s, 1, addr + 0x00200000ULL);
565: /* TEC (dummy) */
566: sysbus_mmio_map(s, 2, addr + 0x00700000ULL);
567: /* THC 24 bit: NetBSD writes here even with 8-bit display: dummy */
568: sysbus_mmio_map(s, 3, addr + 0x00301000ULL);
569: if (depth == 24) {
570: /* 24-bit plane */
571: sysbus_mmio_map(s, 4, addr + 0x02000000ULL);
572: /* Control plane */
573: sysbus_mmio_map(s, 5, addr + 0x0a000000ULL);
574: } else {
575: /* THC 8 bit (dummy) */
576: sysbus_mmio_map(s, 4, addr + 0x00300000ULL);
577: }
1.1.1.8 root 578: }
579:
580: /* NCR89C100/MACIO Internal ID register */
581: static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 };
582:
583: static void idreg_init(target_phys_addr_t addr)
584: {
585: DeviceState *dev;
586: SysBusDevice *s;
587:
588: dev = qdev_create(NULL, "macio_idreg");
1.1.1.10 root 589: qdev_init_nofail(dev);
1.1.1.8 root 590: s = sysbus_from_qdev(dev);
591:
592: sysbus_mmio_map(s, 0, addr);
593: cpu_physical_memory_write_rom(addr, idreg_data, sizeof(idreg_data));
594: }
595:
1.1.1.10 root 596: static int idreg_init1(SysBusDevice *dev)
1.1.1.8 root 597: {
598: ram_addr_t idreg_offset;
599:
1.1.1.11! root 600: idreg_offset = qemu_ram_alloc(NULL, "sun4m.idreg", sizeof(idreg_data));
1.1.1.8 root 601: sysbus_init_mmio(dev, sizeof(idreg_data), idreg_offset | IO_MEM_ROM);
1.1.1.10 root 602: return 0;
1.1.1.8 root 603: }
604:
605: static SysBusDeviceInfo idreg_info = {
606: .init = idreg_init1,
607: .qdev.name = "macio_idreg",
608: .qdev.size = sizeof(SysBusDevice),
609: };
610:
611: static void idreg_register_devices(void)
612: {
613: sysbus_register_withprop(&idreg_info);
614: }
615:
616: device_init(idreg_register_devices);
617:
1.1.1.11! root 618: /* SS-5 TCX AFX register */
! 619: static void afx_init(target_phys_addr_t addr)
! 620: {
! 621: DeviceState *dev;
! 622: SysBusDevice *s;
! 623:
! 624: dev = qdev_create(NULL, "tcx_afx");
! 625: qdev_init_nofail(dev);
! 626: s = sysbus_from_qdev(dev);
! 627:
! 628: sysbus_mmio_map(s, 0, addr);
! 629: }
! 630:
! 631: static int afx_init1(SysBusDevice *dev)
! 632: {
! 633: ram_addr_t afx_offset;
! 634:
! 635: afx_offset = qemu_ram_alloc(NULL, "sun4m.afx", 4);
! 636: sysbus_init_mmio(dev, 4, afx_offset | IO_MEM_RAM);
! 637: return 0;
! 638: }
! 639:
! 640: static SysBusDeviceInfo afx_info = {
! 641: .init = afx_init1,
! 642: .qdev.name = "tcx_afx",
! 643: .qdev.size = sizeof(SysBusDevice),
! 644: };
! 645:
! 646: static void afx_register_devices(void)
! 647: {
! 648: sysbus_register_withprop(&afx_info);
! 649: }
! 650:
! 651: device_init(afx_register_devices);
! 652:
1.1.1.8 root 653: /* Boot PROM (OpenBIOS) */
1.1.1.11! root 654: static uint64_t translate_prom_address(void *opaque, uint64_t addr)
! 655: {
! 656: target_phys_addr_t *base_addr = (target_phys_addr_t *)opaque;
! 657: return addr + *base_addr - PROM_VADDR;
! 658: }
! 659:
1.1.1.8 root 660: static void prom_init(target_phys_addr_t addr, const char *bios_name)
661: {
662: DeviceState *dev;
663: SysBusDevice *s;
664: char *filename;
665: int ret;
666:
667: dev = qdev_create(NULL, "openprom");
1.1.1.10 root 668: qdev_init_nofail(dev);
1.1.1.8 root 669: s = sysbus_from_qdev(dev);
670:
671: sysbus_mmio_map(s, 0, addr);
672:
673: /* load boot prom */
674: if (bios_name == NULL) {
675: bios_name = PROM_FILENAME;
676: }
677: filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
678: if (filename) {
1.1.1.11! root 679: ret = load_elf(filename, translate_prom_address, &addr, NULL,
! 680: NULL, NULL, 1, ELF_MACHINE, 0);
1.1.1.8 root 681: if (ret < 0 || ret > PROM_SIZE_MAX) {
682: ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
683: }
684: qemu_free(filename);
685: } else {
686: ret = -1;
687: }
688: if (ret < 0 || ret > PROM_SIZE_MAX) {
689: fprintf(stderr, "qemu: could not load prom '%s'\n", bios_name);
690: exit(1);
691: }
692: }
693:
1.1.1.10 root 694: static int prom_init1(SysBusDevice *dev)
1.1.1.8 root 695: {
696: ram_addr_t prom_offset;
697:
1.1.1.11! root 698: prom_offset = qemu_ram_alloc(NULL, "sun4m.prom", PROM_SIZE_MAX);
1.1.1.8 root 699: sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM);
1.1.1.10 root 700: return 0;
1.1.1.8 root 701: }
702:
703: static SysBusDeviceInfo prom_info = {
704: .init = prom_init1,
705: .qdev.name = "openprom",
706: .qdev.size = sizeof(SysBusDevice),
707: .qdev.props = (Property[]) {
708: {/* end of property list */}
709: }
710: };
711:
712: static void prom_register_devices(void)
713: {
714: sysbus_register_withprop(&prom_info);
715: }
716:
717: device_init(prom_register_devices);
718:
719: typedef struct RamDevice
720: {
721: SysBusDevice busdev;
1.1.1.10 root 722: uint64_t size;
1.1.1.8 root 723: } RamDevice;
724:
725: /* System RAM */
1.1.1.10 root 726: static int ram_init1(SysBusDevice *dev)
1.1.1.8 root 727: {
728: ram_addr_t RAM_size, ram_offset;
729: RamDevice *d = FROM_SYSBUS(RamDevice, dev);
730:
731: RAM_size = d->size;
732:
1.1.1.11! root 733: ram_offset = qemu_ram_alloc(NULL, "sun4m.ram", RAM_size);
1.1.1.8 root 734: sysbus_init_mmio(dev, RAM_size, ram_offset);
1.1.1.10 root 735: return 0;
1.1.1.8 root 736: }
737:
738: static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size,
739: uint64_t max_mem)
740: {
741: DeviceState *dev;
742: SysBusDevice *s;
743: RamDevice *d;
744:
745: /* allocate RAM */
746: if ((uint64_t)RAM_size > max_mem) {
747: fprintf(stderr,
748: "qemu: Too much memory for this machine: %d, maximum %d\n",
749: (unsigned int)(RAM_size / (1024 * 1024)),
750: (unsigned int)(max_mem / (1024 * 1024)));
751: exit(1);
752: }
753: dev = qdev_create(NULL, "memory");
754: s = sysbus_from_qdev(dev);
755:
756: d = FROM_SYSBUS(RamDevice, s);
757: d->size = RAM_size;
1.1.1.10 root 758: qdev_init_nofail(dev);
1.1.1.8 root 759:
760: sysbus_mmio_map(s, 0, addr);
761: }
762:
763: static SysBusDeviceInfo ram_info = {
764: .init = ram_init1,
765: .qdev.name = "memory",
766: .qdev.size = sizeof(RamDevice),
767: .qdev.props = (Property[]) {
1.1.1.10 root 768: DEFINE_PROP_UINT64("size", RamDevice, size, 0),
769: DEFINE_PROP_END_OF_LIST(),
1.1.1.8 root 770: }
771: };
772:
773: static void ram_register_devices(void)
774: {
775: sysbus_register_withprop(&ram_info);
776: }
777:
778: device_init(ram_register_devices);
779:
1.1.1.11! root 780: static void cpu_devinit(const char *cpu_model, unsigned int id,
! 781: uint64_t prom_addr, qemu_irq **cpu_irqs)
1.1.1.8 root 782: {
783: CPUState *env;
784:
785: env = cpu_init(cpu_model);
786: if (!env) {
787: fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
788: exit(1);
789: }
790:
791: cpu_sparc_set_id(env, id);
792: if (id == 0) {
793: qemu_register_reset(main_cpu_reset, env);
794: } else {
795: qemu_register_reset(secondary_cpu_reset, env);
796: env->halted = 1;
797: }
798: *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
799: env->prom_addr = prom_addr;
800: }
801:
1.1.1.7 root 802: static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
1.1.1.6 root 803: const char *boot_device,
1.1.1.7 root 804: const char *kernel_filename,
1.1.1.6 root 805: const char *kernel_cmdline,
806: const char *initrd_filename, const char *cpu_model)
807: {
808: unsigned int i;
1.1.1.8 root 809: void *iommu, *espdma, *ledma, *nvram;
810: qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
811: espdma_irq, ledma_irq;
1.1.1.10 root 812: qemu_irq esp_reset;
1.1.1.8 root 813: qemu_irq fdc_tc;
1.1.1.7 root 814: qemu_irq *cpu_halt;
815: unsigned long kernel_size;
1.1.1.10 root 816: DriveInfo *fd[MAX_FD];
1.1.1.7 root 817: void *fw_cfg;
1.1.1.11! root 818: unsigned int num_vsimms;
1.1.1.6 root 819:
1.1.1.2 root 820: /* init CPUs */
1.1.1.6 root 821: if (!cpu_model)
822: cpu_model = hwdef->default_cpu_model;
823:
1.1.1.2 root 824: for(i = 0; i < smp_cpus; i++) {
1.1.1.11! root 825: cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
1.1.1.2 root 826: }
1.1.1.6 root 827:
828: for (i = smp_cpus; i < MAX_CPUS; i++)
829: cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
830:
831:
1.1.1.8 root 832: /* set up devices */
833: ram_init(0, RAM_size, hwdef->max_mem);
1.1.1.11! root 834: /* models without ECC don't trap when missing ram is accessed */
! 835: if (!hwdef->ecc_base) {
! 836: empty_slot_init(RAM_size, hwdef->max_mem - RAM_size);
! 837: }
1.1 root 838:
1.1.1.8 root 839: prom_init(hwdef->slavio_base, bios_name);
1.1.1.6 root 840:
1.1.1.10 root 841: slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
842: hwdef->intctl_base + 0x10000ULL,
843: cpu_irqs);
1.1.1.2 root 844:
1.1.1.8 root 845: for (i = 0; i < 32; i++) {
1.1.1.10 root 846: slavio_irq[i] = qdev_get_gpio_in(slavio_intctl, i);
1.1.1.8 root 847: }
848: for (i = 0; i < MAX_CPUS; i++) {
1.1.1.10 root 849: slavio_cpu_irq[i] = qdev_get_gpio_in(slavio_intctl, 32 + i);
1.1.1.8 root 850: }
1.1.1.6 root 851:
1.1.1.7 root 852: if (hwdef->idreg_base) {
1.1.1.8 root 853: idreg_init(hwdef->idreg_base);
1.1.1.3 root 854: }
1.1.1.6 root 855:
1.1.1.11! root 856: if (hwdef->afx_base) {
! 857: afx_init(hwdef->afx_base);
! 858: }
! 859:
1.1.1.6 root 860: iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
1.1.1.10 root 861: slavio_irq[30]);
1.1.1.6 root 862:
1.1.1.11! root 863: if (hwdef->iommu_pad_base) {
! 864: /* On the real hardware (SS-5, LX) the MMU is not padded, but aliased.
! 865: Software shouldn't use aliased addresses, neither should it crash
! 866: when does. Using empty_slot instead of aliasing can help with
! 867: debugging such accesses */
! 868: empty_slot_init(hwdef->iommu_pad_base,hwdef->iommu_pad_len);
! 869: }
! 870:
1.1.1.10 root 871: espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18],
872: iommu, &espdma_irq);
1.1.1.6 root 873:
874: ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
1.1.1.10 root 875: slavio_irq[16], iommu, &ledma_irq);
1.1.1.6 root 876:
877: if (graphic_depth != 8 && graphic_depth != 24) {
878: fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
879: exit (1);
880: }
1.1.1.11! root 881: num_vsimms = 0;
! 882: if (num_vsimms == 0) {
! 883: tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
! 884: graphic_depth);
! 885: }
! 886:
! 887: for (i = num_vsimms; i < MAX_VSIMMS; i++) {
! 888: /* vsimm registers probed by OBP */
! 889: if (hwdef->vsimm[i].reg_base) {
! 890: empty_slot_init(hwdef->vsimm[i].reg_base, 0x2000);
! 891: }
! 892: }
! 893:
! 894: if (hwdef->sx_base) {
! 895: empty_slot_init(hwdef->sx_base, 0x2000);
! 896: }
1.1.1.6 root 897:
1.1.1.10 root 898: lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
1.1.1.6 root 899:
1.1.1.10 root 900: nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 8);
1.1.1.6 root 901:
1.1.1.10 root 902: slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, smp_cpus);
1.1.1.6 root 903:
1.1.1.10 root 904: slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],
1.1.1.8 root 905: display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
1.1 root 906: // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
907: // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
1.1.1.10 root 908: escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],
1.1.1.7 root 909: serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
1.1.1.6 root 910:
1.1.1.7 root 911: cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1);
1.1.1.10 root 912: slavio_misc_init(hwdef->slavio_base, hwdef->aux1_base, hwdef->aux2_base,
913: slavio_irq[30], fdc_tc);
914:
1.1.1.8 root 915: if (hwdef->apc_base) {
916: apc_init(hwdef->apc_base, cpu_halt[0]);
917: }
1.1.1.7 root 918:
919: if (hwdef->fd_base) {
1.1.1.6 root 920: /* there is zero or one floppy drive */
1.1.1.7 root 921: memset(fd, 0, sizeof(fd));
1.1.1.10 root 922: fd[0] = drive_get(IF_FLOPPY, 0, 0);
923: sun4m_fdctrl_init(slavio_irq[22], hwdef->fd_base, fd,
1.1.1.8 root 924: &fdc_tc);
1.1.1.6 root 925: }
926:
927: if (drive_get_max_bus(IF_SCSI) > 0) {
928: fprintf(stderr, "qemu: too many SCSI bus\n");
929: exit(1);
930: }
931:
1.1.1.10 root 932: esp_reset = qdev_get_gpio_in(espdma, 0);
1.1.1.8 root 933: esp_init(hwdef->esp_base, 2,
934: espdma_memory_read, espdma_memory_write,
1.1.1.10 root 935: espdma, espdma_irq, &esp_reset);
936:
1.1.1.8 root 937:
938: if (hwdef->cs_base) {
939: sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,
1.1.1.10 root 940: slavio_irq[5]);
1.1.1.6 root 941: }
942:
1.1.1.11! root 943: if (hwdef->dbri_base) {
! 944: /* ISDN chip with attached CS4215 audio codec */
! 945: /* prom space */
! 946: empty_slot_init(hwdef->dbri_base+0x1000, 0x30);
! 947: /* reg space */
! 948: empty_slot_init(hwdef->dbri_base+0x10000, 0x100);
! 949: }
! 950:
! 951: if (hwdef->bpp_base) {
! 952: /* parallel port */
! 953: empty_slot_init(hwdef->bpp_base, 0x20);
! 954: }
! 955:
1.1.1.7 root 956: kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
957: RAM_size);
1.1.1.6 root 958:
959: nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
960: boot_device, RAM_size, kernel_size, graphic_width,
1.1.1.7 root 961: graphic_height, graphic_depth, hwdef->nvram_machine_id,
962: "Sun4m");
1.1.1.6 root 963:
1.1.1.7 root 964: if (hwdef->ecc_base)
1.1.1.10 root 965: ecc_init(hwdef->ecc_base, slavio_irq[28],
1.1.1.7 root 966: hwdef->ecc_version);
967:
968: fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
969: fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
970: fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
971: fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
972: fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
1.1.1.8 root 973: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
974: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
975: if (kernel_cmdline) {
976: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
1.1.1.10 root 977: pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
1.1.1.11! root 978: fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
! 979: (uint8_t*)strdup(kernel_cmdline),
! 980: strlen(kernel_cmdline) + 1);
1.1.1.8 root 981: } else {
982: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
983: }
984: fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
985: fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
986: fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
987: qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
1.1.1.7 root 988: }
989:
990: enum {
991: ss2_id = 0,
992: ss5_id = 32,
993: vger_id,
994: lx_id,
995: ss4_id,
996: scls_id,
997: sbook_id,
998: ss10_id = 64,
999: ss20_id,
1000: ss600mp_id,
1001: ss1000_id = 96,
1002: ss2000_id,
1003: };
1.1.1.6 root 1004:
1.1.1.7 root 1005: static const struct sun4m_hwdef sun4m_hwdefs[] = {
1.1.1.6 root 1006: /* SS-5 */
1007: {
1008: .iommu_base = 0x10000000,
1.1.1.11! root 1009: .iommu_pad_base = 0x10004000,
! 1010: .iommu_pad_len = 0x0fffb000,
1.1.1.6 root 1011: .tcx_base = 0x50000000,
1012: .cs_base = 0x6c000000,
1013: .slavio_base = 0x70000000,
1014: .ms_kb_base = 0x71000000,
1015: .serial_base = 0x71100000,
1016: .nvram_base = 0x71200000,
1017: .fd_base = 0x71400000,
1018: .counter_base = 0x71d00000,
1019: .intctl_base = 0x71e00000,
1020: .idreg_base = 0x78000000,
1021: .dma_base = 0x78400000,
1022: .esp_base = 0x78800000,
1023: .le_base = 0x78c00000,
1.1.1.7 root 1024: .apc_base = 0x6a000000,
1.1.1.11! root 1025: .afx_base = 0x6e000000,
1.1.1.7 root 1026: .aux1_base = 0x71900000,
1027: .aux2_base = 0x71910000,
1028: .nvram_machine_id = 0x80,
1029: .machine_id = ss5_id,
1.1.1.6 root 1030: .iommu_version = 0x05000000,
1031: .max_mem = 0x10000000,
1032: .default_cpu_model = "Fujitsu MB86904",
1033: },
1034: /* SS-10 */
1035: {
1036: .iommu_base = 0xfe0000000ULL,
1037: .tcx_base = 0xe20000000ULL,
1038: .slavio_base = 0xff0000000ULL,
1039: .ms_kb_base = 0xff1000000ULL,
1040: .serial_base = 0xff1100000ULL,
1041: .nvram_base = 0xff1200000ULL,
1042: .fd_base = 0xff1700000ULL,
1043: .counter_base = 0xff1300000ULL,
1044: .intctl_base = 0xff1400000ULL,
1045: .idreg_base = 0xef0000000ULL,
1046: .dma_base = 0xef0400000ULL,
1047: .esp_base = 0xef0800000ULL,
1048: .le_base = 0xef0c00000ULL,
1.1.1.7 root 1049: .apc_base = 0xefa000000ULL, // XXX should not exist
1050: .aux1_base = 0xff1800000ULL,
1051: .aux2_base = 0xff1a01000ULL,
1.1.1.6 root 1052: .ecc_base = 0xf00000000ULL,
1053: .ecc_version = 0x10000000, // version 0, implementation 1
1.1.1.7 root 1054: .nvram_machine_id = 0x72,
1055: .machine_id = ss10_id,
1.1.1.6 root 1056: .iommu_version = 0x03000000,
1.1.1.7 root 1057: .max_mem = 0xf00000000ULL,
1.1.1.6 root 1058: .default_cpu_model = "TI SuperSparc II",
1059: },
1060: /* SS-600MP */
1061: {
1062: .iommu_base = 0xfe0000000ULL,
1063: .tcx_base = 0xe20000000ULL,
1064: .slavio_base = 0xff0000000ULL,
1065: .ms_kb_base = 0xff1000000ULL,
1066: .serial_base = 0xff1100000ULL,
1067: .nvram_base = 0xff1200000ULL,
1068: .counter_base = 0xff1300000ULL,
1069: .intctl_base = 0xff1400000ULL,
1070: .dma_base = 0xef0081000ULL,
1071: .esp_base = 0xef0080000ULL,
1072: .le_base = 0xef0060000ULL,
1.1.1.7 root 1073: .apc_base = 0xefa000000ULL, // XXX should not exist
1074: .aux1_base = 0xff1800000ULL,
1075: .aux2_base = 0xff1a01000ULL, // XXX should not exist
1.1.1.6 root 1076: .ecc_base = 0xf00000000ULL,
1077: .ecc_version = 0x00000000, // version 0, implementation 0
1.1.1.7 root 1078: .nvram_machine_id = 0x71,
1079: .machine_id = ss600mp_id,
1.1.1.6 root 1080: .iommu_version = 0x01000000,
1.1.1.7 root 1081: .max_mem = 0xf00000000ULL,
1.1.1.6 root 1082: .default_cpu_model = "TI SuperSparc II",
1083: },
1084: /* SS-20 */
1085: {
1086: .iommu_base = 0xfe0000000ULL,
1087: .tcx_base = 0xe20000000ULL,
1088: .slavio_base = 0xff0000000ULL,
1089: .ms_kb_base = 0xff1000000ULL,
1090: .serial_base = 0xff1100000ULL,
1091: .nvram_base = 0xff1200000ULL,
1092: .fd_base = 0xff1700000ULL,
1093: .counter_base = 0xff1300000ULL,
1094: .intctl_base = 0xff1400000ULL,
1095: .idreg_base = 0xef0000000ULL,
1096: .dma_base = 0xef0400000ULL,
1097: .esp_base = 0xef0800000ULL,
1098: .le_base = 0xef0c00000ULL,
1.1.1.11! root 1099: .bpp_base = 0xef4800000ULL,
1.1.1.7 root 1100: .apc_base = 0xefa000000ULL, // XXX should not exist
1101: .aux1_base = 0xff1800000ULL,
1102: .aux2_base = 0xff1a01000ULL,
1.1.1.11! root 1103: .dbri_base = 0xee0000000ULL,
! 1104: .sx_base = 0xf80000000ULL,
! 1105: .vsimm = {
! 1106: {
! 1107: .reg_base = 0x9c000000ULL,
! 1108: .vram_base = 0xfc000000ULL
! 1109: }, {
! 1110: .reg_base = 0x90000000ULL,
! 1111: .vram_base = 0xf0000000ULL
! 1112: }, {
! 1113: .reg_base = 0x94000000ULL
! 1114: }, {
! 1115: .reg_base = 0x98000000ULL
! 1116: }
! 1117: },
1.1.1.6 root 1118: .ecc_base = 0xf00000000ULL,
1119: .ecc_version = 0x20000000, // version 0, implementation 2
1.1.1.7 root 1120: .nvram_machine_id = 0x72,
1121: .machine_id = ss20_id,
1.1.1.6 root 1122: .iommu_version = 0x13000000,
1.1.1.7 root 1123: .max_mem = 0xf00000000ULL,
1.1.1.6 root 1124: .default_cpu_model = "TI SuperSparc II",
1125: },
1.1.1.7 root 1126: /* Voyager */
1.1.1.6 root 1127: {
1.1.1.7 root 1128: .iommu_base = 0x10000000,
1129: .tcx_base = 0x50000000,
1130: .slavio_base = 0x70000000,
1131: .ms_kb_base = 0x71000000,
1132: .serial_base = 0x71100000,
1133: .nvram_base = 0x71200000,
1134: .fd_base = 0x71400000,
1135: .counter_base = 0x71d00000,
1136: .intctl_base = 0x71e00000,
1137: .idreg_base = 0x78000000,
1138: .dma_base = 0x78400000,
1139: .esp_base = 0x78800000,
1140: .le_base = 0x78c00000,
1141: .apc_base = 0x71300000, // pmc
1142: .aux1_base = 0x71900000,
1143: .aux2_base = 0x71910000,
1144: .nvram_machine_id = 0x80,
1145: .machine_id = vger_id,
1146: .iommu_version = 0x05000000,
1.1.1.6 root 1147: .max_mem = 0x10000000,
1.1.1.7 root 1148: .default_cpu_model = "Fujitsu MB86904",
1149: },
1150: /* LX */
1151: {
1152: .iommu_base = 0x10000000,
1.1.1.11! root 1153: .iommu_pad_base = 0x10004000,
! 1154: .iommu_pad_len = 0x0fffb000,
1.1.1.7 root 1155: .tcx_base = 0x50000000,
1156: .slavio_base = 0x70000000,
1157: .ms_kb_base = 0x71000000,
1158: .serial_base = 0x71100000,
1159: .nvram_base = 0x71200000,
1160: .fd_base = 0x71400000,
1161: .counter_base = 0x71d00000,
1162: .intctl_base = 0x71e00000,
1163: .idreg_base = 0x78000000,
1164: .dma_base = 0x78400000,
1165: .esp_base = 0x78800000,
1166: .le_base = 0x78c00000,
1167: .aux1_base = 0x71900000,
1168: .aux2_base = 0x71910000,
1169: .nvram_machine_id = 0x80,
1170: .machine_id = lx_id,
1171: .iommu_version = 0x04000000,
1172: .max_mem = 0x10000000,
1173: .default_cpu_model = "TI MicroSparc I",
1174: },
1175: /* SS-4 */
1176: {
1177: .iommu_base = 0x10000000,
1178: .tcx_base = 0x50000000,
1179: .cs_base = 0x6c000000,
1180: .slavio_base = 0x70000000,
1181: .ms_kb_base = 0x71000000,
1182: .serial_base = 0x71100000,
1183: .nvram_base = 0x71200000,
1184: .fd_base = 0x71400000,
1185: .counter_base = 0x71d00000,
1186: .intctl_base = 0x71e00000,
1187: .idreg_base = 0x78000000,
1188: .dma_base = 0x78400000,
1189: .esp_base = 0x78800000,
1190: .le_base = 0x78c00000,
1191: .apc_base = 0x6a000000,
1192: .aux1_base = 0x71900000,
1193: .aux2_base = 0x71910000,
1194: .nvram_machine_id = 0x80,
1195: .machine_id = ss4_id,
1196: .iommu_version = 0x05000000,
1197: .max_mem = 0x10000000,
1198: .default_cpu_model = "Fujitsu MB86904",
1199: },
1200: /* SPARCClassic */
1201: {
1202: .iommu_base = 0x10000000,
1203: .tcx_base = 0x50000000,
1204: .slavio_base = 0x70000000,
1205: .ms_kb_base = 0x71000000,
1206: .serial_base = 0x71100000,
1207: .nvram_base = 0x71200000,
1208: .fd_base = 0x71400000,
1209: .counter_base = 0x71d00000,
1210: .intctl_base = 0x71e00000,
1211: .idreg_base = 0x78000000,
1212: .dma_base = 0x78400000,
1213: .esp_base = 0x78800000,
1214: .le_base = 0x78c00000,
1215: .apc_base = 0x6a000000,
1216: .aux1_base = 0x71900000,
1217: .aux2_base = 0x71910000,
1218: .nvram_machine_id = 0x80,
1219: .machine_id = scls_id,
1220: .iommu_version = 0x05000000,
1221: .max_mem = 0x10000000,
1222: .default_cpu_model = "TI MicroSparc I",
1223: },
1224: /* SPARCbook */
1225: {
1226: .iommu_base = 0x10000000,
1227: .tcx_base = 0x50000000, // XXX
1228: .slavio_base = 0x70000000,
1229: .ms_kb_base = 0x71000000,
1230: .serial_base = 0x71100000,
1231: .nvram_base = 0x71200000,
1232: .fd_base = 0x71400000,
1233: .counter_base = 0x71d00000,
1234: .intctl_base = 0x71e00000,
1235: .idreg_base = 0x78000000,
1236: .dma_base = 0x78400000,
1237: .esp_base = 0x78800000,
1238: .le_base = 0x78c00000,
1239: .apc_base = 0x6a000000,
1240: .aux1_base = 0x71900000,
1241: .aux2_base = 0x71910000,
1242: .nvram_machine_id = 0x80,
1243: .machine_id = sbook_id,
1244: .iommu_version = 0x05000000,
1245: .max_mem = 0x10000000,
1246: .default_cpu_model = "TI MicroSparc I",
1.1.1.6 root 1247: },
1248: };
1249:
1250: /* SPARCstation 5 hardware initialisation */
1.1.1.8 root 1251: static void ss5_init(ram_addr_t RAM_size,
1.1.1.7 root 1252: const char *boot_device,
1.1.1.6 root 1253: const char *kernel_filename, const char *kernel_cmdline,
1254: const char *initrd_filename, const char *cpu_model)
1255: {
1.1.1.7 root 1256: sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
1.1.1.6 root 1257: kernel_cmdline, initrd_filename, cpu_model);
1258: }
1259:
1260: /* SPARCstation 10 hardware initialisation */
1.1.1.8 root 1261: static void ss10_init(ram_addr_t RAM_size,
1.1.1.7 root 1262: const char *boot_device,
1.1.1.6 root 1263: const char *kernel_filename, const char *kernel_cmdline,
1264: const char *initrd_filename, const char *cpu_model)
1265: {
1.1.1.7 root 1266: sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
1.1.1.6 root 1267: kernel_cmdline, initrd_filename, cpu_model);
1268: }
1269:
1270: /* SPARCserver 600MP hardware initialisation */
1.1.1.8 root 1271: static void ss600mp_init(ram_addr_t RAM_size,
1.1.1.7 root 1272: const char *boot_device,
1273: const char *kernel_filename,
1274: const char *kernel_cmdline,
1.1.1.6 root 1275: const char *initrd_filename, const char *cpu_model)
1276: {
1.1.1.7 root 1277: sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
1.1.1.6 root 1278: kernel_cmdline, initrd_filename, cpu_model);
1279: }
1280:
1281: /* SPARCstation 20 hardware initialisation */
1.1.1.8 root 1282: static void ss20_init(ram_addr_t RAM_size,
1.1.1.7 root 1283: const char *boot_device,
1.1.1.6 root 1284: const char *kernel_filename, const char *kernel_cmdline,
1285: const char *initrd_filename, const char *cpu_model)
1286: {
1.1.1.7 root 1287: sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
1.1.1.6 root 1288: kernel_cmdline, initrd_filename, cpu_model);
1289: }
1290:
1.1.1.7 root 1291: /* SPARCstation Voyager hardware initialisation */
1.1.1.8 root 1292: static void vger_init(ram_addr_t RAM_size,
1.1.1.7 root 1293: const char *boot_device,
1294: const char *kernel_filename, const char *kernel_cmdline,
1295: const char *initrd_filename, const char *cpu_model)
1296: {
1297: sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
1298: kernel_cmdline, initrd_filename, cpu_model);
1299: }
1300:
1301: /* SPARCstation LX hardware initialisation */
1.1.1.8 root 1302: static void ss_lx_init(ram_addr_t RAM_size,
1.1.1.7 root 1303: const char *boot_device,
1304: const char *kernel_filename, const char *kernel_cmdline,
1305: const char *initrd_filename, const char *cpu_model)
1306: {
1307: sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
1308: kernel_cmdline, initrd_filename, cpu_model);
1309: }
1310:
1311: /* SPARCstation 4 hardware initialisation */
1.1.1.8 root 1312: static void ss4_init(ram_addr_t RAM_size,
1.1.1.7 root 1313: const char *boot_device,
1.1.1.6 root 1314: const char *kernel_filename, const char *kernel_cmdline,
1315: const char *initrd_filename, const char *cpu_model)
1316: {
1.1.1.7 root 1317: sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
1318: kernel_cmdline, initrd_filename, cpu_model);
1319: }
1320:
1321: /* SPARCClassic hardware initialisation */
1.1.1.8 root 1322: static void scls_init(ram_addr_t RAM_size,
1.1.1.7 root 1323: const char *boot_device,
1324: const char *kernel_filename, const char *kernel_cmdline,
1325: const char *initrd_filename, const char *cpu_model)
1326: {
1327: sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
1328: kernel_cmdline, initrd_filename, cpu_model);
1329: }
1330:
1331: /* SPARCbook hardware initialisation */
1.1.1.8 root 1332: static void sbook_init(ram_addr_t RAM_size,
1.1.1.7 root 1333: const char *boot_device,
1334: const char *kernel_filename, const char *kernel_cmdline,
1335: const char *initrd_filename, const char *cpu_model)
1336: {
1337: sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
1.1.1.6 root 1338: kernel_cmdline, initrd_filename, cpu_model);
1339: }
1340:
1.1.1.8 root 1341: static QEMUMachine ss5_machine = {
1.1.1.7 root 1342: .name = "SS-5",
1343: .desc = "Sun4m platform, SPARCstation 5",
1344: .init = ss5_init,
1345: .use_scsi = 1,
1.1.1.8 root 1346: .is_default = 1,
1.1.1.6 root 1347: };
1348:
1.1.1.8 root 1349: static QEMUMachine ss10_machine = {
1.1.1.7 root 1350: .name = "SS-10",
1351: .desc = "Sun4m platform, SPARCstation 10",
1352: .init = ss10_init,
1353: .use_scsi = 1,
1354: .max_cpus = 4,
1.1.1.6 root 1355: };
1356:
1.1.1.8 root 1357: static QEMUMachine ss600mp_machine = {
1.1.1.7 root 1358: .name = "SS-600MP",
1359: .desc = "Sun4m platform, SPARCserver 600MP",
1360: .init = ss600mp_init,
1361: .use_scsi = 1,
1362: .max_cpus = 4,
1.1.1.6 root 1363: };
1364:
1.1.1.8 root 1365: static QEMUMachine ss20_machine = {
1.1.1.7 root 1366: .name = "SS-20",
1367: .desc = "Sun4m platform, SPARCstation 20",
1368: .init = ss20_init,
1369: .use_scsi = 1,
1370: .max_cpus = 4,
1.1.1.6 root 1371: };
1372:
1.1.1.8 root 1373: static QEMUMachine voyager_machine = {
1.1.1.7 root 1374: .name = "Voyager",
1375: .desc = "Sun4m platform, SPARCstation Voyager",
1376: .init = vger_init,
1377: .use_scsi = 1,
1378: };
1379:
1.1.1.8 root 1380: static QEMUMachine ss_lx_machine = {
1.1.1.7 root 1381: .name = "LX",
1382: .desc = "Sun4m platform, SPARCstation LX",
1383: .init = ss_lx_init,
1384: .use_scsi = 1,
1385: };
1386:
1.1.1.8 root 1387: static QEMUMachine ss4_machine = {
1.1.1.7 root 1388: .name = "SS-4",
1389: .desc = "Sun4m platform, SPARCstation 4",
1390: .init = ss4_init,
1391: .use_scsi = 1,
1392: };
1393:
1.1.1.8 root 1394: static QEMUMachine scls_machine = {
1.1.1.7 root 1395: .name = "SPARCClassic",
1396: .desc = "Sun4m platform, SPARCClassic",
1397: .init = scls_init,
1398: .use_scsi = 1,
1399: };
1400:
1.1.1.8 root 1401: static QEMUMachine sbook_machine = {
1.1.1.7 root 1402: .name = "SPARCbook",
1403: .desc = "Sun4m platform, SPARCbook",
1404: .init = sbook_init,
1405: .use_scsi = 1,
1.1.1.6 root 1406: };
1407:
1408: static const struct sun4d_hwdef sun4d_hwdefs[] = {
1409: /* SS-1000 */
1410: {
1411: .iounit_bases = {
1412: 0xfe0200000ULL,
1413: 0xfe1200000ULL,
1414: 0xfe2200000ULL,
1415: 0xfe3200000ULL,
1416: -1,
1417: },
1418: .tcx_base = 0x820000000ULL,
1419: .slavio_base = 0xf00000000ULL,
1420: .ms_kb_base = 0xf00240000ULL,
1421: .serial_base = 0xf00200000ULL,
1422: .nvram_base = 0xf00280000ULL,
1423: .counter_base = 0xf00300000ULL,
1424: .espdma_base = 0x800081000ULL,
1425: .esp_base = 0x800080000ULL,
1426: .ledma_base = 0x800040000ULL,
1427: .le_base = 0x800060000ULL,
1428: .sbi_base = 0xf02800000ULL,
1.1.1.7 root 1429: .nvram_machine_id = 0x80,
1430: .machine_id = ss1000_id,
1.1.1.6 root 1431: .iounit_version = 0x03000000,
1.1.1.7 root 1432: .max_mem = 0xf00000000ULL,
1.1.1.6 root 1433: .default_cpu_model = "TI SuperSparc II",
1434: },
1435: /* SS-2000 */
1436: {
1437: .iounit_bases = {
1438: 0xfe0200000ULL,
1439: 0xfe1200000ULL,
1440: 0xfe2200000ULL,
1441: 0xfe3200000ULL,
1442: 0xfe4200000ULL,
1443: },
1444: .tcx_base = 0x820000000ULL,
1445: .slavio_base = 0xf00000000ULL,
1446: .ms_kb_base = 0xf00240000ULL,
1447: .serial_base = 0xf00200000ULL,
1448: .nvram_base = 0xf00280000ULL,
1449: .counter_base = 0xf00300000ULL,
1450: .espdma_base = 0x800081000ULL,
1451: .esp_base = 0x800080000ULL,
1452: .ledma_base = 0x800040000ULL,
1453: .le_base = 0x800060000ULL,
1454: .sbi_base = 0xf02800000ULL,
1.1.1.7 root 1455: .nvram_machine_id = 0x80,
1456: .machine_id = ss2000_id,
1.1.1.6 root 1457: .iounit_version = 0x03000000,
1.1.1.7 root 1458: .max_mem = 0xf00000000ULL,
1.1.1.6 root 1459: .default_cpu_model = "TI SuperSparc II",
1460: },
1461: };
1462:
1.1.1.10 root 1463: static DeviceState *sbi_init(target_phys_addr_t addr, qemu_irq **parent_irq)
1464: {
1465: DeviceState *dev;
1466: SysBusDevice *s;
1467: unsigned int i;
1468:
1469: dev = qdev_create(NULL, "sbi");
1470: qdev_init_nofail(dev);
1471:
1472: s = sysbus_from_qdev(dev);
1473:
1474: for (i = 0; i < MAX_CPUS; i++) {
1475: sysbus_connect_irq(s, i, *parent_irq[i]);
1476: }
1477:
1478: sysbus_mmio_map(s, 0, addr);
1479:
1480: return dev;
1481: }
1482:
1.1.1.7 root 1483: static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
1.1.1.6 root 1484: const char *boot_device,
1.1.1.7 root 1485: const char *kernel_filename,
1.1.1.6 root 1486: const char *kernel_cmdline,
1487: const char *initrd_filename, const char *cpu_model)
1488: {
1489: unsigned int i;
1.1.1.10 root 1490: void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram;
1491: qemu_irq *cpu_irqs[MAX_CPUS], sbi_irq[32], sbi_cpu_irq[MAX_CPUS],
1.1.1.8 root 1492: espdma_irq, ledma_irq;
1.1.1.10 root 1493: qemu_irq esp_reset;
1.1.1.7 root 1494: unsigned long kernel_size;
1495: void *fw_cfg;
1.1.1.10 root 1496: DeviceState *dev;
1.1.1.6 root 1497:
1498: /* init CPUs */
1499: if (!cpu_model)
1500: cpu_model = hwdef->default_cpu_model;
1501:
1.1.1.8 root 1502: for(i = 0; i < smp_cpus; i++) {
1.1.1.11! root 1503: cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
1.1.1.6 root 1504: }
1505:
1506: for (i = smp_cpus; i < MAX_CPUS; i++)
1507: cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
1508:
1.1.1.8 root 1509: /* set up devices */
1510: ram_init(0, RAM_size, hwdef->max_mem);
1.1.1.6 root 1511:
1.1.1.8 root 1512: prom_init(hwdef->slavio_base, bios_name);
1.1.1.6 root 1513:
1.1.1.10 root 1514: dev = sbi_init(hwdef->sbi_base, cpu_irqs);
1515:
1516: for (i = 0; i < 32; i++) {
1517: sbi_irq[i] = qdev_get_gpio_in(dev, i);
1518: }
1519: for (i = 0; i < MAX_CPUS; i++) {
1520: sbi_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
1521: }
1.1.1.6 root 1522:
1523: for (i = 0; i < MAX_IOUNITS; i++)
1524: if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1)
1525: iounits[i] = iommu_init(hwdef->iounit_bases[i],
1526: hwdef->iounit_version,
1.1.1.10 root 1527: sbi_irq[0]);
1.1.1.6 root 1528:
1.1.1.10 root 1529: espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[3],
1530: iounits[0], &espdma_irq);
1.1.1.6 root 1531:
1.1.1.10 root 1532: ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[4],
1533: iounits[0], &ledma_irq);
1.1.1.6 root 1534:
1535: if (graphic_depth != 8 && graphic_depth != 24) {
1536: fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
1537: exit (1);
1538: }
1.1.1.10 root 1539: tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
1.1.1.8 root 1540: graphic_depth);
1.1.1.6 root 1541:
1.1.1.10 root 1542: lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
1.1.1.6 root 1543:
1.1.1.10 root 1544: nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0, 0x2000, 8);
1.1.1.6 root 1545:
1.1.1.10 root 1546: slavio_timer_init_all(hwdef->counter_base, sbi_irq[10], sbi_cpu_irq, smp_cpus);
1.1.1.6 root 1547:
1.1.1.10 root 1548: slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[12],
1.1.1.8 root 1549: display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
1.1.1.6 root 1550: // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
1551: // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
1.1.1.10 root 1552: escc_init(hwdef->serial_base, sbi_irq[12], sbi_irq[12],
1.1.1.7 root 1553: serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
1.1.1.6 root 1554:
1555: if (drive_get_max_bus(IF_SCSI) > 0) {
1556: fprintf(stderr, "qemu: too many SCSI bus\n");
1557: exit(1);
1558: }
1559:
1.1.1.10 root 1560: esp_reset = qdev_get_gpio_in(espdma, 0);
1.1.1.8 root 1561: esp_init(hwdef->esp_base, 2,
1562: espdma_memory_read, espdma_memory_write,
1.1.1.10 root 1563: espdma, espdma_irq, &esp_reset);
1.1.1.6 root 1564:
1.1.1.7 root 1565: kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
1566: RAM_size);
1.1.1.6 root 1567:
1568: nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
1569: boot_device, RAM_size, kernel_size, graphic_width,
1.1.1.7 root 1570: graphic_height, graphic_depth, hwdef->nvram_machine_id,
1571: "Sun4d");
1572:
1573: fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
1574: fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
1575: fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
1576: fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
1.1.1.8 root 1577: fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
1578: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
1579: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
1580: if (kernel_cmdline) {
1581: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
1.1.1.10 root 1582: pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
1.1.1.11! root 1583: fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
! 1584: (uint8_t*)strdup(kernel_cmdline),
! 1585: strlen(kernel_cmdline) + 1);
1.1.1.8 root 1586: } else {
1587: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
1588: }
1589: fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
1590: fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
1591: fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
1592: qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
1.1.1.6 root 1593: }
1594:
1595: /* SPARCserver 1000 hardware initialisation */
1.1.1.8 root 1596: static void ss1000_init(ram_addr_t RAM_size,
1.1.1.7 root 1597: const char *boot_device,
1.1.1.6 root 1598: const char *kernel_filename, const char *kernel_cmdline,
1599: const char *initrd_filename, const char *cpu_model)
1600: {
1.1.1.7 root 1601: sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
1.1.1.6 root 1602: kernel_cmdline, initrd_filename, cpu_model);
1.1 root 1603: }
1604:
1.1.1.6 root 1605: /* SPARCcenter 2000 hardware initialisation */
1.1.1.8 root 1606: static void ss2000_init(ram_addr_t RAM_size,
1.1.1.7 root 1607: const char *boot_device,
1.1.1.6 root 1608: const char *kernel_filename, const char *kernel_cmdline,
1609: const char *initrd_filename, const char *cpu_model)
1610: {
1.1.1.7 root 1611: sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
1.1.1.6 root 1612: kernel_cmdline, initrd_filename, cpu_model);
1613: }
1614:
1.1.1.8 root 1615: static QEMUMachine ss1000_machine = {
1.1.1.7 root 1616: .name = "SS-1000",
1617: .desc = "Sun4d platform, SPARCserver 1000",
1618: .init = ss1000_init,
1619: .use_scsi = 1,
1620: .max_cpus = 8,
1.1.1.6 root 1621: };
1622:
1.1.1.8 root 1623: static QEMUMachine ss2000_machine = {
1.1.1.7 root 1624: .name = "SS-2000",
1625: .desc = "Sun4d platform, SPARCcenter 2000",
1626: .init = ss2000_init,
1627: .use_scsi = 1,
1628: .max_cpus = 20,
1629: };
1630:
1631: static const struct sun4c_hwdef sun4c_hwdefs[] = {
1632: /* SS-2 */
1633: {
1634: .iommu_base = 0xf8000000,
1635: .tcx_base = 0xfe000000,
1636: .slavio_base = 0xf6000000,
1637: .intctl_base = 0xf5000000,
1638: .counter_base = 0xf3000000,
1639: .ms_kb_base = 0xf0000000,
1640: .serial_base = 0xf1000000,
1641: .nvram_base = 0xf2000000,
1642: .fd_base = 0xf7200000,
1643: .dma_base = 0xf8400000,
1644: .esp_base = 0xf8800000,
1645: .le_base = 0xf8c00000,
1646: .aux1_base = 0xf7400003,
1647: .nvram_machine_id = 0x55,
1648: .machine_id = ss2_id,
1649: .max_mem = 0x10000000,
1650: .default_cpu_model = "Cypress CY7C601",
1651: },
1652: };
1653:
1.1.1.10 root 1654: static DeviceState *sun4c_intctl_init(target_phys_addr_t addr,
1655: qemu_irq *parent_irq)
1656: {
1657: DeviceState *dev;
1658: SysBusDevice *s;
1659: unsigned int i;
1660:
1661: dev = qdev_create(NULL, "sun4c_intctl");
1662: qdev_init_nofail(dev);
1663:
1664: s = sysbus_from_qdev(dev);
1665:
1666: for (i = 0; i < MAX_PILS; i++) {
1667: sysbus_connect_irq(s, i, parent_irq[i]);
1668: }
1669: sysbus_mmio_map(s, 0, addr);
1670:
1671: return dev;
1672: }
1673:
1.1.1.7 root 1674: static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
1675: const char *boot_device,
1676: const char *kernel_filename,
1677: const char *kernel_cmdline,
1678: const char *initrd_filename, const char *cpu_model)
1679: {
1.1.1.8 root 1680: void *iommu, *espdma, *ledma, *nvram;
1.1.1.10 root 1681: qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq;
1682: qemu_irq esp_reset;
1.1.1.8 root 1683: qemu_irq fdc_tc;
1.1.1.7 root 1684: unsigned long kernel_size;
1.1.1.10 root 1685: DriveInfo *fd[MAX_FD];
1.1.1.7 root 1686: void *fw_cfg;
1.1.1.10 root 1687: DeviceState *dev;
1688: unsigned int i;
1.1.1.7 root 1689:
1690: /* init CPU */
1691: if (!cpu_model)
1692: cpu_model = hwdef->default_cpu_model;
1693:
1.1.1.11! root 1694: cpu_devinit(cpu_model, 0, hwdef->slavio_base, &cpu_irqs);
1.1.1.7 root 1695:
1.1.1.8 root 1696: /* set up devices */
1697: ram_init(0, RAM_size, hwdef->max_mem);
1.1.1.7 root 1698:
1.1.1.8 root 1699: prom_init(hwdef->slavio_base, bios_name);
1.1.1.7 root 1700:
1.1.1.10 root 1701: dev = sun4c_intctl_init(hwdef->intctl_base, cpu_irqs);
1702:
1703: for (i = 0; i < 8; i++) {
1704: slavio_irq[i] = qdev_get_gpio_in(dev, i);
1705: }
1.1.1.7 root 1706:
1707: iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
1.1.1.10 root 1708: slavio_irq[1]);
1.1.1.7 root 1709:
1.1.1.10 root 1710: espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[2],
1711: iommu, &espdma_irq);
1.1.1.7 root 1712:
1713: ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
1.1.1.10 root 1714: slavio_irq[3], iommu, &ledma_irq);
1.1.1.7 root 1715:
1716: if (graphic_depth != 8 && graphic_depth != 24) {
1717: fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
1718: exit (1);
1719: }
1.1.1.10 root 1720: tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
1.1.1.8 root 1721: graphic_depth);
1.1.1.7 root 1722:
1.1.1.10 root 1723: lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
1.1.1.7 root 1724:
1.1.1.10 root 1725: nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x800, 2);
1.1.1.7 root 1726:
1.1.1.10 root 1727: slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[1],
1.1.1.8 root 1728: display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
1.1.1.7 root 1729: // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
1730: // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
1.1.1.10 root 1731: escc_init(hwdef->serial_base, slavio_irq[1],
1732: slavio_irq[1], serial_hds[0], serial_hds[1],
1.1.1.7 root 1733: ESCC_CLOCK, 1);
1734:
1.1.1.10 root 1735: slavio_misc_init(0, hwdef->aux1_base, 0, slavio_irq[1], fdc_tc);
1.1.1.7 root 1736:
1737: if (hwdef->fd_base != (target_phys_addr_t)-1) {
1738: /* there is zero or one floppy drive */
1739: memset(fd, 0, sizeof(fd));
1.1.1.10 root 1740: fd[0] = drive_get(IF_FLOPPY, 0, 0);
1741: sun4m_fdctrl_init(slavio_irq[1], hwdef->fd_base, fd,
1.1.1.8 root 1742: &fdc_tc);
1.1.1.7 root 1743: }
1744:
1745: if (drive_get_max_bus(IF_SCSI) > 0) {
1746: fprintf(stderr, "qemu: too many SCSI bus\n");
1747: exit(1);
1748: }
1749:
1.1.1.10 root 1750: esp_reset = qdev_get_gpio_in(espdma, 0);
1.1.1.8 root 1751: esp_init(hwdef->esp_base, 2,
1752: espdma_memory_read, espdma_memory_write,
1.1.1.10 root 1753: espdma, espdma_irq, &esp_reset);
1.1.1.7 root 1754:
1755: kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
1756: RAM_size);
1757:
1758: nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
1759: boot_device, RAM_size, kernel_size, graphic_width,
1760: graphic_height, graphic_depth, hwdef->nvram_machine_id,
1761: "Sun4c");
1762:
1763: fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
1764: fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
1765: fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
1766: fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
1.1.1.8 root 1767: fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
1768: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
1769: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
1770: if (kernel_cmdline) {
1771: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
1.1.1.10 root 1772: pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
1.1.1.11! root 1773: fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
! 1774: (uint8_t*)strdup(kernel_cmdline),
! 1775: strlen(kernel_cmdline) + 1);
1.1.1.8 root 1776: } else {
1777: fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
1778: }
1779: fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
1780: fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
1781: fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
1782: qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
1.1.1.7 root 1783: }
1784:
1785: /* SPARCstation 2 hardware initialisation */
1.1.1.8 root 1786: static void ss2_init(ram_addr_t RAM_size,
1.1.1.7 root 1787: const char *boot_device,
1788: const char *kernel_filename, const char *kernel_cmdline,
1789: const char *initrd_filename, const char *cpu_model)
1790: {
1791: sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
1792: kernel_cmdline, initrd_filename, cpu_model);
1793: }
1794:
1.1.1.8 root 1795: static QEMUMachine ss2_machine = {
1.1.1.7 root 1796: .name = "SS-2",
1797: .desc = "Sun4c platform, SPARCstation 2",
1798: .init = ss2_init,
1799: .use_scsi = 1,
1.1 root 1800: };
1.1.1.8 root 1801:
1802: static void ss2_machine_init(void)
1803: {
1804: qemu_register_machine(&ss5_machine);
1805: qemu_register_machine(&ss10_machine);
1806: qemu_register_machine(&ss600mp_machine);
1807: qemu_register_machine(&ss20_machine);
1808: qemu_register_machine(&voyager_machine);
1809: qemu_register_machine(&ss_lx_machine);
1810: qemu_register_machine(&ss4_machine);
1811: qemu_register_machine(&scls_machine);
1812: qemu_register_machine(&sbook_machine);
1813: qemu_register_machine(&ss1000_machine);
1814: qemu_register_machine(&ss2000_machine);
1815: qemu_register_machine(&ss2_machine);
1816: }
1817:
1818: machine_init(ss2_machine_init);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.