Hi Sometime back I had ported Linux to LSI's SC2005 (TinyMips core with Mips1 and some Mips2 instructions) based board as part of my work. We wanted to release the code to opensource. However we found a bug in the code that it was corrupting the softirq's pending, which I wanted to fix before releaseing to opensource. At that time I temporarily fixed the problem by checking that the softirq is pointing to a proper logic rather than 0 before calling it. Recently I found time to look into the problem, and found the code generated by the compiler is wrong, in that instead of setting the ksoftirqd_task element of the irq_stat structure its setting the pending element, thus causing the system to crash. As mentioned in the subject I was using binutils-mipsel-linux-2.95.3 and egcs-mipsel-linux-1.1.2-4 binary packages from oss.sgi.com on a Redhat 7.2 system. To show the problem I added some test code into the kernel/softirq.c file, as can be noted from the code below the compiler generates proper code in certain places, but wrong code at other instances: ----------------------------------------------------------------------------- binutils-mipsel-linux-2.9.5-3 egcs-mipsel-linux-1.1.2-4 ******************************* ISSUE 1 **************************** Location of irq_stat[] ---------------------- 00000000800f5d38 g F .text 00000000000000d8 __tcp_mem_reclaim 00000000801614d0 g O .data 0000000000000020 irq_stat 00000000800820dc g F .text 0000000000000034 show_buffers ************************************************ In ksoftirqd function /** The actual code - wrong code generated **/ --------------------- ksoftirqd_task(cpu) = current; /* added by me */ debugkvc_softirq_pending("ksoftirqd: before for"); for (;;) { if (!softirq_pending(cpu)) 0000000080059b38 <ksoftirqd>: 80059bf0: 3c108016 lui $s0,0x8016 80059bf4: 261014d0 addiu $s0,$s0,5328 80059bf8: 0c01667e jal 800599f8 <debugkvc_softirq_pending> 80059bfc: ae1c0000 sw $gp,0($s0) /** NOTE ksoftirqd_task offset is wrong **/ 80059c00: 2610fff0 addiu $s0,$s0,-16 /** Nice way to calculate the pending element offset but its wrong has the ksoftirqd_task element offset itself is wrong **/ 80059c04: 8e020000 lw $v0,0($s0) /** as mentioned above the pending element offset wrong **/ 80059c08: 00000000 nop 80059c0c: 14400003 bnez $v0,80059c1c <ksoftirqd+0xe4> ************************************************ void debugkvc_show_gcc_bug_1(void) /* Test case 1 - Proper code generated */ { int cpu = smp_processor_id(); int pending; /* TEMPORARY TO SHOW THE CROSS GCC bUg */ pending = softirq_pending(cpu); pending += 1; softirq_pending(cpu) = pending; ksoftirqd_task(cpu) = current; /* END */ } 0000000080059994 <debugkvc_show_gcc_bug_1>: 80059994: 3c038016 lui $v1,0x8016 80059998: 246314d0 addiu $v1,$v1,5328 8005999c: 8c620000 lw $v0,0($v1) 800599a0: ac7c0010 sw $gp,16($v1) /** Proper offset for ksoftirqd_task element **/ 800599a4: 24420001 addiu $v0,$v0,1 800599a8: 03e00008 jr $ra 800599ac: ac620000 sw $v0,0($v1) ************************************************ void debugkvc_show_gcc_bug_3(void) /* Test case 2 - WRONG code generated */ { int cpu = smp_processor_id(); /* TEMPORARY TO SHOW THE CROSS GCC bUg */ ksoftirqd_task(cpu) = current; /* END */ } 00000000800599cc <debugkvc_show_gcc_bug_3>: 800599cc: 3c018016 lui $at,0x8016 800599d0: ac3c14d0 sw $gp,5328($at) /** wrong offset **/ 800599d4: 03e00008 jr $ra 800599d8: 00000000 nop ************************************************ void debugkvc_show_gcc_bug_4(void) /* Test case 3 - WRONG code generated */ { int cpu = smp_processor_id(); volatile void * task; /* TEMPORARY TO SHOW THE CROSS GCC bUg */ task = ksoftirqd_task(cpu); ksoftirqd_task(cpu) = current; ksoftirqd_task(cpu) = task+1; /* END */ } 00000000800599dc <debugkvc_show_gcc_bug_4>: 800599dc: 3c038016 lui $v1,0x8016 800599e0: 246314d0 addiu $v1,$v1,5328 800599e4: 8c620000 lw $v0,0($v1) /** wrong offset **/ 800599e8: 00000000 nop 800599ec: 24420001 addiu $v0,$v0,1 800599f0: 03e00008 jr $ra 800599f4: ac620000 sw $v0,0($v1) 00000000800599f8 <debugkvc_softirq_pending>: ******************************* ISSUE 2 **************************** mipsel-linux-ld doesn't seem to understand elf32-littlemips even thou mipsel-linux-objdump -i gives elf32-littlemips has part of its output This issue affects the logic used in arch/mips/ramdisk/Makefile to convert the ramdisk.gz file to ramdisk.o Had to force elf32-little for the logic to work. ----------------------------------------------------------------------------- *************** Current status ***************** Because of this, I download the sources for binutils 2.12 and gcc 3.0.4 and created cross compilers for mipsel-linux. Now the compiler is generating proper code for the above case. But linux is failing in the gzips inflate logic (Compressed ramdisk) in some cases, have to verify it properly and identify the issue. It again seems like a compiler problem, but haven't verified it yet. Also I have currently used 2.4.16 with code from linux-mips-kernel on sourceforge as the base on which I have done my porting. Once I find the issue with the gzip logic and also move it to 2.4.18 (or 2.4.19 if it gets released by then), we will release the port to the opensource. **************** Any suggestions **************** In the mean time what do you people think is the best binutils/gcc combination for working with latest Linux kernels for Mips. Keep :-) HanishKVC _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com