/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <efi.h>
#include <efilib.h>
#include <inttypes.h>

#include "ticks.h"
#include "util.h"

EFI_STATUS parse_boolean(const char *v, bool *b) {
        assert(b);

        if (!v)
                return EFI_INVALID_PARAMETER;

        if (streq8(v, "1") || streq8(v, "yes") || streq8(v, "y") || streq8(v, "true") || streq8(v, "t") ||
            streq8(v, "on")) {
                *b = true;
                return EFI_SUCCESS;
        }

        if (streq8(v, "0") || streq8(v, "no") || streq8(v, "n") || streq8(v, "false") || streq8(v, "f") ||
            streq8(v, "off")) {
                *b = false;
                return EFI_SUCCESS;
        }

        return EFI_INVALID_PARAMETER;
}

EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags) {
        assert(vendor);
        assert(name);
        assert(buf || size == 0);

        flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
        return RT->SetVariable((char16_t *) name, (EFI_GUID *) vendor, flags, size, (void *) buf);
}

EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags) {
        assert(vendor);
        assert(name);

        return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
}

EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t i, uint32_t flags) {
        assert(vendor);
        assert(name);

        _cleanup_free_ char16_t *str = xasprintf("%zu", i);
        return efivar_set(vendor, name, str, flags);
}

EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags) {
        uint8_t buf[4];

        assert(vendor);
        assert(name);

        buf[0] = (uint8_t)(value >> 0U & 0xFF);
        buf[1] = (uint8_t)(value >> 8U & 0xFF);
        buf[2] = (uint8_t)(value >> 16U & 0xFF);
        buf[3] = (uint8_t)(value >> 24U & 0xFF);

        return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
}

EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags) {
        uint8_t buf[8];

        assert(vendor);
        assert(name);

        buf[0] = (uint8_t)(value >> 0U & 0xFF);
        buf[1] = (uint8_t)(value >> 8U & 0xFF);
        buf[2] = (uint8_t)(value >> 16U & 0xFF);
        buf[3] = (uint8_t)(value >> 24U & 0xFF);
        buf[4] = (uint8_t)(value >> 32U & 0xFF);
        buf[5] = (uint8_t)(value >> 40U & 0xFF);
        buf[6] = (uint8_t)(value >> 48U & 0xFF);
        buf[7] = (uint8_t)(value >> 56U & 0xFF);

        return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
}

EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **ret) {
        _cleanup_free_ char16_t *buf = NULL;
        EFI_STATUS err;
        char16_t *val;
        size_t size;

        assert(vendor);
        assert(name);

        err = efivar_get_raw(vendor, name, (char **) &buf, &size);
        if (err != EFI_SUCCESS)
                return err;

        /* Make sure there are no incomplete characters in the buffer */
        if ((size % sizeof(char16_t)) != 0)
                return EFI_INVALID_PARAMETER;

        if (!ret)
                return EFI_SUCCESS;

        /* Return buffer directly if it happens to be NUL terminated already */
        if (size >= sizeof(char16_t) && buf[size / sizeof(char16_t) - 1] == 0) {
                *ret = TAKE_PTR(buf);
                return EFI_SUCCESS;
        }

        /* Make sure a terminating NUL is available at the end */
        val = xmalloc(size + sizeof(char16_t));

        memcpy(val, buf, size);
        val[size / sizeof(char16_t) - 1] = 0; /* NUL terminate */

        *ret = val;
        return EFI_SUCCESS;
}

EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t *ret) {
        _cleanup_free_ char16_t *val = NULL;
        EFI_STATUS err;
        uint64_t u;

        assert(vendor);
        assert(name);

        err = efivar_get(vendor, name, &val);
        if (err != EFI_SUCCESS)
                return err;

        if (!parse_number16(val, &u, NULL) || u > SIZE_MAX)
                return EFI_INVALID_PARAMETER;

        if (ret)
                *ret = u;
        return EFI_SUCCESS;
}

EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret) {
        _cleanup_free_ char *buf = NULL;
        size_t size;
        EFI_STATUS err;

        assert(vendor);
        assert(name);

        err = efivar_get_raw(vendor, name, &buf, &size);
        if (err != EFI_SUCCESS)
                return err;

        if (size != sizeof(uint32_t))
                return EFI_BUFFER_TOO_SMALL;

        if (ret)
                *ret = (uint32_t) buf[0] << 0U | (uint32_t) buf[1] << 8U | (uint32_t) buf[2] << 16U |
                        (uint32_t) buf[3] << 24U;

        return EFI_SUCCESS;
}

EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret) {
        _cleanup_free_ char *buf = NULL;
        size_t size;
        EFI_STATUS err;

        assert(vendor);
        assert(name);

        err = efivar_get_raw(vendor, name, &buf, &size);
        if (err != EFI_SUCCESS)
                return err;

        if (size != sizeof(uint64_t))
                return EFI_BUFFER_TOO_SMALL;

        if (ret)
                *ret = (uint64_t) buf[0] << 0U | (uint64_t) buf[1] << 8U | (uint64_t) buf[2] << 16U |
                        (uint64_t) buf[3] << 24U | (uint64_t) buf[4] << 32U | (uint64_t) buf[5] << 40U |
                        (uint64_t) buf[6] << 48U | (uint64_t) buf[7] << 56U;

        return EFI_SUCCESS;
}

EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size) {
        _cleanup_free_ char *buf = NULL;
        size_t l;
        EFI_STATUS err;

        assert(vendor);
        assert(name);

        l = sizeof(char16_t *) * EFI_MAXIMUM_VARIABLE_SIZE;
        buf = xmalloc(l);

        err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &l, buf);
        if (err != EFI_SUCCESS)
                return err;

        if (ret)
                *ret = TAKE_PTR(buf);
        if (ret_size)
                *ret_size = l;

        return EFI_SUCCESS;
}

EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret) {
        _cleanup_free_ char *b = NULL;
        size_t size;
        EFI_STATUS err;

        assert(vendor);
        assert(name);

        err = efivar_get_raw(vendor, name, &b, &size);
        if (err != EFI_SUCCESS)
                return err;

        if (ret)
                *ret = *b > 0;

        return EFI_SUCCESS;
}

void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec) {
        assert(vendor);
        assert(name);

        if (usec == 0)
                usec = time_usec();
        if (usec == 0)
                return;

        _cleanup_free_ char16_t *str = xasprintf("%" PRIu64, usec);
        efivar_set(vendor, name, str, 0);
}

void convert_efi_path(char16_t *path) {
        assert(path);

        for (size_t i = 0, fixed = 0;; i++) {
                /* Fix device path node separator. */
                path[fixed] = (path[i] == '/') ? '\\' : path[i];

                /* Double '\' is not allowed in EFI file paths. */
                if (fixed > 0 && path[fixed - 1] == '\\' && path[fixed] == '\\')
                        continue;

                if (path[i] == '\0')
                        break;

                fixed++;
        }
}

char16_t *xstr8_to_path(const char *str8) {
        assert(str8);
        char16_t *path = xstr8_to_16(str8);
        convert_efi_path(path);
        return path;
}

void mangle_stub_cmdline(char16_t *cmdline) {
        char16_t *p = cmdline;

        for (; *cmdline != '\0'; cmdline++)
                /* Convert ASCII control characters to spaces. */
                if (*cmdline <= 0x1F)
                        *cmdline = ' ';

        /* chomp the trailing whitespaces */
        while (cmdline != p) {
                --cmdline;

                if (*cmdline != ' ')
                        break;

                *cmdline = '\0';
        }
}

EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, size_t off, size_t size, char **ret, size_t *ret_size) {
        _cleanup_(file_closep) EFI_FILE *handle = NULL;
        _cleanup_free_ char *buf = NULL;
        EFI_STATUS err;

        assert(dir);
        assert(name);
        assert(ret);

        err = dir->Open(dir, &handle, (char16_t*) name, EFI_FILE_MODE_READ, 0ULL);
        if (err != EFI_SUCCESS)
                return err;

        if (size == 0) {
                _cleanup_free_ EFI_FILE_INFO *info = NULL;

                err = get_file_info_harder(handle, &info, NULL);
                if (err != EFI_SUCCESS)
                        return err;

                size = info->FileSize;
        }

        if (off > 0) {
                err = handle->SetPosition(handle, off);
                if (err != EFI_SUCCESS)
                        return err;
        }

        /* Allocate some extra bytes to guarantee the result is NUL-terminated for char and char16_t strings. */
        size_t extra = size % sizeof(char16_t) + sizeof(char16_t);

        buf = xmalloc(size + extra);
        if (size > 0) {
                err = handle->Read(handle, &size, buf);
                if (err != EFI_SUCCESS)
                        return err;
        }

        /* Note that handle->Read() changes size to reflect the actually bytes read. */
        memset(buf + size, 0, extra);

        *ret = TAKE_PTR(buf);
        if (ret_size)
                *ret_size = size;

        return err;
}

