// vi:ft=c
/**
 * \page l4re_servers_uvmm_ram_details RAM configuration
 *
 * ## RAM configuration for uvmm
 *
 * ### DMA setup
 *
 * If the vBus contains DMA capable devices, uvmm maps the guest RAM into a
 * DMA address space so that those devices can access it. The shape of that
 * DMA address space depends on whether the platform provides an IO-MMU:
 *
 *  * with an IO-MMU, the DMA address space is independent of host-physical
 *    addresses;
 *  * without an IO-MMU, DMA addresses are the host-physical addresses of the
 *    backing dataspace.
 *
 * If the vBus has no DMA capable devices, no DMA mapping is performed and
 * RAM is placed at the guest-physical address requested by the
 * configuration.
 *
 * Other components in the system may reserve DMA address ranges. RAM placement
 * within the configured range therefore searches for free DMA addresses and
 * may shift inside the configured range or be split into multiple chunks.
 *
 *
 * ### Congruent vs. incongruent placement
 *
 * Per memory region, uvmm chooses one of two placement modes:
 *
 *  * __Congruent__ (default, no `dma-ranges` property): the guest-physical
 *    address equals the DMA address. The actual placement is the DMA
 *    address found by searching the configured range. On a system without
 *    IO-MMU, this is the host-physical address of the backing dataspace, so
 *    the guest sees its RAM at its host-physical address.
 *  * __Incongruent__ (`dma-ranges` property present): the guest-physical
 *    address is honoured as configured, but the corresponding DMA addresses
 *    may differ. uvmm fills the `dma-ranges` property with the resulting
 *    (DMA address, guest address, size) triplets. Use of this property
 *    __requires__ modification of guest code so that DMA-capable devices
 *    are programmed with the correct DMA addresses.
 *
 *
 * ### Without a memory node in the device tree
 *
 * uvmm uses the dataspace bound to the `ram` capability with congruent
 * placement. The base address defaults to 0x0 or the value of the `-b`
 * command-line option. If a DMA address space is in use, the actual base
 * address may be shifted upwards to the first free DMA address at or above
 * the requested base. On a system without IO-MMU this is the host-physical
 * address of the backing dataspace.
 *
 * If a device tree is loaded, uvmm adds a synthesized `memory@<addr>` node
 * with the resulting `reg` value. No `dma-ranges` property is added.
 *
 *
 * ### With a memory node in the device tree
 *
 * The memory node needs at least the properties device_type, l4vmm,dscap and
 * reg:
 *
 *      memory@0 {
 *        device_type = "memory";
 *        l4vmm,dscap = "ram";
 *        reg = < ... >;
 *      }
 *
 * A memory node without a `reg` property is invalid and uvmm refuses to boot.
 * The given l4vmm,dscap name must be accessible in the capability namespace of
 * the uvmm. If the capability is invalid, the memory node is disabled.
 *
 * The `reg` property describes the allowable guest-physical placement
 * range(s) for the dataspace. It is mandatory for explicit memory nodes.
 * uvmm fills the listed `reg` ranges in order with chunks of the dataspace,
 * potentially using multiple chunks per `reg` entry if DMA address space
 * reservations require it. A `reg` entry with `size == 0` means "use the
 * remaining dataspace size". After setup, uvmm rewrites the `reg` property
 * to reflect the actual placement(s) used.
 *
 * If the listed `reg` ranges cannot accommodate the full dataspace, uvmm
 * emits a warning and stops mapping; the guest sees only the portion that
 * fitted.
 *
 * The optional `dma-ranges` property, if present, switches the memory node to
 * incongruent placement (see above). uvmm fills it with the resulting DMA
 * mappings.
 *
 * If memory nodes are given, but none provides valid RAM, the configuration is
 * invalid and uvmm refuses to boot.
 *
 */
