Commit f1ccf904778f7a840d2b751b5e429d4088ba9cb4
1 parent
94cff60a
CRIS support in toplevel, by Edgar E. Iglesias.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3363 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
143 additions
and
2 deletions
cpu-exec.c
| ... | ... | @@ -210,6 +210,10 @@ static inline TranslationBlock *tb_find_fast(void) |
| 210 | 210 | flags = env->ps; |
| 211 | 211 | cs_base = 0; |
| 212 | 212 | pc = env->pc; |
| 213 | +#elif defined(TARGET_CRIS) | |
| 214 | + flags = 0; | |
| 215 | + cs_base = 0; | |
| 216 | + pc = env->pc; | |
| 213 | 217 | #else |
| 214 | 218 | #error unsupported CPU |
| 215 | 219 | #endif |
| ... | ... | @@ -284,6 +288,7 @@ int cpu_exec(CPUState *env1) |
| 284 | 288 | #elif defined(TARGET_PPC) |
| 285 | 289 | #elif defined(TARGET_MIPS) |
| 286 | 290 | #elif defined(TARGET_SH4) |
| 291 | +#elif defined(TARGET_CRIS) | |
| 287 | 292 | /* XXXXX */ |
| 288 | 293 | #else |
| 289 | 294 | #error unsupported target CPU |
| ... | ... | @@ -335,6 +340,8 @@ int cpu_exec(CPUState *env1) |
| 335 | 340 | do_interrupt(env); |
| 336 | 341 | #elif defined(TARGET_ALPHA) |
| 337 | 342 | do_interrupt(env); |
| 343 | +#elif defined(TARGET_CRIS) | |
| 344 | + do_interrupt(env); | |
| 338 | 345 | #elif defined(TARGET_M68K) |
| 339 | 346 | do_interrupt(0); |
| 340 | 347 | #endif |
| ... | ... | @@ -385,7 +392,7 @@ int cpu_exec(CPUState *env1) |
| 385 | 392 | cpu_loop_exit(); |
| 386 | 393 | } |
| 387 | 394 | #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ |
| 388 | - defined(TARGET_PPC) || defined(TARGET_ALPHA) | |
| 395 | + defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) | |
| 389 | 396 | if (interrupt_request & CPU_INTERRUPT_HALT) { |
| 390 | 397 | env->interrupt_request &= ~CPU_INTERRUPT_HALT; |
| 391 | 398 | env->halted = 1; |
| ... | ... | @@ -517,6 +524,11 @@ int cpu_exec(CPUState *env1) |
| 517 | 524 | if (interrupt_request & CPU_INTERRUPT_HARD) { |
| 518 | 525 | do_interrupt(env); |
| 519 | 526 | } |
| 527 | +#elif defined(TARGET_CRIS) | |
| 528 | + if (interrupt_request & CPU_INTERRUPT_HARD) { | |
| 529 | + do_interrupt(env); | |
| 530 | + env->interrupt_request &= ~CPU_INTERRUPT_HARD; | |
| 531 | + } | |
| 520 | 532 | #elif defined(TARGET_M68K) |
| 521 | 533 | if (interrupt_request & CPU_INTERRUPT_HARD |
| 522 | 534 | && ((env->sr & SR_I) >> SR_I_SHIFT) |
| ... | ... | @@ -576,6 +588,8 @@ int cpu_exec(CPUState *env1) |
| 576 | 588 | cpu_dump_state(env, logfile, fprintf, 0); |
| 577 | 589 | #elif defined(TARGET_ALPHA) |
| 578 | 590 | cpu_dump_state(env, logfile, fprintf, 0); |
| 591 | +#elif defined(TARGET_CRIS) | |
| 592 | + cpu_dump_state(env, logfile, fprintf, 0); | |
| 579 | 593 | #else |
| 580 | 594 | #error unsupported target CPU |
| 581 | 595 | #endif |
| ... | ... | @@ -769,6 +783,7 @@ int cpu_exec(CPUState *env1) |
| 769 | 783 | #elif defined(TARGET_MIPS) |
| 770 | 784 | #elif defined(TARGET_SH4) |
| 771 | 785 | #elif defined(TARGET_ALPHA) |
| 786 | +#elif defined(TARGET_CRIS) | |
| 772 | 787 | /* XXXXX */ |
| 773 | 788 | #else |
| 774 | 789 | #error unsupported target CPU |
| ... | ... | @@ -1200,6 +1215,51 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
| 1200 | 1215 | /* never comes here */ |
| 1201 | 1216 | return 1; |
| 1202 | 1217 | } |
| 1218 | +#elif defined (TARGET_CRIS) | |
| 1219 | +static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | |
| 1220 | + int is_write, sigset_t *old_set, | |
| 1221 | + void *puc) | |
| 1222 | +{ | |
| 1223 | + TranslationBlock *tb; | |
| 1224 | + int ret; | |
| 1225 | + | |
| 1226 | + if (cpu_single_env) | |
| 1227 | + env = cpu_single_env; /* XXX: find a correct solution for multithread */ | |
| 1228 | +#if defined(DEBUG_SIGNAL) | |
| 1229 | + printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", | |
| 1230 | + pc, address, is_write, *(unsigned long *)old_set); | |
| 1231 | +#endif | |
| 1232 | + /* XXX: locking issue */ | |
| 1233 | + if (is_write && page_unprotect(h2g(address), pc, puc)) { | |
| 1234 | + return 1; | |
| 1235 | + } | |
| 1236 | + | |
| 1237 | + /* see if it is an MMU fault */ | |
| 1238 | + ret = cpu_cris_handle_mmu_fault(env, address, is_write, 1, 0); | |
| 1239 | + if (ret < 0) | |
| 1240 | + return 0; /* not an MMU fault */ | |
| 1241 | + if (ret == 0) | |
| 1242 | + return 1; /* the MMU fault was handled without causing real CPU fault */ | |
| 1243 | + | |
| 1244 | + /* now we have a real cpu fault */ | |
| 1245 | + tb = tb_find_pc(pc); | |
| 1246 | + if (tb) { | |
| 1247 | + /* the PC is inside the translated code. It means that we have | |
| 1248 | + a virtual CPU fault */ | |
| 1249 | + cpu_restore_state(tb, env, pc, puc); | |
| 1250 | + } | |
| 1251 | +#if 0 | |
| 1252 | + printf("PF exception: NIP=0x%08x error=0x%x %p\n", | |
| 1253 | + env->nip, env->error_code, tb); | |
| 1254 | +#endif | |
| 1255 | + /* we restore the process signal mask as the sigreturn should | |
| 1256 | + do it (XXX: use sigsetjmp) */ | |
| 1257 | + sigprocmask(SIG_SETMASK, old_set, NULL); | |
| 1258 | + cpu_loop_exit(); | |
| 1259 | + /* never comes here */ | |
| 1260 | + return 1; | |
| 1261 | +} | |
| 1262 | + | |
| 1203 | 1263 | #else |
| 1204 | 1264 | #error unsupported target CPU |
| 1205 | 1265 | #endif | ... | ... |
exec-all.h
| ... | ... | @@ -617,6 +617,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) |
| 617 | 617 | is_user = ((env->ps >> 3) & 3); |
| 618 | 618 | #elif defined (TARGET_M68K) |
| 619 | 619 | is_user = ((env->sr & SR_S) == 0); |
| 620 | +#elif defined (TARGET_CRIS) | |
| 621 | + is_user = (0); | |
| 620 | 622 | #else |
| 621 | 623 | #error unimplemented CPU |
| 622 | 624 | #endif | ... | ... |
exec.c
| ... | ... | @@ -2066,6 +2066,8 @@ static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr) |
| 2066 | 2066 | #endif |
| 2067 | 2067 | #ifdef TARGET_SPARC |
| 2068 | 2068 | do_unassigned_access(addr, 0, 0, 0); |
| 2069 | +#elif TARGET_CRIS | |
| 2070 | + do_unassigned_access(addr, 0, 0, 0); | |
| 2069 | 2071 | #endif |
| 2070 | 2072 | return 0; |
| 2071 | 2073 | } |
| ... | ... | @@ -2077,6 +2079,8 @@ static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_ |
| 2077 | 2079 | #endif |
| 2078 | 2080 | #ifdef TARGET_SPARC |
| 2079 | 2081 | do_unassigned_access(addr, 1, 0, 0); |
| 2082 | +#elif TARGET_CRIS | |
| 2083 | + do_unassigned_access(addr, 1, 0, 0); | |
| 2080 | 2084 | #endif |
| 2081 | 2085 | } |
| 2082 | 2086 | ... | ... |
gdbstub.c
| ... | ... | @@ -728,6 +728,66 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) |
| 728 | 728 | for (i = 0; i < 8; i++) LOAD(env->gregs[i]); |
| 729 | 729 | for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]); |
| 730 | 730 | } |
| 731 | +#elif defined (TARGET_CRIS) | |
| 732 | + | |
| 733 | +static int cris_save_32 (unsigned char *d, uint32_t value) | |
| 734 | +{ | |
| 735 | + *d++ = (value); | |
| 736 | + *d++ = (value >>= 8); | |
| 737 | + *d++ = (value >>= 8); | |
| 738 | + *d++ = (value >>= 8); | |
| 739 | + return 4; | |
| 740 | +} | |
| 741 | +static int cris_save_16 (unsigned char *d, uint32_t value) | |
| 742 | +{ | |
| 743 | + *d++ = (value); | |
| 744 | + *d++ = (value >>= 8); | |
| 745 | + return 2; | |
| 746 | +} | |
| 747 | +static int cris_save_8 (unsigned char *d, uint32_t value) | |
| 748 | +{ | |
| 749 | + *d++ = (value); | |
| 750 | + return 1; | |
| 751 | +} | |
| 752 | + | |
| 753 | +/* FIXME: this will bug on archs not supporting unaligned word accesses. */ | |
| 754 | +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | |
| 755 | +{ | |
| 756 | + uint8_t *ptr = mem_buf; | |
| 757 | + uint8_t srs; | |
| 758 | + int i; | |
| 759 | + | |
| 760 | + for (i = 0; i < 16; i++) | |
| 761 | + ptr += cris_save_32 (ptr, env->regs[i]); | |
| 762 | + | |
| 763 | + srs = env->pregs[SR_SRS]; | |
| 764 | + | |
| 765 | + ptr += cris_save_8 (ptr, env->pregs[0]); | |
| 766 | + ptr += cris_save_8 (ptr, env->pregs[1]); | |
| 767 | + ptr += cris_save_32 (ptr, env->pregs[2]); | |
| 768 | + ptr += cris_save_8 (ptr, srs); | |
| 769 | + ptr += cris_save_16 (ptr, env->pregs[4]); | |
| 770 | + | |
| 771 | + for (i = 5; i < 16; i++) | |
| 772 | + ptr += cris_save_32 (ptr, env->pregs[i]); | |
| 773 | + | |
| 774 | + ptr += cris_save_32 (ptr, env->pc); | |
| 775 | + | |
| 776 | + for (i = 0; i < 16; i++) | |
| 777 | + ptr += cris_save_32 (ptr, env->sregs[srs][i]); | |
| 778 | + | |
| 779 | + return ((uint8_t *)ptr - mem_buf); | |
| 780 | +} | |
| 781 | + | |
| 782 | +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) | |
| 783 | +{ | |
| 784 | + uint32_t *ptr = (uint32_t *)mem_buf; | |
| 785 | + int i; | |
| 786 | + | |
| 787 | +#define LOAD(x) (x)=*ptr++; | |
| 788 | + for (i = 0; i < 16; i++) LOAD(env->regs[i]); | |
| 789 | + LOAD (env->pc); | |
| 790 | +} | |
| 731 | 791 | #else |
| 732 | 792 | static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
| 733 | 793 | { |
| ... | ... | @@ -745,7 +805,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) |
| 745 | 805 | const char *p; |
| 746 | 806 | int ch, reg_size, type; |
| 747 | 807 | char buf[4096]; |
| 748 | - uint8_t mem_buf[2000]; | |
| 808 | + uint8_t mem_buf[4096]; | |
| 749 | 809 | uint32_t *registers; |
| 750 | 810 | target_ulong addr, len; |
| 751 | 811 | |
| ... | ... | @@ -776,6 +836,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) |
| 776 | 836 | env->pc = addr; |
| 777 | 837 | #elif defined (TARGET_MIPS) |
| 778 | 838 | env->PC[env->current_tc] = addr; |
| 839 | +#elif defined (TARGET_CRIS) | |
| 840 | + env->pc = addr; | |
| 779 | 841 | #endif |
| 780 | 842 | } |
| 781 | 843 | #ifdef CONFIG_USER_ONLY |
| ... | ... | @@ -800,6 +862,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) |
| 800 | 862 | env->pc = addr; |
| 801 | 863 | #elif defined (TARGET_MIPS) |
| 802 | 864 | env->PC[env->current_tc] = addr; |
| 865 | +#elif defined (TARGET_CRIS) | |
| 866 | + env->pc = addr; | |
| 803 | 867 | #endif |
| 804 | 868 | } |
| 805 | 869 | cpu_single_step(env, 1); | ... | ... |
softmmu_header.h
| ... | ... | @@ -67,6 +67,9 @@ |
| 67 | 67 | #define CPU_MEM_INDEX ((env->ps >> 3) & 3) |
| 68 | 68 | #elif defined (TARGET_M68K) |
| 69 | 69 | #define CPU_MEM_INDEX ((env->sr & SR_S) == 0) |
| 70 | +#elif defined (TARGET_CRIS) | |
| 71 | +/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */ | |
| 72 | +#define CPU_MEM_INDEX (0) | |
| 70 | 73 | #else |
| 71 | 74 | #error unsupported CPU |
| 72 | 75 | #endif |
| ... | ... | @@ -90,6 +93,9 @@ |
| 90 | 93 | #define CPU_MEM_INDEX ((env->ps >> 3) & 3) |
| 91 | 94 | #elif defined (TARGET_M68K) |
| 92 | 95 | #define CPU_MEM_INDEX ((env->sr & SR_S) == 0) |
| 96 | +#elif defined (TARGET_CRIS) | |
| 97 | +/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */ | |
| 98 | +#define CPU_MEM_INDEX (0) | |
| 93 | 99 | #else |
| 94 | 100 | #error unsupported CPU |
| 95 | 101 | #endif | ... | ... |
vl.c
| ... | ... | @@ -7390,6 +7390,8 @@ void register_machines(void) |
| 7390 | 7390 | #elif defined(TARGET_M68K) |
| 7391 | 7391 | qemu_register_machine(&mcf5208evb_machine); |
| 7392 | 7392 | qemu_register_machine(&an5206_machine); |
| 7393 | +#elif defined(TARGET_CRIS) | |
| 7394 | + qemu_register_machine(&bareetraxfs_machine); | |
| 7393 | 7395 | #else |
| 7394 | 7396 | #error unsupported CPU |
| 7395 | 7397 | #endif | ... | ... |
vl.h
| ... | ... | @@ -1173,6 +1173,9 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base); |
| 1173 | 1173 | void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); |
| 1174 | 1174 | void acpi_bios_init(void); |
| 1175 | 1175 | |
| 1176 | +/* Axis ETRAX. */ | |
| 1177 | +extern QEMUMachine bareetraxfs_machine; | |
| 1178 | + | |
| 1176 | 1179 | /* pc.c */ |
| 1177 | 1180 | extern QEMUMachine pc_machine; |
| 1178 | 1181 | extern QEMUMachine isapc_machine; | ... | ... |