Memory overlap with SiFive U NIC
When initializing the GEM descriptors, the heap pointer address (log_addr=0x80400060) is overwritten when writing to word 0 of the 13th RX descriptor. This descriptor has the same log address as the heap pointer. Then, in the next Heap::alloc() call, this pointer is 0x21feef60 (phy_addr of the 13th descriptor buffer).
When using less than 13 buffers for RX and TX each (e.g. 8), even though a descriptor (now TX) is the same as the heap pointer address, writing to it doesn't cause the same behavior as before. Instead, the system becomes locked inside Alarm::init() when calling the Alarm_Timer constructor (probably corrupting a further heap address instead of the pointer).
The heap size is configured to be (MAX_THREADS + CPUS) * STACK_SIZE. When adding more memory (e.g. 100MB), the errors happen at the same places and behave the same, only with another DMA phy address.
The branch being used is this.