mainboard/qemu-riscv: Get top of memory from device-tree blob

Trying to probe RAM space to figure out top of memory causes an
exception on RISC-V virtual machines with recent versions of QEMU, but
we temporarily enable exception handlers for that and use it to help
detect if a RAM address is usable or not. However, QEMU docs recommend
reading device information from the device-tree blob it provides us at
the start of RAM.

A previous commit adds a library function to parse device-tree blob that
QEMU provides us. Use it to determine top of memory in RISC-V QEMU
virtual machines, but still fall back to the RAM probing approach as a
last-ditch effort.

Change-Id: I9e4a95f49ad373675939329eef40d7423a4132ab
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/80363
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
diff --git a/src/mainboard/emulation/qemu-riscv/Kconfig b/src/mainboard/emulation/qemu-riscv/Kconfig
index 94f9e56..27b1b58 100644
--- a/src/mainboard/emulation/qemu-riscv/Kconfig
+++ b/src/mainboard/emulation/qemu-riscv/Kconfig
@@ -23,6 +23,7 @@
 config BOARD_SPECIFIC_OPTIONS
 	def_bool y
 	select BOARD_ROMSIZE_KB_32768
+	select FLATTENED_DEVICE_TREE
 	select MISSING_BOARD_RESET
 	select DRIVERS_UART_8250MEM
 	select RISCV_HAS_OPENSBI
diff --git a/src/mainboard/emulation/qemu-riscv/cbmem.c b/src/mainboard/emulation/qemu-riscv/cbmem.c
index e4d21cc..8c37957 100644
--- a/src/mainboard/emulation/qemu-riscv/cbmem.c
+++ b/src/mainboard/emulation/qemu-riscv/cbmem.c
@@ -3,10 +3,17 @@
 #include <cbmem.h>
 #include <symbols.h>
 #include <ramdetect.h>
+#include <device_tree.h>
+#include <mcall.h>
 
 uintptr_t cbmem_top_chipset(void)
 {
-	//TODO get memory range from QEMUs FDT
+	uint64_t top;
+
+	top = fdt_get_memory_top((void *)HLS()->fdt);
+	if (top)
+		return MIN(top, (uint64_t)4 * GiB - 1);
+
 	size_t dram_mb_detected = probe_ramsize((uintptr_t)_dram, CONFIG_DRAM_SIZE_MB);
 	return (uintptr_t)_dram + dram_mb_detected * MiB;
 }