From 71cd50883896dc043f1025a3b96f3c0c7f3b2184 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 22 Mar 2013 13:42:16 +0000 Subject: [PATCH] [efi] Add "reboot" command for EFI Abstract out the ability to reboot the system to a separate reboot() function (with platform-specific implementations), add an EFI implementation, and make the existing "reboot" command available under EFI. Signed-off-by: Michael Brown --- src/arch/i386/include/bits/reboot.h | 14 +++++ src/arch/i386/include/ipxe/bios_reboot.h | 18 ++++++ src/arch/i386/interface/pcbios/bios_reboot.c | 41 +++++++++++++ src/arch/x86_64/include/bits/reboot.h | 12 ++++ src/config/defaults/efi.h | 3 + src/config/defaults/linux.h | 1 + src/config/defaults/pcbios.h | 1 + src/config/reboot.h | 16 ++++++ src/core/null_reboot.c | 42 ++++++++++++++ src/{arch/i386 => }/hci/commands/reboot_cmd.c | 4 +- src/include/ipxe/efi/efi_reboot.h | 18 ++++++ src/include/ipxe/null_reboot.h | 18 ++++++ src/include/ipxe/reboot.h | 57 +++++++++++++++++++ src/interface/efi/efi_reboot.c | 43 ++++++++++++++ 14 files changed, 286 insertions(+), 2 deletions(-) create mode 100644 src/arch/i386/include/bits/reboot.h create mode 100644 src/arch/i386/include/ipxe/bios_reboot.h create mode 100644 src/arch/i386/interface/pcbios/bios_reboot.c create mode 100644 src/arch/x86_64/include/bits/reboot.h create mode 100644 src/config/reboot.h create mode 100644 src/core/null_reboot.c rename src/{arch/i386 => }/hci/commands/reboot_cmd.c (94%) create mode 100644 src/include/ipxe/efi/efi_reboot.h create mode 100644 src/include/ipxe/null_reboot.h create mode 100644 src/include/ipxe/reboot.h create mode 100644 src/interface/efi/efi_reboot.c diff --git a/src/arch/i386/include/bits/reboot.h b/src/arch/i386/include/bits/reboot.h new file mode 100644 index 00000000..5b09e95f --- /dev/null +++ b/src/arch/i386/include/bits/reboot.h @@ -0,0 +1,14 @@ +#ifndef _BITS_REBOOT_H +#define _BITS_REBOOT_H + +/** @file + * + * i386-specific reboot API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include + +#endif /* _BITS_REBOOT_H */ diff --git a/src/arch/i386/include/ipxe/bios_reboot.h b/src/arch/i386/include/ipxe/bios_reboot.h new file mode 100644 index 00000000..a0845328 --- /dev/null +++ b/src/arch/i386/include/ipxe/bios_reboot.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_BIOS_REBOOT_H +#define _IPXE_BIOS_REBOOT_H + +/** @file + * + * Standard PC-BIOS reboot mechanism + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef REBOOT_PCBIOS +#define REBOOT_PREFIX_pcbios +#else +#define REBOOT_PREFIX_pcbios __pcbios_ +#endif + +#endif /* _IPXE_BIOS_REBOOT_H */ diff --git a/src/arch/i386/interface/pcbios/bios_reboot.c b/src/arch/i386/interface/pcbios/bios_reboot.c new file mode 100644 index 00000000..86f4e3eb --- /dev/null +++ b/src/arch/i386/interface/pcbios/bios_reboot.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** @file + * + * Standard PC-BIOS reboot mechanism + * + */ + +#include +#include + +/** + * Reboot system + * + */ +static void bios_reboot ( void ) { + + /* Jump to system reset vector */ + __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) : : ); +} + +PROVIDE_REBOOT ( pcbios, reboot, bios_reboot ); diff --git a/src/arch/x86_64/include/bits/reboot.h b/src/arch/x86_64/include/bits/reboot.h new file mode 100644 index 00000000..f1bce054 --- /dev/null +++ b/src/arch/x86_64/include/bits/reboot.h @@ -0,0 +1,12 @@ +#ifndef _BITS_REBOOT_H +#define _BITS_REBOOT_H + +/** @file + * + * x86_64-specific reboot API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#endif /* _BITS_REBOOT_H */ diff --git a/src/config/defaults/efi.h b/src/config/defaults/efi.h index 923360ae..c453e89a 100644 --- a/src/config/defaults/efi.h +++ b/src/config/defaults/efi.h @@ -19,8 +19,11 @@ #define BOFM_EFI #define ENTROPY_NULL #define TIME_NULL +#define REBOOT_EFI #define IMAGE_EFI /* EFI image support */ #define IMAGE_SCRIPT /* iPXE script image support */ +#define REBOOT_CMD /* Reboot command */ + #endif /* CONFIG_DEFAULTS_EFI_H */ diff --git a/src/config/defaults/linux.h b/src/config/defaults/linux.h index 50897560..666db6b8 100644 --- a/src/config/defaults/linux.h +++ b/src/config/defaults/linux.h @@ -16,6 +16,7 @@ #define SANBOOT_NULL #define ENTROPY_LINUX #define TIME_LINUX +#define REBOOT_NULL #define DRIVERS_LINUX diff --git a/src/config/defaults/pcbios.h b/src/config/defaults/pcbios.h index c52fca97..7debc8d2 100644 --- a/src/config/defaults/pcbios.h +++ b/src/config/defaults/pcbios.h @@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define SANBOOT_PCBIOS #define ENTROPY_RTC #define TIME_RTC +#define REBOOT_PCBIOS #define IMAGE_ELF /* ELF image support */ #define IMAGE_MULTIBOOT /* MultiBoot image support */ diff --git a/src/config/reboot.h b/src/config/reboot.h new file mode 100644 index 00000000..240ef87b --- /dev/null +++ b/src/config/reboot.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_REBOOT_H +#define CONFIG_REBOOT_H + +/** @file + * + * Reboot API configuration + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include + +#include + +#endif /* CONFIG_REBOOT_H */ diff --git a/src/core/null_reboot.c b/src/core/null_reboot.c new file mode 100644 index 00000000..b7e55bce --- /dev/null +++ b/src/core/null_reboot.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * @file + * + * Null reboot mechanism + * + */ + +#include +#include + +/** + * Reboot system + * + */ +static void null_reboot ( void ) { + + printf ( "Cannot reboot; not implemented\n" ); + while ( 1 ) {} +} + +PROVIDE_REBOOT ( null, reboot, null_reboot ); diff --git a/src/arch/i386/hci/commands/reboot_cmd.c b/src/hci/commands/reboot_cmd.c similarity index 94% rename from src/arch/i386/hci/commands/reboot_cmd.c rename to src/hci/commands/reboot_cmd.c index 74c69c94..19d3d6df 100644 --- a/src/arch/i386/hci/commands/reboot_cmd.c +++ b/src/hci/commands/reboot_cmd.c @@ -17,9 +17,9 @@ * 02110-1301, USA. */ -#include #include #include +#include FILE_LICENCE ( GPL2_OR_LATER ); @@ -55,7 +55,7 @@ static int reboot_exec ( int argc, char **argv ) { return rc; /* Reboot system */ - __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) : : ); + reboot(); return 0; } diff --git a/src/include/ipxe/efi/efi_reboot.h b/src/include/ipxe/efi/efi_reboot.h new file mode 100644 index 00000000..33921b91 --- /dev/null +++ b/src/include/ipxe/efi/efi_reboot.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_EFI_REBOOT_H +#define _IPXE_EFI_REBOOT_H + +/** @file + * + * iPXE reboot API for EFI + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef REBOOT_EFI +#define REBOOT_PREFIX_efi +#else +#define REBOOT_PREFIX_efi __efi_ +#endif + +#endif /* _IPXE_EFI_REBOOT_H */ diff --git a/src/include/ipxe/null_reboot.h b/src/include/ipxe/null_reboot.h new file mode 100644 index 00000000..3de36c5b --- /dev/null +++ b/src/include/ipxe/null_reboot.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_NULL_REBOOT_H +#define _IPXE_NULL_REBOOT_H + +/** @file + * + * iPXE do-nothing reboot API + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef REBOOT_NULL +#define REBOOT_PREFIX_null +#else +#define REBOOT_PREFIX_null __null_ +#endif + +#endif /* _IPXE_NULL_REBOOT_H */ diff --git a/src/include/ipxe/reboot.h b/src/include/ipxe/reboot.h new file mode 100644 index 00000000..043c5e10 --- /dev/null +++ b/src/include/ipxe/reboot.h @@ -0,0 +1,57 @@ +#ifndef _IPXE_REBOOT_H +#define _IPXE_REBOOT_H + +/** @file + * + * iPXE reboot API + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include +#include + +/** + * Calculate static inline reboot API function name + * + * @v _prefix Subsystem prefix + * @v _api_func API function + * @ret _subsys_func Subsystem API function + */ +#define REBOOT_INLINE( _subsys, _api_func ) \ + SINGLE_API_INLINE ( REBOOT_PREFIX_ ## _subsys, _api_func ) + +/** + * Provide an reboot API implementation + * + * @v _prefix Subsystem prefix + * @v _api_func API function + * @v _func Implementing function + */ +#define PROVIDE_REBOOT( _subsys, _api_func, _func ) \ + PROVIDE_SINGLE_API ( REBOOT_PREFIX_ ## _subsys, _api_func, _func ) + +/** + * Provide a static inline reboot API implementation + * + * @v _prefix Subsystem prefix + * @v _api_func API function + */ +#define PROVIDE_REBOOT_INLINE( _subsys, _api_func ) \ + PROVIDE_SINGLE_API_INLINE ( REBOOT_PREFIX_ ## _subsys, _api_func ) + +/* Include all architecture-independent reboot API headers */ +#include +#include + +/* Include all architecture-dependent reboot API headers */ +#include + +/** + * Reboot system + * + */ +void reboot ( void ); + +#endif /* _IPXE_REBOOT_H */ diff --git a/src/interface/efi/efi_reboot.c b/src/interface/efi/efi_reboot.c new file mode 100644 index 00000000..1ecccc46 --- /dev/null +++ b/src/interface/efi/efi_reboot.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * @file + * + * EFI reboot mechanism + * + */ + +#include +#include + +/** + * Reboot system + * + */ +static void efi_reboot ( void ) { + EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices; + + /* Use runtime services to reset system */ + rs->ResetSystem ( EfiResetCold, 0, 0, NULL ); +} + +PROVIDE_REBOOT ( efi, reboot, efi_reboot );