Commit 48733d195b10a61a18c0aafcdd0ae711bdfe03a6
1 parent
e69b4065
CRIS Linux userland emulation, part 2. By Edgar E. Iglesias.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3367 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
104 additions
and
5 deletions
linux-user/elfload.c
| ... | ... | @@ -334,6 +334,26 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i |
| 334 | 334 | |
| 335 | 335 | #endif |
| 336 | 336 | |
| 337 | +#ifdef TARGET_CRIS | |
| 338 | + | |
| 339 | +#define ELF_START_MMAP 0x80000000 | |
| 340 | + | |
| 341 | +#define elf_check_arch(x) ( (x) == EM_CRIS ) | |
| 342 | + | |
| 343 | +#define ELF_CLASS ELFCLASS32 | |
| 344 | +#define ELF_DATA ELFDATA2LSB | |
| 345 | +#define ELF_ARCH EM_CRIS | |
| 346 | + | |
| 347 | +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) | |
| 348 | +{ | |
| 349 | + regs->erp = infop->entry; | |
| 350 | +} | |
| 351 | + | |
| 352 | +#define USE_ELF_CORE_DUMP | |
| 353 | +#define ELF_EXEC_PAGESIZE 8192 | |
| 354 | + | |
| 355 | +#endif | |
| 356 | + | |
| 337 | 357 | #ifdef TARGET_M68K |
| 338 | 358 | |
| 339 | 359 | #define ELF_START_MMAP 0x80000000 | ... | ... |
linux-user/main.c
| ... | ... | @@ -1601,6 +1601,61 @@ void cpu_loop (CPUState *env) |
| 1601 | 1601 | } |
| 1602 | 1602 | #endif |
| 1603 | 1603 | |
| 1604 | +#ifdef TARGET_CRIS | |
| 1605 | +void cpu_loop (CPUState *env) | |
| 1606 | +{ | |
| 1607 | + int trapnr, ret; | |
| 1608 | + target_siginfo_t info; | |
| 1609 | + | |
| 1610 | + while (1) { | |
| 1611 | + trapnr = cpu_cris_exec (env); | |
| 1612 | + switch (trapnr) { | |
| 1613 | + case 0xaa: | |
| 1614 | + { | |
| 1615 | + info.si_signo = SIGSEGV; | |
| 1616 | + info.si_errno = 0; | |
| 1617 | + /* XXX: check env->error_code */ | |
| 1618 | + info.si_code = TARGET_SEGV_MAPERR; | |
| 1619 | + info._sifields._sigfault._addr = env->debug1; | |
| 1620 | + queue_signal(info.si_signo, &info); | |
| 1621 | + } | |
| 1622 | + break; | |
| 1623 | + case EXCP_BREAK: | |
| 1624 | + ret = do_syscall(env, | |
| 1625 | + env->regs[9], | |
| 1626 | + env->regs[10], | |
| 1627 | + env->regs[11], | |
| 1628 | + env->regs[12], | |
| 1629 | + env->regs[13], | |
| 1630 | + env->pregs[7], | |
| 1631 | + env->pregs[11]); | |
| 1632 | + env->regs[10] = ret; | |
| 1633 | + env->pc += 2; | |
| 1634 | + break; | |
| 1635 | + case EXCP_DEBUG: | |
| 1636 | + { | |
| 1637 | + int sig; | |
| 1638 | + | |
| 1639 | + sig = gdb_handlesig (env, TARGET_SIGTRAP); | |
| 1640 | + if (sig) | |
| 1641 | + { | |
| 1642 | + info.si_signo = sig; | |
| 1643 | + info.si_errno = 0; | |
| 1644 | + info.si_code = TARGET_TRAP_BRKPT; | |
| 1645 | + queue_signal(info.si_signo, &info); | |
| 1646 | + } | |
| 1647 | + } | |
| 1648 | + break; | |
| 1649 | + default: | |
| 1650 | + printf ("Unhandled trap: 0x%x\n", trapnr); | |
| 1651 | + cpu_dump_state(env, stderr, fprintf, 0); | |
| 1652 | + exit (1); | |
| 1653 | + } | |
| 1654 | + process_pending_signals (env); | |
| 1655 | + } | |
| 1656 | +} | |
| 1657 | +#endif | |
| 1658 | + | |
| 1604 | 1659 | #ifdef TARGET_M68K |
| 1605 | 1660 | |
| 1606 | 1661 | void cpu_loop(CPUM68KState *env) |
| ... | ... | @@ -2195,6 +2250,26 @@ int main(int argc, char **argv) |
| 2195 | 2250 | env->pc = regs->pc; |
| 2196 | 2251 | env->unique = regs->unique; |
| 2197 | 2252 | } |
| 2253 | +#elif defined(TARGET_CRIS) | |
| 2254 | + { | |
| 2255 | + env->regs[0] = regs->r0; | |
| 2256 | + env->regs[1] = regs->r1; | |
| 2257 | + env->regs[2] = regs->r2; | |
| 2258 | + env->regs[3] = regs->r3; | |
| 2259 | + env->regs[4] = regs->r4; | |
| 2260 | + env->regs[5] = regs->r5; | |
| 2261 | + env->regs[6] = regs->r6; | |
| 2262 | + env->regs[7] = regs->r7; | |
| 2263 | + env->regs[8] = regs->r8; | |
| 2264 | + env->regs[9] = regs->r9; | |
| 2265 | + env->regs[10] = regs->r10; | |
| 2266 | + env->regs[11] = regs->r11; | |
| 2267 | + env->regs[12] = regs->r12; | |
| 2268 | + env->regs[13] = regs->r13; | |
| 2269 | + env->regs[14] = info->start_stack; | |
| 2270 | + env->regs[15] = regs->acr; | |
| 2271 | + env->pc = regs->erp; | |
| 2272 | + } | |
| 2198 | 2273 | #else |
| 2199 | 2274 | #error unsupported target CPU |
| 2200 | 2275 | #endif | ... | ... |
linux-user/syscall.c
| ... | ... | @@ -74,7 +74,7 @@ |
| 74 | 74 | //#define DEBUG |
| 75 | 75 | |
| 76 | 76 | #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ |
| 77 | - || defined(TARGET_M68K) || defined(TARGET_SH4) | |
| 77 | + || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) | |
| 78 | 78 | /* 16 bit uid wrappers emulation */ |
| 79 | 79 | #define USE_UID16 |
| 80 | 80 | #endif |
| ... | ... | @@ -2286,6 +2286,10 @@ int do_fork(CPUState *env, unsigned int flags, target_ulong newsp) |
| 2286 | 2286 | for (i = 7; i < 30; i++) |
| 2287 | 2287 | new_env->ir[i] = 0; |
| 2288 | 2288 | } |
| 2289 | +#elif defined(TARGET_CRIS) | |
| 2290 | + if (!newsp) | |
| 2291 | + newsp = env->regs[14]; | |
| 2292 | + new_env->regs[14] = newsp; | |
| 2289 | 2293 | #else |
| 2290 | 2294 | #error unsupported target CPU |
| 2291 | 2295 | #endif |
| ... | ... | @@ -3502,7 +3506,7 @@ target_long do_syscall(void *cpu_env, int num, target_long arg1, |
| 3502 | 3506 | #endif |
| 3503 | 3507 | #ifdef TARGET_NR_mmap |
| 3504 | 3508 | case TARGET_NR_mmap: |
| 3505 | -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K) | |
| 3509 | +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) | |
| 3506 | 3510 | { |
| 3507 | 3511 | target_ulong *v; |
| 3508 | 3512 | target_ulong v1, v2, v3, v4, v5, v6; | ... | ... |
linux-user/syscall_defs.h
| ... | ... | @@ -49,7 +49,7 @@ |
| 49 | 49 | #define TARGET_IOC_TYPEBITS 8 |
| 50 | 50 | |
| 51 | 51 | #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ |
| 52 | - || defined(TARGET_M68K) || defined(TARGET_ALPHA) | |
| 52 | + || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) | |
| 53 | 53 | |
| 54 | 54 | #define TARGET_IOC_SIZEBITS 14 |
| 55 | 55 | #define TARGET_IOC_DIRBITS 2 |
| ... | ... | @@ -289,7 +289,7 @@ struct target_sigaction; |
| 289 | 289 | int do_sigaction(int sig, const struct target_sigaction *act, |
| 290 | 290 | struct target_sigaction *oact); |
| 291 | 291 | |
| 292 | -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) | |
| 292 | +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) | |
| 293 | 293 | |
| 294 | 294 | #if defined(TARGET_SPARC) |
| 295 | 295 | #define TARGET_SA_NOCLDSTOP 8u |
| ... | ... | @@ -884,7 +884,7 @@ struct target_winsize { |
| 884 | 884 | #define TARGET_MAP_NONBLOCK 0x10000 /* do not block on IO */ |
| 885 | 885 | #endif |
| 886 | 886 | |
| 887 | -#if defined(TARGET_I386) || defined(TARGET_ARM) | |
| 887 | +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_CRIS) | |
| 888 | 888 | struct target_stat { |
| 889 | 889 | unsigned short st_dev; |
| 890 | 890 | unsigned short __pad1; | ... | ... |