by mhonman » Tue Jan 07, 2014 11:14 pm
In partial answer to the OP, strictly speaking the only thing that has to be polled is the DEBUGSTATUS register - if that indicates a halt condition, only then do other core registers need to be read. These polls do take bandwidth away from the interface between Epiphany and host-side memory buses but I think this is not too bad because the TRAPs underlying newlib are all for I/O and we're unlikely to see more than 100MB/s on any of the Parallella host peripherals - thus for block transfers of 1KB there is little point to polling more frequently than every 10us.
It is also possible to make this polling adaptive, e.g. there is a good chance that if a core has just made an IO call, then either it or another core may be about to make another IO request, so poll again almost as soon as the result of the call have been posted to the Epiphany (I say almost as soon, because the core will spend some time processing the IO results and preparing for the next operation, so an immediate repoll is unlikely to find anything to do).
IMO the alternate approach of writing to special locations in external RAM and then waiting for ILAT[0] won't really help because the host must still poll the external RAM & will thus compete with the Epiphany chip for RAM bandwidth. I guess it all boils down to whether the e-link has more bandwidth than the host RAM - if so, polling DEBUGSTATUS may be the lesser evil.
Some example code:
"simon" is a Simple IO Monitor that is supposed to handle the IO traps (I say supposed to because it's not fully tested!) & uses the x_epiphany_exception module to check for traps.
Polling is normally every 10uS - if it services a trap then the next 5 polls are at a 2us interval. This could be made smarter to take account of the type of request, e.g. for console I/O there is no point in a fast repoll.