Media Engine?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

StrmnNrmn
Posts: 46
Joined: Wed Feb 14, 2007 11:32 pm
Location: London, UK
Contact:

Post by StrmnNrmn »

Ok, just to confirm, the following does appear to work:

Code: Select all

void dcache_wbinv_all()
{
   int i;
   for&#40;i = 0; i < 8192; i += 64&#41;
   &#123;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
   &#125;
&#125;
(As does iterating up to 16384 with a single call to __builtin_allegrex_cache, or performing the loop twice).

Does this imply that the other cache invalidation routines need similar tweaking (i.e doubling up)? I haven't found any issues to date with dcache_inv_all, dcache_inv_range or dcache_wbinv_range, but I'll post back here if I spot anything.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

crazyc wrote:
Raphael wrote:Isn't the cache 16kb?
I believe the entire cache (i+d) is 16kb, but i'm not 100% sure.
http://en.wikipedia.org/wiki/PlayStation_Portable wrote:Both CPUs contain 16KiB of two-way set associative instruction cache and data cache respectively.
Though not the best source of information, I understand that as 16kb for each.
Someone reversed the sony function for wbinvall to check?

@StrmnNrmn: The inv_range ops definitely shouldn't need the doubling, as those operate on addresses and not indices.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

Raphael wrote:Though not the best source of information, I understand that as 16kb for each.
Someone reversed the sony function for wbinvall to check?
The code in sceKernelWritebackInvalidateAll looks like:

Code: Select all

int sceKernelWritebackInvalidateAll&#40;void&#41; &#123;
   int i, j;
   j = mfc0&#40;0x16&#41;;   // Config register
   j = &#40;j >> 6&#41; & 3;
   j = 2048 << j;
   for&#40;i = 0; i < j; i += 64&#41;
  &#123;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
  &#125; 
&#125;
mfc0 0x16 is 0x480 so 2048 << 2 is 8192, but after testing, it does appear the dcache is 16kb. I don't know why it's done this way.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

Well, makes sense then to do it that way :) thanks
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

crazyc wrote:
Raphael wrote:Though not the best source of information, I understand that as 16kb for each.
Someone reversed the sony function for wbinvall to check?
The code in sceKernelWritebackInvalidateAll looks like:

Code: Select all

int sceKernelWritebackInvalidateAll&#40;void&#41; &#123;
   int i, j;
   j = mfc0&#40;0x16&#41;;   // Config register
   j = &#40;j >> 6&#41; & 3;
   j = 2048 << j;
   for&#40;i = 0; i < j; i += 64&#41;
  &#123;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
  &#125; 
&#125;
mfc0 0x16 is 0x480 so 2048 << 2 is 8192, but after testing, it does appear the dcache is 16kb. I don't know why it's done this way.
Being a two-way set, you have two entries for the same index, so 2 x 128 x 64b = 16kb. You need to do it twice only if you want to invalidate and/or writeback an index in both cache-lines. The reason is probably because those cache operations would handle the oldest entry (using LRU algorithm ?).

EDIT:
For a two-way set associative cache, the replacement algorithm is a bit more complex. [...] However, remember the principle of temporal locality : if a memory location has been referenced recently, it is likely to be referenced again in the very near future. A corollary to this is "if a memory location has not been accessed in a while, it is likely to be a long time before the CPU accesses it again." Therefore, a good replacement policy that many caching controllers use is the "least recently used" or LRU algorithm. The idea is to pick the cache line that was not most frequently accessed and replace that cache line with the new data. An LRU policy is fairly easy to implement in a two-way set associative cache system. All you need is a bit that is set to zero whenever the CPU accessing one cache line and set it to one when you access the other cache line. This bit will indicate which cache line to replace when a replacement is necessary
So if we suppose whenever we call CACHE instruction we are setting or resetting this bit LRU, it makes sense we need to do it twice to clear both cache-lines, since this LRU bit acts as a selector for WayA or WayB cache-line.
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

