Index: head/sys/boot/efi/include/efilib.h =================================================================== --- head/sys/boot/efi/include/efilib.h +++ head/sys/boot/efi/include/efilib.h @@ -55,6 +55,9 @@ int efi_status_to_errno(EFI_STATUS); +void efi_time_init(void); +void efi_time_fini(void); + EFI_STATUS main(int argc, CHAR16 *argv[]); void exit(EFI_STATUS status); void delay(int usecs); Index: head/sys/boot/efi/libefi/Makefile =================================================================== --- head/sys/boot/efi/libefi/Makefile +++ head/sys/boot/efi/libefi/Makefile @@ -5,7 +5,13 @@ WARNS?= 2 SRCS= delay.c devpath.c efi_console.c efinet.c efipart.c env.c errno.c \ - handles.c libefi.c time.c + handles.c libefi.c + +.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +SRCS+= time.c +.elif ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" +SRCS+= time_event.c +.endif # We implement a slightly non-standard %S in that it always takes a # CHAR16 that's common in UEFI-land instead of a wchar_t. This only Index: head/sys/boot/efi/libefi/time.c =================================================================== --- head/sys/boot/efi/libefi/time.c +++ head/sys/boot/efi/libefi/time.c @@ -58,6 +58,16 @@ #define SECSPERHOUR ( 60*60 ) #define SECSPERDAY (24 * SECSPERHOUR) +void +efi_time_init(void) +{ +} + +void +efi_time_fini(void) +{ +} + static time_t efi_time(EFI_TIME *ETime) { Index: head/sys/boot/efi/libefi/time_event.c =================================================================== --- head/sys/boot/efi/libefi/time_event.c +++ head/sys/boot/efi/libefi/time_event.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2016 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +static EFI_EVENT time_event; +static uint64_t curtime; + +static void +time_update(EFI_EVENT event, void *context) +{ + + curtime += 10; +} + +void +efi_time_init(void) +{ + + /* Create a timer event */ + BS->CreateEvent(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, + time_update, 0, &time_event); + /* Use a 10ms timer */ + BS->SetTimer(time_event, TimerPeriodic, 100000); +} + +void +efi_time_fini(void) +{ + + /* Cancel the timer */ + BS->SetTimer(time_event, TimerCancel, 0); + BS->CloseEvent(time_event); +} + +time_t +time(time_t *tloc) +{ + time_t t; + + t = curtime / 1000; + if (tloc != NULL) + *tloc = t; + + return (t); +} + +time_t +getsecs() +{ + return time(0); +} Index: head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c =================================================================== --- head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c +++ head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c @@ -186,9 +186,12 @@ printf("Start @ 0x%lx ...\n", ehdr->e_entry); + efi_time_fini(); err = bi_load(fp->f_args, &modulep, &kernend); - if (err != 0) + if (err != 0) { + efi_time_init(); return(err); + } dev_cleanup(); Index: head/sys/boot/efi/loader/arch/arm/exec.c =================================================================== --- head/sys/boot/efi/loader/arch/arm/exec.c +++ head/sys/boot/efi/loader/arch/arm/exec.c @@ -73,8 +73,11 @@ e = (Elf_Ehdr *)&fmp->md_data; - if ((error = bi_load(fp->f_args, &modulep, &kernend)) != 0) + efi_time_fini(); + if ((error = bi_load(fp->f_args, &modulep, &kernend)) != 0) { + efi_time_init(); return (error); + } entry = efi_translate(e->e_entry); printf("Kernel entry at 0x%x...\n", (unsigned)entry); Index: head/sys/boot/efi/loader/arch/arm64/exec.c =================================================================== --- head/sys/boot/efi/loader/arch/arm64/exec.c +++ head/sys/boot/efi/loader/arch/arm64/exec.c @@ -113,9 +113,12 @@ ehdr = (Elf_Ehdr *)&(md->md_data); entry = efi_translate(ehdr->e_entry); + efi_time_fini(); err = bi_load(fp->f_args, &modulep, &kernendp); - if (err != 0) + if (err != 0) { + efi_time_init(); return (err); + } dev_cleanup(); Index: head/sys/boot/efi/loader/arch/i386/elf32_freebsd.c =================================================================== --- head/sys/boot/efi/loader/arch/i386/elf32_freebsd.c +++ head/sys/boot/efi/loader/arch/i386/elf32_freebsd.c @@ -71,9 +71,12 @@ return(EFTYPE); ehdr = (Elf_Ehdr *)&(md->md_data); + efi_time_fini(); err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend); - if (err != 0) + if (err != 0) { + efi_time_init(); return(err); + } entry = ehdr->e_entry & 0xffffff; printf("Start @ 0x%lx ...\n", entry); Index: head/sys/boot/efi/loader/main.c =================================================================== --- head/sys/boot/efi/loader/main.c +++ head/sys/boot/efi/loader/main.c @@ -246,6 +246,9 @@ archsw.arch_zfs_probe = efi_zfs_probe; #endif + /* Init the time source */ + efi_time_init(); + has_kbd = has_keyboard(); /*