From e68a6ca225115a8796e6d63ffc32856043e25886 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 22 Mar 2013 13:54:44 +0000 Subject: [PATCH] [cmdline] Add ability to perform a warm reboot Signed-off-by: Michael Brown --- src/arch/i386/include/bios.h | 2 ++ src/arch/i386/interface/pcbios/bios_reboot.c | 9 ++++++++- src/core/null_reboot.c | 3 ++- src/hci/commands/reboot_cmd.c | 15 +++++++++++---- src/include/ipxe/reboot.h | 3 ++- src/interface/efi/efi_reboot.c | 5 +++-- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/arch/i386/include/bios.h b/src/arch/i386/include/bios.h index fadb9f1b..3e6a845e 100644 --- a/src/arch/i386/include/bios.h +++ b/src/arch/i386/include/bios.h @@ -6,6 +6,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define BDA_SEG 0x0040 #define BDA_EQUIPMENT_WORD 0x0010 #define BDA_FBMS 0x0013 +#define BDA_REBOOT 0x0072 +#define BDA_REBOOT_WARM 0x1234 #define BDA_NUM_DRIVES 0x0075 #endif /* BIOS_H */ diff --git a/src/arch/i386/interface/pcbios/bios_reboot.c b/src/arch/i386/interface/pcbios/bios_reboot.c index 86f4e3eb..68546b2e 100644 --- a/src/arch/i386/interface/pcbios/bios_reboot.c +++ b/src/arch/i386/interface/pcbios/bios_reboot.c @@ -27,12 +27,19 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include +#include /** * Reboot system * + * @v warm Perform a warm reboot */ -static void bios_reboot ( void ) { +static void bios_reboot ( int warm ) { + uint16_t flag; + + /* Configure BIOS for cold/warm reboot */ + flag = ( warm ? BDA_REBOOT_WARM : 0 ); + put_real ( flag, BDA_SEG, BDA_REBOOT ); /* Jump to system reset vector */ __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) : : ); diff --git a/src/core/null_reboot.c b/src/core/null_reboot.c index b7e55bce..8e3ed0bb 100644 --- a/src/core/null_reboot.c +++ b/src/core/null_reboot.c @@ -32,8 +32,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** * Reboot system * + * @v warm Perform a warm reboot */ -static void null_reboot ( void ) { +static void null_reboot ( int warm __unused ) { printf ( "Cannot reboot; not implemented\n" ); while ( 1 ) {} diff --git a/src/hci/commands/reboot_cmd.c b/src/hci/commands/reboot_cmd.c index 19d3d6df..44dcfc71 100644 --- a/src/hci/commands/reboot_cmd.c +++ b/src/hci/commands/reboot_cmd.c @@ -17,6 +17,7 @@ * 02110-1301, USA. */ +#include #include #include #include @@ -30,14 +31,20 @@ FILE_LICENCE ( GPL2_OR_LATER ); */ /** "reboot" options */ -struct reboot_options {}; +struct reboot_options { + /** Perform a warm reboot */ + int warm; +}; /** "reboot" option list */ -static struct option_descriptor reboot_opts[] = {}; +static struct option_descriptor reboot_opts[] = { + OPTION_DESC ( "warm", 'w', no_argument, + struct reboot_options, warm, parse_flag ), +}; /** "reboot" command descriptor */ static struct command_descriptor reboot_cmd = - COMMAND_DESC ( struct reboot_options, reboot_opts, 0, 0, "" ); + COMMAND_DESC ( struct reboot_options, reboot_opts, 0, 0, "[--warm]" ); /** * The "reboot" command @@ -55,7 +62,7 @@ static int reboot_exec ( int argc, char **argv ) { return rc; /* Reboot system */ - reboot(); + reboot ( opts.warm ); return 0; } diff --git a/src/include/ipxe/reboot.h b/src/include/ipxe/reboot.h index 043c5e10..5d882d3d 100644 --- a/src/include/ipxe/reboot.h +++ b/src/include/ipxe/reboot.h @@ -51,7 +51,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** * Reboot system * + * @v warm Perform a warm reboot */ -void reboot ( void ); +void reboot ( int warm ); #endif /* _IPXE_REBOOT_H */ diff --git a/src/interface/efi/efi_reboot.c b/src/interface/efi/efi_reboot.c index 1ecccc46..bfee36aa 100644 --- a/src/interface/efi/efi_reboot.c +++ b/src/interface/efi/efi_reboot.c @@ -32,12 +32,13 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** * Reboot system * + * @v warm Perform a warm reboot */ -static void efi_reboot ( void ) { +static void efi_reboot ( int warm ) { EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices; /* Use runtime services to reset system */ - rs->ResetSystem ( EfiResetCold, 0, 0, NULL ); + rs->ResetSystem ( ( warm ? EfiResetWarm : EfiResetCold ), 0, 0, NULL ); } PROVIDE_REBOOT ( efi, reboot, efi_reboot );