hlide wrote:Being a two-way set, you have two entries for the same index, so 2 x 128 x 64b = 16kb. You need to do it twice only if you want to invalidate and/or writeback an index in both cache-lines. The reason is probably because those cache operations would handle the oldest entry (using LRU algorithm ?).
I guess by this dcache_inv_all should be wrong too, and looking at sceKernelDcacheInvalidateAll does 4096 << 2 so it is.

Code: Select all

static void dcache_inv_all&#40;&#41; &#123;
	int i;
	store_tag&#40;i, 0, 0&#41;;
	for&#40;i = 0; i < 16384; i += 64&#41; &#123;
		__builtin_allegrex_cache&#40;0x13, i&#41;;
		__builtin_allegrex_cache&#40;0x11, i&#41;;
	&#125;
&#125;
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

indeed,

Code: Select all

int sceKernelWritebackInvalidateAll&#40;void&#41; &#123;
   int i, j;
   j = mfc0&#40;0x16&#41;;   // Config register
   j = &#40;j >> 6&#41; & 3;
   j = 2048 << j;
   for&#40;i = 0; i < j; i += 64&#41;
  &#123;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
  &#125;
&#125;
and

Code: Select all

int sceKernelWritebackInvalidateAll&#40;void&#41; &#123;
   int i, j;
   j = mfc0&#40;0x16&#41;;   // Config register
   j = &#40;j >> 6&#41; & 3;
   j = 4096 << j;
   for&#40;i = 0; i < j; i += 64&#41;
  &#123;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
  &#125;
&#125;
should have similar effect if we suppose CACHE index operation truncates index in the range between 0 and 8191.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

hlide wrote:indeed,

Code: Select all

int sceKernelWritebackInvalidateAll&#40;void&#41; &#123;
   int i, j;
   j = mfc0&#40;0x16&#41;;   // Config register
   j = &#40;j >> 6&#41; & 3;
   j = 2048 << j;
   for&#40;i = 0; i < j; i += 64&#41;
  &#123;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
  &#125;
&#125;
and

Code: Select all

int sceKernelWritebackInvalidateAll&#40;void&#41; &#123;
   int i, j;
   j = mfc0&#40;0x16&#41;;   // Config register
   j = &#40;j >> 6&#41; & 3;
   j = 4096 << j;
   for&#40;i = 0; i < j; i += 64&#41;
  &#123;
      __builtin_allegrex_cache&#40;0x14, i&#41;;
  &#125;
&#125;
should have similar effect if we suppose CACHE index operation truncates index in the range between 0 and 8191.
I wonder why SCE decided to use both ways in different functions though. Must have a reason why.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Could just be two different programmers who think about things differently. One thought of writing the same index twice because of the two entries, while the other thought of the aliasing present on the opcode that handled it automatically.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Wow, been a while since anything new on the ME was posted. I have always had a sneaking suspicion that since the Slim doubled the GPU EDRAM from 2MB to 4MB that they probably doubled the ME local EDRAM as well. I FINALLY got around to testing my hypothesis... and it seems I was right! The local memory for the ME seems to extend all the way to 4MB now. Trying to check memory beyond 4MB hangs the ME... probably generates an exception.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

does it make sense to double this ME local EDRAM ? I wonder why... could the latest 2 MB for VRAM fit the first 2MB of ME EDRAM and the latest 2MB for ME EDRAM the first 2MB of VRAM ? It would be awesome but probably wrong.

EDIT: "couldn't" !? sometimes i should reread my sentences :/
Last edited by hlide on Mon Sep 22, 2008 9:09 am, edited 2 times in total.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

hlide wrote:does it make sense to double this ME local EDRAM ? I wonder why... the latest 2 MB for VRAM couldn't fit the first 2MB of ME EDRAM and the latest 2MB for ME EDRAM the first 2MB of VRAM. It would be awesome but probably wrong.
If they keep frames in the local memory for use when decoding video, it makes lots of sense to double the local memory. Just as you couldn't fit two full video frames (720x503) into vram, you can't fit them in local memory either unless you double it.

That might not be the case as the ME can't directly access the vram, but if the ME is used in any way to help decode the video, doubling the local memory would be useful since the move to TV resolutions.

