diff --git a/src/startup/mldr/commpage.c b/src/startup/mldr/commpage.c index b7e17c4a5..bfcf9a0b1 100644 --- a/src/startup/mldr/commpage.c +++ b/src/startup/mldr/commpage.c @@ -21,6 +21,8 @@ static const char* SIGNATURE64 = "commpage 64-bit"; static uint64_t get_cpu_caps(void); +int PAGE_SIZE; + #define CGET(p) (commpage + ((p)-_COMM_PAGE_START_ADDRESS)) void commpage_setup(bool _64bit) @@ -36,6 +38,8 @@ void commpage_setup(bool _64bit) uint8_t *user_page_shift, *kernel_page_shift; struct sysinfo si; + PAGE_SIZE = sysconf(_SC_PAGESIZE); + commpage = (uint8_t*) mmap((void*)(_64bit ? _COMM_PAGE64_BASE_ADDRESS : _COMM_PAGE32_BASE_ADDRESS), _64bit ? _COMM_PAGE64_AREA_LENGTH : _COMM_PAGE32_AREA_LENGTH, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (commpage == MAP_FAILED) @@ -69,7 +73,7 @@ void commpage_setup(bool _64bit) // as a substitute for log2(). user_page_shift = (uint8_t*)CGET(_64bit ? _COMM_PAGE_USER_PAGE_SHIFT_64 : _COMM_PAGE_USER_PAGE_SHIFT_32); kernel_page_shift = (uint8_t*)CGET(_COMM_PAGE_KERNEL_PAGE_SHIFT); - *kernel_page_shift = *user_page_shift = (uint8_t)__builtin_ctzl(sysconf(_SC_PAGESIZE)); + *kernel_page_shift = *user_page_shift = (uint8_t)__builtin_ctzl(PAGE_SIZE); my_caps = get_cpu_caps(); if (*ncpus == 1) @@ -166,3 +170,9 @@ unsigned long commpage_address(bool _64bit) return _64bit ? _COMM_PAGE64_BASE_ADDRESS : _COMM_PAGE32_BASE_ADDRESS; } +#ifdef __aarch64__ +vm_address_t _get_commpage_priv_address(void) { + // Not sure if this is correct... + return _COMM_PAGE64_BASE_ADDRESS; +} +#endif \ No newline at end of file diff --git a/src/startup/mldr/elfcalls/threads.c b/src/startup/mldr/elfcalls/threads.c index e789986ea..e98cafb25 100644 --- a/src/startup/mldr/elfcalls/threads.c +++ b/src/startup/mldr/elfcalls/threads.c @@ -268,6 +268,13 @@ static void* darling_thread_entry(void* p) register uintptr_t arg6 asm("r9") = args.arg3; #elif __i386__ uintptr_t arg3 = args.real_entry_point; +#elif __aarch64__ + register void* arg1 asm("x0") = args.pth; + register int arg2 asm("w1") = args.port; + register uintptr_t arg3 asm("x2") = args.real_entry_point; + register uintptr_t arg4 asm("x3") = args.arg1; + register uintptr_t arg5 asm("x4") = args.arg2; + register uintptr_t arg6 asm("x5") = args.arg3; #endif if (arg3 == 0) { @@ -314,6 +321,22 @@ static void* darling_thread_entry(void* p) // Function arguments to push to the stack. [args] "r"(&args), [arg3]"r"(arg3), + [entry_point] "r"(args.entry_point), + [stack_ptr] "r"(stack_ptr) + ); +#elif defined(__aarch64__) + asm volatile( + // Zero out the frame base register. + "mov fp, #0\n" + // Switch to the new stack. + "mov %[stack_ptr], sp\n" + // Push a fake return address. + "mov lr, #0\n" + // Jump to the entry point. + "br %[entry_point]" :: + // Function arguments + "r"(arg1),"r"(arg2),"r"(arg3),"r"(arg4),"r"(arg5),"r"(arg6), + [entry_point] "r"(args.entry_point), [stack_ptr] "r"(stack_ptr) ); diff --git a/src/startup/mldr/mldr.c b/src/startup/mldr/mldr.c index 41491f356..54454ee4f 100644 --- a/src/startup/mldr/mldr.c +++ b/src/startup/mldr/mldr.c @@ -383,7 +383,8 @@ static void load_fat(int fd, cpu_type_t forced_arch, bool expect_dylinker, char* if (arch.cputype == CPU_TYPE_X86) best_arch = arch; #elif defined (__aarch64__) - #error TODO: arm + if (arch.cputype == CPU_TYPE_ARM64) + best_arch = arch; #else #error Unsupported CPU architecture #endif @@ -420,7 +421,7 @@ static void load_fat(int fd, cpu_type_t forced_arch, bool expect_dylinker, char* } }; -#ifdef __x86_64__ +#if defined(__x86_64__ ) || defined(__aarch64__) #define GEN_64BIT #include "loader.c" #include "stack.c" @@ -816,9 +817,9 @@ static void setup_space(struct load_results* lr, bool is_64_bit) { // Using the default stack top would cause the stack to be placed just above the commpage // and would collide with it eventually. // Instead, we manually allocate a new stack below the commpage. -#if __x86_64__ +#if defined(__x86_64__) || defined(__aarch64__) lr->stack_top = commpage_address(true); -#elif __i386__ +#elif defined(__i386__) lr->stack_top = commpage_address(false); #else #error Unsupported architecture @@ -936,6 +937,15 @@ static void start_thread(struct load_results* lr) { "r"(lr->stack_top) : ); +#elif defined(__aarch64__) + __asm__ volatile( + "mov sp, %1\n" + "br %0" + :: + "r"(lr->entry_point), + "r"(lr->stack_top) + : + ); #else # error Unsupported platform! #endif