Add UEFI support

This is mutually exclusive with Windows support. Documentation for how
to use it has been written in libc/runtime/efimain.c
This commit is contained in:
Justine Tunney
2021-02-21 16:26:36 -08:00
committed by Justine Tunney
parent c6c9b5dfde
commit 537c21338b
24 changed files with 1381 additions and 391 deletions

23
libc/calls/efi.c Normal file
View File

@@ -0,0 +1,23 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/efi.h"
#include "libc/nt/efi.h"
EFI_HANDLE __efi_image_handle;
EFI_SYSTEM_TABLE *__efi_system_table;

12
libc/calls/efi.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_EFI_H_
#define COSMOPOLITAN_LIBC_CALLS_EFI_H_
#include "libc/nt/efi.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern EFI_HANDLE __efi_image_handle;
extern EFI_SYSTEM_TABLE *__efi_system_table;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_EFI_H_ */

View File

@@ -31,9 +31,9 @@ int fstat(int fd, struct stat *st) {
if (__isfdkind(fd, kFdZip)) {
return weaken(__zipos_fstat)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);
} else if (!IsWindows() && !IsMetal()) {
} else if (!IsWindows() && !IsMetal() && !IsUefi()) {
return sys_fstat(fd, st);
} else if (IsMetal()) {
} else if (IsMetal() || IsUefi()) {
return fstat_metal(fd, st);
} else {
if (!__isfdkind(fd, kFdFile)) return ebadf();

View File

@@ -30,7 +30,7 @@ hidden textstartup void InitializeFileDescriptors(void) {
fds = VEIL("r", &g_fds);
pushmov(&fds->n, ARRAYLEN(fds->__init_p));
fds->p = fds->__init_p;
if (IsMetal()) {
if (IsMetal() || IsUefi()) {
pushmov(&fds->f, 3ull);
fds->__init_p[STDIN_FILENO].kind = pushpop(kFdSerial);
fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdSerial);

View File

@@ -199,6 +199,7 @@ u32 sys_gettid(void) hidden;
u32 sys_getuid(void) hidden;
void *sys_mmap(void *, u64, u32, u32, i64, i64, i64) hidden;
void *sys_mremap(void *, u64, u64, i32, void *) hidden;
void sys_exit(int) hidden;
/*───────────────────────────────────────────────────────────────────────────│─╗
│ cosmopolitan § syscalls » system five » support ─╬─│┼
@@ -294,6 +295,12 @@ unsigned __wincrash_nt(struct NtExceptionPointers *);
int fstat_metal(int, struct stat *);
/*───────────────────────────────────────────────────────────────────────────│─╗
│ cosmopolitan § syscalls » uefi ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
int sys_nanosleep_uefi(const struct timespec *, struct timespec *);
/*───────────────────────────────────────────────────────────────────────────│─╗
│ cosmopolitan § syscalls » drivers ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/

View File

@@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/efi.h"
#include "libc/nt/efi.h"
#include "libc/sysv/errfuns.h"
int sys_nanosleep_uefi(const struct timespec *req, struct timespec *rem) {
if (__efi_system_table->BootServices->Stall(
req->tv_sec * 1000000 + req->tv_nsec / 1000) == EFI_SUCCESS) {
if (rem) {
rem->tv_sec = 0;
rem->tv_nsec = 0;
}
return 0;
} else {
return eintr();
}
}

View File

@@ -26,10 +26,15 @@
*/
int nanosleep(const struct timespec *req, struct timespec *rem) {
if (!req) return efault();
if (!IsWindows() && !IsMetal() && !IsXnu()) {
if (req->tv_sec < 0 || !(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) {
return einval();
}
if (!IsWindows() && !IsMetal() && !IsUefi() && !IsXnu()) {
return sys_nanosleep(req, rem);
} else if (IsXnu()) {
return sys_nanosleep_xnu(req, rem);
} else if (IsUefi()) {
return sys_nanosleep_uefi(req, rem);
} else if (IsMetal()) {
return enosys(); /* TODO: Sleep on Metal */
} else {

View File

@@ -36,7 +36,8 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_read)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
} else if (SupportsMetal() && fd < g_fds.n && g_fds.p[fd].kind == kFdSerial) {
} else if ((SupportsMetal() || SupportsUefi()) && fd < g_fds.n &&
g_fds.p[fd].kind == kFdSerial) {
return readv_serial(&g_fds.p[fd], iov, iovlen);
} else if (!IsWindows()) {
return sys_readv(fd, iov, iovlen);

View File

@@ -144,7 +144,7 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_netbsd));
if (IsMetal()) return enosys(); /* TODO: Signals on Metal */
if (IsMetal() || IsUefi()) return enosys(); /* TODO: Signals on Metal */
if (!(0 < sig && sig < NSIG)) return einval();
if (sig == SIGKILL || sig == SIGSTOP) return einval();
if (!act) {

View File

@@ -39,7 +39,8 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_write)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
} else if (SupportsMetal() && fd < g_fds.n && g_fds.p[fd].kind == kFdSerial) {
} else if ((SupportsMetal() || SupportsUefi()) && fd < g_fds.n &&
g_fds.p[fd].kind == kFdSerial) {
return writev_serial(&g_fds.p[fd], iov, iovlen);
} else if (!IsWindows()) {
return sys_writev(fd, iov, iovlen);