GP2X Dangerous Linux Hacking Code


well done Squidge :)

did you try other "cache" options on translation lookaside buffer?

i mean, instead of "cacheable coherent exclusive" (100), how about
"uncached accelerated" (111) or "cacheable coherent update on write" (101)?
 
I've not tried any of the other caching options, I simply use the same options as Linux uses for the memory that is below the 32mb limit.
 
well done Squidge :)

did you try other "cache" options on translation lookaside buffer?

i mean, instead of "cacheable coherent exclusive" (100), how about
"uncached accelerated" (111) or "cacheable coherent update on write" (101)?

In the most cases write-update will waste bandwith. shared mem communication can be faster with that on.
 
Last edited by a moderator:
Seeing as this patch essentially overwrites a system call (if I understand it correctly), is there a possibility fo doing one of the following to see what happens, namely:

1) Create a script to run it at startup - presumably the system call would stay overwritten for the duration of the time the GP2x was on, thus eliminating the need to have specially coded software. Might introduce incompatibilities or issues though on some stuff - we'd have to see.

Or

2) Patch a brand new system call into the linux kernel itself, thus eliminating the need to overwrite it in the first place. Course, it wouldn't be there until everyone had patched their firmwares, but who would say no to a firmware that reliably increases the speed everything ran at a fair bit?

Just a couple of thoughts which I'm sure people have already had, but which I'd like to know why they aren't feasible!
 
Would this code work as a kernel module?

Surely you could fudge the page tables from the module then map the memory down into user space. If the API was clean then everybody could use the higher memory more easily than the "voodoo" SWI hack (I mean no disrespect with that; it's a great hack, but a hack nonetheless :) ).

If somebody knowledgeable can give me a yay/nay to the general principle then I'll have a go at stuffing it into a module if it's likely to work...
 
It should work as a kernel module, and by doing so, you shouldn't need to overwrite the system call, as you'll be in kernel mode already. The only reasons I've not done it this way is because I don't know how to create kernel modules for the gp2x, I've a feeling it'll require gcc2.95, and it means it's no longer standalone. Oh, and it wouldn't be as cool a hack ;)

What happens if a program attempts to use an api from a kernel module that doesn't exist? Does it fail to run, or does that program get told the kernel isn't there? Last thing we want is people complaining they are trying to run app X and only getting a blank screen and then finding out it's because of a missing kernel module. If the program can detect the module is missing and output a suitable message (or work without it), it would be much better. Like I say though, I know almost nothing about kernel modules, so I don't know what's possible.

vobbo: If you just included the kernel as pasted, it only accelerates the first 1MB of upper memory - you have to modify it to accelerate the memory you actually use, or to accelerate the frame buffer, etc, depending on what you want.
 
Giving this a shot in the Stargazer engine-- I've heard it causes significant gains in accessing the upper 32MB of RAM and since all my graphics are stored there (Hardware SDL surfaces in the upper 32MB, using the '16MB VRAM' SDL Lib by Paeryn) this could be very beneficial, methinks. But, now that I have it compiling properly, I don't see any gains-- it seems I need to specify the range of memory to make cacheable on the 920T? What line would I alter to do this and to what address(es) to make this 16MB area (or perhaps just the whole upper 32MB) cacheable?

I tried changing this line:
Code:
// This is where we look for any virtual addresses that map to physical address and 					// alter the cachable and bufferable bits...
					if (((cpt[i] & 0xffff0000) == 0x03000000) && ((cpt[i] & 12)==0))

to read:
Code:
if (((cpt[i] & 0xffff0000) == 0x02000000) && ((cpt[i] & 12)==0))
and also tried:
Code:
if (((cpt[i] & 0xff000000) == 0x02000000) && ((cpt[i] & 12)==0))

