mirror of
https://github.com/limine-bootloader/limine
synced 2024-12-13 18:17:17 +03:00
e1f6ac8860
* Initial aarch64 port * Enable chainload on aarch64 No changes necessary since it's all UEFI anyway. * Add specification for Limine protocol for aarch64 * PROTOCOL: Specify state of information in DT /chosen node * common: Add spinup code for aarch64 * common: Port elf and term to aarch64 * common: Port vmm to aarch64 Also prepare to drop VMM_FLAG_PRESENT on x86. * protos: Port limine boot protocol to aarch64 Also drop VMM_FLAG_PRESENT since we never unmap pages anyway. * test: Add DTB request * PROTOCOL: Port SMP request to aarch64 * cpu: Add cache maintenance functions for aarch64 * protos/limine, sys: Port SMP to aarch64 Also move common asm macros into a header file. * test: Start up APs * vmm: Unify get_next_level and implement large page splitting * protos/limine: Map framebuffer using correct caching mode on AArch64 * CI: Fix GCC build for aarch64 * entry, menu: Replace uses of naked attribute with separate asm file GCC does not understand the naked attribute on aarch64, and didn't understand it for x86 in older versions.
233 lines
7.2 KiB
C
233 lines
7.2 KiB
C
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdarg.h>
|
|
#include <lib/libc.h>
|
|
#include <lib/blib.h>
|
|
#include <lib/print.h>
|
|
#include <lib/trace.h>
|
|
#include <lib/real.h>
|
|
#include <fs/file.h>
|
|
#include <mm/pmm.h>
|
|
|
|
#if uefi == 1
|
|
EFI_SYSTEM_TABLE *gST;
|
|
EFI_BOOT_SERVICES *gBS;
|
|
EFI_RUNTIME_SERVICES *gRT;
|
|
EFI_HANDLE efi_image_handle;
|
|
EFI_MEMORY_DESCRIPTOR *efi_mmap = NULL;
|
|
UINTN efi_mmap_size = 0, efi_desc_size = 0;
|
|
UINT32 efi_desc_ver = 0;
|
|
#endif
|
|
|
|
bool editor_enabled = true;
|
|
|
|
bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf) {
|
|
size_t res[3] = {0};
|
|
|
|
const char *first = buf;
|
|
for (size_t i = 0; i < 3; i++) {
|
|
const char *last;
|
|
size_t x = strtoui(first, &last, 10);
|
|
if (first == last)
|
|
break;
|
|
res[i] = x;
|
|
if (*last == 0)
|
|
break;
|
|
first = last + 1;
|
|
}
|
|
|
|
if (res[0] == 0 || res[1] == 0)
|
|
return false;
|
|
|
|
if (res[2] == 0)
|
|
res[2] = 32;
|
|
|
|
*width = res[0], *height = res[1];
|
|
if (bpp != NULL)
|
|
*bpp = res[2];
|
|
|
|
return true;
|
|
}
|
|
|
|
// This integer sqrt implementation has been adapted from:
|
|
// https://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2
|
|
uint64_t sqrt(uint64_t a_nInput) {
|
|
uint64_t op = a_nInput;
|
|
uint64_t res = 0;
|
|
uint64_t one = (uint64_t)1 << 62;
|
|
|
|
// "one" starts at the highest power of four <= than the argument.
|
|
while (one > op) {
|
|
one >>= 2;
|
|
}
|
|
|
|
while (one != 0) {
|
|
if (op >= res + one) {
|
|
op = op - (res + one);
|
|
res = res + 2 * one;
|
|
}
|
|
res >>= 1;
|
|
one >>= 2;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
size_t get_trailing_zeros(uint64_t val) {
|
|
for (size_t i = 0; i < 64; i++) {
|
|
if ((val & 1) != 0) {
|
|
return i;
|
|
}
|
|
val >>= 1;
|
|
}
|
|
return 64;
|
|
}
|
|
|
|
// This table from https://web.mit.edu/freebsd/head/sys/libkern/crc32.c
|
|
static const uint32_t crc32_table[] = {
|
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
|
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
|
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
|
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
|
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
|
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
|
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
|
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
|
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
|
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
|
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
|
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
|
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
|
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
|
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
|
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
|
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
|
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
|
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
|
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
|
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
|
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
|
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
|
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
|
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
|
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
|
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
|
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
|
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
|
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
|
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
|
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
|
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
|
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
|
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
|
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
|
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
|
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
|
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
|
};
|
|
|
|
uint32_t get_crc32(void *_stream, size_t len) {
|
|
uint8_t *stream = _stream;
|
|
uint32_t ret = 0xffffffff;
|
|
|
|
for (size_t i = 0; i < len; i++) {
|
|
ret = (ret >> 8) ^ crc32_table[(ret ^ stream[i]) & 0xff];
|
|
}
|
|
|
|
ret ^= 0xffffffff;
|
|
return ret;
|
|
}
|
|
|
|
uint32_t oct2bin(uint8_t *str, uint32_t max) {
|
|
uint32_t value = 0;
|
|
while (max-- > 0) {
|
|
value <<= 3;
|
|
value += *str++ - '0';
|
|
}
|
|
return value;
|
|
}
|
|
|
|
uint32_t hex2bin(uint8_t *str, uint32_t size) {
|
|
uint32_t value = 0;
|
|
while (size-- > 0) {
|
|
value <<= 4;
|
|
if (*str >= '0' && *str <= '9')
|
|
value += (uint32_t)((*str) - '0');
|
|
else if (*str >= 'A' && *str <= 'F')
|
|
value += (uint32_t)((*str) - 'A' + 10);
|
|
else if (*str >= 'a' && *str <= 'f')
|
|
value += (uint32_t)((*str) - 'a' + 10);
|
|
str++;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
#if uefi == 1
|
|
|
|
no_unwind bool efi_boot_services_exited = false;
|
|
|
|
#define EFI_COPY_MAX_ENTRIES 512
|
|
|
|
bool efi_exit_boot_services(void) {
|
|
EFI_STATUS status;
|
|
|
|
EFI_MEMORY_DESCRIPTOR tmp_mmap[1];
|
|
efi_mmap_size = sizeof(tmp_mmap);
|
|
UINTN mmap_key = 0;
|
|
|
|
gBS->GetMemoryMap(&efi_mmap_size, tmp_mmap, &mmap_key, &efi_desc_size, &efi_desc_ver);
|
|
|
|
efi_mmap_size += 4096;
|
|
|
|
status = gBS->FreePool(efi_mmap);
|
|
if (status) {
|
|
goto fail;
|
|
}
|
|
|
|
status = gBS->AllocatePool(EfiLoaderData, efi_mmap_size, (void **)&efi_mmap);
|
|
if (status) {
|
|
goto fail;
|
|
}
|
|
|
|
size_t retries = 0;
|
|
|
|
retry:
|
|
status = gBS->GetMemoryMap(&efi_mmap_size, efi_mmap, &mmap_key, &efi_desc_size, &efi_desc_ver);
|
|
if (retries == 0 && status) {
|
|
goto fail;
|
|
}
|
|
|
|
// Be gone, UEFI!
|
|
status = gBS->ExitBootServices(efi_image_handle, mmap_key);
|
|
if (status) {
|
|
if (retries == 128) {
|
|
goto fail;
|
|
}
|
|
retries++;
|
|
goto retry;
|
|
}
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
asm volatile ("cli" ::: "memory");
|
|
#elif defined (__aarch64__)
|
|
asm volatile ("msr daifset, #15" ::: "memory");
|
|
#else
|
|
#error Unknown architecture
|
|
#endif
|
|
|
|
efi_boot_services_exited = true;
|
|
|
|
printv("efi: Exited boot services.\n");
|
|
|
|
return true;
|
|
|
|
fail:
|
|
panic(false, "efi: Failed to exit boot services");
|
|
}
|
|
|
|
#endif
|