aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-07-05 12:51:12 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-08-02 20:11:09 +0100
commit4f2d3e62b61ebe21498844c0ca346482aca118c9 (patch)
tree0a2b37b1453c25e1d758a853d8b7a91ce072c303
parent9e33f739bcf8455a083ffeb1d8f941d4cd9796b9 (diff)
downloadsyslinux-4f2d3e62b61ebe21498844c0ca346482aca118c9.tar.gz
syslinux-4f2d3e62b61ebe21498844c0ca346482aca118c9.tar.xz
syslinux-4f2d3e62b61ebe21498844c0ca346482aca118c9.zip
efi: implement LOCALBOOTsyslinux-6.02-pre16
Booting the next device is in fact fairly trivial under EFI. We simply need to return control to the firmware with an error code that indicates we couldn't execute our OS loader properly. Unlike under BIOS, we don't take any notice of any integer arguments passed to LOCALBOOT for EFI, since there is no variation for "boot next entry". Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--efi/main.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/efi/main.c b/efi/main.c
index b2debfaf..2eeeba32 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -6,6 +6,7 @@
#include <syslinux/firmware.h>
#include <syslinux/linux.h>
#include <sys/ansi.h>
+#include <setjmp.h>
#include "efi.h"
#include "fio.h"
@@ -24,6 +25,8 @@ uint32_t timer_irq;
__export uint8_t KbdMap[256];
char aux_seg[256];
+static jmp_buf load_error_buf;
+
static inline EFI_STATUS
efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid, EFI_HANDLE agent,
EFI_HANDLE controller)
@@ -119,6 +122,11 @@ void printf_init(void)
__export void local_boot(uint16_t ax)
{
+ /*
+ * Inform the firmware that we failed to execute correctly, which
+ * will trigger the next entry in the EFI Boot Manager list.
+ */
+ longjmp(load_error_buf, 1);
}
void bios_timer_cleanup(void)
@@ -1320,7 +1328,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
} while (status != EFI_NOT_READY);
- load_env32(NULL);
+ if (!setjmp(load_error_buf))
+ load_env32(NULL);
/* load_env32() failed.. cancel timer and bailout */
status = cancel_timer(timer_ev);