Neither got me any sort of a performance increase, in fact, it seems to be a few FPS slower. :( Should I be expecting better than this? .. In addition, the program only seems to run perhaps half the time, the other half it crashes to a black screen-- yet it ALWAYS works when run from a Telnet prompt over USB networking (WHAT?!) This is WITH a 1-second delay added just where it was added in GnGeo2x.

Thanks for any advice.
 
Epicenter posted on Jul 4 2006 at 11:00 AM said:
Giving this a shot in the Stargazer engine-- I've heard it causes significant gains in accessing the upper 32MB of RAM and since all my graphics are stored there (Hardware SDL surfaces in the upper 32MB, using the '16MB VRAM' SDL Lib by Paeryn) this could be very beneficial, methinks. But, now that I have it compiling properly, I don't see any gains-- it seems I need to specify the range of memory to make cacheable on the 920T? What line would I alter to do this and to what address(es) to make this 16MB area (or perhaps just the whole upper 32MB) cacheable?

Thanks for any advice.
it depend. Even if all your surface are in the upper memory, I suppose that you write them only once at the begining of the level, then all the blitting are done in hardware anyway. no?

Edit: if you use the 16M version of Paeryn, I guess you sould use the folowing code in the DecodeCoarse function.
Code:
if (((cpt[i] & 0xff000000) == 0x02000000) && ((cpt[i] & 12)==0))
  {
	//printf("c and b bits not set, overwriting\n");
	cpt[i] |= 0xFFC;
	wb = 1;
}
if (((cpt[i] & 0xff000000) == 0x03000000) && ((cpt[i] & 12)==0))
  {
	//printf("c and b bits not set, overwriting\n");
	cpt[i] |= 0xFFC;
	wb = 1;
}
 
Last edited by a moderator:
Squidge posted on Jul 4 2006 at 09:40 AM said:
It should work as a kernel module, and by doing so, you shouldn't need to overwrite the system call, as you'll be in kernel mode already.
Yep, that was my reason for wanting to do it. :)

8< snip 8<
Squidge posted on Jul 4 2006 at 09:40 AM said:
What happens if a program attempts to use an api from a kernel module that doesn't exist? Does it fail to run, or does that program get told the kernel isn't there? Last thing we want is people complaining they are trying to run app X and only getting a blank screen and then finding out it's because of a missing kernel module. If the program can detect the module is missing and output a suitable message (or work without it), it would be much better. Like I say though, I know almost nothing about kernel modules, so I don't know what's possible.
Basically communication with the module is via a special file. If the file cannot be opened then the module isn't loaded; a message can then be presented to the user informing them that they really should load the module. I'm presuming that there's a modprobe/insmod style API call in Linux somewhere to have a go at it before yelling at the user.

I'll start poking it soonish and report back. Thanks for the input (and the hack, of course).
 
Last edited by a moderator:
pepone posted on Jul 4 2006 at 07:34 AM said:
Edit: if you use the 16M version of Paeryn, I guess you sould use the folowing code in the DecodeCoarse function.

Doesn't seem to provide any sort of a performance benefit, unfortunately. Things seem slower. :( Why is this providing performance benefits to emulators exactly? Is it not something with how they draw to the display?
 
Last edited by a moderator:
Epicenter posted on Jul 4 2006 at 03:43 PM said:
pepone posted on Jul 4 2006 at 07:34 AM said:
Edit: if you use the 16M version of Paeryn, I guess you sould use the folowing code in the DecodeCoarse function.

Doesn't seem to provide any sort of a performance benefit, unfortunately. Things seem slower. :( Why is this providing performance benefits to emulators exactly? Is it not something with how they draw to the display?
I don't know. the only thing I do in gngeo is to draw all the sprites to a hardware surface, then the surface is blited to the screen.
 
Last edited by a moderator:
Squidge posted on Jul 4 2006 at 08:40 AM said:
It should work as a kernel module, and by doing so, you shouldn't need to overwrite the system call, as you'll be in kernel mode already. The only reasons I've not done it this way is because I don't know how to create kernel modules for the gp2x, I've a feeling it'll require gcc2.95, and it means it's no longer standalone. Oh, and it wouldn't be as cool a hack ;)

What happens if a program attempts to use an api from a kernel module that doesn't exist? Does it fail to run, or does that program get told the kernel isn't there? Last thing we want is people complaining they are trying to run app X and only getting a blank screen and then finding out it's because of a missing kernel module. If the program can detect the module is missing and output a suitable message (or work without it), it would be much better. Like I say though, I know almost nothing about kernel modules, so I don't know what's possible.

vobbo: If you just included the kernel as pasted, it only accelerates the first 1MB of upper memory - you have to modify it to accelerate the memory you actually use, or to accelerate the frame buffer, etc, depending on what you want.


