Repository navigation
Replies: 18 comments 52 replies
|
Hmm... GCC 9.2 is quite old, maybe that’s a problem? Have you tried booting I use the |
|
I tried out that vmlinuz-pal-ps2-main-77174dd4. Using binwalk terminal utility, I extracted vmlinux from vmlinuz-pal-ps2-main-77174dd4 to compare with the kernelconfig I'm using (which is actually arch/mips/configs/ps2_defconfig) - there are some differences:
have no effect anymore. I had to find out what exactly I must to write instead... Otherwise, stdout goes to somewhere else. After those fixes, I finally could run till that "Welcome!" introduction. I noticed that One of the things I wanted to talk about is ll/sc instructions handling mechanic. Currently, they (transformed by the toolchain into lwc0/swc0) are handled by a Reserved Instruction traps exception with a further appropriate ll or sc emulation. All that long process for "ll" opcode, and the same longness for "sc" opcode. How it should be called, this one for musl-1.2.5: Same for glibc: Updated the codes here. Tested them out, so I consider it is worthy to take place! What would you say? The alternative use of syscall instead of two RI-exceptions must significantly speed things up! |
Well, I changed those /dev/console lines to
Any program linked with -lc have them. For example, that busybox included in your current releases have 33 pares of lwc0/swc0: Each ll and sc instruction triggers Reserved Instruction exception. That leads to the whole stack of registers is saved due to entering kernel mode. Then, searching and comparing the value of the Reserved Instruction to find out what exactly should be emulated. Next, emulation process obviously. After that, restoring the previously saved stack of registers with a concomitant other stuff (like interruptions and etc) processing, and at last, returning to the userspace. The straight Compare and Set realization as a syscall path should be at least twice as short. Doing a syscall - that leads to the whole stack of registers is saved due to entering kernel mode. Next, compare, set. After that, restoring the previously saved stack of registers with a concomitant other stuff (like interruptions and etc) processing, and at last, returning to the userspace. Also, the resulted binary of the resolved with CAS code, is slightly smaller due to all those asm volatile of the ll/sc pares replaced to the jump to the syscall.
Well, I have an installation of toolchain with glibc-2.34 which have the experimental updates I noticed above. Also I noticed, that it is slightly unstable:
despite that, as for a test benchmark, how about 100.000 iterations of 2 processes are processing the same variable with a time passed - by the method of RI exception and by the method of syscall? To compare them between each other. |
|
Alright, maybe the next one will be more interesting. — this way 2 GPRs t4 and t5 are surviving at their whole 128bit. To keep them in the thread_info space, which is attaching to the each process individually. The advantage of this method is that way t4 and t5 are automatically survives by default, so even userspace programs are alright with them! Updated: those edits in thread_info.h should not be used as is. They are not fully enough - something else is interrupting/corrupting as well, after which the bits 127-32 of registers are not surviving. |
|
Hey again. I was making some attempts to successfully transfer a packet from the Linux side (kernel module) to the IOP (.irx) by preparing a SifRpc background server. The goal was to witness the ff_count value changing sequentially in the first byte of g_rpc_buffer on the IOP. Instead, an unexpected layout corruption was encountered. When dumping the exact 16 bytes received by the IOP RPC handler, the target buffer did not contain my raw safe_send_buffer data starting at index 0 at all. I verified and proved on both sides that the server address on the IOP side correctly matches the address identified, again, on by both sides. I'm not sure how it happens... What I am doing wrong? Are SIF1 transfers fully operational under this driver implementation? |
|
Thank you very much, that worked like a charm ^_^
|
Indeed! Every single step of the new concept was tested in advance using them (like pr_info("quack\n")) XD
well... I am not that competent of a person to give a definitive answer to that issue. To be honest, I don't fully grasp the inner workings of DMA channels, all those control bits... |
|
I'd like to introduce an other thing first.
I created the thread on sourceware bugzilla, but eventually handled the things by myself. Please, look at this: — that makes GCC utilizing the r5900's special 'plzcw' instruction everywhere possible (particularly __ctzsi2 is a part of all floating point software calculations, which are using while issue №3 inconcluded, and __clzsi2 is using almost everywhere in libc). And an independent standalone place in the kernel: — I would not say the loading speeded up at the speed of light, but anyway, whatever makes it better while staying stable :D Check with an objdump to grep for 'plzcw' to see how many!
hmm... What are your thoughts about it? Did you notice some... I dunno how to say... non-standard behavior? And, IOP processor, it is MIPSel R3000A , right? Any known limits from MIPS-I ? Any known instruction expands? And about SIO2 DMA. The channels for (that's why I am asking the question about channel number), the channel 5, IOP_DMAC_PIO - it is disabled since loaded to initramfs and module gamepad activated, but the gamepads are working... |
|
@Arch91, I’ve now quickly tested your gamepad driver contribution, and it seems to work nicely. Thanks! :-) How would you like to be credited for your code? Full legal name and email in the commits? Or some alias? I will most likely need to rewrite a lot of it during clean-up, but it’ll be based on your work. I’ve made a provisional These two MIPS program files can then be copied to the INITRAMFS (or some other usable place) for testing on PlayStation 2 hardware: $ file /usr/mipsr5900el-unknown-linux-musl/usr/bin/evtest
evtest: ELF 32-bit LSB executable, MIPS, MIPS-III version 1 (SYSV), statically linked, stripped
$ file /usr/mipsr5900el-unknown-linux-musl/usr/bin/fftest
fftest: ELF 32-bit LSB executable, MIPS, MIPS-III version 1 (SYSV), statically linked, strippedI should probably add some paragraphs about how to do this on the wiki page for the PlayStation 2 controllers, for anyone else wanting to test the gamepads. Plus, the wiki page will have to be expanded with the nifty new gamepad features! |
|
Half is understood, half is accepted as given. Thanks for the explanations! I'm gonna prove, that there HAS TO be a delay between the commands! It's needed in principle, not necessary exactly 5000 μs. Test2: comment the AA, BB and CC pr_infos. You'll see that the success criteria are not met: MADR idiffers from the zx_buf values by only '0x08'; the upper 2 bytes of BCR contain 0001 for CH11 and 0000 for CH12; the highest byte of CHCR contain 01 for CH 11 and 4_0_ for CH12. Test3: make AA pr_infos uncomment, and leave both BB and CC commented. You'll see that the success criteria are not met in this test as well: MADR differs from the zx_buf values by only '0x10'; the upper 2 bytes of BCR contain 0001 for CH11 and 0000 for CH12; the highest byte of CHCR contain 01 for CH 11 and 40 for CH12. Test4: make both AA and BB pr_infos uncomment, and leave only CC one commented. You'll see that the success criteria are not met in this test either: MADR differs from the zx_buf values by only '0x18'; the upper 2 bytes of BCR contain 0001 for CH11 and 0000 for CH12; the highest byte of CHCR contain 01 for CH 11 and 40 for CH12. pr_infos obviously do not directly influence to the DMA mechanism. From that, I am making a conclusion, that it must be because IOP is physically spending the time for preparing and printing those pr_infos, and while it spends time for it, DMA transmittions (particularly which matters for a write one) gain enough time to complete successfully. |
|
@Arch91, a new gamepad driver is now available for testing:
I’m happy with how it turned out, but I’ve only really tested it with a DualShock 2. It makes use of interrupts, with a state machine, but not (yet) DMA. These timings can be adjusted, for example: enum { /* Times in us */
CONTROLLER_DISCOVERY_POLL = 500000, /* 2 Hz device discovery */
CONTROLLER_QUERY_POLL = 100000, /* 10 Hz device query */
CONTROLLER_ACTIVE_POLL = 5000, /* 200 Hz device active */
CONTROLLER_PASSIVE_POLL = 100000, /* 10 Hz device passive */
CONTROLLER_SCHEDULE_TIME = 4000, /* Schedule at least 4 ms */
CONTROLLER_IDLE_TIME = 10*1000000, /* Idle after 10 seconds */
};It’s a bit too chatty in the kernel log now, but I think I’ll change some of the info prints to module debug later on. Are you ready to test it? :-) |
I bet you are the only person in the world who has a network on kernel 5.X XD. As for me, I usually test everything on USB. Centuries will pass before I handle the technique of pseudo-reboots... I even lazy to cut out the USB Wi-Fi drivers from my default kernel config ^) ooh! New function! I like it! But seeing many structs in a gamepad .irx driver code is @_@ I think I wouldn't dare to make any attempts if the code had looked this complex from the beginning :) To be able to compile the kernel modules now, I had to do this: Now, regarding the test. - those I see about DualShock 1. Meanwhile... I updated my scripts for building the toolchain |
Applied'n'tested. Compiled flawlessly.
Now, in test with jstest, it shows axes presented. For a gamepad, to be physically able to provide the axis states, we have to enlight the ANALOG. For DS1 axes are not working in the current driver state! Please, check it. As for the naming - yep, I saw "DualShock", the first.
I think you made a mistake by writing "digital to analog" when you actually meant "digital to pressure"... Even taking that into account, I do not quite understand what you meant by that.
- I'll sign nothing without 0x79 "pressure" mode! XD Holding my DS2 gamepad processed by the current driver feels bright and powerful, but I also feel like I am kind'a holding a eunuch ^) |
|
Soundwise initiation borne fruit! I and AI tamed the noise generator B) Surgical addresses manual writting while looking to the appropriate functions did the trick. And the file I was looking for by is PS2SDK's iop/sound/ahx/src/spu2.c To say in advance, this is the maximum I wanted to do. Next step is up to the real developers, better to those who were dealing with those drivers from PS2SDK. |
|
I’ve measured SIO2 transmission performance, by
Given that the IOP operates at approximately 30 MHz, 1 μs is roughly 30 processor cycles. Note that the closed and idle modes are normally at 2 Hz and 10 Hz, respectively. However, the two controllers are independent, and don’t always “time up” on the same SIO2 transmission, particularly when they are low frequency. The likelihood of the two controllers sharing the same SIO2 transmission is much greater at the frequent 200 Hz active digital and analog modes. We can compute how much time the IOP spends on the (active) analog mode: By the same computation, the (active) digital mode needs 2 %. The idle mode 0.2 %, and the closed mode 0.03 %. The two latter modes are practically negligible, barely using any IOP computational resources at all. With the additional code (apart from the SIO2) managing the controllers, I guess that the total for the (active) analog mode is perhaps 5 % of IOP time. I don’t think DMA would be faster for the IOP, since the amount of tx and rx data is low. However, it will probably work much better in combination with memory card SIO2 transactions. |
|
Well, I believe that even 21μs is the enough pause to switch the context to work somewhere else. I wrote two codes:
Another thing I was thinking about is that at some of your messages you were saying that you implemented the separated threads for port 0 and port 1. But let's imagine the driver will ever became able to handle MX4SIO boards, to handle a linux loaded from that device. I suppose, most of the time SIO2 channels will be occupied by that block device with the high frequency large data DMA transactions, and there will be just a small pauses/windows for switching to the call of gamepads - and I believe particularly in that moment there must be processed all the input SIO2 devices, not just one of them. What do you think? And an another one:
In the process I was rewriting the code logic to DMA 'rails', I had to avoid the use of thbase_set_alarm function. Thanks to the semaphores (and taking that global one which can be used in share in future for SIO2 block devices), the thread could approximate into the simple: So. As my understanding about the alarm, alarm is a high-priority interruption, which triggers the abandoning the other processes immidiately with swtiching to the alarm caller. Is that how really threads queue must be processed? |
I'm not familiar with it, and I have no clue what its purpose is...
At first, I just took that phrase way too literally :) Like, a pages release or memory zeroing mechanism implemented by blasting zeros through an "unneeded" DMA channel XD But yeah, as for zero-copy itself, I had gotten it before - it's about allocations instead of writing.
Well, those conceptual prototypes aren't really meant for public teaching. Sure, they clearly demonstrate how a specific feature is implemented, but where? - it's either in the iopmod project or the Linux kernel. For someone to actually test them, they’d need to know how to build the kernel, set up and use a cross-compiler, have a real console capable of running it, and on top of all that, have an interest in PS2 kernel + iopmod programming. There's a higher chance of Apophis hitting Earth than anyone actually doing that... It’s more likely intended to spark your interest/inspiration to port some of these concepts into your code ;)
It's better for you to not see how it is identified in the system then XD Anyway, I never aimed to maintain the Linux kernel or mainlining anything matching strict standards. Also, what did you do to the gamepad driver I posted?! - you violated it with renaming every single function, stripping the analog mode out of the three digital/analog/pressure modes, skipping implementing the DMA with pauses, and at times it even felt like where I wrote 2+3, you wrote 3+2 just to make it look different XD I'm kidding, of course. But seriously, all of this is just an attempt to make things work. The final word is always up to you. Now, regarding SIF0/1 DMA transfers.
The theory. EE side: IOP side: The practice. EE matches the expected with theory, everything is alright here. But I did manage to transmit 64KB in a single chunk this way, and then, to prove that it wasn't just ghost data running around, I passed it to the SPU, and it successfully played it. Another thing is the absence of a function to receive incoming SIF1 DMA transfers in the logic of the sifman_set_dma_intr function, if we are to believe how it is designed in the PS2SDK — or more precisely, the set_dma_inner function. With it, it is possible to queue a DMA transaction for execution with an interrupt upon its completion, but only for outgoing transfers via SIF0! It turns out that incoming SIF1 DMA transactions are both deprived of a completion interrupt and forced to compete with others like them in a way that is completely unincluded by the sifman queue logic. After a successful Normal<->Slice DMA transfer, how could one avoid to try the chain mode? I saw: and decided to do a test run right away: How to share SIF0/1 DMA transactions, and simultaneously how it would be possible to use sifcmd and sifrpc while doing so, is a question for a month-long round-table meeting... I see the theoretical concept of chain_source->chain_destination on SIF channels as follows:
What are the advantages compared to Slice mode: However, as for a practical use case where it is absolutely necessary or highly beneficial to use chain mode because sliced mode falls short, I still fail to see one to this day. It is not obvious to me which tag the end bit should be inserted into — whether it should go into the tag that carries the final transfer after which there are no more transfers, OR if another almost-empty tag with the end bit raised is required. The theoretical concept, as I see it, somewhat breaks down against what is written in sifman.c of the PS2SDK: - this chcr value, it is Slice mode! How'so?! And this write to BCR, where the upper 16 bits are preserved... All of this completely throws me off... I thought that maybe this was an implementation error in sifman.c within the PS2SDK itself (after all, we are all human, bags of meat, everyone makes mistakes), but after checking out the sifman_set_dchain function on practice, I actually saw the value 0x40000300 in CHCR... This is weird. I expected 0x41000600. So, much like the Vatican and its library, the console once again refuses to reveal the secrets of the chain mode to me }:p |