And yes, making the ME EDRAM the "extra" 2MB for the extra vram (and vice versa) would be a cool hack by Sony, and my test did NOT test that possibility.
tailerb
Posts: 3
Joined: Sun Jun 01, 2008 10:59 pm
Location: Russia

Post by tailerb »

Please tell me, when media engine runs my function how big the stack size is and at what adress(in case of mediaengine.prx)?
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

tailerb wrote:Please tell me, when media engine runs my function how big the stack size is and at what adress(in case of mediaengine.prx)?
Looking at the code, you find:

Code: Select all

li		sp, 0x80200000
So the stack for the ME defaults to the end of local memory... at least, the end of local memory on the Phat. As mentioned above, the Slim has 4 MB of local memory instead of 2 MB. The 0x80000000 means kernel space+cacheable - most references I've seen to local memory use kernel space pointers to it.

Since nothing is currently using local memory, your stack is therefore 2 MB in size.
tailerb
Posts: 3
Joined: Sun Jun 01, 2008 10:59 pm
Location: Russia

Post by tailerb »

Thanks a lot! And one more question: what happens with ME when power saving mode activated/deactivated ?
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

crazyc wrote:
Shazz wrote:Short question, what do we have in 0xbc100080 ?????? (And the value 7 for ?)

Code: Select all

	li	k0, 0xbc100000
	li	t0, 7
	sw    t0, 80&#40;k0&#41;
Shouldn't it be 0xbc100050 to enable the ME clock ?

Thx
Access to system memory causes an exception unless that is done.
Err - I just ran across something interesting today. The ME can't access the extended system memory in the Slim. Accesses to 0x08000000 to 0x09ffffff are fine, but trying to access 0x0a000000 on up hangs the ME.

I tried modifying the code above a few ways to see if I could "unlock" the extra mem, but it didn't work. I also tried accessing the memory through kernel mode (|0x80000000) which also fails. So far as I can tell right now, the ME can only access the first 32M of system memory.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

or there is a new mmio register to unlock access on the upper 32 MB we don't know about. Or the same mmio register may be written with a different value to do so. Did you ever try different values like 15 instead of 7 ? I guess you already did : "I tried modifying the code above a few ways to see if I could "unlock" the extra mem, but it didn't work", right ?
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

what about setting bit0-1 of 0xbc100040 to 2 ? (0 = 16 MB, 1 = 32 MB, 2 = 64 MB, 3 = 128 MB) ? dunno if it works and can have an effect on bus exception.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

hlide wrote:or there is a new mmio register to unlock access on the upper 32 MB we don't know about. Or the same mmio register may be written with a different value to do so. Did you ever try different values like 15 instead of 7 ? I guess you already did : "I tried modifying the code above a few ways to see if I could "unlock" the extra mem, but it didn't work", right ?
Yes, exactly. 15 instead of 7 didn't work. I even tried writing -1 out to 60 instead of 30 as well. I'll check if changing 40 has any affect. Thanks for the tip.

EDIT: Good call. Changing the start of the stub to this worked.

Code: Select all

me_stub&#58;
	li		k0, 0xbc100000
	li		t0, 7
	sw		t0, 80&#40;k0&#41;
	li		t0, 2
	sw		t0, 64&#40;k0&#41;
Is there anything else in that reg I should worry about? You mentioned setting particular bits, but I'm just overwriting the whole thing. It DOES work though. You can now write to the second 32 MB with the ME with that change (the last two lines in the code above).
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

J.F. wrote:

Code: Select all

me_stub&#58;
	li		k0, 0xbc100000
	li		t0, 7
	sw		t0, 80&#40;k0&#41;
	li		t0, 2
	sw		t0, 64&#40;k0&#41;
Is there anything else in that reg I should worry about? You mentioned setting particular bits, but I'm just overwriting the whole thing. It DOES work though. You can now write to the second 32 MB with the ME with that change (the last two lines in the code above).
I don't think you should worry about anything else in that register : its purpose is probably only for setting memory size, and i was speaking about those both bits according to what I read in Groepaz's pspdoc.
emufan
Posts: 2
Joined: Mon Feb 16, 2009 5:30 pm

