* Kernel freezes in r4k_flush_icache_range() with CONFIG_CPU_MIPS32_R2
@ 2005-12-20 2:57 Maxime Bizon
2005-12-20 11:47 ` Maciej W. Rozycki
0 siblings, 1 reply; 4+ messages in thread
From: Maxime Bizon @ 2005-12-20 2:57 UTC (permalink / raw)
To: linux-mips
Hello all,
I'm porting linux for a board with a R4KECr2. So far I was using
CONFIG_CPU_MIPS32_R1 and the kernel (2.6.14) was running well.
But I'm unable to get it working with CONFIG_CPU_MIPS32_R2, it freezes
somewhere in trap_init, more exactly in r4k_flush_icache_range().
Here is a snippet from the generated assembly code:
00002624 <r4k_flush_icache_range>:
2624: 27bdffd0 addiu sp,sp,-48
2628: 3c020000 lui v0,0x0
262c: afb30024 sw s3,36(sp)
2630: afb20020 sw s2,32(sp)
2634: afbf0028 sw ra,40(sp)
2638: afb1001c sw s1,28(sp)
263c: afb00018 sw s0,24(sp)
[...]
26a0: bc900000 cache 0x10,0(a0)
26a4: 1464fffd bne v1,a0,269c <r4k_flush_icache_range+0x78>
26a8: 3c020000 lui v0,0x0
26ac: 2442277c addiu v0,v0,10108 <----------
26b0: 00400408 jr.hb v0
26b4: 00000000 nop
[...]
272c: 8c43000c lw v1,12(v0)
2730: 0060f809 jalr v1
2734: 00000000 nop
2738: 3c020000 lui v0,0x0
273c: 2442277c addiu v0,v0,10108 <----------
2740: 00400408 jr.hb v0
2744: 00000000 nop
2748: 8fbf0028 lw ra,40(sp)
274c: 8fb30024 lw s3,36(sp)
2750: 8fb20020 lw s2,32(sp)
2754: 8fb1001c lw s1,28(sp)
2758: 8fb00018 lw s0,24(sp)
275c: 03e00008 jr ra
2760: 27bd0030 addiu sp,sp,48
2764: 3c020000 lui v0,0x0
2768: 8c430018 lw v1,24(v0)
276c: 0060f809 jalr v1
2770: 00000000 nop
2774: 0800099c j 2670 <r4k_flush_icache_range+0x4c>
2778: 3c030000 lui v1,0x0
0000277c <r4k_dma_cache_inv>:
[...]
At offset 0x26ac and 0x273c, we can see that instruction_hazard() got
duplicated due to inlining, and that the jr.hb is going to send us to
10108 (0x277C), outside the function...
The only way I managed to get a good value in v0 was by using -O0 and
making r4k_flush_icache_range return int.
Now I'm really not familiar with gcc inline assembly so I don't know if
this is a compiler bug or if something is missing in
instruction_hazard().
# mipsel-linux-gcc -v
Using built-in specs.
Target: mipsel-linux-uclibc
Configured
with: /home/work/buildroot/toolchain_build_mipsel/gcc-4.0.2/configure
--prefix=/opt/toolchains/mipsel-uclibc-0.9.28-gcc-4.0.2
--build=i386-pc-linux-gnu --host=i386-pc-linux-gnu
--target=mipsel-linux-uclibc --enable-languages=c,c++ --enable-shared
--disable-__cxa_atexit --enable-target-optspace --with-gnu-ld
--disable-nls --enable-threads --enable-multilib
Thread model: posix
gcc version 4.0.2
#
Thanks,
--
Maxime
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: Kernel freezes in r4k_flush_icache_range() with CONFIG_CPU_MIPS32_R2 2005-12-20 2:57 Kernel freezes in r4k_flush_icache_range() with CONFIG_CPU_MIPS32_R2 Maxime Bizon @ 2005-12-20 11:47 ` Maciej W. Rozycki 2005-12-22 2:31 ` Maxime Bizon 0 siblings, 1 reply; 4+ messages in thread From: Maciej W. Rozycki @ 2005-12-20 11:47 UTC (permalink / raw) To: Maxime Bizon; +Cc: linux-mips On Tue, 20 Dec 2005, Maxime Bizon wrote: > 272c: 8c43000c lw v1,12(v0) > 2730: 0060f809 jalr v1 > 2734: 00000000 nop > 2738: 3c020000 lui v0,0x0 > 273c: 2442277c addiu v0,v0,10108 <---------- > 2740: 00400408 jr.hb v0 > 2744: 00000000 nop > 2748: 8fbf0028 lw ra,40(sp) > 274c: 8fb30024 lw s3,36(sp) > 2750: 8fb20020 lw s2,32(sp) > 2754: 8fb1001c lw s1,28(sp) > 2758: 8fb00018 lw s0,24(sp) > 275c: 03e00008 jr ra > 2760: 27bd0030 addiu sp,sp,48 > 2764: 3c020000 lui v0,0x0 > 2768: 8c430018 lw v1,24(v0) > 276c: 0060f809 jalr v1 > 2770: 00000000 nop > 2774: 0800099c j 2670 <r4k_flush_icache_range+0x4c> > 2778: 3c030000 lui v1,0x0 > > 0000277c <r4k_dma_cache_inv>: > [...] > > At offset 0x26ac and 0x273c, we can see that instruction_hazard() got > duplicated due to inlining, and that the jr.hb is going to send us to > 10108 (0x277C), outside the function... FYI, GCC 3.4.4 produces the following code which is clearly wrong: .align 2 .align 3 .ent r4k_flush_icache_range .type r4k_flush_icache_range, @function r4k_flush_icache_range: .set nomips16 .frame $sp,56,$31 # vars= 16, regs= 5/0, args= 16, gp= 0 .mask 0x800f0000,-8 .fmask 0x00000000,0 [...] lui $2,%hi($L506) # 239 movsi_internal/2 [length = 4] addiu $2,$2,%lo($L506) # 240 *lowsi [length = 4] #APP jr.hb $2 #NO_APP lw $31,48($sp) # 304 movsi_internal/4 [length = 4] lw $19,44($sp) # 305 movsi_internal/4 [length = 4] lw $18,40($sp) # 306 movsi_internal/4 [length = 4] lw $17,36($sp) # 307 movsi_internal/4 [length = 4] lw $16,32($sp) # 308 movsi_internal/4 [length = 4] .set noreorder .set nomacro j $31 # 310 return_internal [length = 4] addiu $sp,$sp,56 # 309 addsi3_internal/2 [length = 4] .set macro .set reorder $L510: lui $2,%hi(r4k_blast_icache) # 181 movsi_internal/2 [length = 4] lw $3,%lo(r4k_blast_icache)($2) # 182 movsi_internal/4 [length = 4] jal $3 # 183 call_internal/1 [length = 8] lui $2,%hi($L506) # 313 movsi_internal/2 [length = 4] addiu $2,$2,%lo($L506) # 314 *lowsi [length = 4] #APP jr.hb $2 #NO_APP lw $31,48($sp) # 316 movsi_internal/4 [length = 4] lw $19,44($sp) # 317 movsi_internal/4 [length = 4] lw $18,40($sp) # 318 movsi_internal/4 [length = 4] lw $17,36($sp) # 319 movsi_internal/4 [length = 4] lw $16,32($sp) # 320 movsi_internal/4 [length = 4] .set noreorder .set nomacro j $31 # 322 return_internal [length = 4] addiu $sp,$sp,56 # 321 addsi3_internal/2 [length = 4] .set macro .set reorder $L508: lui $2,%hi(r4k_blast_dcache) # 67 movsi_internal/2 [length = 4] lw $3,%lo(r4k_blast_dcache)($2) # 68 movsi_internal/4 [length = 4] jal $3 # 69 call_internal/1 [length = 8] .set noreorder .set nomacro b $L512 # 334 jump [length = 4] lui $3,%hi(icache_size) # 170 movsi_internal/2 [length = 4] .set macro .set reorder $L506: .end r4k_flush_icache_range Please file a bug report at: "http://gcc.gnu.org/bugzilla/". Maciej ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Kernel freezes in r4k_flush_icache_range() with CONFIG_CPU_MIPS32_R2 2005-12-20 11:47 ` Maciej W. Rozycki @ 2005-12-22 2:31 ` Maxime Bizon 2005-12-22 11:10 ` Ralf Baechle 0 siblings, 1 reply; 4+ messages in thread From: Maxime Bizon @ 2005-12-22 2:31 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: linux-mips On Tue, 2005-12-20 at 11:47 +0000, Maciej W. Rozycki wrote: > FYI, GCC 3.4.4 produces the following code which is clearly wrong: > Please file a bug report at: "http://gcc.gnu.org/bugzilla/". Same with 3.3 and 3.2... I'm really not familiar with inline assembly so I would appreciate that any gcc guru here confirm instruction_hazard() code is correct before I (or he) submit the bug report. As the bug seems to be in all gcc versions, I guess we should find a workaround... I changed the code to use an asm label instead of the C label and the bug disappeared. But I'm not sure my changes are correct for any platform other than mine... Could anyone with the right skills help me to write a valid workaround please ? Here is what I have: __asm__ __volatile__( "lui $2,1f\n" "addiu $2,1f\n" "jr.hb $2\n1:":: ); Thanks, -- Maxime ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Kernel freezes in r4k_flush_icache_range() with CONFIG_CPU_MIPS32_R2 2005-12-22 2:31 ` Maxime Bizon @ 2005-12-22 11:10 ` Ralf Baechle 0 siblings, 0 replies; 4+ messages in thread From: Ralf Baechle @ 2005-12-22 11:10 UTC (permalink / raw) To: Maxime Bizon; +Cc: Maciej W. Rozycki, linux-mips On Thu, Dec 22, 2005 at 03:31:31AM +0100, Maxime Bizon wrote: > > FYI, GCC 3.4.4 produces the following code which is clearly wrong: > > > Please file a bug report at: "http://gcc.gnu.org/bugzilla/". > > Same with 3.3 and 3.2... > > I'm really not familiar with inline assembly so I would appreciate that > any gcc guru here confirm instruction_hazard() code is correct before I > (or he) submit the bug report. > > As the bug seems to be in all gcc versions, I guess we should find a > workaround... I changed the code to use an asm label instead of the C > label and the bug disappeared. But I'm not sure my changes are correct > for any platform other than mine... We ran into similar problems in the past. It only seems to be a matter of the code nearby and the exact options to trigger it. The alternative is manually loading the address using la / dla which defeats gcc's splitting of address loading. And having to use different code for 32-bit and 64-bit sucks. > Could anyone with the right skills help me to write a valid workaround > please ? > > Here is what I have: > > __asm__ __volatile__( > "lui $2,1f\n" > "addiu $2,1f\n" > "jr.hb $2\n1:":: ); Wrong, breaks 64-bit and uses $2 without telling gcc about it. Ralf ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2005-12-22 11:09 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-12-20 2:57 Kernel freezes in r4k_flush_icache_range() with CONFIG_CPU_MIPS32_R2 Maxime Bizon 2005-12-20 11:47 ` Maciej W. Rozycki 2005-12-22 2:31 ` Maxime Bizon 2005-12-22 11:10 ` Ralf Baechle
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox