Hi Paul,
thanks. Could probably be also done in C/C++, but your description is so
good that this should be enough?
diff --git a/server/src/ARCH-mips/crt0.S b/server/src/ARCH-mips/crt0.S
index b8fa86ba..f4c8d5dd 100644
--- a/server/src/ARCH-mips/crt0.S
+++ b/server/src/ARCH-mips/crt0.S
@@ -49,6 +49,7 @@ syncICache: ;
li $v1, 2 # size is 2 << min(DL, IL)
sllv $v0, $v1, $v0
+ addu $a1, $a0, $a1 # a1 is end = start + size
# run the loop
10:
synci 0($a0)
Thanks,
Adam
On Sun Jun 08, 2025 at 00:35:06 +0200, Paul Boddie wrote:
> Hello,
>
> I have been trying to get L4Re working on another MIPS-based SoC and found
> myself struggling to get the kernel to boot. Initially, I wondered about
> various exotic concurrency issues, particularly since the SoC has two cores
> (each with two threads, apparently), but I started to suspect that our old
> nemesis, cache management, was to blame.
>
> Anyway, to save you the long story, I had a closer look at the syncICache
> routine that resides in the bootstrap package/module:
>
> pkg/bootstrap/server/src/ARCH-mips/crt0.S
>
> It turns out that syncICache is ineffective due to an erroneous loop
> continuation test. Here's the offending code:
>
> 10:
> synci 0($a0)
>
> addu $a0, $a0, $v0
> sltu $v1, $a0, $a1
> bne $v1, $0, 10b
> nop
>
> Here, $a0 is the region start and $a1 is the region size, with $v0
> being the cache line size. The above code is equivalent to the following:
>
> address = start;
> do
> {
> synci 0(address)
>
> address += linesize;
> }
> while (address < size);
>
> The address should, of course, be compared to start + size. So, cache entries
> may not be flushed, particularly later in regions and at higher addresses,
> omitting coverage even of the early kernel regions, making kernel execution
> very unpredictable and unreliable. Perhaps the larger caches make this fault
> more obvious on this particular SoC.
>
> In the startup routine in the bootstrap package/module...
>
> pkg/bootstrap/server/src/startup.cc
>
> ...there is a declaration for syncICache, along with code to flush the
> caches,
> introduced purely for MIPS. To test my suspicions, I wrote a C++ version of
> the routine with inline assembly language for the machine instructions,
> fixing
> the loop continuation test. This seemed to allow the kernel to boot and the
> system to start up as I originally expected.
>
> Would you like me to contribute this fix? I think that unless inline assembly
> is problematic for some toolchain choices, it might be clearer to maintain
> this code in C++ rather than entirely in assembly language, thus avoiding
> such
> faults in the first place.
>
> This problem may have been around since the introduction of MIPS support into
> L4Re, appearing first in r70 of the public Subversion repository from back in
> May 2016.
>
> Paul
>
>
> _______________________________________________
> l4-hackers mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
Adam
--
Adam [email protected]
Lackorzynski http://os.inf.tu-dresden.de/~adam/
_______________________________________________
l4-hackers mailing list -- [email protected]
To unsubscribe send an email to [email protected]