SifBindRpc after SifIopRest

Discuss the development of software, tools, libraries and anything else that helps make ps2dev happen.

Moderators: cheriff, Herben

Post Reply
ole
Posts: 92
Joined: Sat May 08, 2004 11:14 pm
Location: Czech Republic

SifBindRpc after SifIopRest

Post by ole »

I can't bind my iop rpc (SifBindRpc) after having reseting the iop by SifIopReset.
The startup code on EE looks like this:

Code: Select all

init_scr();
SifInitRpc(0);
SifExitIopHeap(); //x1
SifLoadFileExit();
SifExitRpc();

SifIopReset(NULL, 0);
while (SifIopSync()) ;
SifInitRpc(0); //x2
loadModules();
bindRpc&#40;&#41;; // <-----here the prog hangs in the loop waiting for SifBindRpc
If I remove the whole section marked from //x1 to //x2 the binding runs just well (but iop is infested ...).
I'm trying to remove naplink modules out of IOP in order to load usbd.irx.
The rpc on iop should send debug messages from iop to ee.

Am'I missing something ? Or should be the SifIopReset called with some magic string (rom0:UDNL makes no difference) ?

Ole
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

while (SifIopSync()) ;

should be:

while (!SifIopSync()) ;

since SifIopSync() returns true if all IOP modules have successfully loaded.
ole
Posts: 92
Joined: Sat May 08, 2004 11:14 pm
Location: Czech Republic

Post by ole »

thanks mrbrown,
I corrected it in my program but the problem remains.
Maybe the problem is that the module is not loaded properly (after the SifIopReset is performed) - so the rpc server is not created at the iop side and the Bind function just can't find the server.

Actually the SifLoadModuleBuffer is returning me number that is exactly the iop memory address of the module buffer. When the SifIopReset is not executed then SifLoadModuleBuffer returns much smaller number (for example: 28). So I assume the SifLoadModuleBuffer causes the trouble.

