|
|
1.1 root 1: /*
1.1.1.7 root 2: * QEMU Sun4u/Sun4v System Emulator
1.1.1.6 root 3: *
1.1 root 4: * Copyright (c) 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 "pci.h"
1.1.1.9 root 26: #include "apb_pci.h"
1.1.1.6 root 27: #include "pc.h"
28: #include "nvram.h"
29: #include "fdc.h"
30: #include "net.h"
31: #include "qemu-timer.h"
32: #include "sysemu.h"
33: #include "boards.h"
34: #include "firmware_abi.h"
1.1.1.7 root 35: #include "fw_cfg.h"
1.1.1.9 root 36: #include "sysbus.h"
37: #include "ide.h"
38: #include "loader.h"
39: #include "elf.h"
1.1.1.11 root 40: #include "blockdev.h"
1.1.1.13 root 41: #include "exec-memory.h"
1.1.1.7 root 42:
43: //#define DEBUG_IRQ
1.1.1.10 root 44: //#define DEBUG_EBUS
45: //#define DEBUG_TIMER
1.1.1.7 root 46:
47: #ifdef DEBUG_IRQ
1.1.1.10 root 48: #define CPUIRQ_DPRINTF(fmt, ...) \
1.1.1.8 root 49: do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
1.1.1.7 root 50: #else
1.1.1.10 root 51: #define CPUIRQ_DPRINTF(fmt, ...)
52: #endif
53:
54: #ifdef DEBUG_EBUS
55: #define EBUS_DPRINTF(fmt, ...) \
56: do { printf("EBUS: " fmt , ## __VA_ARGS__); } while (0)
57: #else
58: #define EBUS_DPRINTF(fmt, ...)
59: #endif
60:
61: #ifdef DEBUG_TIMER
62: #define TIMER_DPRINTF(fmt, ...) \
63: do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0)
64: #else
65: #define TIMER_DPRINTF(fmt, ...)
1.1.1.7 root 66: #endif
1.1 root 67:
68: #define KERNEL_LOAD_ADDR 0x00404000
69: #define CMDLINE_ADDR 0x003ff000
1.1.1.7 root 70: #define PROM_SIZE_MAX (4 * 1024 * 1024)
1.1.1.6 root 71: #define PROM_VADDR 0x000ffd00000ULL
1.1 root 72: #define APB_SPECIAL_BASE 0x1fe00000000ULL
1.1.1.6 root 73: #define APB_MEM_BASE 0x1ff00000000ULL
1.1.1.10 root 74: #define APB_PCI_IO_BASE (APB_SPECIAL_BASE + 0x02000000ULL)
1.1.1.6 root 75: #define PROM_FILENAME "openbios-sparc64"
1.1 root 76: #define NVRAM_SIZE 0x2000
1.1.1.6 root 77: #define MAX_IDE_BUS 2
1.1.1.7 root 78: #define BIOS_CFG_IOPORT 0x510
1.1.1.9 root 79: #define FW_CFG_SPARC64_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
80: #define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
81: #define FW_CFG_SPARC64_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
1.1 root 82:
1.1.1.14! root 83: #define IVEC_MAX 0x30
1.1 root 84:
1.1.1.7 root 85: #define TICK_MAX 0x7fffffffffffffffULL
86:
87: struct hwdef {
88: const char * const default_cpu_model;
89: uint16_t machine_id;
90: uint64_t prom_addr;
91: uint64_t console_serial_base;
92: };
1.1 root 93:
1.1.1.13 root 94: typedef struct EbusState {
95: PCIDevice pci_dev;
96: MemoryRegion bar0;
97: MemoryRegion bar1;
98: } EbusState;
99:
1.1 root 100: int DMA_get_channel_mode (int nchan)
101: {
102: return 0;
103: }
104: int DMA_read_memory (int nchan, void *buf, int pos, int size)
105: {
106: return 0;
107: }
108: int DMA_write_memory (int nchan, void *buf, int pos, int size)
109: {
110: return 0;
111: }
112: void DMA_hold_DREQ (int nchan) {}
113: void DMA_release_DREQ (int nchan) {}
114: void DMA_schedule(int nchan) {}
1.1.1.10 root 115:
116: void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit)
117: {
118: }
119:
1.1 root 120: void DMA_register_channel (int nchan,
121: DMA_transfer_handler transfer_handler,
122: void *opaque)
123: {
124: }
125:
1.1.1.8 root 126: static int fw_cfg_boot_set(void *opaque, const char *boot_device)
1.1.1.7 root 127: {
1.1.1.8 root 128: fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
1.1.1.7 root 129: return 0;
130: }
1.1 root 131:
1.1.1.10 root 132: static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size,
133: const char *arch, ram_addr_t RAM_size,
134: const char *boot_devices,
135: uint32_t kernel_image, uint32_t kernel_size,
136: const char *cmdline,
137: uint32_t initrd_image, uint32_t initrd_size,
138: uint32_t NVRAM_image,
139: int width, int height, int depth,
140: const uint8_t *macaddr)
1.1 root 141: {
1.1.1.6 root 142: unsigned int i;
143: uint32_t start, end;
144: uint8_t image[0x1ff0];
145: struct OpenBIOS_nvpart_v1 *part_header;
146:
147: memset(image, '\0', sizeof(image));
148:
1.1.1.8 root 149: start = 0;
1.1.1.6 root 150:
151: // OpenBIOS nvram variables
152: // Variable partition
153: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
154: part_header->signature = OPENBIOS_PART_SYSTEM;
1.1.1.7 root 155: pstrcpy(part_header->name, sizeof(part_header->name), "system");
1.1.1.6 root 156:
157: end = start + sizeof(struct OpenBIOS_nvpart_v1);
158: for (i = 0; i < nb_prom_envs; i++)
159: end = OpenBIOS_set_var(image, end, prom_envs[i]);
160:
161: // End marker
162: image[end++] = '\0';
163:
164: end = start + ((end - start + 15) & ~15);
165: OpenBIOS_finish_partition(part_header, end - start);
166:
167: // free partition
168: start = end;
169: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
170: part_header->signature = OPENBIOS_PART_FREE;
1.1.1.7 root 171: pstrcpy(part_header->name, sizeof(part_header->name), "free");
1.1 root 172:
1.1.1.6 root 173: end = 0x1fd0;
174: OpenBIOS_finish_partition(part_header, end - start);
1.1 root 175:
1.1.1.7 root 176: Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80);
177:
1.1.1.6 root 178: for (i = 0; i < sizeof(image); i++)
179: m48t59_write(nvram, i, image[i]);
1.1 root 180:
1.1.1.6 root 181: return 0;
1.1 root 182: }
1.1.1.14! root 183:
! 184: static uint64_t sun4u_load_kernel(const char *kernel_filename,
! 185: const char *initrd_filename,
! 186: ram_addr_t RAM_size, uint64_t *initrd_size,
! 187: uint64_t *initrd_addr, uint64_t *kernel_addr,
! 188: uint64_t *kernel_entry)
1.1.1.9 root 189: {
190: int linux_boot;
191: unsigned int i;
192: long kernel_size;
1.1.1.10 root 193: uint8_t *ptr;
1.1.1.14! root 194: uint64_t kernel_top;
1.1.1.9 root 195:
196: linux_boot = (kernel_filename != NULL);
197:
198: kernel_size = 0;
199: if (linux_boot) {
200: int bswap_needed;
201:
202: #ifdef BSWAP_NEEDED
203: bswap_needed = 1;
204: #else
205: bswap_needed = 0;
206: #endif
1.1.1.14! root 207: kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry,
! 208: kernel_addr, &kernel_top, 1, ELF_MACHINE, 0);
! 209: if (kernel_size < 0) {
! 210: *kernel_addr = KERNEL_LOAD_ADDR;
! 211: *kernel_entry = KERNEL_LOAD_ADDR;
1.1.1.9 root 212: kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
213: RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
214: TARGET_PAGE_SIZE);
1.1.1.14! root 215: }
! 216: if (kernel_size < 0) {
1.1.1.9 root 217: kernel_size = load_image_targphys(kernel_filename,
218: KERNEL_LOAD_ADDR,
219: RAM_size - KERNEL_LOAD_ADDR);
1.1.1.14! root 220: }
1.1.1.9 root 221: if (kernel_size < 0) {
222: fprintf(stderr, "qemu: could not load kernel '%s'\n",
223: kernel_filename);
224: exit(1);
225: }
1.1.1.14! root 226: /* load initrd above kernel */
1.1.1.9 root 227: *initrd_size = 0;
228: if (initrd_filename) {
1.1.1.14! root 229: *initrd_addr = TARGET_PAGE_ALIGN(kernel_top);
! 230:
1.1.1.9 root 231: *initrd_size = load_image_targphys(initrd_filename,
1.1.1.14! root 232: *initrd_addr,
! 233: RAM_size - *initrd_addr);
! 234: if ((int)*initrd_size < 0) {
1.1.1.9 root 235: fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
236: initrd_filename);
237: exit(1);
238: }
239: }
240: if (*initrd_size > 0) {
241: for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
1.1.1.14! root 242: ptr = rom_ptr(*kernel_addr + i);
1.1.1.10 root 243: if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
1.1.1.14! root 244: stl_p(ptr + 24, *initrd_addr + *kernel_addr);
1.1.1.10 root 245: stl_p(ptr + 28, *initrd_size);
1.1.1.9 root 246: break;
247: }
248: }
249: }
250: }
251: return kernel_size;
252: }
1.1 root 253:
1.1.1.14! root 254: void cpu_check_irqs(CPUSPARCState *env)
1.1.1.7 root 255: {
1.1.1.10 root 256: uint32_t pil = env->pil_in |
257: (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
258:
1.1.1.14! root 259: /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
! 260: if (env->ivec_status & 0x20) {
! 261: return;
! 262: }
1.1.1.10 root 263: /* check if TM or SM in SOFTINT are set
264: setting these also causes interrupt 14 */
265: if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
266: pil |= 1 << 14;
267: }
268:
1.1.1.13 root 269: /* The bit corresponding to psrpil is (1<< psrpil), the next bit
270: is (2 << psrpil). */
271: if (pil < (2 << env->psrpil)){
1.1.1.10 root 272: if (env->interrupt_request & CPU_INTERRUPT_HARD) {
273: CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
274: env->interrupt_index);
275: env->interrupt_index = 0;
276: cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
277: }
278: return;
279: }
280:
281: if (cpu_interrupts_enabled(env)) {
1.1.1.7 root 282:
283: unsigned int i;
284:
1.1.1.10 root 285: for (i = 15; i > env->psrpil; i--) {
1.1.1.7 root 286: if (pil & (1 << i)) {
287: int old_interrupt = env->interrupt_index;
1.1.1.10 root 288: int new_interrupt = TT_EXTINT | i;
1.1.1.7 root 289:
1.1.1.14! root 290: if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
! 291: && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
1.1.1.10 root 292: CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
293: "current %x >= pending %x\n",
294: env->tl, cpu_tsptr(env)->tt, new_interrupt);
295: } else if (old_interrupt != new_interrupt) {
296: env->interrupt_index = new_interrupt;
297: CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i,
298: old_interrupt, new_interrupt);
1.1.1.7 root 299: cpu_interrupt(env, CPU_INTERRUPT_HARD);
300: }
301: break;
302: }
303: }
1.1.1.13 root 304: } else if (env->interrupt_request & CPU_INTERRUPT_HARD) {
1.1.1.10 root 305: CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
306: "current interrupt %x\n",
307: pil, env->pil_in, env->softint, env->interrupt_index);
1.1.1.13 root 308: env->interrupt_index = 0;
309: cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
1.1.1.7 root 310: }
311: }
312:
1.1.1.14! root 313: static void cpu_kick_irq(CPUSPARCState *env)
1.1.1.10 root 314: {
315: env->halted = 0;
316: cpu_check_irqs(env);
1.1.1.12 root 317: qemu_cpu_kick(env);
1.1.1.10 root 318: }
319:
1.1.1.14! root 320: static void cpu_set_ivec_irq(void *opaque, int irq, int level)
1.1.1.7 root 321: {
1.1.1.14! root 322: CPUSPARCState *env = opaque;
1.1.1.7 root 323:
324: if (level) {
1.1.1.14! root 325: if (!(env->ivec_status & 0x20)) {
! 326: CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
! 327: env->halted = 0;
! 328: env->interrupt_index = TT_IVEC;
! 329: env->ivec_status |= 0x20;
! 330: env->ivec_data[0] = (0x1f << 6) | irq;
! 331: env->ivec_data[1] = 0;
! 332: env->ivec_data[2] = 0;
! 333: cpu_interrupt(env, CPU_INTERRUPT_HARD);
! 334: }
1.1.1.7 root 335: } else {
1.1.1.14! root 336: if (env->ivec_status & 0x20) {
! 337: CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
! 338: env->ivec_status &= ~0x20;
! 339: cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
! 340: }
1.1.1.7 root 341: }
342: }
343:
344: typedef struct ResetData {
1.1.1.14! root 345: CPUSPARCState *env;
1.1.1.9 root 346: uint64_t prom_addr;
1.1.1.7 root 347: } ResetData;
348:
1.1.1.10 root 349: void cpu_put_timer(QEMUFile *f, CPUTimer *s)
350: {
351: qemu_put_be32s(f, &s->frequency);
352: qemu_put_be32s(f, &s->disabled);
353: qemu_put_be64s(f, &s->disabled_mask);
354: qemu_put_sbe64s(f, &s->clock_offset);
355:
356: qemu_put_timer(f, s->qtimer);
357: }
358:
359: void cpu_get_timer(QEMUFile *f, CPUTimer *s)
360: {
361: qemu_get_be32s(f, &s->frequency);
362: qemu_get_be32s(f, &s->disabled);
363: qemu_get_be64s(f, &s->disabled_mask);
364: qemu_get_sbe64s(f, &s->clock_offset);
365:
366: qemu_get_timer(f, s->qtimer);
367: }
368:
1.1.1.14! root 369: static CPUTimer* cpu_timer_create(const char* name, CPUSPARCState *env,
1.1.1.10 root 370: QEMUBHFunc *cb, uint32_t frequency,
371: uint64_t disabled_mask)
372: {
1.1.1.13 root 373: CPUTimer *timer = g_malloc0(sizeof (CPUTimer));
1.1.1.10 root 374:
375: timer->name = name;
376: timer->frequency = frequency;
377: timer->disabled_mask = disabled_mask;
378:
379: timer->disabled = 1;
1.1.1.12 root 380: timer->clock_offset = qemu_get_clock_ns(vm_clock);
1.1.1.10 root 381:
1.1.1.12 root 382: timer->qtimer = qemu_new_timer_ns(vm_clock, cb, env);
1.1.1.10 root 383:
384: return timer;
385: }
386:
387: static void cpu_timer_reset(CPUTimer *timer)
388: {
389: timer->disabled = 1;
1.1.1.12 root 390: timer->clock_offset = qemu_get_clock_ns(vm_clock);
1.1.1.10 root 391:
392: qemu_del_timer(timer->qtimer);
393: }
394:
1.1.1.6 root 395: static void main_cpu_reset(void *opaque)
1.1 root 396: {
1.1.1.7 root 397: ResetData *s = (ResetData *)opaque;
1.1.1.14! root 398: CPUSPARCState *env = s->env;
1.1.1.9 root 399: static unsigned int nr_resets;
1.1 root 400:
1.1.1.14! root 401: cpu_state_reset(env);
1.1.1.10 root 402:
403: cpu_timer_reset(env->tick);
404: cpu_timer_reset(env->stick);
405: cpu_timer_reset(env->hstick);
406:
1.1.1.7 root 407: env->gregs[1] = 0; // Memory start
408: env->gregs[2] = ram_size; // Memory size
409: env->gregs[3] = 0; // Machine description XXX
1.1.1.9 root 410: if (nr_resets++ == 0) {
411: /* Power on reset */
412: env->pc = s->prom_addr + 0x20ULL;
413: } else {
414: env->pc = s->prom_addr + 0x40ULL;
415: }
1.1.1.7 root 416: env->npc = env->pc + 4;
1.1 root 417: }
418:
1.1.1.7 root 419: static void tick_irq(void *opaque)
1.1 root 420: {
1.1.1.14! root 421: CPUSPARCState *env = opaque;
1.1 root 422:
1.1.1.10 root 423: CPUTimer* timer = env->tick;
424:
425: if (timer->disabled) {
426: CPUIRQ_DPRINTF("tick_irq: softint disabled\n");
427: return;
428: } else {
429: CPUIRQ_DPRINTF("tick: fire\n");
1.1.1.7 root 430: }
1.1.1.10 root 431:
432: env->softint |= SOFTINT_TIMER;
433: cpu_kick_irq(env);
1.1 root 434: }
435:
1.1.1.7 root 436: static void stick_irq(void *opaque)
1.1 root 437: {
1.1.1.14! root 438: CPUSPARCState *env = opaque;
1.1 root 439:
1.1.1.10 root 440: CPUTimer* timer = env->stick;
441:
442: if (timer->disabled) {
443: CPUIRQ_DPRINTF("stick_irq: softint disabled\n");
444: return;
445: } else {
446: CPUIRQ_DPRINTF("stick: fire\n");
1.1.1.7 root 447: }
1.1.1.10 root 448:
449: env->softint |= SOFTINT_STIMER;
450: cpu_kick_irq(env);
1.1 root 451: }
452:
1.1.1.7 root 453: static void hstick_irq(void *opaque)
1.1 root 454: {
1.1.1.14! root 455: CPUSPARCState *env = opaque;
1.1 root 456:
1.1.1.10 root 457: CPUTimer* timer = env->hstick;
458:
459: if (timer->disabled) {
460: CPUIRQ_DPRINTF("hstick_irq: softint disabled\n");
461: return;
462: } else {
463: CPUIRQ_DPRINTF("hstick: fire\n");
1.1.1.7 root 464: }
1.1.1.10 root 465:
466: env->softint |= SOFTINT_STIMER;
467: cpu_kick_irq(env);
1.1.1.7 root 468: }
469:
1.1.1.10 root 470: static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency)
1.1.1.7 root 471: {
1.1.1.10 root 472: return muldiv64(cpu_ticks, get_ticks_per_sec(), frequency);
473: }
474:
475: static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency)
476: {
477: return muldiv64(timer_ticks, frequency, get_ticks_per_sec());
478: }
479:
480: void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
481: {
482: uint64_t real_count = count & ~timer->disabled_mask;
483: uint64_t disabled_bit = count & timer->disabled_mask;
484:
1.1.1.12 root 485: int64_t vm_clock_offset = qemu_get_clock_ns(vm_clock) -
1.1.1.10 root 486: cpu_to_timer_ticks(real_count, timer->frequency);
487:
488: TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n",
489: timer->name, real_count,
490: timer->disabled?"disabled":"enabled", timer);
491:
492: timer->disabled = disabled_bit ? 1 : 0;
493: timer->clock_offset = vm_clock_offset;
1.1 root 494: }
495:
1.1.1.10 root 496: uint64_t cpu_tick_get_count(CPUTimer *timer)
1.1.1.2 root 497: {
1.1.1.10 root 498: uint64_t real_count = timer_to_cpu_ticks(
1.1.1.12 root 499: qemu_get_clock_ns(vm_clock) - timer->clock_offset,
1.1.1.10 root 500: timer->frequency);
501:
502: TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n",
503: timer->name, real_count,
504: timer->disabled?"disabled":"enabled", timer);
505:
506: if (timer->disabled)
507: real_count |= timer->disabled_mask;
508:
509: return real_count;
1.1.1.7 root 510: }
511:
1.1.1.10 root 512: void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
1.1.1.7 root 513: {
1.1.1.12 root 514: int64_t now = qemu_get_clock_ns(vm_clock);
1.1.1.10 root 515:
516: uint64_t real_limit = limit & ~timer->disabled_mask;
517: timer->disabled = (limit & timer->disabled_mask) ? 1 : 0;
518:
519: int64_t expires = cpu_to_timer_ticks(real_limit, timer->frequency) +
520: timer->clock_offset;
521:
522: if (expires < now) {
523: expires = now + 1;
524: }
525:
526: TIMER_DPRINTF("%s set_limit limit=0x%016lx (%s) p=%p "
527: "called with limit=0x%016lx at 0x%016lx (delta=0x%016lx)\n",
528: timer->name, real_limit,
529: timer->disabled?"disabled":"enabled",
530: timer, limit,
531: timer_to_cpu_ticks(now - timer->clock_offset,
532: timer->frequency),
533: timer_to_cpu_ticks(expires - now, timer->frequency));
534:
535: if (!real_limit) {
536: TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n",
537: timer->name);
538: qemu_del_timer(timer->qtimer);
539: } else if (timer->disabled) {
540: qemu_del_timer(timer->qtimer);
541: } else {
542: qemu_mod_timer(timer->qtimer, expires);
543: }
1.1.1.2 root 544: }
545:
1.1.1.14! root 546: static void isa_irq_handler(void *opaque, int n, int level)
1.1.1.9 root 547: {
1.1.1.14! root 548: static const int isa_irq_to_ivec[16] = {
! 549: [1] = 0x29, /* keyboard */
! 550: [4] = 0x2b, /* serial */
! 551: [6] = 0x27, /* floppy */
! 552: [7] = 0x22, /* parallel */
! 553: [12] = 0x2a, /* mouse */
! 554: };
! 555: qemu_irq *irqs = opaque;
! 556: int ivec;
! 557:
! 558: assert(n < 16);
! 559: ivec = isa_irq_to_ivec[n];
! 560: EBUS_DPRINTF("Set ISA IRQ %d level %d -> ivec 0x%x\n", n, level, ivec);
! 561: if (ivec) {
! 562: qemu_set_irq(irqs[ivec], level);
! 563: }
1.1.1.9 root 564: }
565:
1.1.1.7 root 566: /* EBUS (Eight bit bus) bridge */
1.1.1.14! root 567: static ISABus *
! 568: pci_ebus_init(PCIBus *bus, int devfn, qemu_irq *irqs)
1.1.1.7 root 569: {
1.1.1.9 root 570: qemu_irq *isa_irq;
1.1.1.14! root 571: PCIDevice *pci_dev;
! 572: ISABus *isa_bus;
1.1.1.9 root 573:
1.1.1.14! root 574: pci_dev = pci_create_simple(bus, devfn, "ebus");
! 575: isa_bus = DO_UPCAST(ISABus, qbus,
! 576: qdev_get_child_bus(&pci_dev->qdev, "isa.0"));
! 577: isa_irq = qemu_allocate_irqs(isa_irq_handler, irqs, 16);
! 578: isa_bus_irqs(isa_bus, isa_irq);
! 579: return isa_bus;
1.1.1.8 root 580: }
1.1.1.7 root 581:
1.1.1.9 root 582: static int
1.1.1.13 root 583: pci_ebus_init1(PCIDevice *pci_dev)
1.1.1.8 root 584: {
1.1.1.13 root 585: EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev);
1.1.1.9 root 586:
1.1.1.13 root 587: isa_bus_new(&pci_dev->qdev, pci_address_space_io(pci_dev));
588:
589: pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
590: pci_dev->config[0x05] = 0x00;
591: pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
592: pci_dev->config[0x07] = 0x03; // status = medium devsel
593: pci_dev->config[0x09] = 0x00; // programming i/f
594: pci_dev->config[0x0D] = 0x0a; // latency_timer
595:
596: isa_mmio_setup(&s->bar0, 0x1000000);
597: pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
598: isa_mmio_setup(&s->bar1, 0x800000);
599: pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);
1.1.1.9 root 600: return 0;
1.1.1.7 root 601: }
602:
1.1.1.14! root 603: static void ebus_class_init(ObjectClass *klass, void *data)
1.1.1.8 root 604: {
1.1.1.14! root 605: PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1.1.1.8 root 606:
1.1.1.14! root 607: k->init = pci_ebus_init1;
! 608: k->vendor_id = PCI_VENDOR_ID_SUN;
! 609: k->device_id = PCI_DEVICE_ID_SUN_EBUS;
! 610: k->revision = 0x01;
! 611: k->class_id = PCI_CLASS_BRIDGE_OTHER;
! 612: }
! 613:
! 614: static TypeInfo ebus_info = {
! 615: .name = "ebus",
! 616: .parent = TYPE_PCI_DEVICE,
! 617: .instance_size = sizeof(EbusState),
! 618: .class_init = ebus_class_init,
! 619: };
1.1.1.8 root 620:
1.1.1.13 root 621: typedef struct PROMState {
622: SysBusDevice busdev;
623: MemoryRegion prom;
624: } PROMState;
625:
1.1.1.10 root 626: static uint64_t translate_prom_address(void *opaque, uint64_t addr)
627: {
628: target_phys_addr_t *base_addr = (target_phys_addr_t *)opaque;
629: return addr + *base_addr - PROM_VADDR;
630: }
631:
1.1.1.9 root 632: /* Boot PROM (OpenBIOS) */
633: static void prom_init(target_phys_addr_t addr, const char *bios_name)
1.1 root 634: {
1.1.1.9 root 635: DeviceState *dev;
636: SysBusDevice *s;
1.1.1.8 root 637: char *filename;
1.1.1.9 root 638: int ret;
639:
640: dev = qdev_create(NULL, "openprom");
641: qdev_init_nofail(dev);
642: s = sysbus_from_qdev(dev);
643:
644: sysbus_mmio_map(s, 0, addr);
645:
646: /* load boot prom */
647: if (bios_name == NULL) {
648: bios_name = PROM_FILENAME;
649: }
650: filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
651: if (filename) {
1.1.1.10 root 652: ret = load_elf(filename, translate_prom_address, &addr,
653: NULL, NULL, NULL, 1, ELF_MACHINE, 0);
1.1.1.9 root 654: if (ret < 0 || ret > PROM_SIZE_MAX) {
655: ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
656: }
1.1.1.13 root 657: g_free(filename);
1.1.1.9 root 658: } else {
659: ret = -1;
660: }
661: if (ret < 0 || ret > PROM_SIZE_MAX) {
662: fprintf(stderr, "qemu: could not load prom '%s'\n", bios_name);
663: exit(1);
664: }
665: }
666:
667: static int prom_init1(SysBusDevice *dev)
668: {
1.1.1.13 root 669: PROMState *s = FROM_SYSBUS(PROMState, dev);
1.1.1.9 root 670:
1.1.1.14! root 671: memory_region_init_ram(&s->prom, "sun4u.prom", PROM_SIZE_MAX);
! 672: vmstate_register_ram_global(&s->prom);
1.1.1.13 root 673: memory_region_set_readonly(&s->prom, true);
1.1.1.14! root 674: sysbus_init_mmio(dev, &s->prom);
1.1.1.9 root 675: return 0;
676: }
677:
1.1.1.14! root 678: static Property prom_properties[] = {
! 679: {/* end of property list */},
1.1.1.9 root 680: };
681:
1.1.1.14! root 682: static void prom_class_init(ObjectClass *klass, void *data)
1.1.1.9 root 683: {
1.1.1.14! root 684: DeviceClass *dc = DEVICE_CLASS(klass);
! 685: SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
! 686:
! 687: k->init = prom_init1;
! 688: dc->props = prom_properties;
1.1.1.9 root 689: }
690:
1.1.1.14! root 691: static TypeInfo prom_info = {
! 692: .name = "openprom",
! 693: .parent = TYPE_SYS_BUS_DEVICE,
! 694: .instance_size = sizeof(PROMState),
! 695: .class_init = prom_class_init,
! 696: };
1.1.1.9 root 697:
698:
699: typedef struct RamDevice
700: {
701: SysBusDevice busdev;
1.1.1.13 root 702: MemoryRegion ram;
1.1.1.9 root 703: uint64_t size;
704: } RamDevice;
705:
706: /* System RAM */
707: static int ram_init1(SysBusDevice *dev)
708: {
709: RamDevice *d = FROM_SYSBUS(RamDevice, dev);
710:
1.1.1.14! root 711: memory_region_init_ram(&d->ram, "sun4u.ram", d->size);
! 712: vmstate_register_ram_global(&d->ram);
! 713: sysbus_init_mmio(dev, &d->ram);
1.1.1.9 root 714: return 0;
715: }
716:
717: static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size)
718: {
719: DeviceState *dev;
720: SysBusDevice *s;
721: RamDevice *d;
722:
723: /* allocate RAM */
724: dev = qdev_create(NULL, "memory");
725: s = sysbus_from_qdev(dev);
726:
727: d = FROM_SYSBUS(RamDevice, s);
728: d->size = RAM_size;
729: qdev_init_nofail(dev);
730:
731: sysbus_mmio_map(s, 0, addr);
732: }
733:
1.1.1.14! root 734: static Property ram_properties[] = {
! 735: DEFINE_PROP_UINT64("size", RamDevice, size, 0),
! 736: DEFINE_PROP_END_OF_LIST(),
1.1.1.9 root 737: };
738:
1.1.1.14! root 739: static void ram_class_init(ObjectClass *klass, void *data)
1.1.1.9 root 740: {
1.1.1.14! root 741: DeviceClass *dc = DEVICE_CLASS(klass);
! 742: SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
! 743:
! 744: k->init = ram_init1;
! 745: dc->props = ram_properties;
1.1.1.9 root 746: }
747:
1.1.1.14! root 748: static TypeInfo ram_info = {
! 749: .name = "memory",
! 750: .parent = TYPE_SYS_BUS_DEVICE,
! 751: .instance_size = sizeof(RamDevice),
! 752: .class_init = ram_class_init,
! 753: };
1.1.1.9 root 754:
1.1.1.14! root 755: static CPUSPARCState *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
1.1.1.9 root 756: {
1.1.1.14! root 757: CPUSPARCState *env;
1.1.1.7 root 758: ResetData *reset_info;
1.1 root 759:
1.1.1.10 root 760: uint32_t tick_frequency = 100*1000000;
761: uint32_t stick_frequency = 100*1000000;
762: uint32_t hstick_frequency = 100*1000000;
763:
1.1.1.7 root 764: if (!cpu_model)
765: cpu_model = hwdef->default_cpu_model;
1.1.1.6 root 766: env = cpu_init(cpu_model);
767: if (!env) {
768: fprintf(stderr, "Unable to find Sparc CPU definition\n");
769: exit(1);
770: }
1.1.1.10 root 771:
772: env->tick = cpu_timer_create("tick", env, tick_irq,
773: tick_frequency, TICK_NPT_MASK);
774:
775: env->stick = cpu_timer_create("stick", env, stick_irq,
776: stick_frequency, TICK_INT_DIS);
777:
778: env->hstick = cpu_timer_create("hstick", env, hstick_irq,
779: hstick_frequency, TICK_INT_DIS);
1.1.1.7 root 780:
1.1.1.13 root 781: reset_info = g_malloc0(sizeof(ResetData));
1.1.1.7 root 782: reset_info->env = env;
1.1.1.9 root 783: reset_info->prom_addr = hwdef->prom_addr;
1.1.1.7 root 784: qemu_register_reset(main_cpu_reset, reset_info);
1.1.1.2 root 785:
1.1.1.9 root 786: return env;
787: }
1.1 root 788:
1.1.1.13 root 789: static void sun4uv_init(MemoryRegion *address_space_mem,
790: ram_addr_t RAM_size,
1.1.1.9 root 791: const char *boot_devices,
792: const char *kernel_filename, const char *kernel_cmdline,
793: const char *initrd_filename, const char *cpu_model,
794: const struct hwdef *hwdef)
795: {
1.1.1.14! root 796: CPUSPARCState *env;
1.1.1.10 root 797: M48t59State *nvram;
1.1.1.9 root 798: unsigned int i;
1.1.1.14! root 799: uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
1.1.1.9 root 800: PCIBus *pci_bus, *pci_bus2, *pci_bus3;
1.1.1.14! root 801: ISABus *isa_bus;
! 802: qemu_irq *ivec_irqs, *pbm_irqs;
1.1.1.9 root 803: DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
804: DriveInfo *fd[MAX_FD];
805: void *fw_cfg;
1.1 root 806:
1.1.1.9 root 807: /* init CPUs */
808: env = cpu_devinit(cpu_model, hwdef);
1.1 root 809:
1.1.1.9 root 810: /* set up devices */
811: ram_init(0, RAM_size);
812:
813: prom_init(hwdef->prom_addr, bios_name);
1.1 root 814:
1.1.1.14! root 815: ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, env, IVEC_MAX);
! 816: pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2,
! 817: &pci_bus3, &pbm_irqs);
1.1.1.11 root 818: pci_vga_init(pci_bus);
1.1.1.7 root 819:
820: // XXX Should be pci_bus3
1.1.1.14! root 821: isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs);
1.1.1.7 root 822:
823: i = 0;
824: if (hwdef->console_serial_base) {
1.1.1.13 root 825: serial_mm_init(address_space_mem, hwdef->console_serial_base, 0,
826: NULL, 115200, serial_hds[i], DEVICE_BIG_ENDIAN);
1.1.1.7 root 827: i++;
828: }
829: for(; i < MAX_SERIAL_PORTS; i++) {
1.1 root 830: if (serial_hds[i]) {
1.1.1.14! root 831: serial_isa_init(isa_bus, i, serial_hds[i]);
1.1 root 832: }
833: }
834:
835: for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
836: if (parallel_hds[i]) {
1.1.1.14! root 837: parallel_init(isa_bus, i, parallel_hds[i]);
1.1 root 838: }
839: }
840:
1.1.1.7 root 841: for(i = 0; i < nb_nics; i++)
1.1.1.9 root 842: pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
1.1 root 843:
1.1.1.12 root 844: ide_drive_get(hd, MAX_IDE_BUS);
1.1.1.6 root 845:
1.1.1.7 root 846: pci_cmd646_ide_init(pci_bus, hd, 1);
847:
1.1.1.14! root 848: isa_create_simple(isa_bus, "i8042");
1.1.1.6 root 849: for(i = 0; i < MAX_FD; i++) {
1.1.1.9 root 850: fd[i] = drive_get(IF_FLOPPY, 0, i);
1.1.1.6 root 851: }
1.1.1.14! root 852: fdctrl_init_isa(isa_bus, fd);
! 853: nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59);
1.1.1.9 root 854:
855: initrd_size = 0;
1.1.1.14! root 856: initrd_addr = 0;
1.1.1.9 root 857: kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,
1.1.1.14! root 858: ram_size, &initrd_size, &initrd_addr,
! 859: &kernel_addr, &kernel_entry);
1.1.1.9 root 860:
1.1.1.7 root 861: sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
1.1.1.14! root 862: kernel_addr, kernel_size,
1.1.1.7 root 863: kernel_cmdline,
1.1.1.14! root 864: initrd_addr, initrd_size,
1.1.1.7 root 865: /* XXX: need an option to load a NVRAM image */
866: 0,
867: graphic_width, graphic_height, graphic_depth,
868: (uint8_t *)&nd_table[0].macaddr);
869:
870: fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
871: fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
872: fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
873: fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
1.1.1.14! root 874: fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
! 875: fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
1.1.1.8 root 876: if (kernel_cmdline) {
1.1.1.10 root 877: fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
878: strlen(kernel_cmdline) + 1);
879: fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
880: (uint8_t*)strdup(kernel_cmdline),
881: strlen(kernel_cmdline) + 1);
1.1.1.8 root 882: } else {
1.1.1.10 root 883: fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
1.1.1.8 root 884: }
1.1.1.14! root 885: fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
! 886: fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
1.1.1.8 root 887: fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);
1.1.1.9 root 888:
889: fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
890: fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
891: fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth);
892:
1.1.1.8 root 893: qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
1.1.1.7 root 894: }
895:
896: enum {
897: sun4u_id = 0,
898: sun4v_id = 64,
899: niagara_id,
900: };
1.1 root 901:
1.1.1.7 root 902: static const struct hwdef hwdefs[] = {
903: /* Sun4u generic PC-like machine */
904: {
1.1.1.10 root 905: .default_cpu_model = "TI UltraSparc IIi",
1.1.1.7 root 906: .machine_id = sun4u_id,
907: .prom_addr = 0x1fff0000000ULL,
908: .console_serial_base = 0,
909: },
910: /* Sun4v generic PC-like machine */
911: {
912: .default_cpu_model = "Sun UltraSparc T1",
913: .machine_id = sun4v_id,
914: .prom_addr = 0x1fff0000000ULL,
915: .console_serial_base = 0,
916: },
917: /* Sun4v generic Niagara machine */
918: {
919: .default_cpu_model = "Sun UltraSparc T1",
920: .machine_id = niagara_id,
921: .prom_addr = 0xfff0000000ULL,
922: .console_serial_base = 0xfff0c2c000ULL,
923: },
924: };
925:
926: /* Sun4u hardware initialisation */
1.1.1.8 root 927: static void sun4u_init(ram_addr_t RAM_size,
1.1.1.7 root 928: const char *boot_devices,
929: const char *kernel_filename, const char *kernel_cmdline,
930: const char *initrd_filename, const char *cpu_model)
931: {
1.1.1.13 root 932: sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
1.1.1.7 root 933: kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]);
934: }
935:
936: /* Sun4v hardware initialisation */
1.1.1.8 root 937: static void sun4v_init(ram_addr_t RAM_size,
1.1.1.7 root 938: const char *boot_devices,
939: const char *kernel_filename, const char *kernel_cmdline,
940: const char *initrd_filename, const char *cpu_model)
941: {
1.1.1.13 root 942: sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
1.1.1.7 root 943: kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
944: }
945:
946: /* Niagara hardware initialisation */
1.1.1.8 root 947: static void niagara_init(ram_addr_t RAM_size,
1.1.1.7 root 948: const char *boot_devices,
949: const char *kernel_filename, const char *kernel_cmdline,
950: const char *initrd_filename, const char *cpu_model)
951: {
1.1.1.13 root 952: sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
1.1.1.7 root 953: kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
1.1 root 954: }
955:
1.1.1.8 root 956: static QEMUMachine sun4u_machine = {
1.1.1.7 root 957: .name = "sun4u",
958: .desc = "Sun4u platform",
959: .init = sun4u_init,
960: .max_cpus = 1, // XXX for now
1.1.1.8 root 961: .is_default = 1,
1.1.1.7 root 962: };
963:
1.1.1.8 root 964: static QEMUMachine sun4v_machine = {
1.1.1.7 root 965: .name = "sun4v",
966: .desc = "Sun4v platform",
967: .init = sun4v_init,
968: .max_cpus = 1, // XXX for now
969: };
970:
1.1.1.8 root 971: static QEMUMachine niagara_machine = {
1.1.1.7 root 972: .name = "Niagara",
973: .desc = "Sun4v platform, Niagara",
974: .init = niagara_init,
975: .max_cpus = 1, // XXX for now
1.1 root 976: };
1.1.1.8 root 977:
1.1.1.14! root 978: static void sun4u_register_types(void)
! 979: {
! 980: type_register_static(&ebus_info);
! 981: type_register_static(&prom_info);
! 982: type_register_static(&ram_info);
! 983: }
! 984:
1.1.1.8 root 985: static void sun4u_machine_init(void)
986: {
987: qemu_register_machine(&sun4u_machine);
988: qemu_register_machine(&sun4v_machine);
989: qemu_register_machine(&niagara_machine);
990: }
991:
1.1.1.14! root 992: type_init(sun4u_register_types)
1.1.1.8 root 993: machine_init(sun4u_machine_init);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.