The Blackfin arch supports a simple sram allocator for userspace, as well as a DMA memcpy function to access the sram.
Signed-off-by: Mike Frysinger <vap...@gentoo.org> --- linux-user/strace.list | 9 ++++++ linux-user/syscall.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/linux-user/strace.list b/linux-user/strace.list index 08f115d..cf093cc 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -105,6 +105,9 @@ #ifdef TARGET_NR_dipc { TARGET_NR_dipc, "dipc" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_dma_memcpy +{ TARGET_NR_dma_memcpy, "dma_memcpy" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_dup { TARGET_NR_dup, "dup" , NULL, NULL, NULL }, #endif @@ -1299,6 +1302,12 @@ #ifdef TARGET_NR_splice { TARGET_NR_splice, "splice" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_sram_alloc +{ TARGET_NR_sram_alloc, "sram_alloc" , NULL, NULL, NULL }, +#endif +#ifdef TARGET_NR_sram_free +{ TARGET_NR_sram_free, "sram_free" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_ssetmask { TARGET_NR_ssetmask, "ssetmask" , NULL, NULL, NULL }, #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a9dce35..a4431f0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4755,6 +4755,14 @@ static inline abi_long host_to_target_stat64(void *cpu_env, } #endif +#ifdef TARGET_NR_sram_alloc +struct sram_frag { + struct sram_frag *next; + abi_ulong addr, size; +}; +static struct sram_frag *sfrags; +#endif + #if defined(CONFIG_USE_NPTL) /* ??? Using host futex calls even when target atomic operations are not really atomic probably breaks things. However implementing @@ -6413,6 +6421,72 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(munlockall()); break; #endif +#ifdef TARGET_NR_sram_alloc + case TARGET_NR_sram_alloc: + { + /* We don't want L1 insn to be read/write, but doing that + * keeps standard qemu funcs from being able to read/write + * that too. So grant r/w access to all. */ + int prot = PROT_READ | PROT_WRITE; + if ((arg2 & 1 /*L1_INST_SRAM*/) || (arg2 & 8 /*L2_SRAM*/)) { + prot |= PROT_EXEC; + } + + ret = get_errno(target_mmap(0, arg1, prot, MAP_PRIVATE | + MAP_ANONYMOUS, -1, 0)); + + if (!is_error(ret)) { + struct sram_frag *sf = malloc(sizeof(*sf)); + sf->addr = ret; + sf->size = arg1; + if (sfrags) { + sf->next = sfrags; + sfrags = sf; + } else { + sf->next = NULL; + sfrags = sf; + } + } + } + break; +#endif +#ifdef TARGET_NR_sram_free + case TARGET_NR_sram_free: + { + struct sram_frag *sf, *prev; + + ret = -TARGET_EINVAL; + + sf = prev = sfrags; + while (sf) { + if (sf->addr == arg1) { + ret = get_errno(target_munmap(arg1, sf->size)); + if (!is_error(ret)) { + if (sfrags == sf) { + sfrags = sf->next; + } else { + prev->next = sf->next; + } + free(sf); + } + break; + } + prev = sf; + sf = sf->next; + } + } + break; +#endif +#ifdef TARGET_NR_dma_memcpy + case TARGET_NR_dma_memcpy: + p = alloca(arg3); + if (copy_from_user(p, arg2, arg3)) + goto efault; + if (copy_to_user(arg1, p, arg3)) + goto efault; + ret = arg1; + break; +#endif case TARGET_NR_truncate: if (!(p = lock_user_string(arg1))) goto efault; -- 1.8.2.1