Any info about that behavior?
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Yeah, I figured this was also the problem .. apologies for not mentioning it. You will need to either reset the IOP using SifIopReset("rom0:UDNL rom0:EELOADCNF", 0); or after resetting the IOP with SifIopReset(NULL, 0), you will have to use the "patch_enable_lmb()" function found in the SBV lite library (see http://www.0xd6.org/). This is because the default IOP image (passing NULL to SifIopReset()) doesn't include SifLoadModuleBuffer (LMB) support, but EELOADCNF does and also the patch from SBV enables it.
ole
Posts: 92
Joined: Sat May 08, 2004 11:14 pm
Location: Czech Republic

Post by ole »

Hmm... no luck.
If I reset iop by SifIopReset("rom0:UDNL rom0:EELOADCNF",0) then the SifLoadModuleBuffer freeze the EE completely.

If I use sbv_patch_enable_lmb() then the SifLoadModuleBuffer returns the IOP address. Btw the ret value from patch_enable is 0.

The strange thing seems to be that SifIopReset(NULL,0) does not reset iop correctly. When I make the listing of the iop modules (after the iop reset - I use te smod_get_next_mod) then I can see both naplink modules loaded! When the iop is reset by the "rom0:UDNL rom0:EELOADCNF", then IOP is reset (?correctly? naplink console writes: peer lost and module listing is free of these naplink modules), but SifLoadModulebuffer hangs. :(

Maybe I'm destined to buy the network adapter.... :(
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Are you using SifLoadModuleBuffer() correctly? Please see http://docs.ps2dev.org/ps2lib-doc/html/ ... dfile.html. If you aren't DMA'ing the contents of the IRX from the EE yourself (before calling LMB), then you have to use SifExecModuleBuffer(). Also, any modules that you plan to load must be aligned to a 16-byte address in EE memory.
ole
Posts: 92
Joined: Sat May 08, 2004 11:14 pm
Location: Czech Republic

Post by ole »

As I wrote: if I do not reset the iop, then the modules are loaded correctly (from buffer). At first I used the dma-ing function for upload to IOP and then SifLoadBuffer call. Current code use the SifExecModuleBuffer() function only.
The data buffer is alligned like this:
unsigned char usbd[] __attribute__((aligned(64))) = {
0x7F, 0x45, 0x4C, 0x46,.......
};

Both versions give me the same results (ExecBuffer use the LoadBuffer too). When IOP is reset(NULL, 0), loadBuffer returns the iop address. When IOP is reset("rom0:UDNL rom0:EELOADCNF",0) then loadBuffers freeze the EE.

My test code that doesn't work for me is here:

Code: Select all

#include <tamtypes.h>
#include <kernel.h>
#include <iopheap.h>
#include <sifrpc.h>
#include <sifcmd.h>
#include <loadfile.h>
#include "sbv_patches.h"
#include "iopcontrol.h"

#include "usbd.h"	 //usbd.irx module
#include "usbtest.h"    //usbtest.irx module
#include "usbtest_size.h"

/*
// content of these header files&#58;

int usbd_size = 33216;
unsigned char usbd&#91;&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41; = &#123;
  0x7F,  0x45,  0x4C,  0x46,.....
&#125;;

*/


#define	USB_TEST	0x500C0F1

static SifRpcClientData_t client __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;
unsigned char rpcBuffer&#91;2048&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;


void printMessage&#40;&#41;
&#123;

	SifCallRpc&#40;&client,0,0,&#40;void*&#41;&#40;&rpcBuffer&#91;0&#93;&#41;,0,&#40;void*&#41;&#40;&rpcBuffer&#91;0&#93;&#41;,2048,0,0&#41;;
	if &#40;rpcBuffer&#91;0&#93; == 0&#41; &#123;
		return;
	&#125;
	scr_printf&#40;"%s", rpcBuffer&#41;;

	SifCallRpc&#40;&client,1,0,&#40;void*&#41;&#40;&rpcBuffer&#91;0&#93;&#41;,0,&#40;void*&#41;&#40;&rpcBuffer&#91;0&#93;&#41;,128,0,0&#41;;
&#125;

void initUsb&#40;&#41;
&#123;
	SifCallRpc&#40;&client,2,0,&#40;void*&#41;&#40;&rpcBuffer&#91;0&#93;&#41;,0,&#40;void*&#41;&#40;&rpcBuffer&#91;0&#93;&#41;,128,0,0&#41;;
&#125;



void loadModules&#40;&#41; &#123;
	int ret;
	int iop_ret;


	SifInitIopHeap&#40;&#41;;
	SifLoadFileInit&#40;&#41;;
	fioInit&#40;&#41;;


	ret = SifExecModuleBuffer&#40;usbd, usbd_size, 0, NULL, &iop_ret&#41;;
	if &#40;ret < 0&#41; &#123;
		scr_printf&#40;"sifLoadModule %s failed&#58; %d\n", "usbd", ret&#41;;
		while&#40;1&#41;;
	    &#125; else scr_printf&#40;"usbd.irx ok  ret=%i\n", ret &#41;;


	ret = SifExecModuleBuffer&#40;usbtest, usbtest_size, 0, NULL, &iop_ret&#41;;    
	if &#40;ret < 0&#41; &#123;
		scr_printf&#40;"sifLoadModule %s failed&#58; %d\n", "test", ret&#41;;
		while&#40;1&#41;;
	&#125; else &#123;
		scr_printf&#40;"test.irx ok. ret=%i \n", ret&#41;;
        &#125;

	//short delay 
	ret = 0x01000000;
	while&#40;ret--&#41; asm&#40;"nop\nnop\nnop\nnop"&#41;;


	scr_printf &#40;"SifBindRpc..."&#41;;
	while&#40;1&#41; &#123;
	        ret = SifBindRpc&#40; &client, USB_TEST, 0&#41;;
        	if &#40; ret  < 0&#41;  &#123;
	           break;
	        &#125;
	        if &#40;client.server != 0&#41; break;

	        // short delay ???
	      	ret = 0x10000;
	    	while&#40;ret--&#41;;
	    &#125;
	if &#40;ret < 0 &#41; &#123;
	        scr_printf&#40;"\nSifBindRpc failed&#58; %d !!!!\n", ret&#41;;
	&#125;else &#123;
		scr_printf&#40;"ok\n"&#41;;
	&#125;

&#125;

void resetIOP&#40;&#41; &#123;
	int ret;

	SifInitRpc&#40;0&#41;;
	SifExitIopHeap&#40;&#41;;
	SifLoadFileExit&#40;&#41;;
	SifExitRpc&#40;&#41;;

	SifIopReset&#40;NULL,0&#41;;
	while &#40;!SifIopSync&#40;&#41;&#41; ; 

	ret = sbv_patch_enable_lmb&#40;&#41;; //sbv-1.0-lite
	scr_printf&#40;"patch lmb=%i \n", ret&#41;;
&#125;

int main&#40;&#41;
&#123;
	init_scr&#40;&#41;;
	scr_printf&#40;"Test...\n"&#41;;

	resetIOP&#40;&#41;;

	SifInitRpc&#40;0&#41;;

	loadModules&#40;&#41;;
	
	initUsb&#40;&#41;;
  	while&#40;1&#41; printMessage&#40;&#41;;
&#125;
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Hmm, to be on the safe side, try putting the SifInitRpc(0) before the call to sbv_patch_enable_lmb(). I'm unsure ATM if it makes any difference, but that's how I have it in my own code.

Also, as a test, what happens if you try to load other modules the "normal" way, using SifLoadModule(), before the call to SifExecModuleBuffer()? For example try loading rom0:SIO2MAN and rom0:MCMAN, and then try loading your embedded usbd.
ole
Posts: 92
Joined: Sat May 08, 2004 11:14 pm
Location: Czech Republic

Post by ole »

rom:SIO2MAN & rom0:MCMAN are loaded correctly (ret code 25, 26).
But I think it can be related to initial memory allocation (?stack size?). Beacause if I remove usbd.h and skip loading the larger module (usbd ) then the second test module (the smaller one) doesn't make the EE to freeze. Although the return code = -200 (any clue what this means? - not documented in headers) it's some progress :). Just for test I have tried to embed and load hello.irx (from the samples directory) and it loads correctly!
Mayby some modification of the crt0 (linkfile?) coud help.
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Any chance you could post your source and Makefile up somewhere? I'd like to take a closer look.
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Except for the usbd.irx -> header file, of course :). I'll supply my own.
ole
Posts: 92
Joined: Sat May 08, 2004 11:14 pm
Location: Czech Republic

