diff options
-rw-r--r-- | audio/winwaveaudio.c | 12 | ||||
-rw-r--r-- | linux-user/main.c | 11 | ||||
-rw-r--r-- | linux-user/syscall.c | 11 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 8 | ||||
-rw-r--r-- | pc-bios/README | 2 | ||||
-rw-r--r-- | pc-bios/openbios-ppc | bin | 729876 -> 729908 bytes | |||
m--------- | roms/openbios | 0 | ||||
-rw-r--r-- | target-ppc/translate.c | 2 | ||||
-rw-r--r-- | tcg/mips/tcg-target.c | 158 |
9 files changed, 120 insertions, 84 deletions
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c index 663abb9b50..72babbf184 100644 --- a/audio/winwaveaudio.c +++ b/audio/winwaveaudio.c @@ -349,21 +349,15 @@ static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...) else { hw->poll_mode = 0; } - if (wave->paused) { - mr = waveOutRestart (wave->hwo); - if (mr != MMSYSERR_NOERROR) { - winwave_logerr (mr, "waveOutRestart"); - } - wave->paused = 0; - } + wave->paused = 0; } return 0; case VOICE_DISABLE: if (!wave->paused) { - mr = waveOutPause (wave->hwo); + mr = waveOutReset (wave->hwo); if (mr != MMSYSERR_NOERROR) { - winwave_logerr (mr, "waveOutPause"); + winwave_logerr (mr, "waveOutReset"); } else { wave->paused = 1; diff --git a/linux-user/main.c b/linux-user/main.c index 7dea084873..1a1c661ee4 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3222,7 +3222,7 @@ struct qemu_argument { const char *help; }; -struct qemu_argument arg_table[] = { +static const struct qemu_argument arg_table[] = { {"h", "", false, handle_arg_help, "", "print this help"}, {"g", "QEMU_GDB", true, handle_arg_gdb, @@ -3264,7 +3264,7 @@ struct qemu_argument arg_table[] = { static void usage(void) { - struct qemu_argument *arginfo; + const struct qemu_argument *arginfo; int maxarglen; int maxenvlen; @@ -3330,7 +3330,7 @@ static int parse_args(int argc, char **argv) { const char *r; int optind; - struct qemu_argument *arginfo; + const struct qemu_argument *arginfo; for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { if (arginfo->env == NULL) { @@ -3519,7 +3519,10 @@ int main(int argc, char **argv, char **envp) guest_base = init_guest_space(guest_base, reserved_va, 0, have_guest_base); if (guest_base == (unsigned long)-1) { - fprintf(stderr, "Unable to reserve guest address space\n"); + fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address " + "space for use as guest address space (check your virtual " + "memory ulimit setting or reserve less using -R option)\n", + reserved_va); exit(1); } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 11743065e9..6257a04d0a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7025,15 +7025,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, tde = target_dirp; while (len > 0) { reclen = de->d_reclen; - treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long))); + tnamelen = reclen - offsetof(struct linux_dirent, d_name); + assert(tnamelen >= 0); + treclen = tnamelen + offsetof(struct target_dirent, d_name); + assert(count1 + treclen <= count); tde->d_reclen = tswap16(treclen); tde->d_ino = tswapal(de->d_ino); tde->d_off = tswapal(de->d_off); - tnamelen = treclen - (2 * sizeof(abi_long) + 2); - if (tnamelen > 256) - tnamelen = 256; - /* XXX: may not be correct */ - pstrcpy(tde->d_name, tnamelen, de->d_name); + memcpy(tde->d_name, de->d_name, tnamelen); de = (struct linux_dirent *)((char *)de + reclen); len -= reclen; tde = (struct target_dirent *)((char *)tde + treclen); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 2cfda5afd5..a98cbf7b80 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -255,10 +255,10 @@ struct kernel_statfs { }; struct target_dirent { - abi_long d_ino; - abi_long d_off; - unsigned short d_reclen; - char d_name[256]; /* We must not include limits.h! */ + abi_long d_ino; + abi_long d_off; + unsigned short d_reclen; + char d_name[]; }; struct target_dirent64 { diff --git a/pc-bios/README b/pc-bios/README index fc07ebc21c..303713099e 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -12,7 +12,7 @@ 1275-1994 (referred to as Open Firmware) compliant firmware. The included images for PowerPC (for 32 and 64 bit PPC CPUs), Sparc32 and Sparc64 are built from OpenBIOS SVN revision - 1062. + 1063. - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc Binary files differindex 1c3753d3eb..5311eca691 100644 --- a/pc-bios/openbios-ppc +++ b/pc-bios/openbios-ppc diff --git a/roms/openbios b/roms/openbios -Subproject d1d2787f87167edf487a60e61b9168514d5a743 +Subproject f095c858136896d236931357b8d597f407286f7 diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 91eb7a062c..ac915ccade 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6530,7 +6530,7 @@ static void glue(gen_, name)(DisasContext *ctx) \ ra = gen_avr_ptr(rA(ctx->opcode)); \ rb = gen_avr_ptr(rB(ctx->opcode)); \ rd = gen_avr_ptr(rD(ctx->opcode)); \ - gen_helper_##name(rd, cpu_env, ra, rb); \ + gen_helper_##name(cpu_env, rd, ra, rb); \ tcg_temp_free_ptr(ra); \ tcg_temp_free_ptr(rb); \ tcg_temp_free_ptr(rd); \ diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 393ba07f25..1006e28000 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -217,6 +217,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) tcg_regset_set(ct->u.regs, 0xffffffff); #if defined(CONFIG_SOFTMMU) tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0); +# if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64) + tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2); +# endif #endif break; case 'S': /* qemu_st constraint */ @@ -224,10 +227,14 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) tcg_regset_set(ct->u.regs, 0xffffffff); tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0); #if defined(CONFIG_SOFTMMU) -# if TARGET_LONG_BITS == 64 +# if (defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 32) || \ + (!defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 64) tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1); # endif tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2); +# if defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 64 + tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3); +# endif #endif break; case 'I': @@ -382,7 +389,10 @@ static inline void tcg_out_nop(TCGContext *s) static inline void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { - tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO); + /* Simple reg-reg move, optimising out the 'do nothing' case */ + if (ret != arg) { + tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO); + } } static inline void tcg_out_movi(TCGContext *s, TCGType type, @@ -503,6 +513,67 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) } } +/* Helper routines for marshalling helper function arguments into + * the correct registers and stack. + * arg_num is where we want to put this argument, and is updated to be ready + * for the next call. arg is the argument itself. Note that arg_num 0..3 is + * real registers, 4+ on stack. + * + * We provide routines for arguments which are: immediate, 32 bit + * value in register, 16 and 8 bit values in register (which must be zero + * extended before use) and 64 bit value in a lo:hi register pair. + */ +#define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM) \ + static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM) \ + { \ + if (*arg_num < 4) { \ + DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \ + } else { \ + DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT); \ + tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num)); \ + } \ + (*arg_num)++; \ +} +#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \ + tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff); +DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg) +#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG +#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \ + tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff); +DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg) +#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG +#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \ + tcg_out_movi(s, TCG_TYPE_I32, A, arg); +DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, uint32_t arg) +#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG + +/* We don't use the macro for this one to avoid an unnecessary reg-reg + move when storing to the stack. */ +static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num, + TCGReg arg) +{ + if (*arg_num < 4) { + tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg); + } else { + tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num)); + } + (*arg_num)++; +} + +static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num, + TCGReg arg_low, TCGReg arg_high) +{ + (*arg_num) = (*arg_num + 1) & ~1; + +#if defined(TCG_TARGET_WORDS_BIGENDIAN) + tcg_out_call_iarg_reg32(s, arg_num, arg_high); + tcg_out_call_iarg_reg32(s, arg_num, arg_low); +#else + tcg_out_call_iarg_reg32(s, arg_num, arg_low); + tcg_out_call_iarg_reg32(s, arg_num, arg_high); +#endif +} + static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1, int arg2, int label_index) { @@ -792,18 +863,18 @@ static void *qemu_st_helpers[4] = { static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) { - int addr_regl, addr_reg1, addr_meml; + int addr_regl, addr_meml; int data_regl, data_regh, data_reg1, data_reg2; int mem_index, s_bits; #if defined(CONFIG_SOFTMMU) void *label1_ptr, *label2_ptr; - int sp_args; + int arg_num; #endif #if TARGET_LONG_BITS == 64 # if defined(CONFIG_SOFTMMU) uint8_t *label3_ptr; # endif - int addr_regh, addr_reg2, addr_memh; + int addr_regh, addr_memh; #endif data_regl = *args++; if (opc == 3) @@ -831,18 +902,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, } #if TARGET_LONG_BITS == 64 # if defined(TCG_TARGET_WORDS_BIGENDIAN) - addr_reg1 = addr_regh; - addr_reg2 = addr_regl; addr_memh = 0; addr_meml = 4; # else - addr_reg1 = addr_regl; - addr_reg2 = addr_regh; addr_memh = 4; addr_meml = 0; # endif #else - addr_reg1 = addr_regl; addr_meml = 0; #endif @@ -875,22 +941,17 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, # endif /* slow path */ - sp_args = TCG_REG_A0; - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1); + arg_num = 0; +# ifdef CONFIG_TCG_PASS_AREG0 + tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0); +# endif # if TARGET_LONG_BITS == 64 - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2); + tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh); +# else + tcg_out_call_iarg_reg32(s, &arg_num, addr_regl); # endif - tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index); + tcg_out_call_iarg_imm32(s, &arg_num, mem_index); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]); -#ifdef CONFIG_TCG_PASS_AREG0 - /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */ - tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], - tcg_target_call_iarg_regs[1]); - tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1], - tcg_target_call_iarg_regs[0]); - tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], - TCG_AREG0); -#endif tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0); tcg_out_nop(s); @@ -991,18 +1052,18 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) { - int addr_regl, addr_reg1, addr_meml; + int addr_regl, addr_meml; int data_regl, data_regh, data_reg1, data_reg2; int mem_index, s_bits; #if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr; - int sp_args; + int arg_num; #endif #if TARGET_LONG_BITS == 64 # if defined(CONFIG_SOFTMMU) uint8_t *label3_ptr; # endif - int addr_regh, addr_reg2, addr_memh; + int addr_regh, addr_memh; #endif data_regl = *args++; @@ -1024,18 +1085,13 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, #if TARGET_LONG_BITS == 64 addr_regh = *args++; # if defined(TCG_TARGET_WORDS_BIGENDIAN) - addr_reg1 = addr_regh; - addr_reg2 = addr_regl; addr_memh = 0; addr_meml = 4; # else - addr_reg1 = addr_regl; - addr_reg2 = addr_regh; addr_memh = 4; addr_meml = 0; # endif #else - addr_reg1 = addr_regl; addr_meml = 0; #endif mem_index = *args; @@ -1070,49 +1126,33 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, # endif /* slow path */ - sp_args = TCG_REG_A0; - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1); + arg_num = 0; +# ifdef CONFIG_TCG_PASS_AREG0 + tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0); +# endif # if TARGET_LONG_BITS == 64 - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2); + tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh); +# else + tcg_out_call_iarg_reg32(s, &arg_num, addr_regl); # endif switch(opc) { case 0: - tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff); + tcg_out_call_iarg_reg8(s, &arg_num, data_regl); break; case 1: - tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff); + tcg_out_call_iarg_reg16(s, &arg_num, data_regl); break; case 2: - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1); + tcg_out_call_iarg_reg32(s, &arg_num, data_regl); break; case 3: - sp_args = (sp_args + 1) & ~1; - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1); - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2); + tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh); break; default: tcg_abort(); } - if (sp_args > TCG_REG_A3) { - /* Push mem_index on the stack */ - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index); - tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16); - } else { - tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index); - } - + tcg_out_call_iarg_imm32(s, &arg_num, mem_index); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]); -#ifdef CONFIG_TCG_PASS_AREG0 - /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */ - tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], - tcg_target_call_iarg_regs[2]); - tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2], - tcg_target_call_iarg_regs[1]); - tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1], - tcg_target_call_iarg_regs[0]); - tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], - TCG_AREG0); -#endif tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0); tcg_out_nop(s); |