void print_at(size_t x, size_t y, size_t attr, const char16_t *str) {
        assert(str);
        ST->ConOut->SetCursorPosition(ST->ConOut, x, y);
        ST->ConOut->SetAttribute(ST->ConOut, attr);
        ST->ConOut->OutputString(ST->ConOut, (char16_t *) str);
}

void clear_screen(size_t attr) {
        log_wait();
        ST->ConOut->SetAttribute(ST->ConOut, attr);
        ST->ConOut->ClearScreen(ST->ConOut);
}

void sort_pointer_array(
                void **array,
                size_t n_members,
                compare_pointer_func_t compare) {

        assert(array || n_members == 0);
        assert(compare);

        if (n_members <= 1)
                return;

        for (size_t i = 1; i < n_members; i++) {
                size_t k;
                void *entry = array[i];

                for (k = i; k > 0; k--) {
                        if (compare(array[k - 1], entry) <= 0)
                                break;

                        array[k] = array[k - 1];
                }

                array[k] = entry;
        }
}

EFI_STATUS get_file_info_harder(
                EFI_FILE *handle,
                EFI_FILE_INFO **ret,
                size_t *ret_size) {

        size_t size = offsetof(EFI_FILE_INFO, FileName) + 256;
        _cleanup_free_ EFI_FILE_INFO *fi = NULL;
        EFI_STATUS err;

        assert(handle);
        assert(ret);

        /* A lot like LibFileInfo() but with useful error propagation */

        fi = xmalloc(size);
        err = handle->GetInfo(handle, MAKE_GUID_PTR(EFI_FILE_INFO), &size, fi);
        if (err == EFI_BUFFER_TOO_SMALL) {
                free(fi);
                fi = xmalloc(size);  /* GetInfo tells us the required size, let's use that now */
                err = handle->GetInfo(handle, MAKE_GUID_PTR(EFI_FILE_INFO), &size, fi);
        }

        if (err != EFI_SUCCESS)
                return err;

        *ret = TAKE_PTR(fi);

        if (ret_size)
                *ret_size = size;

        return EFI_SUCCESS;
}

EFI_STATUS readdir_harder(
                EFI_FILE *handle,
                EFI_FILE_INFO **buffer,
                size_t *buffer_size) {

        EFI_STATUS err;
        size_t sz;

        assert(handle);
        assert(buffer);
        assert(buffer_size);

        /* buffer/buffer_size are both in and output parameters. Should be zero-initialized initially, and
         * the specified buffer needs to be freed by caller, after final use. */

        if (!*buffer) {
                /* Some broken firmware violates the EFI spec by still advancing the readdir
                 * position when returning EFI_BUFFER_TOO_SMALL, effectively skipping over any files when
                 * the buffer was too small. Therefore, start with a buffer that should handle FAT32 max
                 * file name length.
                 * As a side effect, most readdir_harder() calls will now be slightly faster. */
                sz = sizeof(EFI_FILE_INFO) + 256 * sizeof(char16_t);
                *buffer = xmalloc(sz);
                *buffer_size = sz;
        } else
                sz = *buffer_size;

        err = handle->Read(handle, &sz, *buffer);
        if (err == EFI_BUFFER_TOO_SMALL) {
                free(*buffer);
                *buffer = xmalloc(sz);
                *buffer_size = sz;
                err = handle->Read(handle, &sz, *buffer);
        }
        if (err != EFI_SUCCESS)
                return err;

        if (sz == 0) {
                /* End of directory */
                free(*buffer);
                *buffer = NULL;
                *buffer_size = 0;
        }

        return EFI_SUCCESS;
}

bool is_ascii(const char16_t *f) {
        if (!f)
                return false;

        for (; *f != 0; f++)
                if (*f > 127)
                        return false;

        return true;
}

char16_t **strv_free(char16_t **v) {
        if (!v)
                return NULL;

        for (char16_t **i = v; *i; i++)
                free(*i);

        free(v);
        return NULL;
}

