diff -ruN qemu/Makefile qemu-solaris/Makefile --- qemu/Makefile 2006-04-23 13:57:59.000000000 -0400 +++ qemu-solaris/Makefile 2006-04-27 20:49:08.299867000 -0400 @@ -4,6 +4,9 @@ ifdef CONFIG_DARWIN CFLAGS+= -mdynamic-no-pic endif +ifeq ($(ARCH),sparc) +CFLAGS+=-mcpu=ultrasparc +endif LDFLAGS=-g LIBS= DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE diff -ruN qemu/Makefile.target qemu-solaris/Makefile.target --- qemu/Makefile.target 2006-04-27 19:15:07.000000000 -0400 +++ qemu-solaris/Makefile.target 2006-04-27 20:51:14.468478000 -0400 @@ -107,6 +107,11 @@ endif ifeq ($(ARCH),sparc) +ifeq ($(CONFIG_SOLARIS),yes) +CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g2 -ffixed-g3 +LDFLAGS+=-m32 +OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -fno-omit-frame-pointer -ffixed-i0 +else CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6 LDFLAGS+=-m32 OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0 @@ -114,6 +119,7 @@ # -static is used to avoid g1/g3 usage by the dynamic linker LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static endif +endif ifeq ($(ARCH),sparc64) CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6 diff -ruN qemu/cpu-exec.c qemu-solaris/cpu-exec.c --- qemu/cpu-exec.c 2006-04-27 17:05:14.000000000 -0400 +++ qemu-solaris/cpu-exec.c 2006-04-28 02:22:03.576500000 -0400 @@ -253,7 +253,7 @@ uint32_t *saved_regwptr; #endif #endif -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) int saved_i7, tmp_T0; #endif int ret, interrupt_request; @@ -323,7 +323,7 @@ #if defined(reg_T2) saved_T2 = T2; #endif -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) /* we also save i7 because longjmp may not restore it */ asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); #endif @@ -447,7 +447,7 @@ T0 = 0; /* force lookup of first TB */ for(;;) { -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) /* g1 can be modified by some libc? functions */ tmp_T0 = T0; #endif @@ -467,7 +467,7 @@ do_interrupt(intno, 0, 0, 0, 1); /* ensure that no TB jump will be modified as the program flow was changed */ -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) tmp_T0 = 0; #else T0 = 0; @@ -486,7 +486,7 @@ env->error_code = 0; do_interrupt(env); env->interrupt_request &= ~CPU_INTERRUPT_HARD; -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) tmp_T0 = 0; #else T0 = 0; @@ -497,7 +497,7 @@ env->error_code = 0; do_interrupt(env); env->interrupt_request &= ~CPU_INTERRUPT_TIMER; -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) tmp_T0 = 0; #else T0 = 0; @@ -516,7 +516,7 @@ env->error_code = 0; do_interrupt(env); env->interrupt_request &= ~CPU_INTERRUPT_HARD; -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) tmp_T0 = 0; #else T0 = 0; @@ -534,7 +534,7 @@ env->interrupt_request &= ~CPU_INTERRUPT_HARD; do_interrupt(env->interrupt_index); env->interrupt_index = 0; -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) tmp_T0 = 0; #else T0 = 0; @@ -565,7 +565,7 @@ env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; /* ensure that no TB jump will be modified as the program flow was changed */ -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) tmp_T0 = 0; #else T0 = 0; @@ -633,7 +633,7 @@ lookup_symbol(tb->pc)); } #endif -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) T0 = tmp_T0; #endif /* see if we can patch the calling TB. When the TB @@ -669,7 +669,9 @@ "mov %%o7,%%i0" : /* no outputs */ : "r" (gen_func) - : "i0", "i1", "i2", "i3", "i4", "i5"); + : "i0", "i1", "i2", "i3", "i4", "i5", + "l0", "l1", "l2", "l3", "l4", "l5", + "l6", "l7"); #elif defined(__arm__) asm volatile ("mov pc, %0\n\t" ".global exec_loop\n\t" @@ -834,7 +836,7 @@ #else #error unsupported target CPU #endif -#ifdef __sparc__ +#if defined(__sparc__) && !defined(SOLARISREV) asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); #endif T0 = saved_T0; diff -ruN qemu/dyngen-exec.h qemu-solaris/dyngen-exec.h --- qemu/dyngen-exec.h 2006-04-25 18:36:06.000000000 -0400 +++ qemu-solaris/dyngen-exec.h 2006-04-27 21:04:58.187059000 -0400 @@ -121,6 +121,13 @@ #define AREG3 "s2" #endif #ifdef __sparc__ +#ifdef SOLARISREV +#define AREG0 "g2" +#define AREG1 "g3" +#define AREG2 "g4" +#define AREG3 "g5" +#define AREG4 "g6" +#else #define AREG0 "g6" #define AREG1 "g1" #define AREG2 "g2" @@ -133,6 +140,7 @@ #define AREG9 "l5" #define AREG10 "l6" #define AREG11 "l7" +#endif #define USE_FP_CONVERT #endif #ifdef __s390__ @@ -241,10 +249,8 @@ ASM_NAME(__op_gen_label) #n) #endif #ifdef __sparc__ -#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0\n" \ - "nop") -#define GOTO_LABEL_PARAM(n) asm volatile ( \ - "set " ASM_NAME(__op_gen_label) #n ", %g1; jmp %g1; nop") +#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop") +#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop") #endif #ifdef __arm__ #define EXIT_TB() asm volatile ("b exec_loop") diff -ruN qemu/dyngen.c qemu-solaris/dyngen.c --- qemu/dyngen.c 2006-04-24 16:32:17.000000000 -0400 +++ qemu-solaris/dyngen.c 2006-04-28 04:17:44.774951000 -0400 @@ -1196,7 +1196,7 @@ } else { #ifdef HOST_SPARC if (sym_name[0] == '.') - snprintf(name, sizeof(name), + snprintf(name, name_size, "(long)(&__dot_%s)", sym_name + 1); else @@ -1440,6 +1440,12 @@ } #elif defined(HOST_SPARC) { +#define INSN_SAVE 0x9de3a000 +#define INSN_RET 0x81c7e008 +#define INSN_RESTORE 0x81e80000 +#define INSN_RETURN 0x81cfe008 +#define INSN_NOP 0x01000000 + uint32_t start_insn, end_insn1, end_insn2; uint8_t *p; p = (void *)(p_end - 8); @@ -1448,12 +1454,17 @@ start_insn = get32((uint32_t *)(p_start + 0x0)); end_insn1 = get32((uint32_t *)(p + 0x0)); end_insn2 = get32((uint32_t *)(p + 0x4)); - if ((start_insn & ~0x1fff) == 0x9de3a000) { + if ((start_insn & ~0x1fff) == INSN_SAVE) { p_start += 0x4; start_offset += 0x4; if ((int)(start_insn | ~0x1fff) < -128) error("Found bogus save at the start of %s", name); - if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000) + if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE) + /* SPARC v7: ret; restore; */ ; + else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP) + /* SPARC v9: return; nop; */ ; + else + error("ret; restore; not found at end of %s", name); } else { error("No save at the beginning of %s", name); @@ -1462,7 +1473,7 @@ /* Skip a preceeding nop, if present. */ if (p > p_start) { skip_insn = get32((uint32_t *)(p - 0x4)); - if (skip_insn == 0x01000000) + if (skip_insn == INSN_NOP) p -= 4; } #endif @@ -2151,6 +2162,18 @@ reloc_offset, reloc_offset, name, addend, reloc_offset); break; + case R_SPARC_WDISP22: + fprintf(outfile, + " *(uint32_t *)(gen_code_ptr + %d) = " + "((*(uint32_t *)(gen_code_ptr + %d)) " + " & ~0x3fffff) " + " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) " + " & 0x3fffff);\n", + rel->r_offset - start_offset, + rel->r_offset - start_offset, + name, addend, + rel->r_offset - start_offset); + break; default: error("unsupported sparc relocation (%d)", type); } diff -ruN qemu/dyngen.h qemu-solaris/dyngen.h --- qemu/dyngen.h 2006-04-24 16:32:17.000000000 -0400 +++ qemu-solaris/dyngen.h 2006-04-27 21:11:26.701363000 -0400 @@ -19,7 +19,13 @@ */ int __op_param1, __op_param2, __op_param3; -int __op_gen_label1, __op_gen_label2, __op_gen_label3; +#ifdef __sparc__ + void __op_gen_label1(){} + void __op_gen_label2(){} + void __op_gen_label3(){} +#else + int __op_gen_label1, __op_gen_label2, __op_gen_label3; +#endif int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; #ifdef __i386__ diff -ruN qemu/hw/apic.c qemu-solaris/hw/apic.c --- qemu/hw/apic.c 2005-12-16 20:27:28.000000000 -0500 +++ qemu-solaris/hw/apic.c 2006-04-28 00:59:32.507902000 -0400 @@ -108,7 +108,7 @@ unsigned int ret = 0; #if defined(HOST_I386) - __asm__ __volatile__ ("bsr %1, %0\n" : "+r" (ret) : "rm" (value)); + __asm__ __volatile__ ("bsrl %1, %0\n" : "+r" (ret) : "rm" (value)); return ret; #else if (value > 0xffff) @@ -129,7 +129,7 @@ unsigned int ret = 0; #if defined(HOST_I386) - __asm__ __volatile__ ("bsf %1, %0\n" : "+r" (ret) : "rm" (value)); + __asm__ __volatile__ ("bsfl %1, %0\n" : "+r" (ret) : "rm" (value)); return ret; #else if (!value) diff -ruN qemu/hw/es1370.c qemu-solaris/hw/es1370.c --- qemu/hw/es1370.c 2005-11-20 11:20:39.000000000 -0500 +++ qemu-solaris/hw/es1370.c 2006-04-28 01:02:25.180345000 -0400 @@ -479,9 +479,10 @@ IO_WRITE_PROTO (es1370_writeb) { ES1370State *s = opaque; - addr = es1370_fixup (s, addr); uint32_t shift, mask; + addr = es1370_fixup (s, addr); + switch (addr) { case ES1370_REG_CONTROL: case ES1370_REG_CONTROL + 1: @@ -516,9 +517,11 @@ IO_WRITE_PROTO (es1370_writew) { ES1370State *s = opaque; - addr = es1370_fixup (s, addr); uint32_t shift, mask; - struct chan *d = &s->chan[0]; + struct chan *d; + + addr = es1370_fixup (s, addr); + d = &s->chan[0]; switch (addr) { case ES1370_REG_CODEC: diff -ruN qemu/hw/ide.c qemu-solaris/hw/ide.c --- qemu/hw/ide.c 2006-04-25 17:24:22.000000000 -0400 +++ qemu-solaris/hw/ide.c 2006-04-28 01:30:59.548829000 -0400 @@ -391,6 +391,10 @@ } PCIIDEState; static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); +static int ide_atapi_cmd_read_dma_cb(IDEState *s, + target_phys_addr_t phys_addr, + int transfer_size1); + static void padstr(char *str, const char *src, int len) { @@ -513,10 +517,17 @@ padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */ padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */ put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */ +#ifdef __sun__ + put_le16(p + 49, 1 << 8 | 1 << 9); /* DMA and LBA supported */ + put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */ + put_le16(p + 63, 0x07 | 0x4 << 8); /* Multiword DMA supported/selected */ + put_le16(p + 64, 0x03); /* PIO modes 3,4 supported */ +#else put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */ put_le16(p + 53, 3); /* words 64-70, 54-58 valid */ put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */ put_le16(p + 64, 1); /* PIO modes */ +#endif put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */ put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */ put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */ @@ -994,8 +1005,14 @@ s->elementary_transfer_size = 0; s->io_buffer_index = 0; - s->status = READY_STAT; - ide_atapi_cmd_reply_end(s); + if (s->atapi_dma) { + s->status = READY_STAT | DRQ_STAT; + ide_dma_start(s, ide_atapi_cmd_read_dma_cb); + } else { + s->status = READY_STAT; + ide_atapi_cmd_reply_end(s); + } + } /* start a CD-CDROM read command */ @@ -1026,14 +1043,19 @@ #endif if (s->packet_transfer_size <= 0) break; - len = s->cd_sector_size - s->io_buffer_index; - if (len <= 0) { - /* transfert next data */ - cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size); - s->lba++; - s->io_buffer_index = 0; - len = s->cd_sector_size; + if (s->lba == -1) + len = s->packet_transfer_size; + else { + len = s->cd_sector_size - s->io_buffer_index; + if (len <= 0) { + /* transfert next data */ + cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size); + s->lba++; + s->io_buffer_index = 0; + len = s->cd_sector_size; + } } + if (len > transfer_size) len = transfer_size; cpu_physical_memory_write(phys_addr, @@ -2488,6 +2510,11 @@ cmd646_set_irq, d, 1); } +// PCI 0x04: command(word), 0x06(word): status +#define PCI_COMMAND_IOACCESS 0x0001 +#define PCI_COMMAND_MEMACCESS 0x0002 +#define PCI_COMMAND_BUSMASTER 0x0004 + /* hd_table must contain 4 block drivers */ /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) @@ -2507,7 +2534,9 @@ pci_conf[0x01] = 0x80; pci_conf[0x02] = 0x10; pci_conf[0x03] = 0x70; - pci_conf[0x09] = 0x80; // legacy ATA mode + pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS \ + | PCI_COMMAND_BUSMASTER; + pci_conf[0x09] = 0x8a; // programming interface = PCI_IDE bus master is supported pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage pci_conf[0x0e] = 0x00; // header_type diff -ruN qemu/slirp/mbuf.c qemu-solaris/slirp/mbuf.c --- qemu/slirp/mbuf.c 2004-04-21 20:10:47.000000000 -0400 +++ qemu-solaris/slirp/mbuf.c 2006-04-28 01:27:54.732625000 -0400 @@ -146,16 +146,18 @@ struct mbuf *m; int size; { + int datasize; + /* some compiles throw up on gotos. This one we can fake. */ if(m->m_size>size) return; if (m->m_flags & M_EXT) { - /* datasize = m->m_data - m->m_ext; */ + datasize = m->m_data - m->m_ext; m->m_ext = (char *)realloc(m->m_ext,size); /* if (m->m_ext == NULL) * return (struct mbuf *)NULL; */ - /* m->m_data = m->m_ext + datasize; */ + m->m_data = m->m_ext + datasize; } else { int datasize; char *dat; diff -ruN qemu/slirp/slirp.c qemu-solaris/slirp/slirp.c --- qemu/slirp/slirp.c 2006-04-23 15:41:17.000000000 -0400 +++ qemu-solaris/slirp/slirp.c 2006-04-28 04:12:46.302799000 -0400 @@ -137,6 +137,16 @@ } #endif +#if defined(SOLARISREV) && defined(__sparc__) + /* + * Tell the kernel to fix unaligned accesses for us. + * + * The slirp code accesses at least |struct ip| structures + * from unaligned addresses. + */ + asm("ta 6"); +#endif + link_up = 1; if_init(); diff -ruN qemu/target-mips/cpu.h qemu-solaris/target-mips/cpu.h --- qemu/target-mips/cpu.h 2006-03-11 11:23:39.000000000 -0500 +++ qemu-solaris/target-mips/cpu.h 2006-04-28 04:00:24.365813000 -0400 @@ -8,6 +8,12 @@ #include "config.h" #include "softfloat.h" +// uint_fast8_t and uint_fast16_t not in +#if defined(SOLARISREV) && SOLARISREV < 10 +typedef unsigned char uint_fast8_t; +typedef unsigned int uint_fast16_t; +#endif + typedef union fpr_t fpr_t; union fpr_t { double d; diff -ruN qemu/vl.c qemu-solaris/vl.c --- qemu/vl.c 2006-04-27 19:15:07.000000000 -0400 +++ qemu-solaris/vl.c 2006-04-27 21:14:03.238223000 -0400 @@ -535,6 +535,28 @@ return val; } +#elif defined(SOLARISREV) + +uint64_t cpu_get_real_ticks (void) +{ +#if defined(_LP64) + uint64_t rval; + asm volatile("rd %%tick,%0" : "=r"(rval)); + return rval; +#else + union { + uint64_t i64; + struct { + uint32_t high; + uint32_t low; + } i32; + } rval; + asm volatile("rd %%tick,%1; srlx %1,32,%0" + : "=r"(rval.i32.high), "=r"(rval.i32.low)); + return rval.i64; +#endif +} + #elif defined(__ia64) int64_t cpu_get_real_ticks(void)