[riscv] Relocate to a safe physical address on startup
On startup, we may be running from read-only memory. We need to parse
the devicetree to obtain the system memory map, and identify a safe
location to which we can copy our own binary image along with a
stashed copy of the devicetree, and then transfer execution to this
new location.
Parsing the system memory map realistically requires running C code.
This in turn requires a small temporary stack, and some way to ensure
that symbol references are valid.
We first attempt to enable paging, to make the runtime virtual
addresses equal to the link-time virtual addresses. If this fails,
then we attempt to apply the compressed relocation records.
Assuming that one of these has worked (i.e. that either the CPU
supports paging or that our image started execution in writable
memory), then we call fdtmem_relocate() to parse the system memory map
to find a suitable relocation target address.
After the copy we disable paging, jump to the relocated copy,
re-enable paging, and reapply relocation records (if needed). At this
point, we have a full runtime environment, and can transfer control to
normal C code.
Provide this functionality as part of libprefix.S, since it is likely
to be shared by multiple prefixes.