sparc64 fixes
cover sparc64 fixes
assorted changes, linux kernel can now work with 32bit init task
---
Igor V. Kovalenko (8):
sparc64: fix tag access register on mmu traps
sparc64: fix missing address masking
sparc64: fix 32bit load sign extension
sparc64: fix ldxfsr insn
sparc64: use symbolic name for MMU index
sparc64: improve ldf and stf insns
sparc64: fix udiv and sdiv insns
sparc64: fix umul and smul insns
softmmu_header.h | 2 - target-sparc/helper.c | 5 ++ target-sparc/op_helper.c | 107 ++++++++++++++++++++++++++++++++++++++++------ target-sparc/translate.c | 65 ++++++++++++++++------------ 4 files changed, 137 insertions(+), 42 deletions(-)
PATCH 1/8 sparc64: fix tag access register on mmu traps
From: Igor V. Kovalenko <[email protected]>
- set mmu tag access register on FAULT and PROT traps as well
--- target-sparc/helper.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
target-sparc/helper.c +5 -0
@@ -495,6 +495,9 @@ static int get_physical_address_data(CPUState *env, env->dmmu.sfsr |= (fault_type <<7 ); env->dmmu.sfar = address;/* Fault address register */ + + env->dmmu.tag_access = (address & ~0x1fffULL ) | context; +return 1 ; } }
@@ -544,6 +547,8 @@ static int get_physical_address_code(CPUState *env, env->immu.sfsr |= (is_user <<3 ) |1 ; env->exception_index =TT_TFAULT ; + env->immu.tag_access = (address & ~0x1fffULL ) | context; +DPRINTF_MMU ("TFAULT at %" PRIx64" context %" PRIx64"\n" , address, context);
PATCH 2/8 sparc64: fix missing address masking
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
- address masking for ldqf and stqf insns
- address masking for lddf and stdf insns
- address masking for translating ASI (Ultrasparc IIi)
--- target-sparc/op_helper.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ target-sparc/translate.c | 4 ++++ 2 files changed, 51 insertions(+), 0 deletions(-)
target-sparc/op_helper.c +47 -0
@@ -2315,6 +2315,25 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)#else /* CONFIG_USER_ONLY */ +/* Ultrasparc IIi translating asi +- note this list is defined by cpu implementation +*/ +static inline int is_translating_asi (int asi) +{ +switch (asi) { + case 0x04 ... 0x11: + case 0x18 ... 0x19: + case 0x24 ... 0x2C: + case 0x70 ... 0x73: + case 0x78 ... 0x79: + case 0x80 ... 0xFF: +return 1 ; + +default : +return 0 ; + } +} +uint64_t helper_ld_asi (target_ulong addr,int asi,int size,int sign) {uint64_t ret =0 ;
@@ -2330,7 +2349,12 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) && !(env->hpstate & HS_PRIV)))raise_exception (TT_PRIV_ACT ); +if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + } +helper_check_align (addr, size -1 ); +switch (asi) {case 0x82 :// Primary no-fault case 0x8a :// Primary no-fault LE
@@ -2681,7 +2705,12 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) && !(env->hpstate & HS_PRIV)))raise_exception (TT_PRIV_ACT ); +if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + } +helper_check_align (addr, size -1 ); +/* Convert to little endian */ switch (asi) {case 0x0c :// Nucleus Little Endian (LE)
@@ -3056,6 +3085,12 @@ void helper_ldda_asi(target_ulong addr, int asi, int rd) && !(env->hpstate & HS_PRIV)))raise_exception (TT_PRIV_ACT ); +#if defined (CONFIG_SPARC64 ) +if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + } +#endif +switch (asi) {#if !defined(CONFIG_USER_ONLY )case 0x24 :// Nucleus quad LDD 128 bit atomic
@@ -3102,6 +3137,12 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)unsigned int i;target_ulong val; +#if defined (CONFIG_SPARC64 ) +if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + } +#endif +helper_check_align (addr,3 );switch (asi) {case 0xf0 :// Block load primary
@@ -3144,6 +3185,12 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)unsigned int i;target_ulong val =0 ; +#if defined (CONFIG_SPARC64 ) +if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + } +#endif +helper_check_align (addr,3 );switch (asi) {case 0xe0 :// UA2007 Block commit store primary (cache flush)
target-sparc/translate.c +4 -0
@@ -4490,6 +4490,7 @@ static void disas_sparc_insn(DisasContext * dc)CHECK_FPU_FEATURE (dc,FLOAT128 ); r_const =tcg_const_i32 (dc->mem_idx); +gen_address_mask (dc, cpu_addr);gen_helper_ldqf (cpu_addr, r_const);tcg_temp_free_i32 (r_const);gen_op_store_QT0_fpr (QFPREG (rd));
@@ -4500,6 +4501,7 @@ static void disas_sparc_insn(DisasContext * dc)TCGv_i32 r_const; r_const =tcg_const_i32 (dc->mem_idx); +gen_address_mask (dc, cpu_addr);gen_helper_lddf (cpu_addr, r_const);tcg_temp_free_i32 (r_const);gen_op_store_DT0_fpr (DFPREG (rd));
@@ -4635,6 +4637,7 @@ static void disas_sparc_insn(DisasContext * dc)CHECK_FPU_FEATURE (dc,FLOAT128 );gen_op_load_fpr_QT0 (QFPREG (rd)); r_const =tcg_const_i32 (dc->mem_idx); +gen_address_mask (dc, cpu_addr);gen_helper_stqf (cpu_addr, r_const);tcg_temp_free_i32 (r_const); }
@@ -4657,6 +4660,7 @@ static void disas_sparc_insn(DisasContext * dc)gen_op_load_fpr_DT0 (DFPREG (rd)); r_const =tcg_const_i32 (dc->mem_idx); +gen_address_mask (dc, cpu_addr);gen_helper_stdf (cpu_addr, r_const);tcg_temp_free_i32 (r_const); }
Re: [Qemu-devel] [PATCH 2/8] sparc64: fix missing address masking
target-sparc/op_helper.c uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) · line 2354
Quoted 3 lines · Igor V. Kovalenko
target-sparc/op_helper.c +3
-0+if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + }
I suggest that these be written instead as
if (is_translating_asi(asi)) {
addr = address_mask(addr);
}That should allow you to remove some of the ifdefs.
r~
Re: [Qemu-devel] [PATCH 2/8] sparc64: fix missing address masking
Quoted 5 lines · Richard Henderson
Quoted 3 lines · Igor V. Kovalenko
+ if ((
env->pstate&PS_AM) &&is_translating_asi(asi)) {
+ addr &=0xffffffffULL;
+ }
Quoted 7 lines
I suggest that these be written instead as
if (
is_translating_asi(asi)) {
addr =address_mask(addr);
}That should allow you to remove some of the ifdefs.
All address masking is done for sparc64 target only, sparc32 does not have the notion of translating asi.
I think it's better to do debug printf macro trick then but I see no real benefit at the moment.
Signature · 2 lines
Kind regards, Igor V. Kovalenko
Re: [Qemu-devel] [PATCH 2/8] sparc64: fix missing address masking
Quoted 8 lines · Igor Kovalenko
Quoted 7 lines · Richard Henderson
target-sparc/op_helper.c uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) · line 2354
Quoted 3 lines · Igor V. Kovalenko
target-sparc/op_helper.c +3
-0+if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + }I suggest that these be written instead as
Quoted 8 lines
Quoted 5 lines
if (is_translating_asi(asi)) { addr = address_mask(addr);}
That should allow you to remove some of the ifdefs.
All address masking is done for sparc64 target only, sparc32 does not have the notion of translating asi.
Of course I know that.
Quoted 1 line
I think it's better to do debug printf macro trick ...
... with no evidence. The compiler is happy to optimize away the entire if statement without having to resort to macros.
Quoted 1 line
... then but I see no real benefit at the moment.
Avoiding ifdefs isn't a benefit?
r~
Re: [Qemu-devel] [PATCH 2/8] sparc64: fix missing address masking
Quoted 20 lines · Richard Henderson
Quoted 8 lines · Igor Kovalenko
Quoted 7 lines · Richard Henderson
Quoted 3 lines · Igor V. Kovalenko
+ if ((
env->pstate&PS_AM) &&is_translating_asi(asi)) {
+ addr &=0xffffffffULL;
+ }I suggest that these be written instead as
Quoted 8 lines
Quoted 5 lines
if (
is_translating_asi(asi)) {
addr =address_mask(addr);
}That should allow you to remove some of the ifdefs.
All address masking is done for sparc64 target only, sparc32 does not have the notion of translating asi.
Of course I know that.
Quoted 8 lines
Quoted 1 line
I think it's better to do debug printf macro trick ...
... with no evidence. The compiler is happy to optimize away the entire if statement without having to resort to macros.
Quoted 1 line
... then but I see no real benefit at the moment.
Avoiding ifdefs isn't a benefit?
I agree macros would make the code more tidy, perhaps it could swallow both the check and the masking. The macro can be empty for Sparc32.
Re: [Qemu-devel] [PATCH 2/8] sparc64: fix missing address masking
Am 02.06.2010 um 18:10 schrieb Blue Swirl:
Quoted 21 lines · Richard Henderson
Quoted 20 lines · Igor Kovalenko
Quoted 8 lines · Richard Henderson
Quoted 7 lines · Igor V. Kovalenko
target-sparc/op_helper.c uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) · line 2354
Quoted 3 lines
target-sparc/op_helper.c +3
-0+if ((env->pstate &PS_AM ) &&is_translating_asi (asi)) { + addr &=0xffffffffULL ; + }I suggest that these be written instead as
Quoted 7 lines
Quoted 5 lines
if (is_translating_asi(asi)) { addr = address_mask(addr);}
That should allow you to remove some of the ifdefs.
I think it's better to do debug printf macro trick ...
... with no evidence. The compiler is happy to optimize away the entire if statement without having to resort to macros.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
... then but I see no real benefit at the moment.
Avoiding ifdefs isn't a benefit?
I agree macros would make the code more tidy, perhaps it could swallow both the check and the masking. The macro can be empty for Sparc32.
I usually prefer static inline functions over multi-line macros. Probably a matter of taste.
Re: [Qemu-devel] [PATCH 2/8] sparc64: fix missing address masking
Quoted 30 lines · Andreas Färber
Am 02.06.2010 um 18:10 schrieb Blue Swirl:
Quoted 28 lines · Richard Henderson
Quoted 27 lines · Igor Kovalenko
Quoted 12 lines
Quoted 9 lines · Richard Henderson
Quoted 4 lines · Igor V. Kovalenko
+ if ((
env->pstate&PS_AM) &&is_translating_asi(asi)) {
+ addr &=0xffffffffULL;
+ }I suggest that these be written instead as
Quoted 7 lines
Quoted 5 lines
if (
is_translating_asi(asi)) {
addr =address_mask(addr);
}That should allow you to remove some of the ifdefs.
I think it's better to do debug printf macro trick ...
... with no evidence. The compiler is happy to optimize away the entire if statement without having to resort to macros.
Quoted 1 line
... then but I see no real benefit at the moment.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Avoiding ifdefs isn't a benefit?
I agree macros would make the code more tidy, perhaps it could swallow both the check and the masking. The macro can be empty for Sparc32.
I usually prefer static inline functions over multi-line macros. Probably a matter of taste.
I'll resend this one updated to have less ifdefs.
Signature · 2 lines
Kind regards, Igor V. Kovalenko
Re: [Qemu-devel] [PATCH 2/8] sparc64: fix missing address masking
In reply to Richard HendersonQuoted 20 lines · Richard Henderson
Quoted 8 lines · Igor Kovalenko
Quoted 7 lines · Richard Henderson
Quoted 3 lines · Igor V. Kovalenko
+ if ((
env->pstate&PS_AM) &&is_translating_asi(asi)) {
+ addr &=0xffffffffULL;
+ }I suggest that these be written instead as
Quoted 8 lines
Quoted 5 lines
if (
is_translating_asi(asi)) {
addr =address_mask(addr);
}That should allow you to remove some of the ifdefs.
All address masking is done for sparc64 target only, sparc32 does not have the notion of translating asi.
Of course I know that.
Quoted 8 lines
Quoted 1 line
I think it's better to do debug printf macro trick ...
... with no evidence. The compiler is happy to optimize away the entire if statement without having to resort to macros.
Quoted 1 line
... then but I see no real benefit at the moment.
Avoiding ifdefs isn't a benefit?
Reading through the code you will have false evidence of possible extra steps taken by hardware we emulate.
Looking at sparcv8 docs it is clear that similar steps are done there as well so I'll drop ifdefs at call sites and redo the patch.
Signature · 2 lines
Kind regards, Igor V. Kovalenko
PATCH 3/8 sparc64: fix 32bit load sign extension
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
- change return type of ldl_* to uint32_t to prevent unwanted sign extension visible in sparc64 load alternate address space methods
- note this change makes ldl_* softmmu implementations match ldl_phys one
--- softmmu_header.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
softmmu_header.h +1 -1
@@ -60,7 +60,7 @@#if DATA_SIZE ==8 #define RES_TYPE uint64_t#else -#define RES_TYPE int +#define RES_TYPE uint32_t#endif #if ACCESS_TYPE == (NB_MMU_MODES +1 )
[Qemu-devel] Re: [PATCH 3/8] sparc64: fix 32bit load sign extension
Quoted 5 lines · Igor V. Kovalenko
From: Igor V. Kovalenko<[email protected]>
- change return type of ldl_* to
uint32_tto prevent unwanted sign extension visible in sparc64 load alternate address space methods
- note this change makes ldl_* softmmu implementations matchldl_physone
This patch breaks -kernel/-initrd.
Paolo
[Qemu-devel] Re: [PATCH 3/8] sparc64: fix 32bit load sign extension
Am 03.06.2010 um 15:18 schrieb Paolo Bonzini <[email protected]>:
Quoted 10 lines · Igor V. Kovalenko
Quoted 7 lines
From: Igor V. Kovalenko<[email protected]>
- change return type of ldl_* to
uint32_tto prevent unwanted sign extension
visible in sparc64 load alternate address space methods
- note this change makes ldl_* softmmu implementations matchldl_physoneThis patch breaks -kernel/-initrd.
Breaks it where and when?
Alex
Quoted 1 line
[Qemu-devel] Re: [PATCH 3/8] sparc64: fix 32bit load sign extension
Quoted 12 lines · Alexander Graf
Am 03.06.2010 um 15:18 schrieb Paolo Bonzini <[email protected]>:
Quoted 9 lines · Igor V. Kovalenko
Quoted 7 lines
From: Igor V. Kovalenko<[email protected]>
- change return type of ldl_* to
uint32_tto prevent unwanted sign extension
visible in sparc64 load alternate address space methods
- note this change makes ldl_* softmmu implementations matchldl_physone
Quoted 3 lines
Quoted 1 line
This patch breaks -kernel/-initrd.
Breaks it where and when?
x86_64 TCG reboots after the "Probing EDD" step.
Paolo
[Qemu-devel] Re: [PATCH 3/8] sparc64: fix 32bit load sign extension
Quoted 14 lines · Paolo Bonzini
Quoted 13 lines · Alexander Graf
Am 03.06.2010 um 15:18 schrieb Paolo Bonzini <[email protected]>:
Quoted 10 lines · Igor V. Kovalenko
Quoted 8 lines
From: Igor V. Kovalenko<[email protected]>
- change return type of ldl_* to
uint32_tto prevent unwanted sign extension
visible in sparc64 load alternate address space methods
- note this change makes ldl_* softmmu implementations matchldl_physone
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
This patch breaks -kernel/-initrd.
Breaks it where and when?
x86_64TCG reboots after the "Probing EDD" step.
My local build appears to work, qemu-system-x86_64 loads my gentoo linux setup. I use x86_64 host, gcc 4.4.3, qemu configured with ./configure --prefix=/inst --target-list=sparc64-softmmu,x86_64-softmmu
Signature · 2 lines
Kind regards, Igor V. Kovalenko
[Qemu-devel] Re: [PATCH 3/8] sparc64: fix 32bit load sign extension
Quoted 17 lines · Igor Kovalenko
Quoted 16 lines · Paolo Bonzini
Quoted 15 lines · Alexander Graf
Am 03.06.2010 um 15:18 schrieb Paolo Bonzini<[email protected]>:
Quoted 11 lines · Igor V. Kovalenko
Quoted 8 lines
From: Igor V. Kovalenko<[email protected]>
- change return type of ldl_* to
uint32_tto prevent unwanted sign extension
visible in sparc64 load alternate address space methods
- note this change makes ldl_* softmmu implementations matchldl_physoneThis patch breaks -kernel/-initrd.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
Breaks it where and when?
x86_64TCG reboots after the "Probing EDD" step.My local build appears to work, qemu-system-x86_64 loads my gentoo linux setup. I use
x86_64host, gcc 4.4.3, qemu configured with ./configure --prefix=/inst --target-list=sparc64-softmmu,x86_64-softmmu
Normal boot works. Only -kernel/-initrd fails.
Paolo
[Qemu-devel] Re: [PATCH 3/8] sparc64: fix 32bit load sign extension
Quoted 20 lines · Paolo Bonzini
Quoted 19 lines · Igor Kovalenko
Quoted 18 lines · Paolo Bonzini
Quoted 16 lines · Alexander Graf
Am 03.06.2010 um 15:18 schrieb Paolo Bonzini<[email protected]>:
Quoted 11 lines · Igor V. Kovalenko
Quoted 8 lines
From: Igor V. Kovalenko<[email protected]>
- change return type of ldl_* to
uint32_tto prevent unwanted sign extension
visible in sparc64 load alternate address space methods
- note this change makes ldl_* softmmu implementations matchldl_physoneThis patch breaks -kernel/-initrd.
Breaks it where and when?
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
x86_64TCG reboots after the "Probing EDD" step.My local build appears to work, qemu-system-x86_64 loads my gentoo linux setup.
I usex86_64host, gcc 4.4.3, qemu configured with ./configure --prefix=/inst --target-list=sparc64-softmmu,x86_64-softmmuNormal boot works. Only -kernel/-initrd fails.
Hmm, PEBKAC. Boot of Fedora and RHEL5 guests always fails, so it's not related to -kernel/-initrd. (Of course, without -kernel/-initrd it reboots into GRUB rather than looping quickly).
I've placed a failing vmlinuz at http://people.redhat.com/people/vmlinuz-fail -- if it fails it should reboot continuously. The failure happens pretty soon after the kernel starts running. The sequence is:
lock_kernel
-> __lock_kernel
-> preempt_disable
-> current_thread_info()
IN:
0xffffffff80063064: push %rbp 0xffffffff80063065: mov %rsp,%rbp 0xffffffff80063068: mov %gs:0x10,%rax 0xffffffff80063071: mov -0x1fc8(%rax),%eax 0xffffffff80063077: test $0x8,%al 0xffffffff80063079: je 0xffffffff800630a2
%rax is 0xffffffff803f1fd8, but it page faults with %cr2=0x00000000803f0010. The reason is that in the generated x86 assembly -0x1fc8 is erroneously zero extended:
0x4180347b: mov %rbp,%rbx 0x4180347e: mov $0xffffe038,%r12d 0x41803484: add %r12,%rbx
so it gives the wrong address:
(gdb) info reg rbp
rbp 0xffffffff803f1fd8 0xffffffff803f1fd8
(gdb) info reg r12
r12 0xffffe038 4294959160
(gdb) info reg rbx
rbx 0x803f0010 2151612432
From there it's obvious: general protection, double fault, general protection, triple fault.
So it's a TCG bug that is expecting ldl_* to sign extend. I'll send a patch after I come back from lunch.
Paolo
PATCH 1/1 target-i386: fix decoding of negative 4-byte displacements
Negative four byte displacements need to be sign-extended after c086b783eb7a578993d6d2ab62c4c2666800b63d. Do so.
---
There are quite a few other ldl's to audit after the patch (about 70 in target-*). Any volunteers? :-)
target-i386/translate.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
target-i386/translate.c +1 -1
@@ -2016,7 +2016,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_break ;default :case 2 : - disp =ldl_code (s->pc); + disp = (int32_t )ldl_code (s->pc); s->pc +=4 ;break ; }
Signature · 1 line
1.7.0.1
Re: [Qemu-devel] [PATCH] target-i386: fix decoding of negative 4-byte displacements
Quoted 2 lines · Paolo Bonzini
Negative four byte displacements need to be sign-extended after
c086b783eb7a578993d6d2ab62c4c2666800b63d. Do so.
Quoted 2 lines
There are quite a few other ldl's to audit after the patch (about 70 in target-*). Any volunteers? :-)
I've looked over all the uses of ldl_code. Thankfully 95% of them are immediately stored into an explicit 32-bit variable. I do not see any other problematic uses of that particular identifier.
r~
Blue Swirl
AppliedRe: [Qemu-devel] [PATCH] target-i386: fix decoding of negative 4-byte displacements
Thanks, applied.
Quoted 17 lines · Richard Henderson
Quoted 2 lines · Paolo Bonzini
Negative four byte displacements need to be sign-extended after
c086b783eb7a578993d6d2ab62c4c2666800b63d. Do so.Quoted 2 lines
There are quite a few other ldl's to audit after the patch (about 70 in target-*). Any volunteers? :-)
I've looked over all the uses of
ldl_code. Thankfully 95% of them are immediately stored into an explicit 32-bit variable. I do not see any other problematic uses of that particular identifier.r~
PATCH 4/8 sparc64: fix ldxfsr insn
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
- rearrange code to break from switch when appropriate
- allow deprecated ldfsr insn
--- target-sparc/translate.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
target-sparc/translate.c +5 -1
@@ -4476,7 +4476,11 @@ static void disas_sparc_insn(DisasContext * dc)if (rd ==1 ) {tcg_gen_qemu_ld64 (cpu_tmp64, cpu_addr, dc->mem_idx);gen_helper_ldxfsr (cpu_tmp64); - } else + }else { +tcg_gen_qemu_ld32u (cpu_tmp0, cpu_addr, dc->mem_idx); +tcg_gen_trunc_tl_i32 (cpu_tmp32, cpu_tmp0); +gen_helper_ldfsr (cpu_tmp32); + }#else {tcg_gen_qemu_ld32u (cpu_tmp32, cpu_addr, dc->mem_idx);
PATCH 5/8 sparc64: use symbolic name for MMU index
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
--- target-sparc/op_helper.c | 28 ++++++++++++++++------------ 1 files changed, 16 insertions(+), 12 deletions(-)
target-sparc/op_helper.c +16 -12
@@ -3322,18 +3322,19 @@ void helper_stdf(target_ulong addr, int mem_idx)helper_check_align (addr,7 );#if !defined(CONFIG_USER_ONLY )switch (mem_idx) { -case 0 : +case MMU_USER_IDX :stfq_user (addr,DT0 );break ; -case 1 : +case MMU_KERNEL_IDX :stfq_kernel (addr,DT0 );break ;#ifdef TARGET_SPARC64 -case 2 : +case MMU_HYPV_IDX :stfq_hypv (addr,DT0 );break ;#endif default : +printf ("helper_stdf: need to check MMU idx %d\n" , mem_idx);break ; }#else
@@ -3346,18 +3347,19 @@ void helper_lddf(target_ulong addr, int mem_idx)helper_check_align (addr,7 );#if !defined(CONFIG_USER_ONLY )switch (mem_idx) { -case 0 : +case MMU_USER_IDX :DT0 =ldfq_user (addr);break ; -case 1 : +case MMU_KERNEL_IDX :DT0 =ldfq_kernel (addr);break ;#ifdef TARGET_SPARC64 -case 2 : +case MMU_HYPV_IDX :DT0 =ldfq_hypv (addr);break ;#endif default : +printf ("helper_stdf: need to check MMU idx %d\n" , mem_idx);break ; }#else
@@ -3373,24 +3375,25 @@ void helper_ldqf(target_ulong addr, int mem_idx)helper_check_align (addr,7 );#if !defined(CONFIG_USER_ONLY )switch (mem_idx) { -case 0 : +case MMU_USER_IDX : u.ll.upper =ldq_user (addr); u.ll.lower =ldq_user (addr +8 );QT0 = u.q;break ; -case 1 : +case MMU_KERNEL_IDX : u.ll.upper =ldq_kernel (addr); u.ll.lower =ldq_kernel (addr +8 );QT0 = u.q;break ;#ifdef TARGET_SPARC64 -case 2 : +case MMU_HYPV_IDX : u.ll.upper =ldq_hypv (addr); u.ll.lower =ldq_hypv (addr +8 );QT0 = u.q;break ;#endif default : +printf ("helper_stdf: need to check MMU idx %d\n" , mem_idx);break ; }#else
@@ -3408,24 +3411,25 @@ void helper_stqf(target_ulong addr, int mem_idx)helper_check_align (addr,7 );#if !defined(CONFIG_USER_ONLY )switch (mem_idx) { -case 0 : +case MMU_USER_IDX : u.q =QT0 ;stq_user (addr, u.ll.upper);stq_user (addr +8 , u.ll.lower);break ; -case 1 : +case MMU_KERNEL_IDX : u.q =QT0 ;stq_kernel (addr, u.ll.upper);stq_kernel (addr +8 , u.ll.lower);break ;#ifdef TARGET_SPARC64 -case 2 : +case MMU_HYPV_IDX : u.q =QT0 ;stq_hypv (addr, u.ll.upper);stq_hypv (addr +8 , u.ll.lower);break ;#endif default : +printf ("helper_stdf: need to check MMU idx %d\n" , mem_idx);break ; }#else
Re: [Qemu-devel] [PATCH 5/8] sparc64: use symbolic name for MMU index
Quoted 29 lines · Igor V. Kovalenko
From: Igor V. Kovalenko <[email protected]>
Signed-off-by Igor V. Kovalenko <[email protected]>---
target-sparc/op_helper.c | 28 ++++++++++++++++------------1 files changed, 16 insertions(+), 12 deletions(-)target-sparc/op_helper.c +3
-3@@ -3322,18 +3322,19 @@ void helper_stdf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: stfq_user(addr, DT0); break; - case 1: + case MMU_KERNEL_IDX: stfq_kernel(addr, DT0); break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: stfq_hypv(addr, DT0); break; #endif
Quoted 2 lines
default:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx);
Are these going to be useful or just leftover debugging?
Quoted 21 lines
break;
}
#elsetarget-sparc/op_helper.c +3
-3@@ -3346,18 +3347,19 @@ void helper_lddf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: DT0 = ldfq_user(addr); break; - case 1: + case MMU_KERNEL_IDX: DT0 = ldfq_kernel(addr); break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: DT0 = ldfq_hypv(addr); break; #endif
Quoted 2 lines
default:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx);
The function name is not correct for this and other cases below.
Quoted 64 lines
break;
}
#elsetarget-sparc/op_helper.c +3
-3@@ -3373,24 +3375,25 @@ void helper_ldqf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: u.ll.upper = ldq_user(addr); u.ll.lower = ldq_user(addr + 8); QT0 = u.q; break; - case 1: + case MMU_KERNEL_IDX: u.ll.upper = ldq_kernel(addr); u.ll.lower = ldq_kernel(addr + 8); QT0 = u.q; break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: u.ll.upper = ldq_hypv(addr); u.ll.lower = ldq_hypv(addr + 8); QT0 = u.q; break; #endifdefault:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx); break;
}
#elsetarget-sparc/op_helper.c +3
-3@@ -3408,24 +3411,25 @@ void helper_stqf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: u.q = QT0; stq_user(addr, u.ll.upper); stq_user(addr + 8, u.ll.lower); break; - case 1: + case MMU_KERNEL_IDX: u.q = QT0; stq_kernel(addr, u.ll.upper); stq_kernel(addr + 8, u.ll.lower); break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: u.q = QT0; stq_hypv(addr, u.ll.upper); stq_hypv(addr + 8, u.ll.lower); break; #endifdefault:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx); break;
}
#else
Re: [Qemu-devel] [PATCH 5/8] sparc64: use symbolic name for MMU index
Quoted 115 lines · Blue Swirl
Quoted 29 lines · Igor V. Kovalenko
From: Igor V. Kovalenko <[email protected]>
Signed-off-by Igor V. Kovalenko <[email protected]>---
target-sparc/op_helper.c | 28 ++++++++++++++++------------1 files changed, 16 insertions(+), 12 deletions(-)target-sparc/op_helper.c +3
-3@@ -3322,18 +3322,19 @@ void helper_stdf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: stfq_user(addr, DT0); break; - case 1: + case MMU_KERNEL_IDX: stfq_kernel(addr, DT0); break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: stfq_hypv(addr, DT0); break; #endifQuoted 2 lines
default:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx);Are these going to be useful or just leftover debugging?
Quoted 21 lines
break;
}
#elsetarget-sparc/op_helper.c +3
-3@@ -3346,18 +3347,19 @@ void helper_lddf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: DT0 = ldfq_user(addr); break; - case 1: + case MMU_KERNEL_IDX: DT0 = ldfq_kernel(addr); break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: DT0 = ldfq_hypv(addr); break; #endifQuoted 2 lines
default:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx);The function name is not correct for this and other cases below.
Quoted 53 lines
break;
}
#elsetarget-sparc/op_helper.c +3
-3@@ -3373,24 +3375,25 @@ void helper_ldqf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: u.ll.upper = ldq_user(addr); u.ll.lower = ldq_user(addr + 8); QT0 = u.q; break; - case 1: + case MMU_KERNEL_IDX: u.ll.upper = ldq_kernel(addr); u.ll.lower = ldq_kernel(addr + 8); QT0 = u.q; break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: u.ll.upper = ldq_hypv(addr); u.ll.lower = ldq_hypv(addr + 8); QT0 = u.q; break; #endifdefault:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx); break;
}
#elsetarget-sparc/op_helper.c +3
-3@@ -3408,24 +3411,25 @@ void helper_stqf(target_ulong addr, int mem_idx) helper_check_align(addr, 7); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { - case 0: + case MMU_USER_IDX: u.q = QT0; stq_user(addr, u.ll.upper); stq_user(addr + 8, u.ll.lower); break; - case 1: + case MMU_KERNEL_IDX: u.q = QT0; stq_kernel(addr, u.ll.upper); stq_kernel(addr + 8, u.ll.lower); break; #ifdef TARGET_SPARC64 - case 2: + case MMU_HYPV_IDX: u.q = QT0; stq_hypv(addr, u.ll.upper);
Quoted 8 lines
Quoted 8 lines
target-sparc/op_helper.c +0
-0stq_hypv(addr + 8, u.ll.lower); break; #endifdefault:
+ printf("helper_stdf: need to check MMU idx %d\n",mem_idx); break;
}
#else
I'll fix names, turn printf into DPRINTF_MMU and resend.
Signature · 2 lines
Kind regards, Igor V. Kovalenko
PATCH 6/8 sparc64: improve ldf and stf insns
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
- implemented block load/store primary/secondary with user privilege
--- target-sparc/op_helper.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-)
target-sparc/op_helper.c +28 -0
@@ -3161,6 +3161,20 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) }return ; +case 0x70 :// Block load primary, user privilege +case 0x71 :// Block load secondary, user privilege +if (rd &7 ) { +raise_exception (TT_ILL_INSN ); +return ; + } +helper_check_align (addr,0x3f ); +for (i =0 ; i <16 ; i++) { + *(uint32_t *)&env->fpr[rd++] =helper_ld_asi (addr, asi &0x1f ,4 , +0 ); + addr +=4 ; + } + +return ;default :break ; }
@@ -3211,6 +3225,20 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) }return ; +case 0x70 :// Block store primary, user privilege +case 0x71 :// Block store secondary, user privilege +if (rd &7 ) { +raise_exception (TT_ILL_INSN ); +return ; + } +helper_check_align (addr,0x3f ); +for (i =0 ; i <16 ; i++) { + val = *(uint32_t *)&env->fpr[rd++]; +helper_st_asi (addr, val, asi &0x1f ,4 ); + addr +=4 ; + } + +return ;default :break ; }
PATCH 7/8 sparc64: fix udiv and sdiv insns
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
- truncate second operand to 32bit
--- target-sparc/op_helper.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
target-sparc/op_helper.c +2 -2
@@ -3307,7 +3307,7 @@ target_ulong helper_udiv(target_ulong a, target_ulong b)uint32_t x1; x0 = (a &0xffffffff ) | ((int64_t ) (env->y) <<32 ); - x1 = b; + x1 = (b &0xffffffff );if (x1 ==0 ) {raise_exception (TT_DIV_ZERO );
@@ -3329,7 +3329,7 @@ target_ulong helper_sdiv(target_ulong a, target_ulong b)int32_t x1; x0 = (a &0xffffffff ) | ((int64_t ) (env->y) <<32 ); - x1 = b; + x1 = (b &0xffffffff );if (x1 ==0 ) {raise_exception (TT_DIV_ZERO );
PATCH 8/8 sparc64: fix umul and smul insns
In reply to Igor V. KovalenkoFrom: Igor V. Kovalenko <[email protected]>
- truncate and sign or zero extend operands before multiplication
- factor out common code to gen_op_multiply() with parameter to sign/zero extend
- call gen_op_multiply from gen_op_umul and gen_op_smul
--- target-sparc/translate.c | 55 ++++++++++++++++++++++++---------------------- 1 files changed, 29 insertions(+), 26 deletions(-)
target-sparc/translate.c +29 -26
@@ -662,50 +662,53 @@ static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)tcg_gen_mov_tl (dst, cpu_cc_dst); } -static inline void gen_op_umul (TCGv dst,TCGv src1,TCGv src2) +static inline void gen_op_multiply (TCGv dst,TCGv src1,TCGv src2,int sign_ext) { +TCGv_i32 r_src1, r_src2;TCGv_i64 r_temp, r_temp2; + r_src1 =tcg_temp_new_i32 (); + r_src2 =tcg_temp_new_i32 (); + +tcg_gen_trunc_tl_i32 (r_src1, src1); +tcg_gen_trunc_tl_i32 (r_src2, src2); + r_temp =tcg_temp_new_i64 (); r_temp2 =tcg_temp_new_i64 (); -tcg_gen_extu_tl_i64 (r_temp, src2); -tcg_gen_extu_tl_i64 (r_temp2, src1); +if (sign_ext) { +tcg_gen_ext_i32_i64 (r_temp, r_src2); +tcg_gen_ext_i32_i64 (r_temp2, r_src1); + }else { +tcg_gen_extu_i32_i64 (r_temp, r_src2); +tcg_gen_extu_i32_i64 (r_temp2, r_src1); + } +tcg_gen_mul_i64 (r_temp2, r_temp, r_temp2);tcg_gen_shri_i64 (r_temp, r_temp2,32 );tcg_gen_trunc_i64_tl (cpu_tmp0, r_temp);tcg_temp_free_i64 (r_temp);tcg_gen_andi_tl (cpu_y, cpu_tmp0,0xffffffff ); -#ifdef TARGET_SPARC64 -tcg_gen_mov_i64 (dst, r_temp2); -#else +tcg_gen_trunc_i64_tl (dst, r_temp2); -#endif +tcg_temp_free_i64 (r_temp2); + +tcg_temp_free_i32 (r_src1); +tcg_temp_free_i32 (r_src2); } -static inline void gen_op_smul (TCGv dst,TCGv src1,TCGv src2) +static inline void gen_op_umul (TCGv dst,TCGv src1,TCGv src2) { -TCGv_i64 r_temp, r_temp2; - - r_temp =tcg_temp_new_i64 (); - r_temp2 =tcg_temp_new_i64 (); - -tcg_gen_ext_tl_i64 (r_temp, src2); -tcg_gen_ext_tl_i64 (r_temp2, src1); -tcg_gen_mul_i64 (r_temp2, r_temp, r_temp2); +/* zero-extend truncated operands before multiplication */ +gen_op_multiply (dst, src1, src2,0 ); +} -tcg_gen_shri_i64 (r_temp, r_temp2,32 ); -tcg_gen_trunc_i64_tl (cpu_tmp0, r_temp); -tcg_temp_free_i64 (r_temp); -tcg_gen_andi_tl (cpu_y, cpu_tmp0,0xffffffff ); -#ifdef TARGET_SPARC64 -tcg_gen_mov_i64 (dst, r_temp2); -#else -tcg_gen_trunc_i64_tl (dst, r_temp2); -#endif -tcg_temp_free_i64 (r_temp2); +static inline void gen_op_smul (TCGv dst,TCGv src1,TCGv src2) +{ +/* sign-extend truncated operands before multiplication */ +gen_op_multiply (dst, src1, src2,1 ); }#ifdef TARGET_SPARC64
Blue Swirl
AppliedThanks, applied all.
Quoted 24 lines · Igor V. Kovalenko
assorted changes, linux kernel can now work with 32bit init task
---
Igor V. Kovalenko (8):
sparc64: fix tag access register on mmu traps
sparc64: fix missing address masking
sparc64: fix 32bit load sign extension
sparc64: fix ldxfsr insn
sparc64: use symbolic name for MMU index
sparc64: improve ldf and stf insns
sparc64: fix udiv and sdiv insns
sparc64: fix umul and smul insnssoftmmu_header.h | 2 -
target-sparc/helper.c | 5 ++
target-sparc/op_helper.c | 107 ++++++++++++++++++++++++++++++++++++++++------target-sparc/translate.c| 65 ++++++++++++++++------------4 files changed, 137 insertions(+), 42 deletions(-)--