Linux 2.6 on PS2
Hi, everybody
Just register but I have been following this thread for some time.
I'm coming from the Linux side, user of gentoo Linux and found this on the mips handbook to install gentoo :
This was in the part setting the right CFLAGS. The n32 flag seems interesting from what I have understood.
I think it might solve the problem concerning the cast problem Chewi has been having.
Keep up on this wonderful work!
Just register but I have been following this thread for some time.
I'm coming from the Linux side, user of gentoo Linux and found this on the mips handbook to install gentoo :
Code: Select all
A very important setting in the MIPS world is the -mabi= flag. MIPS has 3 different ABIs: 32 (pure 32-bit, aka o32), 64 (full 64-bit, aka n64) and n32 (a mix of 32-bit data structures with 64-bit instructions). This flag selects which of these you wish to use. Note you need libraries for the ABI you select. In layman's terms, this means, for example, you can't use -mabi=64 on a 32-bit userland (or even an n32 userland).
I think it might solve the problem concerning the cast problem Chewi has been having.
Keep up on this wonderful work!
You're very welcome, J.F.! Believe it or not, I actually enjoy this.
Azurief, you're right, the ABI is very important. I did know that but I don't think I'd mentioned it here yet. I gather that n64 generally isn't supported yet. The gcc default is n32 and that's what I'm using for Linux already. I suspect this is where I had trouble with gcc 3.2.2 in the past because back then, I was trying to use o32. There is actually another ABI besides the ones mentioned there and that's EABI. This is what I'm using for the home brew stuff. It was also used for the home brew stuff in 3.2.2. From what I've seen, the key difference is that EABI can use 64-bit longs. I now know that this is why 64-bit longs were used in 3.2.2.
Although the ABI can be set through the CFLAGS, my toolchains are automatically selecting the correct ABI for each target so please don't try setting it by hand.
When I first tried to build ps2sdk, I got a lot of cast warnings. I realised that gcc enabled 64-bit longs automatically when using EABI on a 64-bit target. This is what we want but by enabling 64-bit longs, it was also setting the pointer size to 64. I fixed this back to 32 and the warnings disappeared.
The warnings in uClibc are a bit different. I need to know whether to favour the 32-bit pointer size or the 64-bit register size. Once we have a working kernel, we should be able to find out which is the right option simply by trial and error.
ps2sdk now builds entirely. uLaunchELF needs a couple of other things from ps2dev so I'm going to try and build those now.
Azurief, you're right, the ABI is very important. I did know that but I don't think I'd mentioned it here yet. I gather that n64 generally isn't supported yet. The gcc default is n32 and that's what I'm using for Linux already. I suspect this is where I had trouble with gcc 3.2.2 in the past because back then, I was trying to use o32. There is actually another ABI besides the ones mentioned there and that's EABI. This is what I'm using for the home brew stuff. It was also used for the home brew stuff in 3.2.2. From what I've seen, the key difference is that EABI can use 64-bit longs. I now know that this is why 64-bit longs were used in 3.2.2.
Although the ABI can be set through the CFLAGS, my toolchains are automatically selecting the correct ABI for each target so please don't try setting it by hand.
When I first tried to build ps2sdk, I got a lot of cast warnings. I realised that gcc enabled 64-bit longs automatically when using EABI on a 64-bit target. This is what we want but by enabling 64-bit longs, it was also setting the pointer size to 64. I fixed this back to 32 and the warnings disappeared.
The warnings in uClibc are a bit different. I need to know whether to favour the 32-bit pointer size or the 64-bit register size. Once we have a working kernel, we should be able to find out which is the right option simply by trial and error.
ps2sdk now builds entirely. uLaunchELF needs a couple of other things from ps2dev so I'm going to try and build those now.
I was a bit disheartened the other day because when I actually tried to run some code, very little seemed to work. I managed a "Hello Chewi!" over ps2link but that was about it. Other code was giving me reserved instruction exceptions. The first one was on the ddiv instruction. When the second one occurred on the dmult instruction, I checked the EE Core manual and realised that the double precision multiplication and division instructions are the ones missing from MIPS3. I had forgotten that they were actually the instructions tackled by Alex's patch.
I wanted to deal with them in a way that wouldn't break gcc for other machines. In fact, I don't believe Alex's patch would work anyway. The instructions would still be matched in DImode and consequently, a single precision instruction would be executed with double precision operands. Not good. I found a way to prevent the instruction from being matched but now I get this.
I'm not sure but I think I'm going to have to add some of the TImode stuff from the old patch in order to make this work. I've tried this already but no luck so far. I think it needs some adjusting.
I wanted to deal with them in a way that wouldn't break gcc for other machines. In fact, I don't believe Alex's patch would work anyway. The instructions would still be matched in DImode and consequently, a single precision instruction would be executed with double precision operands. Not good. I found a way to prevent the instruction from being matched but now I get this.
Code: Select all
/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/build/./gcc/xgcc -B/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/build/./gcc/ -B/usr/mips64r5900el-scei-elf/bin/ -B/usr/mips64r5900el-scei-elf/lib/ -isystem /usr/mips64r5900el-scei-elf/include -isystem /usr/mips64r5900el-scei-elf/sys-include -O2 -O2 -O2 -pipe -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -G 0 -g -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -Dinhibit_libc -I. -I. -I/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc -I/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/. -I/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/../include -I/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/../libcpp/include -I/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/../libdecnumber -I../libdecnumber -DL_muldi3 -c /var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/libgcc2.c -o libgcc/./_muldi3.o
/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/libgcc2.c: In function '__multi3':
/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/libgcc2.c:542: error: unrecognizable insn:
(insn 40 39 41 3 /var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/libgcc2.c:536 (parallel [
(set (reg/v:DI 202 [ __x0 ])
(mult:DI (reg/v:DI 197 [ __vl ])
(reg/v:DI 198 [ __ul ])))
(clobber (scratch:DI))
]) -1 (nil)
(nil))
/var/tmp/cross/mips64r5900el-scei-elf/portage/cross-mips64r5900el-scei-elf/gcc-4.2.0-r1/work/gcc-4.2.0/gcc/libgcc2.c:542: internal compiler error: in extract_insn, at recog.c:2077
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://bugs.gentoo.org/> for instructions.
Disabling these instructions has had a bigger effect than I expected. This is cutting a long story short but I managed to get a bit further by changing the word size from 64 to 32. According to the docs, it's supposed to be 32 anyway but gcc 3.2.2 somehow managed to get away with setting it to 64. It's still failing though. I think 3.2.2 worked without these instructions because it included support for the second pipeline. 2.95 probably avoided the problem by being 32-bit. So it seems I need to add support for the second pipeline. This isn't something I wanted to tackle yet because it looks pretty complicated but I guess I have no choice. Here goes.
It took a while but... I DID IT!! XD
Yes, my friends, I reckon this must be the first time the PS2 has ever successfully run anything built by gcc 4. (-: I was gonna capture a video but my tuner was being an arse. So it's definitely not outputting dmult or ddiv instructions anymore but I can't see any sign of mult1 or div1 either, which I find strange. The R5900 is actually quite smart in that it has register interlocks, something that even most MIPS4 processors don't have, so perhaps it's queuing up two mult/div instructions one after the other instead of doing mult+mult1 or div+div1 in parallel. I'll check that out now.
Yes, my friends, I reckon this must be the first time the PS2 has ever successfully run anything built by gcc 4. (-: I was gonna capture a video but my tuner was being an arse. So it's definitely not outputting dmult or ddiv instructions anymore but I can't see any sign of mult1 or div1 either, which I find strange. The R5900 is actually quite smart in that it has register interlocks, something that even most MIPS4 processors don't have, so perhaps it's queuing up two mult/div instructions one after the other instead of doing mult+mult1 or div+div1 in parallel. I'll check that out now.
Heh cheers. I wish I could work on this more. Work again tomorrow. :(
I figured that problem out. I'd got the register bit masks totally wrong. It's now outputting instructions specifically for the second pipeline. I haven't tested it out yet but judging by the disassembled output, it looks as though it's mixing up the mflo/mtlo/mfhi/mthi instructions for each pipeline. For example, I see mult shortly followed by mfhi1 and elsewhere, I see mult1 shortly followed by mfhi. Maybe they appear out of order because of the latency. That would be okay. I'm not sure though. I would test it but I need to fix something else first.
I figured that problem out. I'd got the register bit masks totally wrong. It's now outputting instructions specifically for the second pipeline. I haven't tested it out yet but judging by the disassembled output, it looks as though it's mixing up the mflo/mtlo/mfhi/mthi instructions for each pipeline. For example, I see mult shortly followed by mfhi1 and elsewhere, I see mult1 shortly followed by mfhi. Maybe they appear out of order because of the latency. That would be okay. I'm not sure though. I would test it but I need to fix something else first.
Well it looks like the second pipeline stuff is okay after all. I built starsim again and found that it contained a lot of divu1, mflo1 and mfhi1 instructions in equal amounts. More importantly, it still runs perfectly. Yay! I've found that it only runs through ps2link though. If I try to run it from uLaunchELF, I just get a black screen. I'm not sure if that's normal. Hopefully nothing's wrong there.
So what next? As far as I know, the only thing that prevents this toolchain from working perfectly is the short loop length bug. This was previously tackled in gcc but wasn't too pretty. It would be much simpler to tackle it in binutils. I'm going to e-mail someone who might have worked this out already. If he hasn't then I'll have a go myself.
After that, the only additional thing present in the gcc 3.2.2 patch is support for the 128-bit instructions. This is optional but could give a significant performance boost. The bad news is that there's quite a lot of code involved. The good news is that a lot of similar code is now present in 4.2.0 since the addition of DSP support. This could serve as a guide.
I think I'll skip the 128-bit stuff for now though and move straight onto the kernel. That's where the real fun begins! :-D
Edit! I suddenly realised that maybe the nprintf statements were causing problems with starsim outside of ps2link, since nprintf is for sending messages to ps2link. My hunch proved correct! It now runs from uLaunchELF.
So what next? As far as I know, the only thing that prevents this toolchain from working perfectly is the short loop length bug. This was previously tackled in gcc but wasn't too pretty. It would be much simpler to tackle it in binutils. I'm going to e-mail someone who might have worked this out already. If he hasn't then I'll have a go myself.
After that, the only additional thing present in the gcc 3.2.2 patch is support for the 128-bit instructions. This is optional but could give a significant performance boost. The bad news is that there's quite a lot of code involved. The good news is that a lot of similar code is now present in 4.2.0 since the addition of DSP support. This could serve as a guide.
I think I'll skip the 128-bit stuff for now though and move straight onto the kernel. That's where the real fun begins! :-D
Edit! I suddenly realised that maybe the nprintf statements were causing problems with starsim outside of ps2link, since nprintf is for sending messages to ps2link. My hunch proved correct! It now runs from uLaunchELF.
Good to see you, Alex. Any help would be appreciated.
I'm a bit disappointed at the moment because my own further testing of the toolchain revealed that it's not quite there yet. madplay returns a "TLB load/inst fetch" exception. I also noticed that invalid IRXs are being produced.
Old toolchain...
New toolchain...
The problems aren't related because I tried madplay with working IRXs and it still didn't work. I have tried tackling the IRX problem first. I've managed to establish that the problem is with gcc, not binutils, because using the old gcc and the new binutils works okay. I'm really puzzled though because the gcc patch for the IRX stuff is really short and mostly trivial due to the fact that the IOP is more or less a standard R3000. Here's the entire patch...
The only interesting part is iop.h. I noticed that 3.2.2 doesn't call the assembler with any -mabi option by default but 4.2.0 does. The problem is that in this case, 4.2.0's default ABI is O32, while gas' default is no ABI. You cannot explicitly ask gas to use no ABI so I added a couple of lines for it to do that and told gcc to use "none" as the default instead. This does not effect gcc itself but just the way it invokes gas.
The following part of iop.h concerns gcc's default options. -march=r3000 is the default and I also disabled certain optimisations by default because I found that they prevented the IRXs from linking. I suspect that once we fix this problem, we may not need to disable these anymore. I have tried building the IRXs with -O0 but that doesn't help.
I've tried this patch on its own without the R5900 patch in case that was screwing things up. Still no good. I've been comparing the assembly output but it's not unusual for it to differ slightly, given the two different versions of gcc involved. Most of it is just in a slightly different order. I'm pretty much out of ideas. :( Help?
I'm a bit disappointed at the moment because my own further testing of the toolchain revealed that it's not quite there yet. madplay returns a "TLB load/inst fetch" exception. I also noticed that invalid IRXs are being produced.
Old toolchain...
Code: Select all
pksh> iopexec isjpcm.irx
log: IOP cmd: 1 args
log: iSjPCM v2.2 - by Sjeep, Lukasz Bruun & Evilo
log: iSjPCM: RPC Initialize
log: loadmodule: id 33, ret 0
Code: Select all
pksh> iopexec isjpcm.irx
log: IOP cmd: 1 args
log: `�(loadmodule: id 33, ret 0
Code: Select all
diff -Naur gcc-4.2.0-old/configure.in gcc-4.2.0-new/configure.in
--- gcc-4.2.0-old/configure.in 2007-09-02 12:50:32.496775367 +0100
+++ gcc-4.2.0-new/configure.in 2007-09-02 12:51:03.509044251 +0100
@@ -737,6 +737,9 @@
mips*-*-linux*)
noconfigdirs="$noconfigdirs target-newlib target-libgloss"
;;
+ mips*-*-irx*)
+ noconfigdirs="$noconfigdirs gprof target-newlib target-libgloss target-libiberty target-libstdc++-v3 ${libgcj}"
+ ;;
mips*-*-*)
noconfigdirs="$noconfigdirs gprof ${libgcj}"
;;
diff -Naur gcc-4.2.0-old/gcc/config/mips/iop.h gcc-4.2.0-new/gcc/config/mips/iop.h
--- gcc-4.2.0-old/gcc/config/mips/iop.h 1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.2.0-new/gcc/config/mips/iop.h 2007-09-02 16:36:18.457254164 +0100
@@ -0,0 +1,8 @@
+#undef MULTILIB_ABI_DEFAULT
+#define MULTILIB_ABI_DEFAULT "mabi=none"
+
+#define DRIVER_SELF_SPECS \
+ "%{!march=*:-march=r3000}", \
+ "%{!funit-at-a-time:-fno-unit-at-a-time}", \
+ "%{!fmerge-constants:-fno-merge-constants}", \
+ "%{!fbuiltin:-fno-builtin}"
diff -Naur gcc-4.2.0-old/gcc/config/mips/t-iop gcc-4.2.0-new/gcc/config/mips/t-iop
--- gcc-4.2.0-old/gcc/config/mips/t-iop 1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.2.0-new/gcc/config/mips/t-iop 2007-09-02 12:51:03.509044251 +0100
@@ -0,0 +1,3 @@
+MULTILIB_OPTIONS =
+MULTILIB_DIRNAMES =
+MULTILIB_MATCHES =
diff -Naur gcc-4.2.0-old/gcc/config.gcc gcc-4.2.0-new/gcc/config.gcc
--- gcc-4.2.0-old/gcc/config.gcc 2007-09-02 12:50:32.533769723 +0100
+++ gcc-4.2.0-new/gcc/config.gcc 2007-09-02 16:36:50.490367312 +0100
@@ -1654,6 +1654,12 @@
tmake_file=mips/t-r3900
use_fixproto=yes
;;
+mips*-*-irx*)
+ tm_file="elfos.h ${tm_file} mips/elf.h mips/iop.h"
+ tmake_file="mips/t-elf mips/t-gofast mips/t-iop"
+ target_cpu_default="MASK_SOFT_FLOAT"
+ use_fixproto=yes
+ ;;
mmix-knuth-mmixware)
need_64bit_hwint=yes
;;
The following part of iop.h concerns gcc's default options. -march=r3000 is the default and I also disabled certain optimisations by default because I found that they prevented the IRXs from linking. I suspect that once we fix this problem, we may not need to disable these anymore. I have tried building the IRXs with -O0 but that doesn't help.
I've tried this patch on its own without the R5900 patch in case that was screwing things up. Still no good. I've been comparing the assembly output but it's not unusual for it to differ slightly, given the two different versions of gcc involved. Most of it is just in a slightly different order. I'm pretty much out of ideas. :( Help?
If anyone's interested in trying my stuff out, I've committed my latest patches for binutils, gcc 4 and newlib. Any help with the recent problems would be very much appreciated.
You can get the Portage overlay from...
svn://gps2.aura-online.co.uk/gentoo-ps2/ps2-overlay
For non-Gentoo users, the rest of the files are at...
http://gps2.aura-online.co.uk/distfiles
As usual, I recommend building the toolchain with crossdev.
You can get the Portage overlay from...
svn://gps2.aura-online.co.uk/gentoo-ps2/ps2-overlay
For non-Gentoo users, the rest of the files are at...
http://gps2.aura-online.co.uk/distfiles
As usual, I recommend building the toolchain with crossdev.
I think I'm one step closer to cracking the IRX dilemma. I was testing stuff out on ps2dev9.irx since it's the first IRX to get built and therefore has few dependencies. It is built from three object files, ps2dev9.o, exports.o and imports.o. I was totally clutching at straws when I discovered that if you build imports.o with the old gcc and the other two with the new gcc then it actually works. No other combination seems to work. The finger therefore points at imports.o. I did some comparisons and the only major difference I can find is the order of the symbol table.
gcc 3.2.2...
gcc 4.2.0...
As you can see, the new gcc appears to sort them. The order produced by the old gcc actually matches the order of the symbols in the ps2sdk source. Looking at the other object files, imports.o is the only one that the new gcc has sorted in this way. I therefore think that the problem lies in ps2sdk's irx.h and not gcc itself. It may need to be updated to work properly with the new gcc. How? Let's just hope I manage to figure that out! Here is the code involved. Note the "comforting" comment.
Where's mrbrown when you need him? :(
gcc 3.2.2...
Code: Select all
Symbol table '.symtab' contains 31 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 1 .text
2: 00000000 0 SECTION LOCAL DEFAULT 2 .data
3: 00000000 0 SECTION LOCAL DEFAULT 3 .bss
4: 00000000 0 SECTION LOCAL DEFAULT 6 .mdebug.abi32
5: 00000000 0 SECTION LOCAL DEFAULT 4 .reginfo
6: 00000000 0 SECTION LOCAL DEFAULT 5 .mdebug
7: 00000000 20 OBJECT LOCAL DEFAULT 1 _imp_dmacman
8: 00000014 0 OBJECT GLOBAL DEFAULT 1 dmac_set_dpcr2
9: 0000001c 0 OBJECT GLOBAL DEFAULT 1 dmac_get_dpcr2
10: 0000002c 20 OBJECT LOCAL DEFAULT 1 _imp_intrman
11: 00000040 0 OBJECT GLOBAL DEFAULT 1 RegisterIntrHandler
12: 00000048 0 OBJECT GLOBAL DEFAULT 1 EnableIntr
13: 00000050 0 OBJECT GLOBAL DEFAULT 1 DisableIntr
14: 00000058 0 OBJECT GLOBAL DEFAULT 1 CpuSuspendIntr
15: 00000060 0 OBJECT GLOBAL DEFAULT 1 CpuResumeIntr
16: 00000070 20 OBJECT LOCAL DEFAULT 1 _imp_loadcore
17: 00000084 0 OBJECT GLOBAL DEFAULT 1 RegisterLibraryEntries
18: 0000008c 0 OBJECT GLOBAL DEFAULT 1 QueryBootMode
19: 00000094 0 OBJECT GLOBAL DEFAULT 1 GetLibraryEntryTable
20: 000000a4 20 OBJECT LOCAL DEFAULT 1 _imp_poweroff
21: 000000b8 0 OBJECT GLOBAL DEFAULT 1 AddPowerOffHandler
22: 000000c8 20 OBJECT LOCAL DEFAULT 1 _imp_stdio
23: 000000dc 0 OBJECT GLOBAL DEFAULT 1 printf
24: 000000ec 20 OBJECT LOCAL DEFAULT 1 _imp_thbase
25: 00000100 0 OBJECT GLOBAL DEFAULT 1 DelayThread
26: 00000110 20 OBJECT LOCAL DEFAULT 1 _imp_thsemap
27: 00000124 0 OBJECT GLOBAL DEFAULT 1 CreateSema
28: 0000012c 0 OBJECT GLOBAL DEFAULT 1 SignalSema
29: 00000134 0 OBJECT GLOBAL DEFAULT 1 iSignalSema
30: 0000013c 0 OBJECT GLOBAL DEFAULT 1 WaitSema
Code: Select all
Symbol table '.symtab' contains 31 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 1 .text
2: 00000000 0 SECTION LOCAL DEFAULT 2 .data
3: 00000000 0 SECTION LOCAL DEFAULT 3 .bss
4: 00000000 0 SECTION LOCAL DEFAULT 6 .mdebug.abi32
5: 00000000 0 SECTION LOCAL DEFAULT 4 .reginfo
6: 00000000 0 SECTION LOCAL DEFAULT 5 .mdebug
7: 00000000 20 OBJECT LOCAL DEFAULT 1 _imp_dmacman
8: 00000014 20 OBJECT LOCAL DEFAULT 1 _imp_intrman
9: 00000028 20 OBJECT LOCAL DEFAULT 1 _imp_loadcore
10: 0000003c 20 OBJECT LOCAL DEFAULT 1 _imp_poweroff
11: 00000050 20 OBJECT LOCAL DEFAULT 1 _imp_stdio
12: 00000064 20 OBJECT LOCAL DEFAULT 1 _imp_thbase
13: 00000078 20 OBJECT LOCAL DEFAULT 1 _imp_thsemap
14: 0000008c 0 OBJECT GLOBAL DEFAULT 1 dmac_set_dpcr2
15: 00000094 0 OBJECT GLOBAL DEFAULT 1 dmac_get_dpcr2
16: 000000a4 0 OBJECT GLOBAL DEFAULT 1 RegisterIntrHandler
17: 000000ac 0 OBJECT GLOBAL DEFAULT 1 EnableIntr
18: 000000b4 0 OBJECT GLOBAL DEFAULT 1 DisableIntr
19: 000000bc 0 OBJECT GLOBAL DEFAULT 1 CpuSuspendIntr
20: 000000c4 0 OBJECT GLOBAL DEFAULT 1 CpuResumeIntr
21: 000000d4 0 OBJECT GLOBAL DEFAULT 1 RegisterLibraryEntries
22: 000000dc 0 OBJECT GLOBAL DEFAULT 1 QueryBootMode
23: 000000e4 0 OBJECT GLOBAL DEFAULT 1 GetLibraryEntryTable
24: 000000f4 0 OBJECT GLOBAL DEFAULT 1 AddPowerOffHandler
25: 00000104 0 OBJECT GLOBAL DEFAULT 1 printf
26: 00000114 0 OBJECT GLOBAL DEFAULT 1 DelayThread
27: 00000124 0 OBJECT GLOBAL DEFAULT 1 CreateSema
28: 0000012c 0 OBJECT GLOBAL DEFAULT 1 SignalSema
29: 00000134 0 OBJECT GLOBAL DEFAULT 1 iSignalSema
30: 0000013c 0 OBJECT GLOBAL DEFAULT 1 WaitSema
Code: Select all
/*
* Module imports
*/
#define IMPORT_MAGIC 0x41e00000
struct irx_import_table
{
u32 magic;
struct irx_import_table *next;
u16 version;
u16 mode;
char name[8];
void *stubs[0];
} __attribute ((packed));
struct irx_import_stub
{
u32 jump;
u16 fno;
u16 ori_zero;
} __attribute ((packed));
/*
* Ugly, yet functional.
*/
#define DECLARE_IMPORT_TABLE(modname, major, minor) \
static struct irx_import_table _imp_##modname \
__attribute__((section(".text\n\t#"), unused))= { \
magic: IMPORT_MAGIC, version: IRX_VER(major, minor), \
name: #modname, };
#define STR(val) #val
#define DECLARE_IMPORT(ord, name) \
__asm__ (".section\t.text\n\t" \
".globl\t"#name"\n\t"#name":\n\t" \
".word 0x3e00008\n\t" \
".word "STR(0x24000000|ord));
#define END_IMPORT_TABLE \
__asm__ (".section\t.text\n\t.word\t0, 0");
I GOT IT!! XD Turns out I needed a gcc option that is so new, it wasn't even in the man page for 4.1.2, which is my system's default gcc version. The option is -fno-toplevel-reordering but in order for it to be effective, you need to have -funit-at-a-time enabled, the option which I previously disabled. -fmerge-constants is still causing problems and so remains disabled. I'm not in the clear yet though. ps2netfs.irx starts but it still doesn't seem to work.
I'm pleased to have just made this small bit of progress though.
Code: Select all
pksh version 2.1
Connecting to 192.168.1.204
pksh> iopexec ps2netfs.irx
log: IOP cmd: 1 args
log: PS2_TcpFileDriver - v1.0 - Copyright (c) 2004 adresd
log:
Server Started
log: loadmodule: id 33, ret 0
pksh> devlist
PS2Net FS connection failed, make sure ps2netfs.irx is loaded
The first time I saw this code, I was thinking: If you have good luck then this is working.
It is better when you do this in an assembler file, because reordering is fatal at this point. I think assembler directives like ".noreorder" can also help. Normally you should put everything into only one __asm__ command and use each section only one time.
You can check if your file is created correctly by using my irxtool and comparing against the old gcc:
http://freenet-homepage.de/ps2dev/irxtool.tgz
It is better when you do this in an assembler file, because reordering is fatal at this point. I think assembler directives like ".noreorder" can also help. Normally you should put everything into only one __asm__ command and use each section only one time.
You can check if your file is created correctly by using my irxtool and comparing against the old gcc:
http://freenet-homepage.de/ps2dev/irxtool.tgz
I'm still getting to grips with assembly. I did consider .noreorder but I didn't think that would work across symbols. Thanks for the tool. That might prove useful.
For anyone wanting to grab the code, I've committed the IOP fix.
I've had a quick look at the ps2netfs.irx problem. It could be similar because despite the earlier fix, a few symbols do appear to be out of order. It's not the imports this time though. I'm not sure if it matters for the others. I rebuilt it with DEBUG enabled and it actually stops when it starts trying to query the iomanx devices. I don't know what the difference is between ioman and iomanx devices. The comments in that area of code mention something about the .bss section, which also indicates that the problem could be similar to the previous one.
For anyone wanting to grab the code, I've committed the IOP fix.
I've had a quick look at the ps2netfs.irx problem. It could be similar because despite the earlier fix, a few symbols do appear to be out of order. It's not the imports this time though. I'm not sure if it matters for the others. I rebuilt it with DEBUG enabled and it actually stops when it starts trying to query the iomanx devices. I don't know what the difference is between ioman and iomanx devices. The comments in that area of code mention something about the .bss section, which also indicates that the problem could be similar to the previous one.
Fixed the IRX stuff. I needed to use -mno-explicit-relocs. I could have sworn I'd tried that before. I also removed the -mabi=none stuff I mentioned earlier since the PS2 doesn't seem to care. I think it actually makes very little difference in binutils, at least in this particular case. I tried running a bunch of IRXs. ps2netfs.irx, freesd.irx, audsrv.irx and usbd.irx all started up okay. Some of the others I tried didn't seem to work but I'm hoping it was due to things like missing dependencies, missing parameters or being already loaded.
I've started incrementing my ebuild versions in the repository now. I wasn't doing this before because I was going to end up at r50 in no time but things are starting to settle down now and one user complained that not changing them was making things confusing. Fair enough.
I'm going to focus on the EE again now. Time to look at that madplay problem.
I've started incrementing my ebuild versions in the repository now. I wasn't doing this before because I was going to end up at r50 in no time but things are starting to settle down now and one user complained that not changing them was making things confusing. Fair enough.
I'm going to focus on the EE again now. Time to look at that madplay problem.
Just committed again. Didn't increment the version this time because I don't think anyone tried my code in the 4 hours since my last post. =P
Someone informed me that gcc was failing to build Fortran support, not that he needed it, but it indicated a problem with my patch. Sure enough, I'd missed out some pipeline stuff. Now it builds. (-:
I've noticed a couple more improvements I can make but this coder needs to go to the gym right now. (-;
Someone informed me that gcc was failing to build Fortran support, not that he needed it, but it indicated a problem with my patch. Sure enough, I'd missed out some pipeline stuff. Now it builds. (-:
I've noticed a couple more improvements I can make but this coder needs to go to the gym right now. (-;
If anyone has any clues about how I can solve the madplay problem, I'd be very grateful. I'm quite stumped so far. This is what happens.
This is the disassembled area where it fails.
It's tricky because the line I've pointed out probably has little to do with the problem itself.
Code: Select all
pksh version 2.1
Connecting to 192.168.1.204
pksh> iopexec isjpcm.irx
log: IOP cmd: 1 args
log: iSjPCM v2.2 - by Sjeep, Lukasz Bruun & Evilo
log: iSjPCM: RPC Initialize
log: loadmodule: id 33, ret 0
pksh> eeexec madplay.elf batt.mp3
log: unmounting
log: unmounted
log: Get Reboot Request From EE
log: ps2ip_ShutDown: Shutting down ps2ip-module
log: tty mounted
log: host: mounted
log: IOP cmd thread started
log: Naplink thread started
log: loadbuffer: id 31, ret 0
log: loadmodule: fname rom0:CLEARSPU args 0 arg
log: clearspu: completed
log: loadmodule: id 32, ret 1
log: read/write allocate memory 4000
log: EE: Cmd thread
log: loadelf: fname host:madplay.elf secname all
log: loadelf version 3.30
log: Input ELF format filename = host:madplay.elf
log: 0 00100000 0005d178 ......
log: Loaded, host:madplay.elf
log: start address 0x100120
log: gp address 00000000
log:
log:
log:
log:
log:
log:
log:
log:
log:
log:
log:
EE Exception handler: TLB load/inst fetch exception
log: Cause 10008008 BadVAddr 02000000 Status 70030c13 EPC 00135234
log: zero: 00000000000000000000000000000000 t8: 0000000000000000FFFFFFFF800212C0
log: at: 0000000000000000FFFFFFFF80020000 t9: 0000000000000000FFFFFFFFFFFFFFC0
log: v0: 00000000000000000000000000051B00 s0: 0000000000000000000000108001A670
log: v1: 00000000000000000000000000000104 s1: 00000000000000000000000000051B00
log: a0: 00000000000000000000000000158B20 s2: 00000000000000000000000000158B20
log: a1: 0000000000000000000000108001A670 s3: 00000000000000000000000000000000
log: a2: 00000000000000000000000000000004 s4: 00000000000000000000000000000000
log: a3: FFABBCBBADADB0BD0000000000000044 s5: 00000000000000000000000001FF7CB0
log: t0: 01010101010101010000000001FFFFC0 s6: 00000000000000000000000000160000
log: t1: 80808080808080800000000000000000 s7: 00000000000000000000000000150000
log: t2: 808080808080808000000000003F0B98 k0: 00000000000000000000000000000000
log: t3: 0000000000000000000000000200069B k1: DFE9DFF9BFFBD77F0000000000000000
log: t4: 00000000000000000000000020167B80 gp: 00000000000000000000000000000000
log: t5: 0000000000000000FFFFFFFFA0000000 sp: 00000000000000000000000001FF7C68
log: t6: 00000000000000000000000000000004 fp: 00000000000000000000000000130000
log: t7: 0000000000000000000000000000001F ra: 000000000000000000000000001363B4
log:
Code: Select all
00135224 <loop8>:
135224: 254affff addiu t2,t2,-1
135228: 0000000f sync
13522c: bd180000 cache 0x18,0(t0)
135230: 0000000f sync
135234: bd180040 cache 0x18,64(t0) <--- THIS LINE
135238: 0000000f sync
13523c: bd180080 cache 0x18,128(t0)
135240: 0000000f sync
135244: bd1800c0 cache 0x18,192(t0)
135248: 0000000f sync
13524c: bd180100 cache 0x18,256(t0)
135250: 0000000f sync
135254: bd180140 cache 0x18,320(t0)
135258: 0000000f sync
13525c: bd180180 cache 0x18,384(t0)
135260: 0000000f sync
135264: bd1801c0 cache 0x18,448(t0)
135268: 0000000f sync
13526c: 1d40ffed bgtz t2,135224 <loop8>
135270: 25080200 addiu t0,t0,512
-
- Posts: 202
- Joined: Wed Aug 09, 2006 1:00 am
I'm not sure if I'll be of any help, but I've been following your project from afar, :D. I went and compiled all the dependencies for madplay, and looked at the loop8 label inside of the disassembly of madplay.elf using gcc-3.2.2. The code is the same except for the differing offsets, so it looks good. The load addresses for the elfs are different, but I don't think that would cause a problem. The values in your registers look a little weird though, filled with FFFFFFFFFF values (upper regions of 64-bit values?). Address 02000000 is exactly 32 megabytes... the maximum size of the ps2 memory (I think), so it seems to be an overflow of some kind. I get the same type of exception when I reference a NULL pointer, except BadVAddr is all 0's.
Im just gonna point out the obvious: BadVAddr 0x2000000, which is exactly 32 MB, so you are refering outside to an address outside of memory. Looks like the t0 register hold an incorrect address. I'd printf this address in both your toolchain and the 3.2.2 toolchain and go from there.
As a sidenote, nice to see that someone is still interested in the PS2, keep up the good work.
As a sidenote, nice to see that someone is still interested in the PS2, keep up the good work.
I interpret this as follows:
The label "loop8" is part of function SifWriteBackDCache() in ps2sdk/ee/kernel/src/kernel.S. The function is called as follows:
The size is too big. 0x1A670 would make more sense.
This function is called from address 0x1363B4 (register ra). You need to look here to debug the caller.
One problem could be that "int" is interpreted as 16 bit (ABI is wrong).
The label "loop8" is part of function SifWriteBackDCache() in ps2sdk/ee/kernel/src/kernel.S. The function is called as follows:
Code: Select all
SifWriteBackDCache(
void *ptr = 0x158B20 /* register a0 */
int size = 0x8001A670 /* register a1 */
);
This function is called from address 0x1363B4 (register ra). You need to look here to debug the caller.
One problem could be that "int" is interpreted as 16 bit (ABI is wrong).
That helps tremendously, thanks guys. For some reason, I assumed loop8 was some kind of internally generated function because it sounded like one. I did use addr2line but it pointed to some other file the first time. It pointed to kernel.S this time but said it was line 0. I figured it was totally wrong and didn't even bother looking at the file. Guess I should have, huh.
I'm pretty sure the ABI stuff is okay but I'm still a little dubious about the pointer size stuff even though I don't get warnings about that anymore. I checked the ABI of madplay.elf with objdump and it says EABI64, which I believe is what it should be.
I've got a lot to go on now so I'll give it my best shot. Thanks again.
I'm pretty sure the ABI stuff is okay but I'm still a little dubious about the pointer size stuff even though I don't get warnings about that anymore. I checked the ABI of madplay.elf with objdump and it says EABI64, which I believe is what it should be.
I've got a lot to go on now so I'll give it my best shot. Thanks again.
-
- Posts: 202
- Joined: Wed Aug 09, 2006 1:00 am
I'm able to build gcc-4.2.1 for a mips64el target using gcc-4.2.1-2-src for the msys/mingw environment using the recently released gcc-4.2.1-dw2-2 toolchain. I chose mips64el-4300-elf as the test build. That gcc source version is patched with mingw-local patches to build a mingw/windows hosted compiler, I'll do a diff later to see what's changed. I hadn't previously built a binutils yet and forgot -mno-crt0, so it failed during the install phase when it tried to assemble crtbegin.o with the host's as.exe, but it reached the install phase which made me happy.
I'll work on it some more until I'm able to build a toolchain, then start from scratch and see if your patches will apply cleanly to it so I can build a mips64r5900-scei-elf toolchain.
I'll work on it some more until I'm able to build a toolchain, then start from scratch and see if your patches will apply cleanly to it so I can build a mips64r5900-scei-elf toolchain.
crossdev gcc 4.2.0
Trying to catch up to you guys...
Using crossdev -t mips64r5900el-unknown-linux-uclibc fails when building gcc 4.2.0 with an internal error in the assembler. Looking closer, gcc emits the 'sdc1' instruction when compiling libgcc2, but we don't have that instruction on the EE.
I believe there is some mechanism to convince gcc that the target can only do single-precision floating point... I'll look into it, but maybe someone already did? I haven't seen this problem mentioned here.
[EDIT] Ok sdc1 is emitted in libgcc2 functions _multc3 and _divtc3. If I remove those from mklibgcc.in, I lose support for long double complex (TCmode) multiplication and division, but it builds.
Next is, how can I make crossdev or emerge use my modified source tree, instead of fetching/unpacking the tarballs?
Using crossdev -t mips64r5900el-unknown-linux-uclibc fails when building gcc 4.2.0 with an internal error in the assembler. Looking closer, gcc emits the 'sdc1' instruction when compiling libgcc2, but we don't have that instruction on the EE.
I believe there is some mechanism to convince gcc that the target can only do single-precision floating point... I'll look into it, but maybe someone already did? I haven't seen this problem mentioned here.
[EDIT] Ok sdc1 is emitted in libgcc2 functions _multc3 and _divtc3. If I remove those from mklibgcc.in, I lose support for long double complex (TCmode) multiplication and division, but it builds.
Next is, how can I make crossdev or emerge use my modified source tree, instead of fetching/unpacking the tarballs?
Why don't we create an project on a site (like sourceforge)? Or perhaps, we should create some projects instead of just one, like a project for porting gcc to ps2, and another for porting/creating a assembler(binutils), and another for creating decent docs/guides for interested people get started. I could help on that last.
I think my trac (http://gps2.aura-online.co.uk) provides everything we need, bar a forum. I'm not a fan of mailing lists, though I like SourceForge's forums even less. I see this stage as the "getting off the ground stage" where it's difficult for more than one person at a time to make any significant process. Once we're onto the kernel, we can get people to work on different drivers and such.
I'm not dead, btw. I've had a ton of other things going on including my parents visiting me up here for the first time. I've got today and tomorrow off work so I may be able to get onto this soon.
I'm not dead, btw. I've had a ton of other things going on including my parents visiting me up here for the first time. I've got today and tomorrow off work so I may be able to get onto this soon.
Before taking my break, I screwed up my ps2dev tree and after trying to fix it, starsim wouldn't build anymore. I've sorted that now. I now know that we can just remove any mention of the -mno-crt0 option since this has been removed and it is effectively the default for *-elf targets.
pontus, I replicated your problem. I'm not sure if you noticed that I haven't been building the Linux target lately. The toolchain has to work with ps2dev before we can realistically have any hope of it working with Linux. It doesn't surprise me that the Linux target doesn't build anymore because I've made a huge amount of changes since then, including changes to the way libgcc2 is built. Thanks for working that problem out for me since the error didn't actually say exactly what the problem was. I haven't paid much attention to the complex stuff but not building _multc3 and _divtc3 sounds like the right answer. If the EE doesn't have sdc1 then it's unlikely that these functions were built before. I don't think any of the T[IFC]mode stuff was being built before, which is why this problem has only appeared now.
So I'll fix that properly tomorrow and push out a new revision. Then I'll try and write a step by step guide on how I build my toolchain and stick that on trac.
pontus, I replicated your problem. I'm not sure if you noticed that I haven't been building the Linux target lately. The toolchain has to work with ps2dev before we can realistically have any hope of it working with Linux. It doesn't surprise me that the Linux target doesn't build anymore because I've made a huge amount of changes since then, including changes to the way libgcc2 is built. Thanks for working that problem out for me since the error didn't actually say exactly what the problem was. I haven't paid much attention to the complex stuff but not building _multc3 and _divtc3 sounds like the right answer. If the EE doesn't have sdc1 then it's unlikely that these functions were built before. I don't think any of the T[IFC]mode stuff was being built before, which is why this problem has only appeared now.
So I'll fix that properly tomorrow and push out a new revision. Then I'll try and write a step by step guide on how I build my toolchain and stick that on trac.
Chewi:Chewi wrote:I think my trac (http://gps2.aura-online.co.uk) provides everything we need, bar a forum. I'm not a fan of mailing lists, though I like SourceForge's forums even less. I see this stage as the "getting off the ground stage" where it's difficult for more than one person at a time to make any significant process. Once we're onto the kernel, we can get people to work on different drivers and such.
I'm not dead, btw. I've had a ton of other things going on including my parents visiting me up here for the first time. I've got today and tomorrow off work so I may be able to get onto this soon.
I had take a look at your site. It's really nice. In fact, everthing on this topic is really very nice. But we see that are so many people interested on running a linux(or any unix) on a ps2. Also, there are so many people interested on ps2 development(like me), and there is no place to get them started. So if we could write some doc's based on the work of the people of this forum, people interested in would be helping us faster. And moving to a site like sourceforge or freashmeat would take attention of others more experienced programmers that could help us solve some of our's worst problems. Maybe even people envolved on kernel development and gcc/binutils development are interested on get it working on ps2. It's just a suggestion. This stuff is your's.
Ah! Ignore some of what I said last night. I was tired and had forgotten exactly what the sdc1 instruction was. Together with ldc1, they are the two MIPS2 instructions that the EE doesn't have. I was going to sort them out ages ago but I couldn't find them in mips.md. For some reason, I didn't think to look in mips.c. Adding these two !TARGET_MIPS5900 conditions should do the trick.
Except it doesn't. It tries to split the instruction as it should but it fails and I can't figure out why.
Code: Select all
/* Return true if a 64-bit move from SRC to DEST should be split into two. */
bool
mips_split_64bit_move_p (rtx dest, rtx src)
{
if (TARGET_64BIT && !TARGET_MIPS5900)
return false;
/* FP->FP moves can be done in a single instruction. */
if (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
return false;
/* Check for floating-point loads and stores. They can be done using
ldc1 and sdc1 on MIPS II and above. */
if (mips_isa > 1 && !TARGET_MIPS5900)
{
if (FP_REG_RTX_P (dest) && MEM_P (src))
return false;
if (FP_REG_RTX_P (src) && MEM_P (dest))
return false;
}
return true;
}
Code: Select all
/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/build/./gcc/xgcc -B/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/build/./gcc/ -B/usr/mips64r5900el-scei-linux-uclibc/bin/ -B/usr/mips64r5900el-scei-linux-uclibc/lib/ -isystem /usr/mips64r5900el-scei-linux-uclibc/include -isystem /usr/mips64r5900el-scei-linux-uclibc/sys-include -O2 -g -Os -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -I. -I. -I/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc -I/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/. -I/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/../include -I/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/../libcpp/include -I/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/../libdecnumber -I../libdecnumber -g0 -finhibit-size-directive -fno-inline-functions -fno-exceptions -fno-zero-initialized-in-bss -fno-toplevel-reorder -Dinhibit_libc \
-c /var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/crtstuff.c -DCRT_BEGIN \
-o crtbegin.o
/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/crtstuff.c: In function '__do_global_dtors_aux':
/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/crtstuff.c:304: error: could not split insn
(insn/f:TI 80 78 91 (set (mem/c:DI (plus:SI (reg/f:SI 29 $sp)
(const_int 8 [0x8])) [10 S8 A64])
(reg:DI 28 $28)) 204 {*movdi_64bit} (nil)
(expr_list:REG_DEAD (reg:DI 28 $28)
(expr_list:REG_FRAME_RELATED_EXPR (set/f (mem/c:DI (plus:SI (reg/f:SI 29 $sp)
(const_int 8 [0x8])) [10 S8 A64])
(reg:DI 28 $28))
(nil))))
/var/tmp/cross/mips64r5900el-scei-linux-uclibc/portage/cross-mips64r5900el-scei-linux-uclibc/gcc-4.2.0-r2/work/gcc-4.2.0/gcc/crtstuff.c:304: internal compiler error: in final_scan_insn, at final.c:2449