Post by emufan »

Why MediaEnginePRX-v1.0a can not run correct on my psp2000(3.71m33-4)?The result is:
mediaengine.prx loaded/started

Initialized MediaEngine Instance
Now testing MediaEngine functions

Testing BeginME...passed!
1 0 0
1 0 0
:
:
1 0 0
1 0 0
Result is 00000000

Testing CallME...failed! Error calling CallME.

Testing SignalME...failed! Error calling BeginME.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

emufan wrote:Why MediaEnginePRX-v1.0a can not run correct on my psp2000(3.71m33-4)?The result is:
mediaengine.prx loaded/started

Initialized MediaEngine Instance
Now testing MediaEngine functions

Testing BeginME...passed!
1 0 0
1 0 0
:
:
1 0 0
1 0 0
Result is 00000000

Testing CallME...failed! Error calling CallME.

Testing SignalME...failed! Error calling BeginME.
Remember that 3.71 had different NIDs for the ME stuff, and no NID resolver. If you look at my MediaEngine PRX, you'll see have have special support for detecting 3.71 and using the 3.71 NIDs.
emufan
Posts: 2
Joined: Mon Feb 16, 2009 5:30 pm

Post by emufan »

J.F. wrote: Remember that 3.71 had different NIDs for the ME stuff, and no NID resolver. If you look at my MediaEngine PRX, you'll see have have special support for detecting 3.71 and using the 3.71 NIDs.
Thanks for your reply! So that's why DisplayTest-v1 can run correct on psp2000(3.71m33).
:)
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Yep! I had to do some RE to find those NIDs... it was "fun". :D
Kreationz
Posts: 52
Joined: Sun May 18, 2008 11:01 am

Current Version

Post by Kreationz »

A few quick questions:

1. Is the current version of your code still "MediaEnginePRX-v1.0a"?
2. This is what we are using in DX64 correct?
3. Is there some short example code for using the MediaEngine? (I'm looking for something other than DX64 as I'm currently tearing it apart to be rebuilt and want to run some tests without interference from other parts of the code.)

(And sorry I resurrected anther old thread J.F.)
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Re: Current Version

Post by J.F. »

Kreationz wrote:A few quick questions:

1. Is the current version of your code still "MediaEnginePRX-v1.0a"?
2. This is what we are using in DX64 correct?
3. Is there some short example code for using the MediaEngine? (I'm looking for something other than DX64 as I'm currently tearing it apart to be rebuilt and want to run some tests without interference from other parts of the code.)

(And sorry I resurrected anther old thread J.F.)
1-2 ) The MediaEngine code in DX64 is the latest. You can tell because it has some fixes to the cache code compared to the original.

3 ) I think I posted this before, but never hurts to post again... this was my original test app for the media lib.

main.c

Code: Select all

#include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspiofilemgr.h>
#include <pspdebug.h>
#include <psppower.h>
#include <pspdisplay.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "me.h"


#define printf pspDebugScreenPrintf


#define VERS    1
#define REVS    1


PSP_MODULE_INFO&#40;"DisplayTest", 0, VERS, REVS&#41;;
PSP_MAIN_THREAD_ATTR&#40;PSP_THREAD_ATTR_USER&#41;;
PSP_HEAP_SIZE_KB&#40;-256&#41;;


__attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41; unsigned int frame&#91;512*272&#93;;
unsigned int *frameBuf;


volatile struct me_struct *mei;
__attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41; struct me_struct meinst;


/*
 * ME functions
 *
 */

int ColorCycle&#40;volatile struct me_struct *mei&#41;
&#123;
	int x, y;
	int c = 0;
	unsigned int *buffer;

	buffer = &#40;unsigned int *&#41;&#40;&#40;int&#41;frameBuf | 0x40000000&#41;;
	while &#40;!&#40;mei->signals & 0x00000001&#41;&#41;
	&#123;
		if &#40;mei->signals & 0x00000002&#41;
			for&#40;y=0;y<272;y++&#41;
				for&#40;x=0;x<480;x++&#41;
					buffer&#91;y*512+x&#93;=&#40;x&255&#41;+&#40;&#40;y&255&#41;<<8&#41;+&#40;&#40;c&255&#41;<<16&#41;;
		c++;
	&#125;
	return 0;