ok squidge! I`ll take a closer look at the code and see if I can snag some speed bonus in hu6280! Thanks for the tip... ;)
 
Last edited by a moderator:
BradN posted on Aug 14 2006 at 01:38 AM said:
pcklee123 posted on Aug 13 2006 at 08:30 PM said:
Anybody know if this is usefull ? What does it do? Will it speed up any games?
http://www.gp2x.de/cgi-bin/cfiles.cgi?0,0,0,0,46,1742

Useful to the end user: No. It's only used by developers who can use it to alter some memory access modes to speed up certain things. It's already been used in some programs.

So do I need to insmod this?
 
Last edited by a moderator:
I'm not much of a kernel hacker so if I would paste this in the start of my code (in main() ) then I won't have to do any other MMU hacking?

Thanks for your awesome code. You change the meaning to opensource :p.
 
I think the MMU hack can be improved a little bit.

Right now the 920 maps the 32MB memory of the 940 as 4 KB pages.

If I understood correctly this memory is not part of the memory used by the kernel to map processes.
If I am right then we could change the size of the pages to 1MB. This would work as long as all 4KB contiguous pages have the same attributes (C, B, protections).

The advantage would be two-fold:
- less TLB thrashing
- more efficient TLB lookup when it misses (only first level descriptor).

These advantages would speed programs that access many different areas in the 32MB used by the 940 in a short period of time.

Thoughts?
 
I think I found *the* solution :D

The upper 32MB are already mapped as sections by the kernel (at least in the kernel provided in my 2.1.0 firmware).

Code:
Indx: 3904 VA: F4000000 Type: 2 [Section]  PA: 03000000 - 030FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3905 VA: F4100000 Type: 2 [Section]  PA: 03100000 - 031FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3906 VA: F4200000 Type: 2 [Section]  PA: 03200000 - 032FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3907 VA: F4300000 Type: 2 [Section]  PA: 03300000 - 033FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3908 VA: F4400000 Type: 2 [Section]  PA: 03400000 - 034FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3909 VA: F4500000 Type: 2 [Section]  PA: 03500000 - 035FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3910 VA: F4600000 Type: 2 [Section]  PA: 03600000 - 036FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3911 VA: F4700000 Type: 2 [Section]  PA: 03700000 - 037FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3912 VA: F4800000 Type: 2 [Section]  PA: 03800000 - 038FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3913 VA: F4900000 Type: 2 [Section]  PA: 03900000 - 039FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3914 VA: F4A00000 Type: 2 [Section]  PA: 03A00000 - 03AFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3915 VA: F4B00000 Type: 2 [Section]  PA: 03B00000 - 03BFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3916 VA: F4C00000 Type: 2 [Section]  PA: 03C00000 - 03CFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3917 VA: F4D00000 Type: 2 [Section]  PA: 03D00000 - 03DFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3918 VA: F4E00000 Type: 2 [Section]  PA: 03E00000 - 03EFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3919 VA: F4F00000 Type: 2 [Section]  PA: 03F00000 - 03FFFFFF A: 1 D: 2 C: 0 B: 0

Indx: 3952 VA: F7000000 Type: 2 [Section]  PA: 02000000 - 020FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3953 VA: F7100000 Type: 2 [Section]  PA: 02100000 - 021FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3954 VA: F7200000 Type: 2 [Section]  PA: 02200000 - 022FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3955 VA: F7300000 Type: 2 [Section]  PA: 02300000 - 023FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3956 VA: F7400000 Type: 2 [Section]  PA: 02400000 - 024FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3957 VA: F7500000 Type: 2 [Section]  PA: 02500000 - 025FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3958 VA: F7600000 Type: 2 [Section]  PA: 02600000 - 026FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3959 VA: F7700000 Type: 2 [Section]  PA: 02700000 - 027FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3960 VA: F7800000 Type: 2 [Section]  PA: 02800000 - 028FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3961 VA: F7900000 Type: 2 [Section]  PA: 02900000 - 029FFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3962 VA: F7A00000 Type: 2 [Section]  PA: 02A00000 - 02AFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3963 VA: F7B00000 Type: 2 [Section]  PA: 02B00000 - 02BFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3964 VA: F7C00000 Type: 2 [Section]  PA: 02C00000 - 02CFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3965 VA: F7D00000 Type: 2 [Section]  PA: 02D00000 - 02DFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3966 VA: F7E00000 Type: 2 [Section]  PA: 02E00000 - 02EFFFFF A: 1 D: 2 C: 0 B: 0
Indx: 3967 VA: F7F00000 Type: 2 [Section]  PA: 02F00000 - 02FFFFFF A: 1 D: 2 C: 0 B: 0
This not contiguous but the VA range F8xxxxxx is not used.
I guess changing the permissions and C/B will do the trick.

Of course this means the mmap used with the current hack will have to be changed.

More about this next year :)
 
Back
Top