diff --git a/bsd-user/e2k/target_arch_thread.h b/bsd-user/e2k/target_arch_thread.h index 869e1c9149..a9179e1405 100644 --- a/bsd-user/e2k/target_arch_thread.h +++ b/bsd-user/e2k/target_arch_thread.h @@ -35,10 +35,44 @@ static inline void target_thread_set_upcall(CPUE2KState *regs, abi_ulong entry, assert(0 && "target_thread_set_upcall is not implemented yet"); } +static abi_ulong e2k_mmap(abi_ulong size) +{ + abi_ulong addr; + abi_ulong guard = TARGET_PAGE_SIZE; + + if (size < TARGET_PAGE_SIZE) { + size = TARGET_PAGE_SIZE; + } + if (guard < qemu_real_host_page_size) { + guard = qemu_real_host_page_size; + } + + addr = target_mmap(0, size + guard, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (addr == -1) { + perror("mmap e2k stack"); + exit(-1); + } + + target_mprotect(addr + size, guard, PROT_NONE); + return addr; +} + +// compare to linux-user/elfload.c:init_thread for e2k static inline void target_thread_init(struct target_pt_regs *regs, struct image_info *infop) { - assert(0 && "target_thread_init is not implemented yet"); + abi_ulong start_stack = infop->start_stack & ~0xf; + + regs->ip = infop->entry; + + // FIXME: set real start stack address + regs->sbr = infop->arg_strings & ~0xf; + regs->usd_lo = (0x1800UL << 48) | start_stack; + regs->usd_hi = (regs->sbr - start_stack) << 32; + + e2k_psp_new(®s->pcsp, E2K_DEFAULT_PCS_SIZE, false); + e2k_psp_new(®s->psp, E2K_DEFAULT_PS_SIZE, true); } #endif /* !_TARGET_ARCH_THREAD_H_ */