aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-03-20 12:23:33 +0000
committerMatt Fleming <matt.fleming@intel.com>2013-03-20 12:39:13 +0000
commitba392ad83d37890d4ec6f0f703076e2b31d350c2 (patch)
tree5cbefa97b850451a71e535d5bd463788308d041d
parent5d6e34ffc660136e5f5a0e54be65ee55c1adf00c (diff)
downloadefilinux-ba392ad83d37890d4ec6f0f703076e2b31d350c2.tar.gz
bzimage: Fixup for kernel changes to EFI handover protocol
The ABI of the EFI handover protocol was changed in v3.8 with the following upstream kernel commit, : commit f791620fa7517e1045742c475a7f005db9a634b8 : Author: David Woodhouse <David.Woodhouse@intel.com> : Date: Mon Jan 7 22:01:50 2013 +0000 : : x86, efi: Fix 32-bit EFI handover protocol entry point from a 'jmp' to a 'call'. This affects the layout of arguments on the stack since 'call' expects the return address to be the data item at the top of the stack. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--loaders/bzimage/bzimage.c3
-rw-r--r--loaders/bzimage/i386.h27
-rw-r--r--loaders/bzimage/x86_64.h3
3 files changed, 22 insertions, 11 deletions
diff --git a/loaders/bzimage/bzimage.c b/loaders/bzimage/bzimage.c
index d683eae..6c992b3 100644
--- a/loaders/bzimage/bzimage.c
+++ b/loaders/bzimage/bzimage.c
@@ -334,7 +334,8 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
* protocol.
*/
if (buf->hdr.version >= 0x20b) {
- handover_jump(image, boot_params, kernel_start);
+ handover_jump(buf->hdr.version, image,
+ boot_params, kernel_start);
goto out;
}
diff --git a/loaders/bzimage/i386.h b/loaders/bzimage/i386.h
index 593e2af..0b74c80 100644
--- a/loaders/bzimage/i386.h
+++ b/loaders/bzimage/i386.h
@@ -42,19 +42,28 @@ static inline void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start,
:: "m" (boot_params), "m" (kernel_start));
}
-static inline void handover_jump(EFI_HANDLE image, struct boot_params *bp,
+typedef void(*handover_func)(void *, EFI_SYSTEM_TABLE *,
+ struct boot_params *) __attribute__((regparm(0)));
+
+static inline void handover_jump(UINT16 kernel_version, EFI_HANDLE image,
+ struct boot_params *bp,
EFI_PHYSICAL_ADDRESS kernel_start)
{
kernel_start += bp->hdr.handover_offset;
- asm volatile ("cli \n"
- "pushl %0 \n"
- "pushl %1 \n"
- "pushl %2 \n"
- "movl %3, %%ecx \n"
- "jmp *%%ecx \n"
- :: "m" (bp), "m" (ST),
- "m" (image), "m" (kernel_start));
+ if (kernel_version == 0x20b) {
+ asm volatile ("cli \n"
+ "pushl %0 \n"
+ "pushl %1 \n"
+ "pushl %2 \n"
+ "movl %3, %%ecx \n"
+ "jmp *%%ecx \n"
+ :: "m" (bp), "m" (ST),
+ "m" (image), "m" (kernel_start));
+ } else {
+ handover_func hf = (handover_func)(UINTN)kernel_start;
+ hf(image, ST, bp);
+ }
}
#endif /* __I386_H__ */
diff --git a/loaders/bzimage/x86_64.h b/loaders/bzimage/x86_64.h
index b63710e..e44f7f9 100644
--- a/loaders/bzimage/x86_64.h
+++ b/loaders/bzimage/x86_64.h
@@ -52,7 +52,8 @@ static inline void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start,
kf(NULL, boot_params);
}
-static inline void handover_jump(EFI_HANDLE image, struct boot_params *bp,
+static inline void handover_jump(UINT16 kernel_version, EFI_HANDLE image,
+ struct boot_params *bp,
EFI_PHYSICAL_ADDRESS kernel_start)
{
UINT32 offset = bp->hdr.handover_offset;