From: Chris Wulff <crwu...@gmail.com> Signed-off-by: Chris Wulff <crwu...@gmail.com> --- MAINTAINERS | 5 +++++ arch_init.c | 2 ++ arch_init.h | 1 + configure | 11 +++++++++++ cpu-exec.c | 12 +++++++++++- dis-asm.h | 3 +++ disas.c | 3 +++ elf.h | 2 ++ exec.c | 6 ++++-- gdbstub.c | 29 +++++++++++++++++++++++++++++ linux-user/elfload.c | 29 +++++++++++++++++++++++++++++ monitor.c | 5 +++-- qapi-schema.json | 2 +- qemu-doc.texi | 3 +++ 14 files changed, 107 insertions(+), 6 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS index 61f8b45..e20adc8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -91,6 +91,11 @@ M: Aurelien Jarno <aurel...@aurel32.net> S: Odd Fixes F: target-mips/ +NiosII +M: Chris Wulff <crwu...@gmail.com> +S: Odd Fixes +F: target-nios2/ + PowerPC M: Alexander Graf <ag...@suse.de> L: qemu-...@nongnu.org diff --git a/arch_init.c b/arch_init.c index 5a1173e..6e9d993 100644 --- a/arch_init.c +++ b/arch_init.c @@ -81,6 +81,8 @@ int graphic_depth = 15; #define QEMU_ARCH QEMU_ARCH_MICROBLAZE #elif defined(TARGET_MIPS) #define QEMU_ARCH QEMU_ARCH_MIPS +#elif defined(TARGET_NIOS2) +#define QEMU_ARCH QEMU_ARCH_NIOS2 #elif defined(TARGET_OPENRISC) #define QEMU_ARCH QEMU_ARCH_OPENRISC #elif defined(TARGET_PPC) diff --git a/arch_init.h b/arch_init.h index d9c572a..b3d01c4 100644 --- a/arch_init.h +++ b/arch_init.h @@ -20,6 +20,7 @@ enum { QEMU_ARCH_XTENSA = 4096, QEMU_ARCH_OPENRISC = 8192, QEMU_ARCH_UNICORE32 = 0x4000, + QEMU_ARCH_NIOS2 = 0x8000, }; extern const uint32_t arch_type; diff --git a/configure b/configure index d97fd81..bfefc42 100755 --- a/configure +++ b/configure @@ -969,6 +969,7 @@ mips-softmmu \ mipsel-softmmu \ mips64-softmmu \ mips64el-softmmu \ +nios2-softmmu \ or32-softmmu \ ppc-softmmu \ ppcemb-softmmu \ @@ -997,6 +998,7 @@ microblaze-linux-user \ microblazeel-linux-user \ mips-linux-user \ mipsel-linux-user \ +nios2-linux-user \ or32-linux-user \ ppc-linux-user \ ppc64-linux-user \ @@ -3746,6 +3748,11 @@ case "$target_arch2" in target_phys_bits=64 target_long_alignment=8 ;; + nios2) + target_nptl="yes" + target_phys_bits=32 + target_libs_softmmu="$fdt_libs" + ;; or32) TARGET_ARCH=openrisc TARGET_BASE_ARCH=openrisc @@ -4013,6 +4020,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_MIPS_DIS=y" >> $config_target_mak echo "CONFIG_MIPS_DIS=y" >> $libdis_config_mak ;; + nios2) + echo "CONFIG_NIOS2_DIS=y" >> $config_target_mak + echo "CONFIG_NIOS2_DIS=y" >> $libdis_config_mak + ;; or32) echo "CONFIG_OPENRISC_DIS=y" >> $config_target_mak echo "CONFIG_OPENRISC_DIS=y" >> $libdis_config_mak diff --git a/cpu-exec.c b/cpu-exec.c index 134b3c4..2d9034b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -222,6 +222,7 @@ int cpu_exec(CPUArchState *env) #elif defined(TARGET_LM32) #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) +#elif defined(TARGET_NIOS2) #elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_CRIS) @@ -277,7 +278,8 @@ int cpu_exec(CPUArchState *env) } #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ - defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32) + defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || \ + defined(TARGET_UNICORE32) || defined(TARGET_NIOS2) if (interrupt_request & CPU_INTERRUPT_HALT) { env->interrupt_request &= ~CPU_INTERRUPT_HALT; env->halted = 1; @@ -531,6 +533,13 @@ int cpu_exec(CPUArchState *env) do_interrupt(env); next_tb = 0; } +#elif defined(TARGET_NIOS2) + if ((interrupt_request & CPU_INTERRUPT_HARD) + && (env->regs[CR_STATUS] & CR_STATUS_PIE)) { + env->exception_index = EXCP_IRQ; + do_interrupt(env); + next_tb = 0; + } #endif /* Don't use the cached interrupt_request value, do_interrupt may have updated the EXITTB flag. */ @@ -656,6 +665,7 @@ int cpu_exec(CPUArchState *env) | env->cc_dest | (env->cc_x << 4); #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) +#elif defined(TARGET_NIOS2) #elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_ALPHA) diff --git a/dis-asm.h b/dis-asm.h index 3944b3c..a7010bf 100644 --- a/dis-asm.h +++ b/dis-asm.h @@ -221,6 +221,8 @@ enum bfd_architecture bfd_arch_ia64, /* HP/Intel ia64 */ #define bfd_mach_ia64_elf64 64 #define bfd_mach_ia64_elf32 32 + bfd_arch_nios2, +#define bfd_mach_nios2 1 bfd_arch_lm32, /* Lattice Mico32 */ #define bfd_mach_lm32 1 bfd_arch_last @@ -407,6 +409,7 @@ int print_insn_crisv10 (bfd_vma, disassemble_info*); int print_insn_microblaze (bfd_vma, disassemble_info*); int print_insn_ia64 (bfd_vma, disassemble_info*); int print_insn_lm32 (bfd_vma, disassemble_info*); +int print_insn_nios2 (bfd_vma, disassemble_info*); #if 0 /* Fetch the disassembler for a given BFD, if that support is available. */ diff --git a/disas.c b/disas.c index 7b2acc9..310bac2 100644 --- a/disas.c +++ b/disas.c @@ -245,6 +245,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) #elif defined(TARGET_MICROBLAZE) disasm_info.mach = bfd_arch_microblaze; print_insn = print_insn_microblaze; +#elif defined(TARGET_NIOS2) + disasm_info.mach = bfd_arch_nios2; + print_insn = print_insn_nios2; #elif defined(TARGET_LM32) disasm_info.mach = bfd_mach_lm32; print_insn = print_insn_lm32; diff --git a/elf.h b/elf.h index a21ea53..e5e667b 100644 --- a/elf.h +++ b/elf.h @@ -124,6 +124,8 @@ typedef int64_t Elf64_Sxword; */ #define EM_S390_OLD 0xA390 +#define EM_ALTERA_NIOS2 113 /* Altera Nios II soft-core processor */ + #define EM_MICROBLAZE 189 #define EM_MICROBLAZE_OLD 0xBAAB diff --git a/exec.c b/exec.c index 5834766..383197a 100644 --- a/exec.c +++ b/exec.c @@ -2843,7 +2843,8 @@ static uint64_t unassigned_mem_read(void *opaque, target_phys_addr_t addr, #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif -#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || \ + defined(TARGET_MICROBLAZE) || defined(TARGET_NIOS2) cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size); #endif return 0; @@ -2855,7 +2856,8 @@ static void unassigned_mem_write(void *opaque, target_phys_addr_t addr, #ifdef DEBUG_UNASSIGNED printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val); #endif -#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || \ + defined(TARGET_MICROBLAZE) || defined(TARGET_NIOS2) cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size); #endif } diff --git a/gdbstub.c b/gdbstub.c index 5d37dd9..c040676 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1331,6 +1331,33 @@ static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) } return 4; } + +#elif defined(TARGET_NIOS2) + +static int cpu_gdb_read_register(CPUNios2State *env, uint8_t *mem_buf, int n) +{ + if (n > NUM_CORE_REGS) { + return 0; + } + + GET_REG32(env->regs[n]); + return 0; +} + +static int cpu_gdb_write_register(CPUNios2State *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + + if (n > NUM_CORE_REGS) { + return 0; + } + + tmp = ldl_p(mem_buf); + + env->regs[n] = tmp; + return 4; +} + #elif defined (TARGET_CRIS) #define NUM_CORE_REGS 49 @@ -1986,6 +2013,8 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) } #elif defined (TARGET_MICROBLAZE) s->c_cpu->sregs[SR_PC] = pc; +#elif defined(TARGET_NIOS2) + s->c_cpu->regs[R_PC] = pc; #elif defined(TARGET_OPENRISC) s->c_cpu->pc = pc; #elif defined (TARGET_CRIS) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 819fdd5..2750f58 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -804,6 +804,35 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env #endif /* TARGET_MICROBLAZE */ +#ifdef TARGET_NIOS2 + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ((x) == EM_ALTERA_NIOS2) + +#define ELF_CLASS ELFCLASS32 +#define ELF_ARCH EM_ALTERA_NIOS2 + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + /* TODO */ +} + +#define ELF_EXEC_PAGESIZE 4096 + +#define USE_ELF_CORE_DUMP +/* TODO - #define ELF_NREG 38 */ +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; + +/* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs. */ +static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env) +{ + /* TODO */ +} + +#endif /* TARGET_NIOS2 */ + #ifdef TARGET_OPENRISC #define ELF_START_MMAP 0x08000000 diff --git a/monitor.c b/monitor.c index b17b1bb..84dbe9b 100644 --- a/monitor.c +++ b/monitor.c @@ -2051,7 +2051,8 @@ static void tlb_info(Monitor *mon) #endif -#if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA) +#if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA) || \ + defined(TARGET_NIOS2) static void tlb_info(Monitor *mon) { CPUArchState *env1 = mon_get_cpu(); @@ -2759,7 +2760,7 @@ static mon_cmd_t info_cmds[] = { .mhandler.info = hmp_info_pci, }, #if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \ - defined(TARGET_PPC) || defined(TARGET_XTENSA) + defined(TARGET_PPC) || defined(TARGET_XTENSA) || defined(TARGET_NIOS2) { .name = "tlb", .args_type = "", diff --git a/qapi-schema.json b/qapi-schema.json index bd8ad74..0a10521 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2467,7 +2467,7 @@ ## { 'enum': 'TargetType', 'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel', - 'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'or32', + 'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'nios2', 'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4', 'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] } diff --git a/qemu-doc.texi b/qemu-doc.texi index 35cabbc..3515f15 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2475,6 +2475,9 @@ The binary format is detected automatically. @command{qemu-mips} TODO. @command{qemu-mipsel} TODO. +@cindex user mode (NiosII) +@command{qemu-nios2} TODO. + @cindex user mode (PowerPC) @command{qemu-ppc64abi32} TODO. @command{qemu-ppc64} TODO. -- 1.7.9.5