&#125;


/*
 * SC functions
 *
 */

void *malloc_64&#40;int size&#41;
&#123;
	int mod_64 = size & 0x3f;
	if &#40;mod_64 != 0&#41; size += 64 - mod_64;
	return&#40;&#40;void *&#41;memalign&#40;64, size&#41;&#41;;
&#125;


int main&#40;void&#41;
&#123;
    //unsigned int b;

	int mode, width, height, bufferwidth, pixelformat, x, y;
	void *topaddr;
	int hasME = 1;
	int err;

    pspDebugScreenInit&#40;&#41;;
    pspDebugScreenSetBackColor&#40;0x00000000&#41;;
    pspDebugScreenSetTextColor&#40;0x00ffffff&#41;;
    pspDebugScreenClear&#40;&#41;;
    sceCtrlSetSamplingCycle&#40;0&#41;;
    sceCtrlSetSamplingMode&#40;PSP_CTRL_MODE_DIGITAL&#41;;

    SceUID mod = pspSdkLoadStartModule&#40;"mediaengine.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
    if &#40;mod < 0&#41;
    &#123;
        printf&#40;" Error 0x%08X loading/starting mediaengine.prx.\n", mod&#41;;
        hasME = 0;
    &#125;

	printf&#40;"\n Display Test\n\n"&#41;;

//	mei = malloc_64&#40;sizeof&#40;struct me_struct&#41;&#41;;
//	mei = &#40;volatile struct me_struct *&#41;&#40;&#40;&#40;int&#41; mei&#41; | 0x40000000&#41;;
	mei = &#40;volatile struct me_struct *&#41;&#40;&#40;u32&#41;&meinst | 0x40000000&#41;;
	sceKernelDcacheWritebackInvalidateAll&#40;&#41;;

	if&#40;hasME&#41;
		if &#40;InitME&#40;mei, sceKernelDevkitVersion&#40;&#41;&#41; != 0&#41;
		&#123;
			printf&#40;" Couldn't initialize MediaEngine Instance\n"&#41;;
			hasME = 0;
		&#125;

	printf&#40;" Media Engine Instance initialized\n"&#41;;
	sceKernelDelayThread&#40;2*1000*1000&#41;;

//	FILE *fh = fopen&#40;"dump.bin", "w"&#41;;
//	fwrite&#40;0x49000000, 1, 0x10000, fh&#41;;
//	fclose&#40;fh&#41;;

	KillME&#40;mei, sceKernelDevkitVersion&#40;&#41;&#41;;
	printf&#40;" Media Engine Instance destroyed\n"&#41;;
	sceKernelDelayThread&#40;2*1000*1000&#41;;

	InitME&#40;mei, sceKernelDevkitVersion&#40;&#41;&#41;;
	printf&#40;" Media Engine Instance initialized\n"&#41;;
	sceKernelDelayThread&#40;2*1000*1000&#41;;

	sceDisplayGetMode&#40;&mode, &width, &height&#41;;
	sceDisplayGetFrameBuf&#40;&topaddr, &bufferwidth, &pixelformat, 0&#41;;

	printf&#40;" mode = %d, width = %d, height = %d\n", mode, width, height&#41;;
	printf&#40;" fbuf = 0x%08X, bufferwidth = %d, pixelformat = %d\n", &#40;int&#41;topaddr, bufferwidth, pixelformat&#41;;

	sceKernelDelayThread&#40;5*1000*1000&#41;;

