diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index 76274cb..a8136a0 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -60,12 +60,8 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
  * address, and how far U-Boot is moved by relocation are set in the global
  * data structure.
  */
-int calculate_relocation_address(void)
+ulong board_get_usable_ram_top(ulong total_size)
 {
-	const uint64_t uboot_size = (uintptr_t)&__bss_end -
-			(uintptr_t)&__text_start;
-	const uint64_t total_size = uboot_size + CONFIG_SYS_MALLOC_LEN +
-		CONFIG_SYS_STACK_SIZE;
 	uintptr_t dest_addr = 0;
 	int i;
 
@@ -87,21 +83,15 @@ int calculate_relocation_address(void)
 			continue;
 
 		/* Use this address if it's the largest so far. */
-		if (end - uboot_size > dest_addr)
+		if (end > dest_addr)
 			dest_addr = end;
 	}
 
 	/* If no suitable area was found, return an error. */
 	if (!dest_addr)
-		return 1;
+		panic("No available memory found for relocation");
 
-	dest_addr -= uboot_size;
-	dest_addr &= ~((1 << 12) - 1);
-	gd->relocaddr = dest_addr;
-	gd->reloc_off = dest_addr - (uintptr_t)&__text_start;
-	gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
-
-	return 0;
+	return (ulong)dest_addr;
 }
 
 int dram_init_f(void)
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 3eec9a6..1a097f1 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -73,26 +73,34 @@ int init_baudrate_f(void)
 	return 0;
 }
 
-__weak int calculate_relocation_address(void)
+/* Get the top of usable RAM */
+__weak ulong board_get_usable_ram_top(ulong total_size)
 {
-	ulong text_start = (ulong)&__text_start;
-	ulong bss_end = (ulong)&__bss_end;
+	return gd->ram_size;
+}
+
+int calculate_relocation_address(void)
+{
+	const ulong uboot_size = (uintptr_t)&__bss_end -
+			(uintptr_t)&__text_start;
+	ulong total_size;
 	ulong dest_addr;
 
+	total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN +
+		CONFIG_SYS_STACK_SIZE;
+
 	/*
 	 * NOTE: All destination address are rounded down to 16-byte
 	 *       boundary to satisfy various worst-case alignment
 	 *       requirements
 	 */
+	dest_addr = board_get_usable_ram_top(total_size);
 
-	/* Stack is at top of available memory */
-	dest_addr = gd->ram_size;
-
-	/* U-Boot is at the top */
-	dest_addr -= (bss_end - text_start);
-	dest_addr &= ~15;
+	/* U-Boot is below the FDT */
+	dest_addr -= uboot_size;
+	dest_addr &= ~((1 << 12) - 1);
 	gd->relocaddr = dest_addr;
-	gd->reloc_off = (dest_addr - text_start);
+	gd->reloc_off = dest_addr - (uintptr_t)&__text_start;
 
 	/* Stack is at the bottom, so it can grow down */
 	gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
