Skip to content

Commit

Permalink
[mldr] Implement WIP ARM64 Support
Browse files Browse the repository at this point in the history
  • Loading branch information
CuriousTommy committed Jan 11, 2024
1 parent 1aa5cdd commit 557794b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
12 changes: 11 additions & 1 deletion src/startup/mldr/commpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
23 changes: 23 additions & 0 deletions src/startup/mldr/elfcalls/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
);
Expand Down
18 changes: 14 additions & 4 deletions src/startup/mldr/mldr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 557794b

Please sign in to comment.