//	frameBuf = &#40;unsigned int *&#41;0x09000000; // phat
//	frameBuf = &#40;unsigned int *&#41;0x0b000000; // slim
	frameBuf = &#40;unsigned int *&#41;&#40;&#40;u32&#41;&frame | 0x40000000&#41;;

	for&#40;y=0;y<272;y++&#41;
	&#123;
		for&#40;x=0;x<480;x++&#41;
		&#123;
			frameBuf&#91;y*512+x&#93;=&#40;x&255&#41;+&#40;&#40;y&255&#41;*256&#41;;
		&#125;
	&#125;
	sceKernelDcacheWritebackAll&#40;&#41;;
	sceDisplaySetMode&#40;0,480,272&#41;;
	sceDisplaySetFrameBuf&#40;frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_NEXTFRAME&#41;;

	sceKernelDelayThread&#40;2*1000*1000&#41;;

	pspDebugScreenSetBase&#40;&#40;u32 *&#41;&#40;0x40000000 | &#40;int&#41;frameBuf&#41;&#41;;
	pspDebugScreenSetXY&#40;0, 0&#41;;
	printf&#40;"                            Display Test"&#41;;

	sceKernelDelayThread&#40;2*1000*1000&#41;;

	if &#40;hasME&#41;
	&#123;
		err = BeginME&#40;mei, &#40;int&#41;ColorCycle, &#40;int&#41;mei, 0, 0, 0, 0&#41;;
		if &#40;err < 0&#41;
			printf&#40;" failed! Error calling BeginME.\n"&#41;;
	&#125;

	if &#40;hasME&#41;
		SignalME&#40;mei, 0x00000002, 0x00000002&#41;; // start 480x272 ColorCycle
	sceKernelDelayThread&#40;3*1000*1000&#41;;
	if &#40;hasME&#41;
		SignalME&#40;mei, 0x00000002, 0x00000000&#41;; // stop ColorCycle
	sceKernelDelayThread&#40;3*1000*1000&#41;;

	if &#40;hasME&#41;
		SignalME&#40;mei, 0x00000002, 0x00000002&#41;; // start 480x272 ColorCycle
	sceKernelDelayThread&#40;3*1000*1000&#41;;
	if &#40;hasME&#41;
		SignalME&#40;mei, 0x00000002, 0x00000000&#41;; // stop ColorCycle

	if &#40;hasME&#41;
	&#123;
		SignalME&#40;mei, 0x00000001, 0x00000001&#41;; // exit ColorCycle
		err = WaitME&#40;mei&#41;;
	&#125;

	sceKernelDelayThread&#40;3*1000*1000&#41;;
	sceKernelExitGame&#40;&#41;;
	return 0;   /* never reaches here - just to suppress warning */
&#125;
makefile

Code: Select all

TARGET = DisplayTest
OBJS = main.o me.o MediaEngine.o

INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

PSP_FW_VERSION=500
BUILD_PRX = 1
PSP_LARGE_MEMORY = 1

LIBDIR =
LIBS = -lpspdisplay -lpsppower
LDFLAGS =

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Display Test
#PSP_EBOOT_ICON="icon0.png"
#PSP_EBOOT_PIC1="pic1.png"
#PSP_EBOOT_SND0="snd0.at3"

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
Kreationz
Posts: 52
Joined: Sun May 18, 2008 11:01 am

Just what I needed.

Post by Kreationz »

Thx, that's exactly what I needed. Also if you did post it before, thx for the repost. I was lazy and didn't read all 5 pages of this topic.
User avatar
Gaby_64
Posts: 33
Joined: Fri Dec 19, 2008 4:04 am

ME interfearing with Mp3Resources

Post by Gaby_64 »

Well since the thread has been revived I might as well ask my question here.
Has anyone ever had problems using mp3lib after using ME to do another task. In AirCrack-PSP for the wpa cracker I use ME to give it a little boost, so for every passphrase tested I do CallME with the crack function then KillME once its done (this is done in a seperate thread from the main thread and is deleted after KillME). After you run the wpa cracker and try using the scanner it just freezes at sceMp3InitResource(); (when scaner finds a new AP and attemps to beep, this is also in a seperate thread so the psp isnt really frozen but stuck in that function)

I will post some code:


Where variables are defined (at begining of app)

