bsp
Very Active Member
- Joined
- Dec 2, 2006
- Messages
- 314
Hi all,
as promised here it is.. the first version of my DspLink replacement, the "c64_tools" package.
It does not have as many bells and whistles as DspLink and rather tries to be "lean and mean".
That means that it does not have message queues, RingIO, and what not.
It *does* have some advantages though:
1) It actually works (DspLink just gave me a kernel crash in PROC_attach(), could be fixed, maybe, I'm not interested.)
2) It is a lot faster.
It should support multiple clients/processes (implemented but not tested so far).
[EDIT 23Sep2013: this has become quite a lengthy thread. if you are looking for the latest release of c64_tools, point your browser here: http://tkscript.de/c64_tools]
The package contains the following main components:
c64_load -- A COFF2 loader that loads .out files (DSP images) created with CodeComposerStudio and boots the DSP (GPL).
libc64 -- A GPP side utility library. Currently it is mainly used by 'c64_load' (LGPL).
c64.ko -- A kernel module that handles messaging between the ARM and the C64+ DSP (GPL)
(tested with 3.2.45, i.e. the SuperZaxxon 1.55 standard kernel)
go64.sh -- A utility script that loads the kernel module (optionally with debug output), and loads/boots the DSP image.
libc64_dsp -- A DSP side utility library that mainly handles the DSP-side messaging part (MIT). It also defines
a simplistic remote procedure call (RPC) interface.
tests/ -- ARM-side testcases. Currently just "test_hello" which can send a single 4 byte message (when called w/o args),
perform a single RPC (when called w/ two args), or run an RPC benchmark (when called w/ three args) (takes a while!).
Architecture-wise, the messaging interface boils down to simple remote procedure calls:
The DSP side registers a number of "components".
Each component has an init() (optional), exec() (required), and exit() (not used ATM) function.
Each component can also have an arbitrary number of "commands".
Each command takes two 32bit input parameters and can return up to two 32bit output values.
I included an example component that is basically a simple calculator that can add/sub/mul/div two signed integers.
Trust me, this thing was a nightmare to code because the "mailbox" subsystem in my Pandora did not behave like the TI docs said it should.
For example, even after all incoming mailbox messages are read and the right bits in the IRQSTATUS_0/1 register were set in the IRQ handlers, that thing refuses to trigger any more "newmsg" interrupts. Sometimes it generates a flood of interrupts and spurious mailbox messages.
Figuring all that out (without a debugger/JTAG emulator!), and implementing workarounds for that, really took quite some time (I spent almost every evening during the past week working on this! and I'm talking long evenings! and entire weekends. gaah!!)
The next issue was cache coherency between the ARM and the C64+.
I knew there was a problem, either on the GPP or the DSP side. Tried a million things, failed a million-1 one times.
It turned out that when the L2 of the DSP cache is enabled, the DSPBIOS BCACHE_wb*() calls do not work as their documentation says they should (cache lines are sometimes not written back).
The only solution was to disable the L2 cache.
Well, I think we can live with that (for now) -- the DSP has 32k 1st level data + 32k code cache so hopefully that will not have a large performance impact (given that each "number-crunching" loop fits into the L1P cache and EDMA transfers are used to stream working buffers in and out of the L1DSRAM (48k available, IIRC). (the L1DSRAM offers single cycle access, in case you did not know).
Pheww.. I'm quite exhausted and the weekend is almost over. What the hack
In case I get hit by a meteoroid tomorrow, please find attached the current sources (and precompiled binaries).
There's still some work to be done:
- add utility functions to allocate physically contiguous shared memory (planned that for today but everything took longer than expected)
- improve kernel module so that it supports select() to wait for reply messages.
- figure out whether the L2 cache issue is a HW problem or a bug in DSPBIOS, and maybe find a solution for that (any help is appreciated!)
Last but not least: Here are the benchmark results (1,000,000 RPCs ("add" command of the "demo_calc" component)):
go64.sh: ARGS="" DSPIMAGE="./c64p_simple_dm3730.out"
[...] loading DSP image from "./c64p_simple_dm3730.out"
[dbg] coff_open: file size=212637 (0x00033e9d)
[...] reading 52 section headers....................................................
[...] initializing DSP memory and copying sections..
[...] text=0x00006080 data=0x000012df bss=0x00704368
[...] DSP image loaded successfully. starting DSP..
[dbg] waiting for DSP startup..
[...] DSP is up and running!
[ 686.469329] c64: init ok. module build date: Sep 15 2013
pandora:/home/bsp# ./test_hello ; dmesg -c
[dbg] DSP numRead=4, debug=0x07000002
[...] write testmsg: 4 bytes written.
[dbg] DSP numRead=4, debug=0x37010007
pandora:/home/bsp# ./test_hello q; dmesg -c
[dbg] DSP numRead=4, debug=0x37010007
[dbg] DSP numRead=4, debug=0x77005607
[...] log_rpc() OK: result=86 (expected 86)
[dbg] DSP numRead=4, debug=0x77005607
pandora:/home/bsp# ./test_hello q l; dmesg -c
[dbg] DSP numRead=4, debug=0x77005607
[...] starting calibration
[...] starting benchmark
[...] benchmark finished. => 1000000 iterations in 73312 millisecs.
pandora:/home/bsp#
Configuration:
[ ] VID2 hack (uses VID scaler regs as msgbuf)
[ ] flush_cache_all()
[x] DSP L1D
[ ] DSP L2D
==> 0.073312 millisec messaging overhead per roundtrip/RPC.
==> 13640.33 roundtrips/RPCs per second.
==> ~46.7863 times faster than DspLink (based on M-HT's measurement)
Last but not least, this could be improved by a 1000 times if it were possible to access the DSP's L1DSRAM on the GPP side. I tried (I used that method once before on a similar TI board running QNX), but on the Pandora that memory is not accessible (maybe that could be fixed? A linux issue ? anyone?).
Greetings,
Bastian
p.s.: In case you are wondering what the "VID2 hack" is: Out of desperation when trying to fix the cache coherency issue, I used the VID2 layer scaler registers of the DSS for IPC / as a message buffer. That did not fix it (interesting, I thought peripheral I/O is always uncached..). So don't worry, that hack is not needed.
p.p.s.: In order to compile this, you must set the following vars: "CROSS_COMPILE=arm-none-linux-gnueabi-" and "CROSS_ROOT=<root of pandora fs>" (must contain usr/src/pandora-kernel/)
p.p.p.s: precompiled binaries can be found in the "bin-15Sep2013/" directory, if you just want to try it out (please do and let me know whether this works on your HW!)
p.p.p.p.s: I almost forgot: put the attached "autoboot.txt" in the root folder of your left SD card (changes some kernel boot params to reserve memory for the DSP)
(if you have a "classic" 256 MBytes Pandora, use the CLASSIC__autoboot.txt and rename it autoboot.txt, of course!)
p.p.p.p.p.s: by "MH-T's measurement" I am referring to this thread: http://boards.openpandora.org/index.php/topic/10788-running-scalers-on-dsp/ (I have previously worked with DspLink and the overhead stated in that thread sounds reasonable)
c64_tools-15Sep2013_dist.tar.gz
autoboot.txt
CLASSIC__autoboot.txt
c64_tools-23Sep2013_dist.tar.gz
as promised here it is.. the first version of my DspLink replacement, the "c64_tools" package.
It does not have as many bells and whistles as DspLink and rather tries to be "lean and mean".
That means that it does not have message queues, RingIO, and what not.
It *does* have some advantages though:
1) It actually works (DspLink just gave me a kernel crash in PROC_attach(), could be fixed, maybe, I'm not interested.)
2) It is a lot faster.
It should support multiple clients/processes (implemented but not tested so far).
[EDIT 23Sep2013: this has become quite a lengthy thread. if you are looking for the latest release of c64_tools, point your browser here: http://tkscript.de/c64_tools]
The package contains the following main components:
c64_load -- A COFF2 loader that loads .out files (DSP images) created with CodeComposerStudio and boots the DSP (GPL).
libc64 -- A GPP side utility library. Currently it is mainly used by 'c64_load' (LGPL).
c64.ko -- A kernel module that handles messaging between the ARM and the C64+ DSP (GPL)
(tested with 3.2.45, i.e. the SuperZaxxon 1.55 standard kernel)
go64.sh -- A utility script that loads the kernel module (optionally with debug output), and loads/boots the DSP image.
libc64_dsp -- A DSP side utility library that mainly handles the DSP-side messaging part (MIT). It also defines
a simplistic remote procedure call (RPC) interface.
tests/ -- ARM-side testcases. Currently just "test_hello" which can send a single 4 byte message (when called w/o args),
perform a single RPC (when called w/ two args), or run an RPC benchmark (when called w/ three args) (takes a while!).
Architecture-wise, the messaging interface boils down to simple remote procedure calls:
The DSP side registers a number of "components".
Each component has an init() (optional), exec() (required), and exit() (not used ATM) function.
Each component can also have an arbitrary number of "commands".
Each command takes two 32bit input parameters and can return up to two 32bit output values.
I included an example component that is basically a simple calculator that can add/sub/mul/div two signed integers.
Trust me, this thing was a nightmare to code because the "mailbox" subsystem in my Pandora did not behave like the TI docs said it should.
For example, even after all incoming mailbox messages are read and the right bits in the IRQSTATUS_0/1 register were set in the IRQ handlers, that thing refuses to trigger any more "newmsg" interrupts. Sometimes it generates a flood of interrupts and spurious mailbox messages.
Figuring all that out (without a debugger/JTAG emulator!), and implementing workarounds for that, really took quite some time (I spent almost every evening during the past week working on this! and I'm talking long evenings! and entire weekends. gaah!!)
The next issue was cache coherency between the ARM and the C64+.
I knew there was a problem, either on the GPP or the DSP side. Tried a million things, failed a million-1 one times.
It turned out that when the L2 of the DSP cache is enabled, the DSPBIOS BCACHE_wb*() calls do not work as their documentation says they should (cache lines are sometimes not written back).
The only solution was to disable the L2 cache.
Well, I think we can live with that (for now) -- the DSP has 32k 1st level data + 32k code cache so hopefully that will not have a large performance impact (given that each "number-crunching" loop fits into the L1P cache and EDMA transfers are used to stream working buffers in and out of the L1DSRAM (48k available, IIRC). (the L1DSRAM offers single cycle access, in case you did not know).
Pheww.. I'm quite exhausted and the weekend is almost over. What the hack
In case I get hit by a meteoroid tomorrow, please find attached the current sources (and precompiled binaries).
There's still some work to be done:
- add utility functions to allocate physically contiguous shared memory (planned that for today but everything took longer than expected)
- improve kernel module so that it supports select() to wait for reply messages.
- figure out whether the L2 cache issue is a HW problem or a bug in DSPBIOS, and maybe find a solution for that (any help is appreciated!)
Last but not least: Here are the benchmark results (1,000,000 RPCs ("add" command of the "demo_calc" component)):
go64.sh: ARGS="" DSPIMAGE="./c64p_simple_dm3730.out"
[...] loading DSP image from "./c64p_simple_dm3730.out"
[dbg] coff_open: file size=212637 (0x00033e9d)
[...] reading 52 section headers....................................................
[...] initializing DSP memory and copying sections..
[...] text=0x00006080 data=0x000012df bss=0x00704368
[...] DSP image loaded successfully. starting DSP..
[dbg] waiting for DSP startup..
[...] DSP is up and running!
[ 686.469329] c64: init ok. module build date: Sep 15 2013
pandora:/home/bsp# ./test_hello ; dmesg -c
[dbg] DSP numRead=4, debug=0x07000002
[...] write testmsg: 4 bytes written.
[dbg] DSP numRead=4, debug=0x37010007
pandora:/home/bsp# ./test_hello q; dmesg -c
[dbg] DSP numRead=4, debug=0x37010007
[dbg] DSP numRead=4, debug=0x77005607
[...] log_rpc() OK: result=86 (expected 86)
[dbg] DSP numRead=4, debug=0x77005607
pandora:/home/bsp# ./test_hello q l; dmesg -c
[dbg] DSP numRead=4, debug=0x77005607
[...] starting calibration
[...] starting benchmark
[...] benchmark finished. => 1000000 iterations in 73312 millisecs.
pandora:/home/bsp#
Configuration:
[ ] VID2 hack (uses VID scaler regs as msgbuf)
[ ] flush_cache_all()
[x] DSP L1D
[ ] DSP L2D
==> 0.073312 millisec messaging overhead per roundtrip/RPC.
==> 13640.33 roundtrips/RPCs per second.
==> ~46.7863 times faster than DspLink (based on M-HT's measurement)
Last but not least, this could be improved by a 1000 times if it were possible to access the DSP's L1DSRAM on the GPP side. I tried (I used that method once before on a similar TI board running QNX), but on the Pandora that memory is not accessible (maybe that could be fixed? A linux issue ? anyone?).
Greetings,
Bastian
p.s.: In case you are wondering what the "VID2 hack" is: Out of desperation when trying to fix the cache coherency issue, I used the VID2 layer scaler registers of the DSS for IPC / as a message buffer. That did not fix it (interesting, I thought peripheral I/O is always uncached..). So don't worry, that hack is not needed.
p.p.s.: In order to compile this, you must set the following vars: "CROSS_COMPILE=arm-none-linux-gnueabi-" and "CROSS_ROOT=<root of pandora fs>" (must contain usr/src/pandora-kernel/)
p.p.p.s: precompiled binaries can be found in the "bin-15Sep2013/" directory, if you just want to try it out (please do and let me know whether this works on your HW!)
p.p.p.p.s: I almost forgot: put the attached "autoboot.txt" in the root folder of your left SD card (changes some kernel boot params to reserve memory for the DSP)
(if you have a "classic" 256 MBytes Pandora, use the CLASSIC__autoboot.txt and rename it autoboot.txt, of course!)
p.p.p.p.p.s: by "MH-T's measurement" I am referring to this thread: http://boards.openpandora.org/index.php/topic/10788-running-scalers-on-dsp/ (I have previously worked with DspLink and the overhead stated in that thread sounds reasonable)
c64_tools-15Sep2013_dist.tar.gz
autoboot.txt
CLASSIC__autoboot.txt
c64_tools-23Sep2013_dist.tar.gz
Attachments
Last edited by a moderator: