[ipxe-devel] Patch: Introduce revocable_pause()
Earl Chew
earl_chew at yahoo.com
Thu Nov 5 15:06:59 UTC 2015
This patch introduces function revocable_pause() that allows for a pause
that can be interrupted if a keystroke is detected. The function will
print the remaining time as the pause counts down.
I don't have an UEFI setup, so the small amount of efi_systab related
code is untested.
commit f6680ded106172f5ffb1c59e032caabb3ab0c54d
Author: Earl Chew <earl_chew at yahoo.com>
Date: Sun Nov 1 07:32:55 2015 -0800
[pause] Introduce revocable_pause
Signed-off-by: Earl Chew <earl_chew at yahoo.com>
diff --git a/src/pause.c b/src/pause.c
index 72c50f0..5f5cec5 100644
--- a/src/pause.c
+++ b/src/pause.c
@@ -25,9 +25,12 @@
*/
#include <stdio.h>
+#include <string.h>
+#include "bootapp.h"
#include "wimboot.h"
#include "cmdline.h"
#include "pause.h"
+#include "efi.h"
/**
* Pause before booting
@@ -44,3 +47,101 @@ void pause ( void ) {
printf ( "\n" );
}
}
+
+/**
+ * Pause allowing revocation from the keyboard
+ *
+ */
+#define TICKS_24HRS 0x1800b0
+
+static uint32_t ticks ( uint32_t mark ) {
+ struct bootapp_callback_params params;
+ uint32_t sample;
+
+ memset ( ¶ms, 0, sizeof ( params ) );
+ params.vector.interrupt = 0x1a;
+ params.ah = 0x00;
+ call_interrupt ( ¶ms );
+
+ sample = params.cx << 16 | params.dx;
+ if (sample < mark)
+ sample += TICKS_24HRS;
+ return sample - mark;
+}
+
+static void pause1s ( void ) {
+ if ( efi_systab ) {
+ efi_systab->BootServices->Stall(1000 * 1000);
+ } else {
+ uint32_t mark = ticks(0);
+
+ while (ticks(mark) < TICKS_24HRS / (24 * 60 * 60))
+ continue;
+ }
+}
+
+static uint32_t keystroke ( void ) {
+ uint32_t key;
+
+ if ( efi_systab ) {
+ EFI_INPUT_KEY efikey;
+
+ if ( efi_systab->ConIn->ReadKeyStroke (
+ efi_systab->ConIn, &efikey ) != EFI_SUCCESS )
+ key = 0;
+ else
+ key = 0x10000 | efikey.UnicodeChar;
+ } else {
+ struct bootapp_callback_params params;
+
+ memset ( ¶ms, 0, sizeof ( params ) );
+ params.vector.interrupt = 0x16;
+ params.ah = 0x01;
+ call_interrupt ( ¶ms );
+
+ if (params.eflags & ZF) {
+ params.eax = 0;
+ } else {
+ memset ( ¶ms, 0, sizeof ( params ) );
+ params.vector.interrupt = 0x16;
+ params.ah = 0x00;
+ call_interrupt ( ¶ms );
+ params.eax = 0x10000 | params.ax;
+ }
+
+ key = params.eax;
+ }
+
+ return key;
+}
+
+static void erase ( const char *text ) {
+ unsigned int ix;
+
+ for (ix = 0; text[ix]; ++ix )
+ printf("\b");
+ for (ix = 0; text[ix]; ++ix )
+ printf(" ");
+ for (ix = 0; text[ix]; ++ix )
+ printf("\b");
+}
+
+unsigned int revocable_pause ( unsigned int seconds ) {
+
+ char text[sizeof(" ") + sizeof(seconds) * 3] = { 0 };
+
+ while ( seconds ) {
+
+ snprintf( text, sizeof(text), " %u", seconds );
+ printf( "%s", text );
+ pause1s ();
+ erase( text );
+
+ if ( keystroke() )
+ break;
+
+ --seconds;
+ }
+
+ return seconds;
+}
diff --git a/src/pause.h b/src/pause.h
index 4fe364b..7846589 100644
--- a/src/pause.h
+++ b/src/pause.h
@@ -28,5 +28,6 @@
*/
extern void pause ( void );
+extern unsigned int revocable_pause ( unsigned int seconds );
#endif /* _PAUSE_H */
More information about the ipxe-devel
mailing list