Code: Select all

	//Do this once. because i think it causes memory leaks.
	mei = malloc_64&#40;sizeof&#40;struct me_struct&#41;&#41;;
	mei = &#40;volatile struct me_struct *&#41;&#40;&#40;&#40;int&#41; mei&#41; | 0x40000000&#41;;
	
	me_param = malloc_64&#40;sizeof&#40;struct me_param_struct&#41;&#41;;
	//me_param = &#40;volatile struct me_param_struct *&#41;&#40;&#40;&#40;int&#41; me_param&#41; | 0x40000000&#41;;
	sceKernelDcacheWritebackInvalidateAll&#40;&#41;;

Where ME is initialized in the main thread

Code: Select all

			else if &#40;!strcasecmp&#40;files&#91;y + scrllpos&#93;.d_name+&#40;strlen&#40;files&#91;y + scrllpos&#93;.d_name&#41;-5&#41;, ".dict"&#41;&#41; &#123;
				PrinToBox&#40;LINESPACING, AUTOSCROLL, COPYPRINT, "Opening dict file %s\n", files&#91;y + scrllpos&#93;.d_name&#41;;
				fp = fopen&#40;files&#91;y + scrllpos&#93;.d_name, "rb"&#41;;
				if &#40;fp == NULL&#41; &#123;
					PrinToBox&#40;LINESPACING, AUTOSCROLL, PRINT, "Error opening dictfile %s\n", files&#91;y + scrllpos&#93;.d_name&#41;;
					goto failed;
				&#125;
				PrinToBox&#40;LINESPACING, AUTOSCROLL, COPYPRINT, "Starting dictionary attack. Please be patient.\n"&#41;;

				sceKernelDelayThread&#40;1500000&#41;;
				gettimeofday&#40;&start, 0&#41;;

				if &#40;InitME&#40;mei&#41; != 0&#41;
				&#123;
					PrinToBox&#40;LINESPACING, AUTOSCROLL, PRINT, "Couldn't initialize MediaEngine Instance\n"&#41;;
					goto failed;
				&#125;

				SceUID me_attack = sceKernelCreateThread&#40;"me_dict_attack_thread", me_dict_attack_thread, 0x30, 512 * 1024, PSP_THREAD_ATTR_USER, NULL&#41;;
				if &#40;me_attack < 0&#41; &#123;
					PrinToBox&#40;LINESPACING, AUTOSCROLL, PRINT, "Could not create me_dict_attack_thread!\n"&#41;;
					goto failed;
				&#125;

				sceKernelStartThread&#40;me_attack, 0, NULL&#41;;

			&#125;

			while &#40;&#40;!keyfound&#41; && &#40;!stop&#41; && &#40;me_done+done != 1&#41;&#41; &#123;
				sceKernelDelayThread&#40;100000&#41;;
				sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
				if&#40;&#40;pad.Buttons & PSP_CTRL_CIRCLE&#41; || &#40;stop&#41;&#41; &#123;
					stop = 1; //Needs to be invalidated for the ME to see it
					sceKernelDcacheWritebackInvalidateAll&#40;&#41;;
					sceKernelDelayThread&#40;300000&#41;;
				&#125;
			&#125;

ME function and thread

Code: Select all

int me_attack&#40;&#41;&#123;
	calc_pmk&#40;&#40;char*&#41;me_param->me_word, &#40;char*&#41;me_param->me_essid,  &#40;unsigned char*&#41;me_param->me_pmk&#41;;
	dcache_wbinv_all&#40;&#41;;
	return 0;
&#125;

