Arm semihosting support.
PATCH 1/1 Arm semihosting support.
The attached patch adds support for ARM "Angel" semihosting syscalls. This is a simple syscall layer which provides basic OS services to embedded applications. It is implemented by several free and proprietary toolchains/ debugging tools, including newlib and the GDB simulator. It's what you get if you configure for "arm-elf".
Paul
Index: Makefile.target
===================================================================
RCS file: /cvsroot/qemu/qemu/Makefile.target,v
retrieving revision 1.64
Makefile.target +1 -1
@@ -233,7 +233,7 @@ endif ifeq ($(TARGET_ARCH), arm) OBJS+=nwfpe/fpa11.o nwfpe/fpa11_cpdo.o \ nwfpe/fpa11_cpdt.o nwfpe/fpa11_cprt.o nwfpe/fpopcode.o nwfpe/single_cpdo.o \ - nwfpe/double_cpdo.o nwfpe/extended_cpdo.o + nwfpe/double_cpdo.o nwfpe/extended_cpdo.o arm-semi.o endif SRCS:= $(OBJS:.o=.c) OBJS+= libqemu.a
Index: linux-user/arm-semi.c
===================================================================
RCS file: linux-user/arm-semi.c
arm-semi.c new file +194 -0
194 lines not on this page · raw message
Index: linux-user/main.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v
retrieving revision 1.63
main.c +7 -0
@@ -363,6 +363,9 @@ void cpu_loop(CPUARMState *env) n = insn &0xffffff ;if (n == ARM_NR_cacheflush) {arm_cache_flush (env->regs[0 ], env->regs[1 ]); + }else if (n == ARM_NR_semihosting + || n == ARM_NR_thumb_semihosting) { + env->regs[0 ] =do_arm_semihosting (env); }else if (n >=ARM_SYSCALL_BASE ) {/* linux syscall */ n -=ARM_SYSCALL_BASE ;
@@ -1207,6 +1210,10 @@ int main(int argc, char **argv) env->regs[i] = regs->uregs[i]; } env->cpsr = regs->uregs[16 ]; + ts->stack_base = info->start_stack; + ts->heap_base = info->brk; +/* This will be filled in on the first SYS_HEAPINFO call. */ + ts->heap_limit =0 ; }#elif defined(TARGET_SPARC) {
Index: linux-user/qemu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/qemu.h,v
retrieving revision 1.23
qemu.h +6 -0
@@ -62,6 +62,11 @@ typedef struct TaskState {#ifdef TARGET_ARM /* FPA state */ FPA11 fpa; +/* Extra fields for semihosted binaries. */ +uint32_t stack_base; +uint32_t heap_base; +uint32_t heap_limit; +int swi_errno;#endif #ifdef TARGET_I386 struct target_vm86plus_struct *target_v86;
@@ -80,6 +85,7 @@ int elf_exec(const char * filename, char struct target_pt_regs * regs, struct image_info *infop);void target_set_brk (char *new_brk); +long do_brk (char *new_brk);void syscall_init (void );long do_syscall (void *cpu_env,int num,long arg1,long arg2,long arg3,long arg4,long arg5,long arg6);
Index: linux-user/syscall.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/syscall.c,v retrieving revision 1.58
syscall.c +1 -1
@@ -264,7 +264,7 @@ void target_set_brk(char *new_brk) target_original_brk = new_brk; } -static long do_brk (char *new_brk) +long do_brk (char *new_brk) {char *brk_page;long mapped_addr;
Index: linux-user/arm/syscall.h
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/arm/syscall.h,v retrieving revision 1.4
arm/syscall.h +5 -0
@@ -29,8 +29,13 @@ struct target_pt_regs {#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) +#define ARM_NR_semihosting 0x123456 +#define ARM_NR_thumb_semihosting 0xAB +#if defined(TARGET_WORDS_BIGENDIAN )#define UNAME_MACHINE "armv5teb"#else #define UNAME_MACHINE "armv5tel"#endif + +uint32_t do_arm_semihosting (CPUState *);