Clearly U-Boot expects this to work and runs on a variety of ARM based boards. The network code does not need to be changed. The ARM processor needs to be told to allow these unaligned accesses and there is a bit to control this behavior.
static void arm_alignment_hack ( void ) { unsigned int val; val = current_el (); printf ( "current EL = %08x\n", val ); asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc"); printf ( "sctlr_el2 = %08x\n", val ); val = get_sctlr (); printf ( "sctlr = %08x\n", val ); }And I get the following:
current EL = 00000002 sctlr_el1 = 30d00800 sctlr_el2 = 30c51830 sctlr = 30c51830Trying to read sctlr_el3 gives me a synchronous abort. Lo and behold, the "A" bit is not set (0x2, aka CR_A) And this is how it should be (setting it enables the strict alignment checking that we thought was giving us the exception). So what is going on? It may have something to do with the cache being enabled or not. Note that 0x4 is the data cache enabled bit, and clearly it is not enabled. The second link above mentions:
The code runs when caches are still disabled and thus all the memory is treated as Device-nGnRnE, requiring aligned accesses.So, when the D cache is not enabled, memory is treated as a device and unaligned access is not supported, no matter if the "A" bit in the SCTLR register is clear. Also note that when you enable the mmu (as you must to enable the D cache), be sure not to set bits that flag memory as device or strongly ordered.
I'll note in passing, that while nosing around I tripped over the following interesting file. Definitely worthy of extra study.
Tom's electronics pages / tom@mmto.org