Post by ole »

Can I send it to your 0xd6.org contact address?
The zip package size is about 15kb.
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Send away :).
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

I tested your program ... the only thing that I can see is that usbd.irx flat-out crashes during initialization. It's possible that this version of usbd.irx relies on bugfixes or other functionality that's only present in updated IOP drivers shipped with games.

No matter which options I specified (FREEZE and/or NO_RESET) I get the same crash. The usbd.irx that I'm using is the same size as the one you've been using.
ole
Posts: 92
Joined: Sat May 08, 2004 11:14 pm
Location: Czech Republic

Post by ole »

Well That's it!
New versions of usbd (I tested ver 0.20.0) are crashing (maybe beacause it's size is larger than 32kb) but older version (tested 0.16.0, 0.17.0 - size is smaler than 32kb) works!
So the crash reason is either:
1)SifLoadBuffer not support sizes > 32kb
or
2)Compiler can't embed data structures > 32kb in continuous block - so loadBuffer crashes
or
3)Iop malloc Heap cant allocate continuous block of memory > 32kb - so load buffer crashes
or
4) I'm dumb... :)
or
5) combinations of above mentioned.

Anyway. It runs for me (embeded ) with older usbd versions and seems to be ok (iop driver correctly registers attached usb devices...).
Thanks mrbrown for your support and bright ideas.

Ole
MrHTFord
Posts: 35
Joined: Tue Feb 10, 2004 2:04 am
Location: England

SifExecModuleBuffer fixes.

Post by MrHTFord »

Hi Ole,

I think I may have found some issues with SifExecModuleBuffer.

There are 2 definite bugs and 1 possible bug, in that order:-

1. Xfer size isn't rounded up to the nearest 16 bytes.
2. The DataCache isn't written back pre-dma.
3. The Dma isn't waited on before freeing the IOP buffer.

Anyway, here's my new code:-

Pixel's just commited it to CVS, so if there's any problems herein, get shouting!

Code: Select all

int SifExecModuleBuffer&#40;void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res&#41;
&#123;
	SifDmaTransfer_t dmat;
	void *iop_addr;
	int res;
	unsigned int qid;

	/* Round the size up to the nearest 16 bytes. */
	size = &#40;size + 15&#41; & -16;

	if &#40;!&#40;iop_addr = SifAllocIopHeap&#40;size&#41;&#41;&#41;
		return -E_IOP_NO_MEMORY;

	dmat.src = ptr;
	dmat.dest = iop_addr;
	dmat.size = size;
	dmat.attr = 0;
	SifWriteBackDCache&#40;ptr, size&#41;;
	qid = SifSetDma&#40;&dmat, 1&#41;;
	if&#40; !qid &#41;
		return -1;

	while&#40; SifDmaStat&#40; qid &#41; >= 0 &#41;
		;

	res = _SifLoadModuleBuffer&#40;iop_addr, arg_len, args, mod_res&#41;;
	SifFreeIopHeap&#40;iop_addr&#41;;

	return res;
&#125;
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

The transfer size is rounded up to of multiple of 16 bytes by sceSifSetDma(). The other fixes are good :), although the blocking SIF RPC call probably takes care of making sure the module transfer has completed. Good stuff.
"He was warned..."
pixel
Posts: 791
Joined: Fri Jan 30, 2004 11:43 pm

Post by pixel »

He seemed to say it was rounded down instead of up. Well, I haven't checked anyway :P

On a complete side note, I am still unable to find where gcc emits the lq/sq code for the move_by_pieces optimisation. I'd say you shouldn't use -O3 at all MrHTFord :P
pixel: A mischievous magical spirit associated with screen displays. The computer industry has frequently borrowed from mythology. Witness the sprites in computer graphics, the demons in artificial intelligence and the trolls in the marketing department.
Post Reply