diff --git a/linux-user/e2k/target_cpu.h b/linux-user/e2k/target_cpu.h index c5e3e3c9d3..d5f45b487e 100644 --- a/linux-user/e2k/target_cpu.h +++ b/linux-user/e2k/target_cpu.h @@ -1,7 +1,7 @@ #ifndef E2K_TARGET_CPU_H #define E2K_TARGET_CPU_H -#include "qemu/log.h" +#include "user-mmap.h" abi_long e2k_copy_from_user_crs(E2KCrs *crs, abi_ulong target_crs_addr); abi_long e2k_copy_to_user_crs(abi_ulong target_crs_addr, E2KCrs *crs); @@ -27,8 +27,9 @@ static inline void cpu_clone_regs_child(CPUE2KState *env, target_ulong newsp, target_ulong ps_base = env->psp.base + env->psp.index; int i; - e2k_psp_new(&pcs, E2K_DEFAULT_PCS_SIZE, false); - e2k_psp_new(&ps, E2K_DEFAULT_PS_SIZE, true); + e2k_psp_new(&pcs, E2K_DEFAULT_PCS_SIZE, e2k_mmap(E2K_DEFAULT_PCS_SIZE), 0); + e2k_psp_new(&ps, E2K_DEFAULT_PS_SIZE, e2k_mmap(E2K_DEFAULT_PS_SIZE), + e2k_mmap(E2K_DEFAULT_PS_SIZE / 8)); // TODO: size checks and a way to report errors // TODO: set a chain info to return to kernel diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 273e3da057..d1f42252ff 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1614,39 +1614,6 @@ static inline void init_thread(struct target_pt_regs *regs, typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; #define USE_ELF_CORE_DUMP -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; -} - -void e2k_psp_new(E2KPsp *psp, unsigned int size, bool tags) -{ - psp->is_readable = true; - psp->is_writable = true; - psp->index = 0; - psp->size = size; - psp->base = e2k_mmap(size); - psp->base_tag = tags ? e2k_mmap(size / 8) : 0; -} - static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { abi_ulong start_stack = infop->start_stack & ~0xf; @@ -1658,8 +1625,9 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i 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); + e2k_psp_new(®s->pcsp, E2K_DEFAULT_PCS_SIZE, e2k_mmap(E2K_DEFAULT_PCS_SIZE), 0); + e2k_psp_new(®s->psp, E2K_DEFAULT_PS_SIZE, e2k_mmap(E2K_DEFAULT_PS_SIZE), + e2k_mmap(E2K_DEFAULT_PS_SIZE / 8)); } static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUE2KState *env) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 48e1373796..1d1951f9f4 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -645,6 +645,31 @@ fail: return -1; } +#ifdef TARGET_E2K +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; +} +#endif + static void mmap_reserve(abi_ulong start, abi_ulong size) { abi_ulong real_start; diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h index d1dec99c02..86342d3bce 100644 --- a/linux-user/user-mmap.h +++ b/linux-user/user-mmap.h @@ -31,4 +31,8 @@ abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong); void mmap_fork_start(void); void mmap_fork_end(int child); +#ifdef TARGET_E2K +abi_ulong e2k_mmap(abi_ulong size); +#endif + #endif /* LINUX_USER_USER_MMAP_H */ diff --git a/target/e2k/cpu.c b/target/e2k/cpu.c index b60b553726..f6c46be2c7 100644 --- a/target/e2k/cpu.c +++ b/target/e2k/cpu.c @@ -330,3 +330,13 @@ void e2k_cpu_list(void) } qemu_printf("\n"); } + +void e2k_psp_new(E2KPsp *psp, uint32_t size, uint64_t base, uint64_t base_tags) +{ + psp->is_readable = true; + psp->is_writable = true; + psp->index = 0; + psp->size = size; + psp->base = base; + psp->base_tag = base_tags; +} diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index ff66b53aa0..6099d6af77 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -954,9 +954,16 @@ bool e2k_cpu_tlb_fill(CPUState *cpu, vaddr address, int size, bool probe, uintptr_t retaddr); void e2k_update_fp_status(CPUE2KState *env); void e2k_update_fx_status(CPUE2KState *env); -#ifdef CONFIG_USER_ONLY -void e2k_psp_new(E2KPsp *psp, unsigned int size, bool tags); -#endif +/* + * PCSP + * @base = mmap(size) + * @base_tags = 0 + * + * PSP + * @base = mmap(size) + * @base_tags = mmap(size / 8) + */ +void e2k_psp_new(E2KPsp *psp, uint32_t size, uint64_t base, uint64_t base_tags); void e2k_proc_call(CPUE2KState *env, int base, target_ulong ret_ip, bool force_fx); void e2k_proc_return(CPUE2KState *env, bool force_fx);