x86: Support booting a 64-bit kernel from 64-bit U-Boot

Add the missing code to handle this. For a 64-bit kernel the entry
address is 0x200 bytes after the normal entry.

Rename the parameter to boot_linux_kernel() accordingly. Update the
comments to indicate that these are addresses, not pointers.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 873e2bc..9beb376 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -149,7 +149,7 @@
 	return 1;
 }
 
-int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
+int boot_linux_kernel(ulong setup_base, ulong entry, bool image_64bit)
 {
 	bootm_announce_and_cleanup();
 
@@ -161,14 +161,23 @@
 			puts("Cannot boot 64-bit kernel on 32-bit machine\n");
 			return -EFAULT;
 		}
-		/* At present 64-bit U-Boot does not support booting a
+		/*
+		 * At present 64-bit U-Boot only supports booting a 64-bit
 		 * kernel.
-		 * TODO(sjg@chromium.org): Support booting both 32-bit and
-		 * 64-bit kernels from 64-bit U-Boot.
+		 *
+		 * TODO(sjg@chromium.org): Support booting 32-bit kernels from
+		 * 64-bit U-Boot
 		 */
-#if !CONFIG_IS_ENABLED(X86_64)
-		return cpu_jump_to_64bit(setup_base, load_address);
-#endif
+		if (CONFIG_IS_ENABLED(X86_64)) {
+			typedef void (*h_func)(ulong zero, ulong setup);
+			h_func func;
+
+			/* jump to Linux with rdi=0, rsi=setup_base */
+			func = (h_func)entry;
+			func(0, setup_base);
+		} else {
+			return cpu_jump_to_64bit(setup_base, entry);
+		}
 	} else {
 		/*
 		* Set %ebx, %ebp, and %edi to 0, %esi to point to the
@@ -190,7 +199,7 @@
 		"movl $0, %%ebp\n"
 		"cli\n"
 		"jmp *%[kernel_entry]\n"
-		:: [kernel_entry]"a"(load_address),
+		:: [kernel_entry]"a"(entry),
 		[boot_params] "S"(setup_base),
 		"b"(0), "D"(0)
 		);