gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Code in vram

#141948 - ingramb - Tue Oct 02, 2007 3:55 am

Apologies if this has been asked before (I think it has), but I couldn't find the topic with searching.

I want to put arm9 code in vram. I've tried to add a vram section to the linker script and ctr0 files, using the itcm section as a guideline. But I'm not so good with linker scripts, and I'm having trouble getting it to work.

This is what I have in my linker script, at the top under the MEMORY heading:
Code:
vram    : ORIGIN = 0x06880000, LENGTH = 64K

Then down in the SECTIONS area, after the itcm:
Code:
__vram_lma = __itcm_lma + SIZEOF(.itcm);

   .vram __vram_start : AT (__vram_lma)
   {
      *(.vram)
      *vram.*(.vram)
      . = ALIGN(4);
      __vram_end = ABSOLUTE(.);
   } >vram

And finally, I've modified __bss_lma to come after __vram_lma.

Doing all this crashes the linker.

So am I even on the right track? Or is there a better way to do this?

#141970 - NeX - Tue Oct 02, 2007 5:45 pm

Why do you want code in VRAM?
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.

#141977 - ingramb - Tue Oct 02, 2007 6:40 pm

Vram has less latency than main ram, and I'm out of itcm. I have code running on the arm7 that reads from main ram, which makes it even slower on the arm9. I've seen large speed ups already by moving code into itcm. I need all the speed I can get. And I have 64K of extra vram that I don't need for gfx.

So right now, I'm using it for data, but I think I would be better served by filling it with some critical code.

#141978 - simonjhall - Tue Oct 02, 2007 7:22 pm

Not wanting to hijack, but how exactly do you put a function in itcm and do you REALLY get that much of a speed up when you do it? Isn't the instruction cache supposed to handle improving access to code?
_________________
Big thanks to everyone who donated for Quake2

#141980 - ingramb - Tue Oct 02, 2007 7:51 pm

Quote:
how exactly do you put a function in itcm

Just add an ITCM_CODE next to the function name.

Quote:
Isn't the instruction cache supposed to handle improving access to code?

Yeah, the instruction cache helps. But It's only 8k. If your working set is larger than this, you'll still be streaming code from main ram. Cache misses are expensive, especially if the arm9 has to compete with the arm7. At the very least, the arm7 is probly playing sound from main ram.

I've seen significant speed increases when moving code and data into the itcm and dtcm.


Last edited by ingramb on Tue Oct 02, 2007 7:54 pm; edited 3 times in total

#141981 - NeX - Tue Oct 02, 2007 7:51 pm

How do I use that? I've tried it in every arrangement I can think of and the compiler constantly gets the wrong end of the stick.
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.

#141983 - simonjhall - Tue Oct 02, 2007 8:20 pm

Yeah, is that all you add to the prototype? You don't need make a trampoline stub function or something?

can you just do this?
Code:
void main(void)
{
   donkey("horse");
}

void donkey(char *str) ITCM_CODE
{
   printf(str);
}


_________________
Big thanks to everyone who donated for Quake2

#141985 - NeX - Tue Oct 02, 2007 8:33 pm

I found more locations in jtypes.h... the code that ITCM_CODE (or whatever) replaces works, but the define itself does not. Not to mention that ITCM actually seems to be slower, and the touchscreen goes a little doo-lally whilst using the ITCM.
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.

#141991 - ingramb - Tue Oct 02, 2007 9:23 pm

Quote:
Yeah, is that all you add to the prototype? You don't need make a trampoline stub function or something?

The code will be loaded into ram, and then copied into itcm by the crt0.s file (I think). You don't have to do anything fancy (that I know of).

For data, there's DTCM_DATA, and DTCM_BSS (for uninitialized globals).

Also, the itcm has a 32 bit bus, so it's more efficient for arm code (vs thumb). Files named *.arm.c will be compiled as arm. Not sure if there's a way to do this on a per-function basis.

Quote:
I found more locations in jtypes.h... the code that ITCM_CODE (or whatever) replaces works, but the define itself does not. Not to mention that ITCM actually seems to be slower, and the touchscreen goes a little doo-lally whilst using the ITCM.


The macros work fine for me. I've gotten lots of speed by using the itcm. You do have to think about what functions should go there.

#141992 - NeX - Tue Oct 02, 2007 9:36 pm

Well, do 40,000-280,000 writes and reads per frame (in tight situations) sound like something that need a little bit of priority?
Is the slowdown due to accessing an array in main RAM?
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.

#141996 - simonjhall - Tue Oct 02, 2007 10:18 pm

Ah I getcha. To redo my previous example, I guess the itcm thing should be like this, since you can't use __attribute__ on a function definition (only its prototype).
Code:

void donkey(char *str) __attribute__((section(".itcm"), long_call));

void main(void)
{
   donkey("horse");
}

void donkey(char *str)
{
   printf(str);
}
I've just checked with objdump and yeah, it's in itcm.
Sorry again about the hijack - I'd imagine that you do something similar with vram. Although tbh if I were doing it, I'd just do it by hand by memcpying the function in and then calling it. But that's cos I'm a hacker ;-)
_________________
Big thanks to everyone who donated for Quake2

#141998 - ingramb - Tue Oct 02, 2007 10:43 pm

No worries about the hijack, itcm is a useful thing to discuss that probly deserves its own thread.

Back on topic, I've thought about copying to vram myself, but then I either need position indepent code, or I need to relocate manually. I'd rather not have to deal with either, but it may turn out easier than the alternative link script nightmare.

I'm really hoping someone who knows about linkscripts can give me some advice though.

#142021 - DiscoStew - Wed Oct 03, 2007 6:15 am

Sorry, going on the ITCM offtopic :P

When I use them, I place the ITCM_CODE define at the front of the functions and prototypes, and they work fine for me.
_________________
DS - It's all about DiscoStew

#142023 - gladius - Wed Oct 03, 2007 7:05 am

This looks suspect "*vram.*(.vram)". Try removing that. You'll also need to fix up the crt to copy your code over to VRAM (and do the appropriate vram bank allocation before the copy, etc.).

Oh yeah, and I forget what the "} >iwram = 0xff" syntax means, but maybe try using the "= 0xff" :). Also, watch your spaces and tabs, I've borked linkscripts by messing up the spacing. The parser isn't too forgiving.

#142024 - ingramb - Wed Oct 03, 2007 7:45 am

Quote:
When I use them, I place the ITCM_CODE define at the front of the functions and prototypes, and they work fine for me.

Same for me.
Quote:
This looks suspect "*vram.*(.vram)". Try removing that.

This was (incorrectly I think) modified from: "*itcm.*(.text)". Anyway, removing it makes no difference.
Quote:
but maybe try using the "= 0xff"

Same thing, it doesn't make any difference.
Quote:
Also, watch your spaces and tabs, I've borked linkscripts by messing up the spacing. The parser isn't too forgiving.

I've copied the itcm block and just changed the names, so I think my spacing is OK. Thanks for the heads up though.

So it's still crashing the linker, with exit code 5 (whatever that means, can't seem to find exit codes anywhere online).

Thanks for the suggestions. I need to just read up on linkscripts I think. Help is still appreciated though =)