Revision 5fafdf24 linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* qemu user main |
3 |
*
|
|
3 |
* |
|
4 | 4 |
* Copyright (c) 2003 Fabrice Bellard |
5 | 5 |
* |
6 | 6 |
* This program is free software; you can redistribute it and/or modify |
... | ... | |
131 | 131 |
return cpu_get_real_ticks(); |
132 | 132 |
} |
133 | 133 |
|
134 |
static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
|
|
134 |
static void write_dt(void *ptr, unsigned long addr, unsigned long limit, |
|
135 | 135 |
int flags) |
136 | 136 |
{ |
137 | 137 |
unsigned int e1, e2; |
... | ... | |
144 | 144 |
p[1] = tswapl(e2); |
145 | 145 |
} |
146 | 146 |
|
147 |
static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
|
|
147 |
static void set_gate(void *ptr, unsigned int type, unsigned int dpl, |
|
148 | 148 |
unsigned long addr, unsigned int sel) |
149 | 149 |
{ |
150 | 150 |
unsigned int e1, e2; |
... | ... | |
176 | 176 |
switch(trapnr) { |
177 | 177 |
case 0x80: |
178 | 178 |
/* linux syscall */ |
179 |
env->regs[R_EAX] = do_syscall(env,
|
|
180 |
env->regs[R_EAX],
|
|
179 |
env->regs[R_EAX] = do_syscall(env, |
|
180 |
env->regs[R_EAX], |
|
181 | 181 |
env->regs[R_EBX], |
182 | 182 |
env->regs[R_ECX], |
183 | 183 |
env->regs[R_EDX], |
... | ... | |
293 | 293 |
break; |
294 | 294 |
default: |
295 | 295 |
pc = env->segs[R_CS].base + env->eip; |
296 |
fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
|
|
296 |
fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", |
|
297 | 297 |
(long)pc, trapnr); |
298 | 298 |
abort(); |
299 | 299 |
} |
... | ... | |
331 | 331 |
unsigned int n, insn; |
332 | 332 |
target_siginfo_t info; |
333 | 333 |
uint32_t addr; |
334 |
|
|
334 |
|
|
335 | 335 |
for(;;) { |
336 | 336 |
trapnr = cpu_arm_exec(env); |
337 | 337 |
switch(trapnr) { |
... | ... | |
343 | 343 |
/* we handle the FPU emulation here, as Linux */ |
344 | 344 |
/* we get the opcode */ |
345 | 345 |
opcode = tget32(env->regs[15]); |
346 |
|
|
346 |
|
|
347 | 347 |
if (EmulateAll(opcode, &ts->fpa, env) == 0) { |
348 | 348 |
info.si_signo = SIGILL; |
349 | 349 |
info.si_errno = 0; |
... | ... | |
395 | 395 |
n -= ARM_SYSCALL_BASE; |
396 | 396 |
env->eabi = 0; |
397 | 397 |
} |
398 |
env->regs[0] = do_syscall(env,
|
|
399 |
n,
|
|
398 |
env->regs[0] = do_syscall(env, |
|
399 |
n, |
|
400 | 400 |
env->regs[0], |
401 | 401 |
env->regs[1], |
402 | 402 |
env->regs[2], |
... | ... | |
443 | 443 |
break; |
444 | 444 |
default: |
445 | 445 |
error: |
446 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
|
446 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
|
447 | 447 |
trapnr); |
448 | 448 |
cpu_dump_state(env, stderr, fprintf, 0); |
449 | 449 |
abort(); |
... | ... | |
475 | 475 |
{ |
476 | 476 |
unsigned int i; |
477 | 477 |
target_ulong sp_ptr; |
478 |
|
|
478 |
|
|
479 | 479 |
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; |
480 | 480 |
#if defined(DEBUG_WIN) |
481 |
printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
|
|
481 |
printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n", |
|
482 | 482 |
(int)sp_ptr, cwp1); |
483 | 483 |
#endif |
484 | 484 |
for(i = 0; i < 16; i++) { |
... | ... | |
506 | 506 |
{ |
507 | 507 |
unsigned int new_wim, i, cwp1; |
508 | 508 |
target_ulong sp_ptr; |
509 |
|
|
509 |
|
|
510 | 510 |
new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) & |
511 | 511 |
((1LL << NWINDOWS) - 1); |
512 |
|
|
512 |
|
|
513 | 513 |
/* restore the invalid window */ |
514 | 514 |
cwp1 = (env->cwp + 1) & (NWINDOWS - 1); |
515 | 515 |
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; |
516 | 516 |
#if defined(DEBUG_WIN) |
517 |
printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
|
|
517 |
printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", |
|
518 | 518 |
(int)sp_ptr, cwp1); |
519 | 519 |
#endif |
520 | 520 |
for(i = 0; i < 16; i++) { |
... | ... | |
555 | 555 |
{ |
556 | 556 |
int trapnr, ret; |
557 | 557 |
target_siginfo_t info; |
558 |
|
|
558 |
|
|
559 | 559 |
while (1) { |
560 | 560 |
trapnr = cpu_sparc_exec (env); |
561 |
|
|
561 |
|
|
562 | 562 |
switch (trapnr) { |
563 | 563 |
#ifndef TARGET_SPARC64 |
564 |
case 0x88:
|
|
564 |
case 0x88: |
|
565 | 565 |
case 0x90: |
566 | 566 |
#else |
567 | 567 |
case 0x16d: |
568 | 568 |
#endif |
569 | 569 |
ret = do_syscall (env, env->gregs[1], |
570 |
env->regwptr[0], env->regwptr[1],
|
|
571 |
env->regwptr[2], env->regwptr[3],
|
|
570 |
env->regwptr[0], env->regwptr[1], |
|
571 |
env->regwptr[2], env->regwptr[3], |
|
572 | 572 |
env->regwptr[4], env->regwptr[5]); |
573 | 573 |
if ((unsigned int)ret >= (unsigned int)(-515)) { |
574 | 574 |
#ifdef TARGET_SPARC64 |
... | ... | |
670 | 670 |
/* TO FIX */ |
671 | 671 |
return 0; |
672 | 672 |
} |
673 |
|
|
673 |
|
|
674 | 674 |
uint32_t cpu_ppc_load_tbl (CPUState *env) |
675 | 675 |
{ |
676 | 676 |
return cpu_ppc_get_tb(env) & 0xFFFFFFFF; |
677 | 677 |
} |
678 |
|
|
678 |
|
|
679 | 679 |
uint32_t cpu_ppc_load_tbu (CPUState *env) |
680 | 680 |
{ |
681 | 681 |
return cpu_ppc_get_tb(env) >> 32; |
682 | 682 |
} |
683 |
|
|
683 |
|
|
684 | 684 |
static void cpu_ppc_store_tb (CPUState *env, uint64_t value) |
685 | 685 |
{ |
686 | 686 |
/* TO FIX */ |
... | ... | |
690 | 690 |
{ |
691 | 691 |
cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env)); |
692 | 692 |
} |
693 |
|
|
693 |
|
|
694 | 694 |
void cpu_ppc_store_tbl (CPUState *env, uint32_t value) |
695 | 695 |
{ |
696 | 696 |
cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value); |
... | ... | |
717 | 717 |
target_siginfo_t info; |
718 | 718 |
int trapnr; |
719 | 719 |
uint32_t ret; |
720 |
|
|
720 |
|
|
721 | 721 |
for(;;) { |
722 | 722 |
trapnr = cpu_ppc_exec(env); |
723 | 723 |
if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH && |
... | ... | |
1026 | 1026 |
} |
1027 | 1027 |
break; |
1028 | 1028 |
default: |
1029 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
|
1029 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
|
1030 | 1030 |
trapnr); |
1031 | 1031 |
if (loglevel) { |
1032 | 1032 |
fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - " |
... | ... | |
1437 | 1437 |
break; |
1438 | 1438 |
default: |
1439 | 1439 |
// error: |
1440 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
|
1440 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
|
1441 | 1441 |
trapnr); |
1442 | 1442 |
cpu_dump_state(env, stderr, fprintf, 0); |
1443 | 1443 |
abort(); |
... | ... | |
1452 | 1452 |
{ |
1453 | 1453 |
int trapnr, ret; |
1454 | 1454 |
target_siginfo_t info; |
1455 |
|
|
1455 |
|
|
1456 | 1456 |
while (1) { |
1457 | 1457 |
trapnr = cpu_sh4_exec (env); |
1458 |
|
|
1458 |
|
|
1459 | 1459 |
switch (trapnr) { |
1460 | 1460 |
case 0x160: |
1461 |
ret = do_syscall(env,
|
|
1462 |
env->gregs[3],
|
|
1463 |
env->gregs[4],
|
|
1464 |
env->gregs[5],
|
|
1465 |
env->gregs[6],
|
|
1466 |
env->gregs[7],
|
|
1467 |
env->gregs[0],
|
|
1461 |
ret = do_syscall(env, |
|
1462 |
env->gregs[3], |
|
1463 |
env->gregs[4], |
|
1464 |
env->gregs[5], |
|
1465 |
env->gregs[6], |
|
1466 |
env->gregs[7], |
|
1467 |
env->gregs[0], |
|
1468 | 1468 |
0); |
1469 | 1469 |
env->gregs[0] = ret; |
1470 | 1470 |
env->pc += 2; |
... | ... | |
1501 | 1501 |
unsigned int n; |
1502 | 1502 |
target_siginfo_t info; |
1503 | 1503 |
TaskState *ts = env->opaque; |
1504 |
|
|
1504 |
|
|
1505 | 1505 |
for(;;) { |
1506 | 1506 |
trapnr = cpu_m68k_exec(env); |
1507 | 1507 |
switch(trapnr) { |
... | ... | |
1537 | 1537 |
ts->sim_syscalls = 0; |
1538 | 1538 |
n = env->dregs[0]; |
1539 | 1539 |
env->pc += 2; |
1540 |
env->dregs[0] = do_syscall(env,
|
|
1541 |
n,
|
|
1540 |
env->dregs[0] = do_syscall(env, |
|
1541 |
n, |
|
1542 | 1542 |
env->dregs[1], |
1543 | 1543 |
env->dregs[2], |
1544 | 1544 |
env->dregs[3], |
... | ... | |
1575 | 1575 |
} |
1576 | 1576 |
break; |
1577 | 1577 |
default: |
1578 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
|
1578 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
|
1579 | 1579 |
trapnr); |
1580 | 1580 |
cpu_dump_state(env, stderr, fprintf, 0); |
1581 | 1581 |
abort(); |
... | ... | |
1590 | 1590 |
{ |
1591 | 1591 |
int trapnr; |
1592 | 1592 |
target_siginfo_t info; |
1593 |
|
|
1593 |
|
|
1594 | 1594 |
while (1) { |
1595 | 1595 |
trapnr = cpu_alpha_exec (env); |
1596 |
|
|
1596 |
|
|
1597 | 1597 |
switch (trapnr) { |
1598 | 1598 |
case EXCP_RESET: |
1599 | 1599 |
fprintf(stderr, "Reset requested. Exit\n"); |
... | ... | |
1608 | 1608 |
exit(1); |
1609 | 1609 |
break; |
1610 | 1610 |
case EXCP_HW_INTERRUPT: |
1611 |
fprintf(stderr, "External interrupt. Exit\n");
|
|
1611 |
fprintf(stderr, "External interrupt. Exit\n"); |
|
1612 | 1612 |
exit(1); |
1613 | 1613 |
break; |
1614 | 1614 |
case EXCP_DFAULT: |
... | ... | |
1695 | 1695 |
"-d options activate log (logfile=%s)\n" |
1696 | 1696 |
"-p pagesize set the host page size to 'pagesize'\n", |
1697 | 1697 |
TARGET_ARCH, |
1698 |
interp_prefix,
|
|
1698 |
interp_prefix, |
|
1699 | 1699 |
x86_stack_size, |
1700 | 1700 |
DEBUG_LOGFILE); |
1701 | 1701 |
_exit(1); |
... | ... | |
1745 | 1745 |
|
1746 | 1746 |
if (optind >= argc) |
1747 | 1747 |
break; |
1748 |
|
|
1748 |
|
|
1749 | 1749 |
r = argv[optind++]; |
1750 | 1750 |
mask = cpu_str_to_log_mask(r); |
1751 | 1751 |
if (!mask) { |
... | ... | |
1794 | 1794 |
} |
1795 | 1795 |
} else if (!strcmp(r, "drop-ld-preload")) { |
1796 | 1796 |
drop_ld_preload = 1; |
1797 |
} else
|
|
1797 |
} else |
|
1798 | 1798 |
#ifdef USE_CODE_COPY |
1799 | 1799 |
if (!strcmp(r, "no-code-copy")) { |
1800 | 1800 |
code_copy_enabled = 0; |
1801 |
} else
|
|
1801 |
} else |
|
1802 | 1802 |
#endif |
1803 | 1803 |
{ |
1804 | 1804 |
usage(); |
... | ... | |
1821 | 1821 |
qemu_host_page_size */ |
1822 | 1822 |
env = cpu_init(); |
1823 | 1823 |
global_env = env; |
1824 |
|
|
1824 |
|
|
1825 | 1825 |
wrk = environ; |
1826 | 1826 |
while (*(wrk++)) |
1827 | 1827 |
environ_count++; |
... | ... | |
1844 | 1844 |
for (wrk = target_environ; *wrk; wrk++) { |
1845 | 1845 |
free(*wrk); |
1846 | 1846 |
} |
1847 |
|
|
1847 |
|
|
1848 | 1848 |
free(target_environ); |
1849 | 1849 |
|
1850 | 1850 |
if (loglevel) { |
1851 | 1851 |
page_dump(logfile); |
1852 |
|
|
1852 |
|
|
1853 | 1853 |
fprintf(logfile, "start_brk 0x%08lx\n" , info->start_brk); |
1854 | 1854 |
fprintf(logfile, "end_code 0x%08lx\n" , info->end_code); |
1855 | 1855 |
fprintf(logfile, "start_code 0x%08lx\n" , info->start_code); |
... | ... | |
1870 | 1870 |
ts->used = 1; |
1871 | 1871 |
ts->info = info; |
1872 | 1872 |
env->user_mode_only = 1; |
1873 |
|
|
1873 |
|
|
1874 | 1874 |
#if defined(TARGET_I386) |
1875 | 1875 |
cpu_x86_set_cpl(env, 3); |
1876 | 1876 |
|
... | ... | |
1883 | 1883 |
|
1884 | 1884 |
/* flags setup : we activate the IRQs by default as in user mode */ |
1885 | 1885 |
env->eflags |= IF_MASK; |
1886 |
|
|
1886 |
|
|
1887 | 1887 |
/* linux register setup */ |
1888 | 1888 |
#if defined(TARGET_X86_64) |
1889 | 1889 |
env->regs[R_EAX] = regs->rax; |
... | ... | |
1936 | 1936 |
env->gdt.base = h2g(gdt_table); |
1937 | 1937 |
env->gdt.limit = sizeof(gdt_table) - 1; |
1938 | 1938 |
write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, |
1939 |
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
|
|
1939 |
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | |
|
1940 | 1940 |
(3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); |
1941 | 1941 |
write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff, |
1942 |
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
|
|
1942 |
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | |
|
1943 | 1943 |
(3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); |
1944 | 1944 |
cpu_x86_load_seg(env, R_CS, __USER_CS); |
1945 | 1945 |
cpu_x86_load_seg(env, R_DS, __USER_DS); |
Also available in: Unified diff