diff options
author | Toomas Soome <tsoome@me.com> | 2017-08-04 11:52:48 +0300 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2017-08-11 23:42:24 +0000 |
commit | 5e9f42abf61392dc608a661563fb49e7707f0478 (patch) | |
tree | c131ba14d21a83994df557e19f8856e966cbd923 | |
parent | c66b8046543352459a11a51501b628d1c98a8c44 (diff) | |
download | illumos-joyent-5e9f42abf61392dc608a661563fb49e7707f0478.tar.gz |
8559 Add EFI utility functions to libefi
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Yuri Pankov <yuripv@gmx.com>
Reviewed by: C Fraire <cfraire@me.com>
Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r-- | usr/src/boot/sys/boot/efi/include/efilib.h | 1 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/libefi/errno.c | 66 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/libefi/time.c | 329 |
3 files changed, 254 insertions, 142 deletions
diff --git a/usr/src/boot/sys/boot/efi/include/efilib.h b/usr/src/boot/sys/boot/efi/include/efilib.h index 77e5525da3..de9e692e74 100644 --- a/usr/src/boot/sys/boot/efi/include/efilib.h +++ b/usr/src/boot/sys/boot/efi/include/efilib.h @@ -52,6 +52,7 @@ CHAR16 *efi_devpath_name(EFI_DEVICE_PATH *); void efi_free_devpath_name(CHAR16 *); int efi_status_to_errno(EFI_STATUS); +EFI_STATUS errno_to_efi_status(int errno); void efi_time_init(void); void efi_time_fini(void); diff --git a/usr/src/boot/sys/boot/efi/libefi/errno.c b/usr/src/boot/sys/boot/efi/libefi/errno.c index fac903faf2..c558bc608b 100644 --- a/usr/src/boot/sys/boot/efi/libefi/errno.c +++ b/usr/src/boot/sys/boot/efi/libefi/errno.c @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * @@ -25,11 +25,73 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); #include <efi.h> #include <efilib.h> +EFI_STATUS +errno_to_efi_status(int errno) +{ + EFI_STATUS status; + + switch (errno) { + case EPERM: + status = EFI_ACCESS_DENIED; + break; + + case EOVERFLOW: + status = EFI_BUFFER_TOO_SMALL; + break; + + case EIO: + status = EFI_DEVICE_ERROR; + break; + + case EINVAL: + status = EFI_INVALID_PARAMETER; + break; + + case ESTALE: + status = EFI_MEDIA_CHANGED; + break; + + case ENXIO: + status = EFI_NO_MEDIA; + break; + + case ENOENT: + status = EFI_NOT_FOUND; + break; + + case ENOMEM: + status = EFI_OUT_OF_RESOURCES; + break; + + case ENOTSUP: + case ENODEV: + status = EFI_UNSUPPORTED; + break; + + case ENOSPC: + status = EFI_VOLUME_FULL; + break; + + case EACCES: + status = EFI_WRITE_PROTECTED; + break; + + case 0: + status = EFI_SUCCESS; + break; + + default: + status = EFI_DEVICE_ERROR; + break; + } + + return (status); +} + int efi_status_to_errno(EFI_STATUS status) { diff --git a/usr/src/boot/sys/boot/efi/libefi/time.c b/usr/src/boot/sys/boot/efi/libefi/time.c index 5ab10b6c43..c475ed7a41 100644 --- a/usr/src/boot/sys/boot/efi/libefi/time.c +++ b/usr/src/boot/sys/boot/efi/libefi/time.c @@ -1,29 +1,29 @@ -/*- +/* * Copyright (c) 1999, 2000 * Intel Corporation. * 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. - * + * * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * + * * This product includes software developed by Intel Corporation and * its contributors. - * + * * 4. Neither the name of Intel Corporation or its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 @@ -35,7 +35,7 @@ * 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 <sys/cdefs.h> @@ -47,15 +47,51 @@ #include <sys/time.h> /* -// Accurate only for the past couple of centuries; -// that will probably do. -// -// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) -*/ + * Accurate only for the past couple of centuries; + * that will probably do. + * + * (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) + */ + +#define isleap(y) (((y) % 4) == 0 && \ + (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERHOUR (60*60) +#define SECSPERDAY (24 * SECSPERHOUR) -#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) -#define SECSPERHOUR ( 60*60 ) -#define SECSPERDAY (24 * SECSPERHOUR) +/* + * These arrays give the cumulative number of days up to the first of the + * month number used as the index (1 -> 12) for regular and leap years. + * The value at index 13 is for the whole year. + */ +static const time_t CumulativeDays[2][14] = { + {0, + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, + {0, + 0, + 31, + 31 + 29, + 31 + 29 + 31, + 31 + 29 + 31 + 30, + 31 + 29 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; void efi_time_init(void) @@ -67,147 +103,157 @@ efi_time_fini(void) { } -static time_t -efi_time(EFI_TIME *ETime) +void +to_efi_time(EFI_TIME *efi_time, time_t time) { - /* - // These arrays give the cumulative number of days up to the first of the - // month number used as the index (1 -> 12) for regular and leap years. - // The value at index 13 is for the whole year. - */ - static time_t CumulativeDays[2][14] = { - {0, - 0, - 31, - 31 + 28, - 31 + 28 + 31, - 31 + 28 + 31 + 30, - 31 + 28 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, - {0, - 0, - 31, - 31 + 29, - 31 + 29 + 31, - 31 + 29 + 31 + 30, - 31 + 29 + 31 + 30 + 31, - 31 + 29 + 31 + 30 + 31 + 30, - 31 + 29 + 31 + 30 + 31 + 30 + 31, - 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, - 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, - 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, - 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, - 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; - - time_t UTime; - int Year; - - /* - // Do a santity check - */ - if ( ETime->Year < 1998 || ETime->Year > 2099 || - ETime->Month == 0 || ETime->Month > 12 || - ETime->Day == 0 || ETime->Month > 31 || - ETime->Hour > 23 || - ETime->Minute > 59 || - ETime->Second > 59 || - ETime->TimeZone < -1440 || - (ETime->TimeZone > 1440 && ETime->TimeZone != 2047) ) { - return (0); - } - - /* - // Years - */ - UTime = 0; - for (Year = 1970; Year != ETime->Year; ++Year) { - UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); - } - - /* - // UTime should now be set to 00:00:00 on Jan 1 of the file's year. - // - // Months - */ - UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); - - /* - // UTime should now be set to 00:00:00 on the first of the file's month and year - // - // Days -- Don't count the file's day - */ - UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); - - /* - // Hours - */ - UTime += (ETime->Hour * SECSPERHOUR); - - /* - // Minutes - */ - UTime += (ETime->Minute * 60); - - /* - // Seconds - */ - UTime += ETime->Second; - - /* - // EFI time is repored in local time. Adjust for any time zone offset to - // get true UT - */ - if ( ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) { - /* - // TimeZone is kept in minues... - */ - UTime += (ETime->TimeZone * 60); - } - - return UTime; + int lyear, month; + time_t seconds; + + if (time >= 0) { + efi_time->Year = 1970; + lyear = isleap(efi_time->Year); + month = 13; + seconds = CumulativeDays[lyear][month] * SECSPERDAY; + while (time > seconds) { + time -= seconds; + efi_time->Year++; + lyear = isleap(efi_time->Year); + seconds = CumulativeDays[lyear][month] * SECSPERDAY; + } + + efi_time->Month = 0; + while (time > + CumulativeDays[lyear][efi_time->Month] * SECSPERDAY) { + efi_time->Month++; + } + + month = efi_time->Month - 1; + time -= CumulativeDays[lyear][month] * SECSPERDAY; + + for (efi_time->Day = 0; time > SECSPERDAY; efi_time->Day++) + time -= SECSPERDAY; + + for (efi_time->Hour = 0; time > SECSPERHOUR; efi_time->Hour++) + time -= SECSPERHOUR; + + for (efi_time->Minute = 0; time > 60; efi_time->Minute++) + time -= 60; + + efi_time->Second = time; + efi_time->Nanosecond = 0; + efi_time->TimeZone = 0; + efi_time->Daylight = 0; + } else { + memset(efi_time, 0, sizeof (EFI_TIME)); + } +} + +time_t +from_efi_time(EFI_TIME *ETime) +{ + time_t UTime; + int Year; + + /* + * Do a santity check + */ + if (ETime->Year < 1998 || ETime->Year > 2099 || + ETime->Month == 0 || ETime->Month > 12 || + ETime->Day == 0 || ETime->Month > 31 || + ETime->Hour > 23 || ETime->Minute > 59 || + ETime->Second > 59 || ETime->TimeZone < -1440 || + (ETime->TimeZone > 1440 && ETime->TimeZone != 2047)) { + return (0); + } + + /* + * Years + */ + UTime = 0; + for (Year = 1970; Year != ETime->Year; ++Year) { + UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); + } + + /* + * UTime should now be set to 00:00:00 on Jan 1 of the file's year. + * + * Months + */ + UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * + SECSPERDAY); + + /* + * UTime should now be set to 00:00:00 on the first of the file's + * month and year. + * + * Days -- Don't count the file's day + */ + UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); + + /* + * Hours + */ + UTime += (ETime->Hour * SECSPERHOUR); + + /* + * Minutes + */ + UTime += (ETime->Minute * 60); + + /* + * Seconds + */ + UTime += ETime->Second; + + /* + * EFI time is repored in local time. Adjust for any time zone + * offset to get true UT + */ + if (ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { + /* + * TimeZone is kept in minues... + */ + UTime += (ETime->TimeZone * 60); + } + + return (UTime); } static int -EFI_GetTimeOfDay( - OUT struct timeval *tp, - OUT struct timezone *tzp - ) +EFI_GetTimeOfDay(OUT struct timeval *tp, OUT struct timezone *tzp) { EFI_TIME EfiTime; EFI_TIME_CAPABILITIES Capabilities; EFI_STATUS Status; /* - // Get time from EFI - */ + * Get time from EFI + */ Status = RS->GetTime(&EfiTime, &Capabilities); if (EFI_ERROR(Status)) return (-1); /* - // Convert to UNIX time (ie seconds since the epoch - */ + * Convert to UNIX time (ie seconds since the epoch) + */ - tp->tv_sec = efi_time( &EfiTime ); + tp->tv_sec = from_efi_time(&EfiTime); tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */ /* - // Do something with the timezone if needed - */ + * Do something with the timezone if needed + */ - if (tzp) { - tzp->tz_minuteswest = - EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE ? 0 : EfiTime.TimeZone; + if (tzp != NULL) { + if (EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) + tzp->tz_minuteswest = 0; + else + tzp->tz_minuteswest = EfiTime.TimeZone; /* - // This isn't quit right since it doesn't deal with EFI_TIME_IN_DAYLIGHT - */ + * This isn't quit right since it doesn't deal with + * EFI_TIME_IN_DAYLIGHT + */ tzp->tz_dsttime = EfiTime.Daylight & EFI_TIME_ADJUST_DAYLIGHT ? 1 : 0; } @@ -219,15 +265,18 @@ time_t time(time_t *tloc) { struct timeval tv; - EFI_GetTimeOfDay(&tv, 0); - + + memset(&tv, 0, sizeof (tv)); + EFI_GetTimeOfDay(&tv, NULL); + if (tloc) *tloc = tv.tv_sec; - return tv.tv_sec; + return (tv.tv_sec); } time_t getsecs(void) { - return time(0); + + return (time(NULL)); } |