Hello,
Pushing on with my efforts to port L4Re to another MIPS-based SoC, I have been attempting to activate more than one CPU core. Although there is some support in Fiasco for the MIPS Coherence Manager (CM) and Cluster Power Controller (CPC), these technologies are not supported in this particular SoC, which is related to the JZ4780 used in the MIPS Creator CI20.
However, the Platform_control abstraction (in src/kern/mips/platform_control- mips.cpp) does seem to provide some flexibility in the way secondary CPUs or cores may be started. It seems that even in situations where the CM is not available, the alloc_secondary_boot_code method will assemble a bootstrap routine from snippets including one, _tramp_mp_cache, that initialises the caches.
Unfortunately, it appears that this cache initialisation code does not work on this particular SoC. The method used by_tramp_mp_cache is the familiar one where the cache tags are invalidated for all cache index entries using the Index_Store_Tag operation for each cache type. This is supposed to work on any MIPS CPU, but through some tedious troubleshooting, I discovered that it does not work for the data cache.
If the data cache variant of the Index_Store_Tag operation is performed for a range of addresses starting from the base of KSEG0, I found that some kind of side-effect would occur, possibly affecting the rather critical addresses in that range. This would prevent Fiasco from continuing to start up, and things like timers and the UART would not function, although the processor was not halted and would still run code, illuminating LEDs as a last-resort debugging tool.
There is some preliminary support for this SoC, as well as the JZ4780, in Linux and it seems that instead of using Index_Store_Tag, the tag records are explicitly invalidated and updated. However, it also seems to be the case that caches can be invalidated using Hit_Invalidate. Changing the cache operations in _tramp_mp_cache to use this invalidation operation in its two variants appears to work, avoiding the problems described above.
Does anyone have any thoughts or recollections about this cache initialisation routine?
On the topic of actually starting secondary cores, this SoC has its own set of registers for resetting cores, interrupt control, mailboxes, and so on. I have developed a fairly simple abstraction that performs similar core bootstrapping work to that of the Cm abstraction (in src/kern/mips/cm.cpp). I then extend the Platform_control abstraction so that it will call the alloc_secondary_boot_code method, followed by the appropriate method to start the secondary cores.
Is there any documentation for the SMP architecture in Fiasco and L4Re? I note that interprocessor interrupts (IPI) are one element that I might need to support, probably using the mailboxes.
Thanks in advance for any advice or feedback that may be given!
Paul