EFI_STATUS open_directory(
                EFI_FILE *root,
                const char16_t *path,
                EFI_FILE **ret) {

        _cleanup_(file_closep) EFI_FILE *dir = NULL;
        _cleanup_free_ EFI_FILE_INFO *file_info = NULL;
        EFI_STATUS err;

        assert(root);

        /* Opens a file, and then verifies it is actually a directory */

        err = root->Open(root, &dir, (char16_t *) path, EFI_FILE_MODE_READ, 0);
        if (err != EFI_SUCCESS)
                return err;

        err = get_file_info_harder(dir, &file_info, NULL);
        if (err != EFI_SUCCESS)
                return err;
        if (!FLAGS_SET(file_info->Attribute, EFI_FILE_DIRECTORY))
                return EFI_LOAD_ERROR;

        *ret = TAKE_PTR(dir);
        return EFI_SUCCESS;
}

uint64_t get_os_indications_supported(void) {
        uint64_t osind;
        EFI_STATUS err;

        /* Returns the supported OS indications. If we can't acquire it, returns a zeroed out mask, i.e. no
         * supported features. */

        err = efivar_get_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndicationsSupported", &osind);
        if (err != EFI_SUCCESS)
                return 0;

        return osind;
}

#ifdef EFI_DEBUG
extern uint8_t _text, _data;
__attribute__((noinline)) void notify_debugger(const char *identity, volatile bool wait) {
        printf("%s@%p,%p\n", identity, &_text, &_data);
        if (wait)
                printf("Waiting for debugger to attach...\n");

        /* This is a poor programmer's breakpoint to wait until a debugger
         * has attached to us. Just "set variable wait = 0" or "return" to continue. */
        while (wait)
                /* Prefer asm based stalling so that gdb has a source location to present. */
#if defined(__i386__) || defined(__x86_64__)
                asm volatile("pause");
#elif defined(__aarch64__)
                asm volatile("wfi");
#else
                BS->Stall(5000);
#endif
}
#endif

#ifdef EFI_DEBUG
void hexdump(const char16_t *prefix, const void *data, size_t size) {
        static const char hex[16] = "0123456789abcdef";
        _cleanup_free_ char16_t *buf = NULL;
        const uint8_t *d = data;

        assert(prefix);
        assert(data || size == 0);

        /* Debugging helper — please keep this around, even if not used */

        buf = xnew(char16_t, size*2+1);

        for (size_t i = 0; i < size; i++) {
                buf[i*2] = hex[d[i] >> 4];
                buf[i*2+1] = hex[d[i] & 0x0F];
        }

        buf[size*2] = 0;

        log_error("%ls[%zu]: %ls", prefix, size, buf);
}
#endif

#if defined(__i386__) || defined(__x86_64__)
static inline uint8_t inb(uint16_t port) {
        uint8_t value;
        asm volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
        return value;
}

static inline void outb(uint16_t port, uint8_t value) {
        asm volatile("outb %0, %1" : : "a"(value), "Nd"(port));
}

void beep(unsigned beep_count) {
        enum {
                PITCH                = 500,
                BEEP_DURATION_USEC   = 100 * 1000,
                WAIT_DURATION_USEC   = 400 * 1000,

                PIT_FREQUENCY        = 0x1234dd,
                SPEAKER_CONTROL_PORT = 0x61,
                SPEAKER_ON_MASK      = 0x03,
                TIMER_PORT_MAGIC     = 0xB6,
                TIMER_CONTROL_PORT   = 0x43,
                TIMER_CONTROL2_PORT  = 0x42,
        };

        /* Set frequency. */
        uint32_t counter = PIT_FREQUENCY / PITCH;
        outb(TIMER_CONTROL_PORT, TIMER_PORT_MAGIC);
        outb(TIMER_CONTROL2_PORT, counter & 0xFF);
        outb(TIMER_CONTROL2_PORT, (counter >> 8) & 0xFF);

        uint8_t value = inb(SPEAKER_CONTROL_PORT);

        while (beep_count > 0) {
                /* Turn speaker on. */
                value |= SPEAKER_ON_MASK;
                outb(SPEAKER_CONTROL_PORT, value);

                BS->Stall(BEEP_DURATION_USEC);

                /* Turn speaker off. */
                value &= ~SPEAKER_ON_MASK;
                outb(SPEAKER_CONTROL_PORT, value);

                beep_count--;
                if (beep_count > 0)
                        BS->Stall(WAIT_DURATION_USEC);
        }
}
#endif

EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file) {
        EFI_STATUS err;
        EFI_FILE *file;
        EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *volume;

        assert(ret_file);

        err = BS->HandleProtocol(device, MAKE_GUID_PTR(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL), (void **) &volume);
        if (err != EFI_SUCCESS)
                return err;

        err = volume->OpenVolume(volume, &file);
        if (err != EFI_SUCCESS)
                return err;

        *ret_file = file;
        return EFI_SUCCESS;
}

EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp) {
        EFI_STATUS err;
        EFI_DEVICE_PATH *dp;

        assert(file);
        assert(ret_dp);

        err = BS->HandleProtocol(device, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void **) &dp);
        if (err != EFI_SUCCESS)
                return err;

        EFI_DEVICE_PATH *end_node = dp;
        while (!IsDevicePathEnd(end_node))
                end_node = NextDevicePathNode(end_node);

        size_t file_size = strsize16(file);
        size_t dp_size = (uint8_t *) end_node - (uint8_t *) dp;

        /* Make a copy that can also hold a file media device path. */
        *ret_dp = xmalloc(dp_size + file_size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
        dp = mempcpy(*ret_dp, dp, dp_size);

        /* Replace end node with file media device path. Use memcpy() in case dp is unaligned (if accessed as
         * FILEPATH_DEVICE_PATH). */
        dp->Type = MEDIA_DEVICE_PATH;
        dp->SubType = MEDIA_FILEPATH_DP;
        memcpy((uint8_t *) dp + offsetof(FILEPATH_DEVICE_PATH, PathName), file, file_size);
        SetDevicePathNodeLength(dp, offsetof(FILEPATH_DEVICE_PATH, PathName) + file_size);

        dp = NextDevicePathNode(dp);
        SetDevicePathEndNode(dp);
        return EFI_SUCCESS;
}

EFI_STATUS device_path_to_str(const EFI_DEVICE_PATH *dp, char16_t **ret) {
        EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *dp_to_text;
        EFI_STATUS err;
        _cleanup_free_ char16_t *str = NULL;

        assert(dp);
        assert(ret);

        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_DEVICE_PATH_TO_TEXT_PROTOCOL), NULL, (void **) &dp_to_text);
        if (err != EFI_SUCCESS) {
                /* If the device path to text protocol is not available we can still do a best-effort attempt
                 * to convert it ourselves if we are given filepath-only device path. */

                size_t size = 0;
                for (const EFI_DEVICE_PATH *node = dp; !IsDevicePathEnd(node);
                     node = NextDevicePathNode(node)) {

                        if (DevicePathType(node) != MEDIA_DEVICE_PATH ||
                            DevicePathSubType(node) != MEDIA_FILEPATH_DP)
                                return err;

                        size_t path_size = DevicePathNodeLength(node);
                        if (path_size <= offsetof(FILEPATH_DEVICE_PATH, PathName) || path_size % sizeof(char16_t))
                                return EFI_INVALID_PARAMETER;
                        path_size -= offsetof(FILEPATH_DEVICE_PATH, PathName);

                        _cleanup_free_ char16_t *old = str;
                        str = xmalloc(size + path_size);
                        if (old) {
                                memcpy(str, old, size);
                                str[size / sizeof(char16_t) - 1] = '\\';
                        }

                        memcpy(str + (size / sizeof(char16_t)),
                               ((uint8_t *) node) + offsetof(FILEPATH_DEVICE_PATH, PathName),
                               path_size);
                        size += path_size;
                }

                *ret = TAKE_PTR(str);
                return EFI_SUCCESS;
        }

        str = dp_to_text->ConvertDevicePathToText(dp, false, false);
        if (!str)
                return EFI_OUT_OF_RESOURCES;

        *ret = TAKE_PTR(str);
        return EFI_SUCCESS;
}

void *find_configuration_table(const EFI_GUID *guid) {
        for (size_t i = 0; i < ST->NumberOfTableEntries; i++)
                if (efi_guid_equal(&ST->ConfigurationTable[i].VendorGuid, guid))
                        return ST->ConfigurationTable[i].VendorTable;

        return NULL;
}

/* libgcc's __aeabi_ldiv0 intrinsic will call raise() on division by zero, so we
 * need to provide one ourselves for now. */
_used_ _noreturn_ int raise(int sig) {
        assert_not_reached();
}
