[Qemu-devel] [PATCH v1 10/21] RISC-V Linux User Emulation

2018-01-02 Thread Michael Clark
Implementation of linux user emulation for RISC-V.

Signed-off-by: Michael Clark 
---
 linux-user/elfload.c  |  22 +++
 linux-user/main.c | 130 -
 linux-user/riscv/syscall_nr.h | 275 +++
 linux-user/riscv/target_cpu.h |  18 +++
 linux-user/riscv/target_signal.h  |  23 +++
 linux-user/riscv/target_structs.h |  46 ++
 linux-user/riscv/target_syscall.h |  56 
 linux-user/riscv/termbits.h   | 220 
 linux-user/signal.c   | 260 ++
 linux-user/syscall.c  |   2 +
 linux-user/syscall_defs.h |  13 +-
 target/riscv/cpu_user.h   |  29 
 target/riscv/user_atomic.c| 291 ++
 target/riscv/user_syscall.c   |  40 ++
 14 files changed, 1387 insertions(+), 38 deletions(-)
 create mode 100644 linux-user/riscv/syscall_nr.h
 create mode 100644 linux-user/riscv/target_cpu.h
 create mode 100644 linux-user/riscv/target_signal.h
 create mode 100644 linux-user/riscv/target_structs.h
 create mode 100644 linux-user/riscv/target_syscall.h
 create mode 100644 linux-user/riscv/termbits.h
 create mode 100644 target/riscv/cpu_user.h
 create mode 100644 target/riscv/user_atomic.c
 create mode 100644 target/riscv/user_syscall.c

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 20f3d8c..178af56 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1272,6 +1272,28 @@ static inline void init_thread(struct target_pt_regs 
*regs,
 
 #endif /* TARGET_TILEGX */
 
+#ifdef TARGET_RISCV
+
+#define ELF_START_MMAP 0x8000
+#define ELF_ARCH  EM_RISCV
+
+#ifdef TARGET_RISCV32
+#define ELF_CLASS ELFCLASS32
+#else
+#define ELF_CLASS ELFCLASS64
+#endif
+
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
+{
+regs->sepc = infop->entry;
+regs->sp = infop->start_stack;
+}
+
+#define ELF_EXEC_PAGESIZE 4096
+
+#endif /* TARGET_RISCV */
+
 #ifdef TARGET_HPPA
 
 #define ELF_START_MMAP  0x8000
diff --git a/linux-user/main.c b/linux-user/main.c
index 71696ed..8900141 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -227,7 +227,7 @@ void cpu_loop(CPUX86State *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case 0x80:
 /* linux syscall from int $0x80 */
 ret = do_syscall(env,
@@ -585,7 +585,7 @@ void cpu_loop(CPUARMState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case EXCP_UDEF:
 case EXCP_NOCP:
 case EXCP_INVSTATE:
@@ -1379,7 +1379,7 @@ void cpu_loop(CPUPPCState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case POWERPC_EXCP_NONE:
 /* Just go on */
 break;
@@ -2251,7 +2251,7 @@ void cpu_loop(CPUMIPSState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case EXCP_SYSCALL:
 env->active_tc.PC += 4;
 # ifdef TARGET_ABI_MIPSO32
@@ -2957,7 +2957,7 @@ void cpu_loop(CPUM68KState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case EXCP_ILLEGAL:
 {
 if (ts->sim_syscalls) {
@@ -3640,6 +3640,121 @@ void cpu_loop(CPUTLGState *env)
 
 #endif
 
+#ifdef TARGET_RISCV
+
+void cpu_loop(CPURISCVState *env)
+{
+CPUState *cs = CPU(riscv_env_get_cpu(env));
+int trapnr, signum, sigcode;
+target_ulong sigaddr;
+target_ulong ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+
+signum = 0;
+sigcode = 0;
+sigaddr = 0;
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case RISCV_EXCP_U_ECALL:
+env->pc += 4;
+if (env->gpr[xA7] == TARGET_NR_arch_specific_syscall + 15) {
+/* kernel-assisted AMO not suitable for do_syscall */
+start_exclusive();
+ret = riscv_flush_icache_syscall(env,
+ env->gpr[xA7],
+ env->gpr[xA0],
+ env->gpr[xA1],
+ env->gpr[xA2],
+ env->gpr[xA3]);
+end_exclusive();
+} else {
+ret = do_syscall(env,
+ env->gpr[xA7],
+ env->gpr[xA0],
+ env->gpr[xA1],
+ env->gpr[xA2],
+   

Re: [Qemu-devel] [PATCH v1 10/21] RISC-V Linux User Emulation

2018-01-03 Thread Richard Henderson
On 01/02/2018 04:44 PM, Michael Clark wrote:
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 20f3d8c..178af56 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1272,6 +1272,28 @@ static inline void init_thread(struct target_pt_regs 
> *regs,
>  
>  #endif /* TARGET_TILEGX */
>  
> +#ifdef TARGET_RISCV
> +
> +#define ELF_START_MMAP 0x8000

For riscv64 too?  Surely closer to ((TASK_SIZE / 3) * 2).

> diff --git a/linux-user/main.c b/linux-user/main.c
> index 71696ed..8900141 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -227,7 +227,7 @@ void cpu_loop(CPUX86State *env)
>  cpu_exec_end(cs);
>  process_queued_cpu_work(cs);
>  
> -switch(trapnr) {
> +switch (trapnr) {

Even though the formatting is wrong, don't change unrelated code.

> +case EXCP_DEBUG:
> +gdbstep:
> +signum = gdb_handlesig(cs, TARGET_SIGTRAP);
> +sigcode = TARGET_TRAP_BRKPT;
> +break;
> +default:
> +EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - 
> aborting\n",
> + trapnr);
> +exit(EXIT_FAILURE);

You will need to handle the generic EXCP_ATOMIC as well.
Though of course you won't see that until you use tcg_gen_atomic_*.


r~



Re: [Qemu-devel] [PATCH v1 10/21] RISC-V Linux User Emulation

2018-01-04 Thread Michael Clark
On Thu, Jan 4, 2018 at 12:47 PM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 01/02/2018 04:44 PM, Michael Clark wrote:
> > diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> > index 20f3d8c..178af56 100644
> > --- a/linux-user/elfload.c
> > +++ b/linux-user/elfload.c
> > @@ -1272,6 +1272,28 @@ static inline void init_thread(struct
> target_pt_regs *regs,
> >
> >  #endif /* TARGET_TILEGX */
> >
> > +#ifdef TARGET_RISCV
> > +
> > +#define ELF_START_MMAP 0x8000
>
> For riscv64 too?  Surely closer to ((TASK_SIZE / 3) * 2).
>
> > diff --git a/linux-user/main.c b/linux-user/main.c
> > index 71696ed..8900141 100644
> > --- a/linux-user/main.c
> > +++ b/linux-user/main.c
> > @@ -227,7 +227,7 @@ void cpu_loop(CPUX86State *env)
> >  cpu_exec_end(cs);
> >  process_queued_cpu_work(cs);
> >
> > -switch(trapnr) {
> > +switch (trapnr) {
>
> Even though the formatting is wrong, don't change unrelated code.


I didn't intend for this to happen. False assumption that only the RISC-V
code was broken. Will attend to this in the next spin.


> > +case EXCP_DEBUG:
> > +gdbstep:
> > +signum = gdb_handlesig(cs, TARGET_SIGTRAP);
> > +sigcode = TARGET_TRAP_BRKPT;
> > +break;
> > +default:
> > +EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x -
> aborting\n",
> > + trapnr);
> > +exit(EXIT_FAILURE);
>
> You will need to handle the generic EXCP_ATOMIC as well.
> Though of course you won't see that until you use tcg_gen_atomic_*.
>