Uh oh!
There was an error while loading. Please reload this page.
Hello again, frno7 ! Long live to your PS2Linux 5.x kernels project :D
While I was in a business trip, I wrote TEN functions which I'd like to test on the real hardware in PS2Linux on your kernel. Four of those functions, if my suppose is correct, eventually can automatically speed up the particular things in ps2dev community a little bit. And other things... I'd like to test before to even talk about them.
...However, even though I archived the scripts and config-files, patches, which are leading to the 'working those days' toolchain, but following them, the result is I simply can not run the kernel/initrd to the "Welcome!" stage. Can you, please, help in re-freshing my building knowledges to find out what I am doing wrong?
Kernel headers:
make ARCH=mips headers_install INSTALL_HDR_PATH=/usr/local/ps2/mipsr5900el-unknown-linux-gnu
binutils-2.34. It's configure flags:
--prefix=/usr/local/ps2 --target=mipsr5900el-unknown-linux-gnu --enable-shared --enable-plugins --disable-werror
gcc-9.2.0, st1. It's configure flags:
--prefix=/usr/local/ps2 --target=mipsr5900el-unknown-linux-gnu --enable-languages=c --includedir=/usr/local/ps2/mipsr5900el-unknown-linux-gnu/include --disable-nls --disable-shared --disable-libssp --disable-libmudflap --disable-threads --disable-libgomp --disable-libquadmath --disable-target-libiberty --disable-target-zlib --without-ppl --without-cloog --with-headers=no --disable-libada --disable-libatomic --with-llsc=no --with-float=soft --disable-multilib
glibc-2.13, glibc-ports-2.13.
mkdir build
cd build
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
configure flags:
mipsel-linux --prefix=/usr/local/ps2/mipsr5900el-unknown-linux-gnu --build=i686-pc-linux-gnu --host=mipsr5900el-unknown-linux-gnu --enable-shared --with-headers=/usr/local/ps2/mipsr5900el-unknown-linux-gnu/include --enable-add-ons --with-tls --with-__thread --without-fp --cache-file=config.cache
gcc-9.2.0, st2. Flags:
--prefix=/usr/local/ps2 --target=mipsr5900el-unknown-linux-gnu --enable-languages=c,c++ --includedir=/usr/local/ps2/mipsr5900el-unknown-linux-gnu/include --enable-libatomic --with-llsc=yes --with-float=soft --disable-multilib
glibc-2.30.
mkdir build
cd build
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
configure flags:
mipsel-linux --prefix=/usr/local/ps2/mipsr5900el-unknown-linux-gnu --build=i686-pc-linux-gnu --host=mipsr5900el-unknown-linux-gnu --enable-shared --with-headers=/usr/local/ps2/mipsr5900el-unknown-linux-gnu/include --enable-add-ons --with-tls --with-__thread --without-fp --disable-experimental-malloc --with-pkgversion="GNU libc v2.30, nothing special" --cache-file=config.cache
gcc-9.2.0, final st. configure flags:
--prefix=/usr/local/ps2 --target=mipsr5900el-unknown-linux-gnu --enable-languages=c,c++ --includedir=/usr/local/ps2/mipsr5900el-unknown-linux-gnu/include --enable-libatomic --with-llsc=yes --with-float=soft --disable-multilib
busybox-1.28.0.
I have a .config file for it from those times I could questionlessly build things by myself. Moved the folder with the installed files to the same directory level which has kernel source. Folder name: "initramfs-ps2". And inside it:
mkdir {dev,lib,proc,sys,mnt,newroot}
mkdir lib/firmware/ps2
cp init-for-busybox.sh init || exit -1
cp actual_init-for-busybox.sh sbin/init
iopmod
cp arch/mips/configs/ps2_defconfig .config
make ARCH=mips CROSS_COMPILE=mipsr5900el-unknown-linux-gnu- oldconfig
make ARCH=mips CROSS_COMPILE=mipsr5900el-unknown-linux-gnu- -j 4 modules
make ARCH=mips CROSS_COMPILE=mipsr5900el-unknown-linux-gnu- -j 4 vmlinuz
make ARCH=mips CROSS_COMPILE=mipsr5900el-unknown-linux-gnu- INSTALL_MOD_PATH=$INITRAMFS_DIR INSTALL_MOD_STRIP=1 modules_install
make ARCH=mips CROSS_COMPILE=mipsr5900el-unknown-linux-gnu- -j 4 vmlinuz
mv vmlinuz /path/to/my_flashdrive/PS2Linux_v5.4.211.ELF
It starts.

As far as I remember, next the screen must flash once (as a result of the /sbin/init's "modprobe ps2fb mode_option=1920x1080p@50") and relocate to an other screen with the "live" things we can operate.
Also, I remember that to be witnessing "initrd not found or empty - disabling initrd" is alright when we have initramfs. I even remember that I edited the code of that message to something else XD to be not confused.
And also, I tried to download pal initrd from the releases of your kernel, unpacked it, saw that it includes busybox, .irx modules but no kernel modules, so I added kernel modules compiled by me and injected into the kernel as initramfs - no result. Can not really suppose what is the case... Initramfs is building and sticking inside the kernel but actually the kernel expects the outside initrd, I dunno?.. Any suggestions?
btw, is it ok to see a bloomed text in the kernel initial run screen resolution as it is on my picture?
All reactions