int me_dict_attack_thread&#40;SceSize args, void *argp&#41;&#123;
	u8   ptk&#91;80&#93;;
	u8   keymic&#91;16&#93;;
	char tpassphrase&#91;MAXPASSLEN+1&#93;;
	int fret;

	sprintf&#40;&#40;char*&#41;me_param->me_essid, ssid&#41;;

	while &#40;!keyfound && !stop&#41; &#123;
		while&#40;eventwarn&#41; &#123;
			cracking = 0;
			sceKernelDelayThread&#40;100000&#41;;
		&#125;
		cracking = 1;
		totalwords++;
		menu.statusbox&#91;0&#93; = R_NULL;
		PrinToBox&#40;LINESPACING, AUTOSCROLL, COPY, "Reading word #%d, %d tested, %d invalid\n", totalwords+1, wordstested, badwords&#41;;
		
		fret = nextword&#40;tpassphrase, fp&#41;;
		if &#40;fret < 8 || fret > 63&#41; &#123;
			if &#40;fret == -1&#41; &#123;
				PrinToBox&#40;LINESPACING, AUTOSCROLL, COPYPRINT, "EOF!\n"&#41;;
				break;
			&#125;
			else if &#40;fret == -2&#41; &#123;
				badwords++;
				PrinToBox&#40;LINESPACING, AUTOSCROLL, COPYPRINT, "Error reading file!\n"&#41;;
				continue;
			&#125;
			else &#123;
				badwords++;
				PrinToBox&#40;LINESPACING, AUTOSCROLL, COPY, "Invalid passphrase length&#58; &#40;%d&#41; %s\n", strlen&#40;tpassphrase&#41;, tpassphrase&#41;;
				continue;
			&#125;
		&#125;
		wordstested++;
		PrinToBox&#40;LINESPACING, AUTOSCROLL, COPY, "Calculating PMK for \"%s\"\n", tpassphrase&#41;;
		
		sprintf&#40;&#40;char*&#41;me_param->me_word, tpassphrase&#41;;
		sceKernelDcacheWritebackInvalidateRange&#40;&#40;struct me_param_struct*&#41;me_param, sizeof&#40;struct me_param_struct&#41;&#41;;

		if &#40;CallME&#40;mei, &#40;int&#41;me_attack, 0&#41; < 0&#41; &#123;
			PrinToBox&#40;LINESPACING, AUTOSCROLL, PRINT, "Error calling CallME.\n"&#41;;
			me_done = 1;
		&#125;

		PrinToBox&#40;LINESPACING, AUTOSCROLL, COPY, "Calculating PTK with collected data and PMK.\n"&#41;;
		wpa_pmk_to_ptk&#40;&#40;unsigned char*&#41;me_param->me_pmk, cdata.aa, cdata.spa, cdata.anonce, cdata.snonce, ptk, sizeof&#40;ptk&#41;&#41;;
		
		PrinToBox&#40;LINESPACING, AUTOSCROLL, COPYPRINT, "Calculating hmac-MD5 Key MIC for this frame.\n"&#41;;
		hmac_hash&#40;cdata.ver, ptk, 16, cdata.eapolframe, sizeof&#40;cdata.eapolframe&#41;, keymic&#41;;
		
		if &#40;memcmp&#40;&cdata.keymic, &keymic, sizeof&#40;keymic&#41;&#41; == 0&#41; &#123;
			strcpy&#40;passphrase, tpassphrase&#41;;
			keyfound = 1;
			break;
		&#125;
		cracking = 0;
	&#125;
	KillME&#40;mei&#41;;
	sceKernelDcacheWritebackAll&#40;&#41;;
	//sceKernelIcacheClearAll&#40;&#41;;
	me_done = 1;
	sceKernelExitDeleteThread&#40;0&#41;;
	return 0;
&#125;
EDIT:

Oh and JF could you post a link toan archive containing the source you posted above and mediaengine.prx source, seems I dont have the latest.
<a><img></a>
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Just pull the MediaEnginePRX from the DX64 source. Also, it's unlikely that the ME code we use right now will work properly with the PSP use of the ME. It bangs on the ME pretty directly. There's a number of things you can't do if you use the ME with the code we have now - namely, change the CPU rate or sleep. Doing either after initializing the ME with MediaEnginePRX will hang the PSP. I've not yet found any way to turn off the ME so that you can sleep or change the cpu rate, so I doubt any of the PSP ME stuff will work either. More research into the PSP ME libs needs to be done.
Kreationz
Posts: 52
Joined: Sun May 18, 2008 11:01 am

Post by Kreationz »

Here is the ME code we use for DX64 along with the Demo Code above in a nice neat VSExpress compatible package for those using MinPSPw. http://www.sendspace.com/file/wmmo8o

BTW: The Demo and the MediaEnginePRX are just set up as different Projects in the Same solution with the only alterations being the copy destination and the includes pointed correctly for how it's set up and one #include I added to make it compile on my system.
Post Reply