mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
target/xtensa linux-user support.
- small cleanup for xtensa registers dumping (-d cpu); - add support for debugging linux-user process with xtensa-linux-gdb (as opposed to xtensa-elf-gdb), which can only access unprivileged registers; - enable MTTCG for target/xtensa; - cleanup in linux-user/mmap area making sure that it works correctly with limited 30-bit-wide user address space; - import xtensa-specific definitions from the linux kernel, conditionalize user-only/softmmu-only code and add handlers for signals, exceptions, process/thread creation and core registers dumping. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEK2eFS5jlMn3N6xfYUfnMkfg/oEQFAlqr9NsTHGpjbXZia2Jj QGdtYWlsLmNvbQAKCRBR+cyR+D+gRHjDD/9dQxuirsTjU+oO2OMU5YjDBF6Hy+KA O4hJoWh/jNyUzgZOAtmpbZmuB1GJ5gNDhl5lifEFIWtAqf/qi/M87ibCQbdjFQ+t sT+FVgSU9X16J9wBKtUPV4DBMeMvJenHtFlCCw6oZxF5cnqGXw7e4yQtn7/KI8jT ymu7hiCaGJJ4ao/FG8KbIs3iSpQcfbIN7kEfuL92tMNjVWWTnNVhPVxyg3Bojkib pRFELL/BO3Ud3P83BncA5TNp6O1rFwKRYBK9nwLGWrjFMEbomdT5LWSZuZK9UVN9 aLoC/GnvGCnvAth8E4L0dDOmyz9MRDJ5rYJoaxoEVYzvz8rexVyAjpC/zOrJVxuK xrgandQtrFGkp5NJD6QpM92b7YDyR1w1s24KlehZivzHoN83cN3CuCHLWcqgicza /x4r/OQ4uiSUTex2Cg2hVQJR6m1LkJKa94Mimrd7G/zCHSF/BDks170o5DpW7JT8 QWfYTtZg13auzPsgZmGE+/b1o5PBXhnlBPzD983X6u5cgS5RWyik3jhmp5rEx8wH sxV5kvMb96JlUDCuwPTu9zJhJ3rqbWtCR7+4Sh1PCcsr6vVgsV0EZHAapwrG5GPp pOxLlZ54ObK3oSW6SB8TnS1rEiGkBHMhSL1O6VdKOvAXFPCVZsIGBGTpuf6MEn6c hRg0iBGQ6GMUUw== =UCny -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/xtensa/tags/20180316-xtensa' into staging target/xtensa linux-user support. - small cleanup for xtensa registers dumping (-d cpu); - add support for debugging linux-user process with xtensa-linux-gdb (as opposed to xtensa-elf-gdb), which can only access unprivileged registers; - enable MTTCG for target/xtensa; - cleanup in linux-user/mmap area making sure that it works correctly with limited 30-bit-wide user address space; - import xtensa-specific definitions from the linux kernel, conditionalize user-only/softmmu-only code and add handlers for signals, exceptions, process/thread creation and core registers dumping. # gpg: Signature made Fri 16 Mar 2018 16:46:19 GMT # gpg: using RSA key 51F9CC91F83FA044 # gpg: Good signature from "Max Filippov <filippov@cadence.com>" # gpg: aka "Max Filippov <max.filippov@cogentembedded.com>" # gpg: aka "Max Filippov <jcmvbkbc@gmail.com>" # Primary key fingerprint: 2B67 854B 98E5 327D CDEB 17D8 51F9 CC91 F83F A044 * remotes/xtensa/tags/20180316-xtensa: MAINTAINERS: fix W: address for xtensa qemu-binfmt-conf.sh: add qemu-xtensa target/xtensa: add linux-user support linux-user: drop unused target_msync function linux-user: fix target_mprotect/target_munmap error return values linux-user: fix assertion in shmdt linux-user: fix mmap/munmap/mprotect/mremap/shmat target/xtensa: support MTTCG target/xtensa: use correct number of registers in gdbstub target/xtensa: mark register windows in the dump target/xtensa: dump correct physical registers Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # linux-user/syscall.c
This commit is contained in:
commit
e1e44a9916
26 changed files with 1790 additions and 75 deletions
|
@ -289,7 +289,7 @@ T: git git://github.com/ehabkost/qemu.git x86-next
|
|||
|
||||
Xtensa
|
||||
M: Max Filippov <jcmvbkbc@gmail.com>
|
||||
W: http://wiki.osll.spb.ru/doku.php?id=etc:users:jcmvbkbc:qemu-target-xtensa
|
||||
W: http://wiki.osll.ru/doku.php?id=etc:users:jcmvbkbc:qemu-target-xtensa
|
||||
S: Maintained
|
||||
F: target/xtensa/
|
||||
F: hw/xtensa/
|
||||
|
|
1
configure
vendored
1
configure
vendored
|
@ -6880,6 +6880,7 @@ case "$target_name" in
|
|||
;;
|
||||
xtensa|xtensaeb)
|
||||
TARGET_ARCH=xtensa
|
||||
mttcg="yes"
|
||||
;;
|
||||
*)
|
||||
error_exit "Unsupported target CPU"
|
||||
|
|
1
default-configs/xtensa-linux-user.mak
Normal file
1
default-configs/xtensa-linux-user.mak
Normal file
|
@ -0,0 +1 @@
|
|||
# Default configuration for xtensa-linux-user
|
1
default-configs/xtensaeb-linux-user.mak
Normal file
1
default-configs/xtensaeb-linux-user.mak
Normal file
|
@ -0,0 +1 @@
|
|||
# Default configuration for xtensa-linux-user
|
|
@ -1273,6 +1273,64 @@ static inline void init_thread(struct target_pt_regs *regs,
|
|||
|
||||
#endif /* TARGET_HPPA */
|
||||
|
||||
#ifdef TARGET_XTENSA
|
||||
|
||||
#define ELF_START_MMAP 0x20000000
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_ARCH EM_XTENSA
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *regs,
|
||||
struct image_info *infop)
|
||||
{
|
||||
regs->windowbase = 0;
|
||||
regs->windowstart = 1;
|
||||
regs->areg[1] = infop->start_stack;
|
||||
regs->pc = infop->entry;
|
||||
}
|
||||
|
||||
/* See linux kernel: arch/xtensa/include/asm/elf.h. */
|
||||
#define ELF_NREG 128
|
||||
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
|
||||
|
||||
enum {
|
||||
TARGET_REG_PC,
|
||||
TARGET_REG_PS,
|
||||
TARGET_REG_LBEG,
|
||||
TARGET_REG_LEND,
|
||||
TARGET_REG_LCOUNT,
|
||||
TARGET_REG_SAR,
|
||||
TARGET_REG_WINDOWSTART,
|
||||
TARGET_REG_WINDOWBASE,
|
||||
TARGET_REG_THREADPTR,
|
||||
TARGET_REG_AR0 = 64,
|
||||
};
|
||||
|
||||
static void elf_core_copy_regs(target_elf_gregset_t *regs,
|
||||
const CPUXtensaState *env)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
(*regs)[TARGET_REG_PC] = tswapreg(env->pc);
|
||||
(*regs)[TARGET_REG_PS] = tswapreg(env->sregs[PS] & ~PS_EXCM);
|
||||
(*regs)[TARGET_REG_LBEG] = tswapreg(env->sregs[LBEG]);
|
||||
(*regs)[TARGET_REG_LEND] = tswapreg(env->sregs[LEND]);
|
||||
(*regs)[TARGET_REG_LCOUNT] = tswapreg(env->sregs[LCOUNT]);
|
||||
(*regs)[TARGET_REG_SAR] = tswapreg(env->sregs[SAR]);
|
||||
(*regs)[TARGET_REG_WINDOWSTART] = tswapreg(env->sregs[WINDOW_START]);
|
||||
(*regs)[TARGET_REG_WINDOWBASE] = tswapreg(env->sregs[WINDOW_BASE]);
|
||||
(*regs)[TARGET_REG_THREADPTR] = tswapreg(env->uregs[THREADPTR]);
|
||||
xtensa_sync_phys_from_window((CPUXtensaState *)env);
|
||||
for (i = 0; i < env->config->nareg; ++i) {
|
||||
(*regs)[TARGET_REG_AR0 + i] = tswapreg(env->phys_regs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
#endif /* TARGET_XTENSA */
|
||||
|
||||
#ifndef ELF_PLATFORM
|
||||
#define ELF_PLATFORM (NULL)
|
||||
#endif
|
||||
|
|
|
@ -3841,6 +3841,242 @@ void cpu_loop(CPUHPPAState *env)
|
|||
|
||||
#endif /* TARGET_HPPA */
|
||||
|
||||
#ifdef TARGET_XTENSA
|
||||
|
||||
static void xtensa_rfw(CPUXtensaState *env)
|
||||
{
|
||||
xtensa_restore_owb(env);
|
||||
env->pc = env->sregs[EPC1];
|
||||
}
|
||||
|
||||
static void xtensa_rfwu(CPUXtensaState *env)
|
||||
{
|
||||
env->sregs[WINDOW_START] |= (1 << env->sregs[WINDOW_BASE]);
|
||||
xtensa_rfw(env);
|
||||
}
|
||||
|
||||
static void xtensa_rfwo(CPUXtensaState *env)
|
||||
{
|
||||
env->sregs[WINDOW_START] &= ~(1 << env->sregs[WINDOW_BASE]);
|
||||
xtensa_rfw(env);
|
||||
}
|
||||
|
||||
static void xtensa_overflow4(CPUXtensaState *env)
|
||||
{
|
||||
put_user_ual(env->regs[0], env->regs[5] - 16);
|
||||
put_user_ual(env->regs[1], env->regs[5] - 12);
|
||||
put_user_ual(env->regs[2], env->regs[5] - 8);
|
||||
put_user_ual(env->regs[3], env->regs[5] - 4);
|
||||
xtensa_rfwo(env);
|
||||
}
|
||||
|
||||
static void xtensa_underflow4(CPUXtensaState *env)
|
||||
{
|
||||
get_user_ual(env->regs[0], env->regs[5] - 16);
|
||||
get_user_ual(env->regs[1], env->regs[5] - 12);
|
||||
get_user_ual(env->regs[2], env->regs[5] - 8);
|
||||
get_user_ual(env->regs[3], env->regs[5] - 4);
|
||||
xtensa_rfwu(env);
|
||||
}
|
||||
|
||||
static void xtensa_overflow8(CPUXtensaState *env)
|
||||
{
|
||||
put_user_ual(env->regs[0], env->regs[9] - 16);
|
||||
get_user_ual(env->regs[0], env->regs[1] - 12);
|
||||
put_user_ual(env->regs[1], env->regs[9] - 12);
|
||||
put_user_ual(env->regs[2], env->regs[9] - 8);
|
||||
put_user_ual(env->regs[3], env->regs[9] - 4);
|
||||
put_user_ual(env->regs[4], env->regs[0] - 32);
|
||||
put_user_ual(env->regs[5], env->regs[0] - 28);
|
||||
put_user_ual(env->regs[6], env->regs[0] - 24);
|
||||
put_user_ual(env->regs[7], env->regs[0] - 20);
|
||||
xtensa_rfwo(env);
|
||||
}
|
||||
|
||||
static void xtensa_underflow8(CPUXtensaState *env)
|
||||
{
|
||||
get_user_ual(env->regs[0], env->regs[9] - 16);
|
||||
get_user_ual(env->regs[1], env->regs[9] - 12);
|
||||
get_user_ual(env->regs[2], env->regs[9] - 8);
|
||||
get_user_ual(env->regs[7], env->regs[1] - 12);
|
||||
get_user_ual(env->regs[3], env->regs[9] - 4);
|
||||
get_user_ual(env->regs[4], env->regs[7] - 32);
|
||||
get_user_ual(env->regs[5], env->regs[7] - 28);
|
||||
get_user_ual(env->regs[6], env->regs[7] - 24);
|
||||
get_user_ual(env->regs[7], env->regs[7] - 20);
|
||||
xtensa_rfwu(env);
|
||||
}
|
||||
|
||||
static void xtensa_overflow12(CPUXtensaState *env)
|
||||
{
|
||||
put_user_ual(env->regs[0], env->regs[13] - 16);
|
||||
get_user_ual(env->regs[0], env->regs[1] - 12);
|
||||
put_user_ual(env->regs[1], env->regs[13] - 12);
|
||||
put_user_ual(env->regs[2], env->regs[13] - 8);
|
||||
put_user_ual(env->regs[3], env->regs[13] - 4);
|
||||
put_user_ual(env->regs[4], env->regs[0] - 48);
|
||||
put_user_ual(env->regs[5], env->regs[0] - 44);
|
||||
put_user_ual(env->regs[6], env->regs[0] - 40);
|
||||
put_user_ual(env->regs[7], env->regs[0] - 36);
|
||||
put_user_ual(env->regs[8], env->regs[0] - 32);
|
||||
put_user_ual(env->regs[9], env->regs[0] - 28);
|
||||
put_user_ual(env->regs[10], env->regs[0] - 24);
|
||||
put_user_ual(env->regs[11], env->regs[0] - 20);
|
||||
xtensa_rfwo(env);
|
||||
}
|
||||
|
||||
static void xtensa_underflow12(CPUXtensaState *env)
|
||||
{
|
||||
get_user_ual(env->regs[0], env->regs[13] - 16);
|
||||
get_user_ual(env->regs[1], env->regs[13] - 12);
|
||||
get_user_ual(env->regs[2], env->regs[13] - 8);
|
||||
get_user_ual(env->regs[11], env->regs[1] - 12);
|
||||
get_user_ual(env->regs[3], env->regs[13] - 4);
|
||||
get_user_ual(env->regs[4], env->regs[11] - 48);
|
||||
get_user_ual(env->regs[5], env->regs[11] - 44);
|
||||
get_user_ual(env->regs[6], env->regs[11] - 40);
|
||||
get_user_ual(env->regs[7], env->regs[11] - 36);
|
||||
get_user_ual(env->regs[8], env->regs[11] - 32);
|
||||
get_user_ual(env->regs[9], env->regs[11] - 28);
|
||||
get_user_ual(env->regs[10], env->regs[11] - 24);
|
||||
get_user_ual(env->regs[11], env->regs[11] - 20);
|
||||
xtensa_rfwu(env);
|
||||
}
|
||||
|
||||
void cpu_loop(CPUXtensaState *env)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
target_siginfo_t info;
|
||||
abi_ulong ret;
|
||||
int trapnr;
|
||||
|
||||
while (1) {
|
||||
cpu_exec_start(cs);
|
||||
trapnr = cpu_exec(cs);
|
||||
cpu_exec_end(cs);
|
||||
process_queued_cpu_work(cs);
|
||||
|
||||
env->sregs[PS] &= ~PS_EXCM;
|
||||
switch (trapnr) {
|
||||
case EXCP_INTERRUPT:
|
||||
break;
|
||||
|
||||
case EXC_WINDOW_OVERFLOW4:
|
||||
xtensa_overflow4(env);
|
||||
break;
|
||||
case EXC_WINDOW_UNDERFLOW4:
|
||||
xtensa_underflow4(env);
|
||||
break;
|
||||
case EXC_WINDOW_OVERFLOW8:
|
||||
xtensa_overflow8(env);
|
||||
break;
|
||||
case EXC_WINDOW_UNDERFLOW8:
|
||||
xtensa_underflow8(env);
|
||||
break;
|
||||
case EXC_WINDOW_OVERFLOW12:
|
||||
xtensa_overflow12(env);
|
||||
break;
|
||||
case EXC_WINDOW_UNDERFLOW12:
|
||||
xtensa_underflow12(env);
|
||||
break;
|
||||
|
||||
case EXC_USER:
|
||||
switch (env->sregs[EXCCAUSE]) {
|
||||
case ILLEGAL_INSTRUCTION_CAUSE:
|
||||
case PRIVILEGED_CAUSE:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code =
|
||||
env->sregs[EXCCAUSE] == ILLEGAL_INSTRUCTION_CAUSE ?
|
||||
TARGET_ILL_ILLOPC : TARGET_ILL_PRVOPC;
|
||||
info._sifields._sigfault._addr = env->sregs[EPC1];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
|
||||
case SYSCALL_CAUSE:
|
||||
env->pc += 3;
|
||||
ret = do_syscall(env, env->regs[2],
|
||||
env->regs[6], env->regs[3],
|
||||
env->regs[4], env->regs[5],
|
||||
env->regs[8], env->regs[9], 0, 0);
|
||||
switch (ret) {
|
||||
default:
|
||||
env->regs[2] = ret;
|
||||
break;
|
||||
|
||||
case -TARGET_ERESTARTSYS:
|
||||
case -TARGET_QEMU_ESIGRETURN:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ALLOCA_CAUSE:
|
||||
env->sregs[PS] = deposit32(env->sregs[PS],
|
||||
PS_OWB_SHIFT,
|
||||
PS_OWB_LEN,
|
||||
env->sregs[WINDOW_BASE]);
|
||||
|
||||
switch (env->regs[0] & 0xc0000000) {
|
||||
case 0x00000000:
|
||||
case 0x40000000:
|
||||
xtensa_rotate_window(env, -1);
|
||||
xtensa_underflow4(env);
|
||||
break;
|
||||
|
||||
case 0x80000000:
|
||||
xtensa_rotate_window(env, -2);
|
||||
xtensa_underflow8(env);
|
||||
break;
|
||||
|
||||
case 0xc0000000:
|
||||
xtensa_rotate_window(env, -3);
|
||||
xtensa_underflow12(env);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case INTEGER_DIVIDE_BY_ZERO_CAUSE:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_INTDIV;
|
||||
info._sifields._sigfault._addr = env->sregs[EPC1];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
|
||||
case LOAD_PROHIBITED_CAUSE:
|
||||
case STORE_PROHIBITED_CAUSE:
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_ACCERR;
|
||||
info._sifields._sigfault._addr = env->sregs[EXCVADDR];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "exccause = %d\n", env->sregs[EXCCAUSE]);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (trapnr) {
|
||||
info.si_signo = trapnr;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, trapnr, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXC_DEBUG:
|
||||
default:
|
||||
fprintf(stderr, "trapnr = %d\n", trapnr);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
process_pending_signals(env);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TARGET_XTENSA */
|
||||
|
||||
__thread CPUState *thread_cpu;
|
||||
|
||||
bool qemu_cpu_is_self(CPUState *cpu)
|
||||
|
@ -4873,6 +5109,15 @@ int main(int argc, char **argv, char **envp)
|
|||
env->iaoq_f = regs->iaoq[0];
|
||||
env->iaoq_b = regs->iaoq[1];
|
||||
}
|
||||
#elif defined(TARGET_XTENSA)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
env->regs[i] = regs->areg[i];
|
||||
}
|
||||
env->sregs[WINDOW_START] = regs->windowstart;
|
||||
env->pc = regs->pc;
|
||||
}
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
|
|
@ -7048,6 +7048,260 @@ long do_rt_sigreturn(CPUArchState *env)
|
|||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_XTENSA)
|
||||
|
||||
struct target_sigcontext {
|
||||
abi_ulong sc_pc;
|
||||
abi_ulong sc_ps;
|
||||
abi_ulong sc_lbeg;
|
||||
abi_ulong sc_lend;
|
||||
abi_ulong sc_lcount;
|
||||
abi_ulong sc_sar;
|
||||
abi_ulong sc_acclo;
|
||||
abi_ulong sc_acchi;
|
||||
abi_ulong sc_a[16];
|
||||
abi_ulong sc_xtregs;
|
||||
};
|
||||
|
||||
struct target_ucontext {
|
||||
abi_ulong tuc_flags;
|
||||
abi_ulong tuc_link;
|
||||
target_stack_t tuc_stack;
|
||||
struct target_sigcontext tuc_mcontext;
|
||||
target_sigset_t tuc_sigmask;
|
||||
};
|
||||
|
||||
struct target_rt_sigframe {
|
||||
target_siginfo_t info;
|
||||
struct target_ucontext uc;
|
||||
/* TODO: xtregs */
|
||||
uint8_t retcode[6];
|
||||
abi_ulong window[4];
|
||||
};
|
||||
|
||||
static abi_ulong get_sigframe(struct target_sigaction *sa,
|
||||
CPUXtensaState *env,
|
||||
unsigned long framesize)
|
||||
{
|
||||
abi_ulong sp = env->regs[1];
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
return (sp - framesize) & -16;
|
||||
}
|
||||
|
||||
static int flush_window_regs(CPUXtensaState *env)
|
||||
{
|
||||
const uint32_t nareg_mask = env->config->nareg - 1;
|
||||
uint32_t wb = env->sregs[WINDOW_BASE];
|
||||
uint32_t ws = (xtensa_replicate_windowstart(env) >> (wb + 1)) &
|
||||
((1 << env->config->nareg / 4) - 1);
|
||||
uint32_t d = ctz32(ws) + 1;
|
||||
uint32_t sp;
|
||||
abi_long ret = 0;
|
||||
|
||||
wb += d;
|
||||
ws >>= d;
|
||||
|
||||
xtensa_sync_phys_from_window(env);
|
||||
sp = env->phys_regs[(wb * 4 + 1) & nareg_mask];
|
||||
|
||||
while (ws && ret == 0) {
|
||||
int d;
|
||||
int i;
|
||||
int idx;
|
||||
|
||||
if (ws & 0x1) {
|
||||
ws >>= 1;
|
||||
d = 1;
|
||||
} else if (ws & 0x2) {
|
||||
ws >>= 2;
|
||||
d = 2;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
idx = (wb * 4 + 4 + i) & nareg_mask;
|
||||
ret |= put_user_ual(env->phys_regs[idx], sp + (i - 12) * 4);
|
||||
}
|
||||
} else if (ws & 0x4) {
|
||||
ws >>= 3;
|
||||
d = 3;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
idx = (wb * 4 + 4 + i) & nareg_mask;
|
||||
ret |= put_user_ual(env->phys_regs[idx], sp + (i - 16) * 4);
|
||||
}
|
||||
} else {
|
||||
g_assert_not_reached();
|
||||
}
|
||||
sp = env->phys_regs[((wb + d) * 4 + 1) & nareg_mask];
|
||||
for (i = 0; i < 4; ++i) {
|
||||
idx = (wb * 4 + i) & nareg_mask;
|
||||
ret |= put_user_ual(env->phys_regs[idx], sp + (i - 4) * 4);
|
||||
}
|
||||
wb += d;
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
static int setup_sigcontext(struct target_rt_sigframe *frame,
|
||||
CPUXtensaState *env)
|
||||
{
|
||||
struct target_sigcontext *sc = &frame->uc.tuc_mcontext;
|
||||
int i;
|
||||
|
||||
__put_user(env->pc, &sc->sc_pc);
|
||||
__put_user(env->sregs[PS], &sc->sc_ps);
|
||||
__put_user(env->sregs[LBEG], &sc->sc_lbeg);
|
||||
__put_user(env->sregs[LEND], &sc->sc_lend);
|
||||
__put_user(env->sregs[LCOUNT], &sc->sc_lcount);
|
||||
if (!flush_window_regs(env)) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__put_user(env->regs[i], sc->sc_a + i);
|
||||
}
|
||||
__put_user(0, &sc->sc_xtregs);
|
||||
/* TODO: xtregs */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
target_siginfo_t *info,
|
||||
target_sigset_t *set, CPUXtensaState *env)
|
||||
{
|
||||
abi_ulong frame_addr;
|
||||
struct target_rt_sigframe *frame;
|
||||
uint32_t ra;
|
||||
int i;
|
||||
|
||||
frame_addr = get_sigframe(ka, env, sizeof(*frame));
|
||||
trace_user_setup_rt_frame(env, frame_addr);
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
if (ka->sa_flags & SA_SIGINFO) {
|
||||
tswap_siginfo(&frame->info, info);
|
||||
}
|
||||
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp,
|
||||
&frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->regs[1]),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
if (!setup_sigcontext(frame, env)) {
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
goto give_sigsegv;
|
||||
}
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
|
||||
__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
|
||||
}
|
||||
|
||||
if (ka->sa_flags & TARGET_SA_RESTORER) {
|
||||
ra = ka->sa_restorer;
|
||||
} else {
|
||||
ra = frame_addr + offsetof(struct target_rt_sigframe, retcode);
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
/* Generate instruction: MOVI a2, __NR_rt_sigreturn */
|
||||
__put_user(0x22, &frame->retcode[0]);
|
||||
__put_user(0x0a, &frame->retcode[1]);
|
||||
__put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]);
|
||||
/* Generate instruction: SYSCALL */
|
||||
__put_user(0x00, &frame->retcode[3]);
|
||||
__put_user(0x05, &frame->retcode[4]);
|
||||
__put_user(0x00, &frame->retcode[5]);
|
||||
#else
|
||||
/* Generate instruction: MOVI a2, __NR_rt_sigreturn */
|
||||
__put_user(0x22, &frame->retcode[0]);
|
||||
__put_user(0xa0, &frame->retcode[1]);
|
||||
__put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]);
|
||||
/* Generate instruction: SYSCALL */
|
||||
__put_user(0x00, &frame->retcode[3]);
|
||||
__put_user(0x50, &frame->retcode[4]);
|
||||
__put_user(0x00, &frame->retcode[5]);
|
||||
#endif
|
||||
}
|
||||
env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER)) {
|
||||
env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT);
|
||||
}
|
||||
memset(env->regs, 0, sizeof(env->regs));
|
||||
env->pc = ka->_sa_handler;
|
||||
env->regs[1] = frame_addr;
|
||||
env->sregs[WINDOW_BASE] = 0;
|
||||
env->sregs[WINDOW_START] = 1;
|
||||
|
||||
env->regs[4] = (ra & 0x3fffffff) | 0x40000000;
|
||||
env->regs[6] = sig;
|
||||
env->regs[7] = frame_addr + offsetof(struct target_rt_sigframe, info);
|
||||
env->regs[8] = frame_addr + offsetof(struct target_rt_sigframe, uc);
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig);
|
||||
return;
|
||||
}
|
||||
|
||||
static void restore_sigcontext(CPUXtensaState *env,
|
||||
struct target_rt_sigframe *frame)
|
||||
{
|
||||
struct target_sigcontext *sc = &frame->uc.tuc_mcontext;
|
||||
uint32_t ps;
|
||||
int i;
|
||||
|
||||
__get_user(env->pc, &sc->sc_pc);
|
||||
__get_user(ps, &sc->sc_ps);
|
||||
__get_user(env->sregs[LBEG], &sc->sc_lbeg);
|
||||
__get_user(env->sregs[LEND], &sc->sc_lend);
|
||||
__get_user(env->sregs[LCOUNT], &sc->sc_lcount);
|
||||
|
||||
env->sregs[WINDOW_BASE] = 0;
|
||||
env->sregs[WINDOW_START] = 1;
|
||||
env->sregs[PS] = deposit32(env->sregs[PS],
|
||||
PS_CALLINC_SHIFT,
|
||||
PS_CALLINC_LEN,
|
||||
extract32(ps, PS_CALLINC_SHIFT,
|
||||
PS_CALLINC_LEN));
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__get_user(env->regs[i], sc->sc_a + i);
|
||||
}
|
||||
/* TODO: xtregs */
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUXtensaState *env)
|
||||
{
|
||||
abi_ulong frame_addr = env->regs[1];
|
||||
struct target_rt_sigframe *frame;
|
||||
sigset_t set;
|
||||
|
||||
trace_user_do_rt_sigreturn(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
|
||||
goto badframe;
|
||||
}
|
||||
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
|
||||
set_sigmask(&set);
|
||||
|
||||
restore_sigcontext(env, frame);
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -TARGET_EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#else
|
||||
#error Target needs to add support for signal handling
|
||||
#endif
|
||||
|
@ -7126,7 +7380,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
|
|||
|| defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) \
|
||||
|| defined(TARGET_PPC64) || defined(TARGET_HPPA) \
|
||||
|| defined(TARGET_NIOS2) || defined(TARGET_X86_64) \
|
||||
|| defined(TARGET_RISCV)
|
||||
|| defined(TARGET_RISCV) || defined(TARGET_XTENSA)
|
||||
/* These targets do not have traditional signals. */
|
||||
setup_rt_frame(sig, sa, &k->info, &target_old_set, cpu_env);
|
||||
#else
|
||||
|
|
|
@ -709,6 +709,8 @@ static inline int regpairs_aligned(void *cpu_env, int num)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
#elif defined(TARGET_XTENSA)
|
||||
static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
|
||||
#else
|
||||
static inline int regpairs_aligned(void *cpu_env, int num) { return 0; }
|
||||
#endif
|
||||
|
|
|
@ -71,7 +71,8 @@
|
|||
|| defined(TARGET_M68K) || defined(TARGET_CRIS) \
|
||||
|| defined(TARGET_S390X) \
|
||||
|| defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) \
|
||||
|| defined(TARGET_NIOS2) || defined(TARGET_RISCV)
|
||||
|| defined(TARGET_NIOS2) || defined(TARGET_RISCV) \
|
||||
|| defined(TARGET_XTENSA)
|
||||
|
||||
#define TARGET_IOC_SIZEBITS 14
|
||||
#define TARGET_IOC_DIRBITS 2
|
||||
|
@ -423,7 +424,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
|||
|| defined(TARGET_MICROBLAZE) \
|
||||
|| defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
|
||||
|| defined(TARGET_TILEGX) || defined(TARGET_HPPA) || defined(TARGET_NIOS2) \
|
||||
|| defined(TARGET_RISCV)
|
||||
|| defined(TARGET_RISCV) || defined(TARGET_XTENSA)
|
||||
|
||||
#if defined(TARGET_SPARC)
|
||||
#define TARGET_SA_NOCLDSTOP 8u
|
||||
|
@ -1379,6 +1380,18 @@ struct target_winsize {
|
|||
#define TARGET_MAP_NONBLOCK 0x20000 /* do not block on IO */
|
||||
#define TARGET_MAP_STACK 0x40000 /* ignored */
|
||||
#define TARGET_MAP_HUGETLB 0x80000 /* create a huge page mapping */
|
||||
#elif defined(TARGET_XTENSA)
|
||||
#define TARGET_MAP_FIXED 0x10 /* Interpret addr exactly */
|
||||
#define TARGET_MAP_ANONYMOUS 0x0800 /* don't use a file */
|
||||
#define TARGET_MAP_GROWSDOWN 0x1000 /* stack-like segment */
|
||||
#define TARGET_MAP_DENYWRITE 0x2000 /* ETXTBSY */
|
||||
#define TARGET_MAP_EXECUTABLE 0x4000 /* mark it as an executable */
|
||||
#define TARGET_MAP_LOCKED 0x8000 /* pages are locked */
|
||||
#define TARGET_MAP_NORESERVE 0x0400 /* don't check for reservations */
|
||||
#define TARGET_MAP_POPULATE 0x10000 /* populate (prefault) pagetables */
|
||||
#define TARGET_MAP_NONBLOCK 0x20000 /* do not block on IO */
|
||||
#define TARGET_MAP_STACK 0x40000
|
||||
#define TARGET_MAP_HUGETLB 0x80000 /* create a huge page mapping */
|
||||
#else
|
||||
#define TARGET_MAP_FIXED 0x10 /* Interpret addr exactly */
|
||||
#define TARGET_MAP_ANONYMOUS 0x20 /* don't use a file */
|
||||
|
@ -2080,6 +2093,51 @@ struct target_stat {
|
|||
abi_ulong target_st_ctime_nsec;
|
||||
unsigned int __unused[2];
|
||||
};
|
||||
#elif defined(TARGET_XTENSA)
|
||||
struct target_stat {
|
||||
abi_ulong st_dev;
|
||||
abi_ulong st_ino;
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
abi_ulong st_rdev;
|
||||
abi_long st_size;
|
||||
abi_ulong st_blksize;
|
||||
abi_ulong st_blocks;
|
||||
abi_ulong target_st_atime;
|
||||
abi_ulong target_st_atime_nsec;
|
||||
abi_ulong target_st_mtime;
|
||||
abi_ulong target_st_mtime_nsec;
|
||||
abi_ulong target_st_ctime;
|
||||
abi_ulong target_st_ctime_nsec;
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
uint64_t st_dev; /* Device */
|
||||
uint64_t st_ino; /* File serial number */
|
||||
unsigned int st_mode; /* File mode. */
|
||||
unsigned int st_nlink; /* Link count. */
|
||||
unsigned int st_uid; /* User ID of the file's owner. */
|
||||
unsigned int st_gid; /* Group ID of the file's group. */
|
||||
uint64_t st_rdev; /* Device number, if device. */
|
||||
int64_t st_size; /* Size of file, in bytes. */
|
||||
abi_ulong st_blksize; /* Optimal block size for I/O. */
|
||||
abi_ulong __unused2;
|
||||
uint64_t st_blocks; /* Number 512-byte blocks allocated. */
|
||||
abi_ulong target_st_atime; /* Time of last access. */
|
||||
abi_ulong target_st_atime_nsec;
|
||||
abi_ulong target_st_mtime; /* Time of last modification. */
|
||||
abi_ulong target_st_mtime_nsec;
|
||||
abi_ulong target_st_ctime; /* Time of last status change. */
|
||||
abi_ulong target_st_ctime_nsec;
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#elif defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) || \
|
||||
defined(TARGET_NIOS2) || defined(TARGET_RISCV)
|
||||
|
||||
|
@ -2590,7 +2648,8 @@ struct target_flock64 {
|
|||
short l_whence;
|
||||
#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) \
|
||||
|| defined(TARGET_SPARC) || defined(TARGET_HPPA) \
|
||||
|| defined(TARGET_MICROBLAZE) || defined(TARGET_TILEGX)
|
||||
|| defined(TARGET_MICROBLAZE) || defined(TARGET_TILEGX) \
|
||||
|| defined(TARGET_XTENSA)
|
||||
int __pad;
|
||||
#endif
|
||||
abi_llong l_start;
|
||||
|
|
0
linux-user/xtensa/syscall.h
Normal file
0
linux-user/xtensa/syscall.h
Normal file
437
linux-user/xtensa/syscall_nr.h
Normal file
437
linux-user/xtensa/syscall_nr.h
Normal file
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* include/asm-xtensa/unistd.h
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001 - 2009 Tensilica Inc.
|
||||
*/
|
||||
|
||||
#ifndef _XTENSA_UNISTD_H
|
||||
#define _XTENSA_UNISTD_H
|
||||
|
||||
#define TARGET_NR_spill 0
|
||||
#define TARGET_NR_xtensa 1
|
||||
#define TARGET_NR_available4 2
|
||||
#define TARGET_NR_available5 3
|
||||
#define TARGET_NR_available6 4
|
||||
#define TARGET_NR_available7 5
|
||||
#define TARGET_NR_available8 6
|
||||
#define TARGET_NR_available9 7
|
||||
|
||||
/* File Operations */
|
||||
|
||||
#define TARGET_NR_open 8
|
||||
#define TARGET_NR_close 9
|
||||
#define TARGET_NR_dup 10
|
||||
#define TARGET_NR_dup2 11
|
||||
#define TARGET_NR_read 12
|
||||
#define TARGET_NR_write 13
|
||||
#define TARGET_NR_select 14
|
||||
#define TARGET_NR_lseek 15
|
||||
#define TARGET_NR_poll 16
|
||||
#define TARGET_NR__llseek 17
|
||||
#define TARGET_NR_epoll_wait 18
|
||||
#define TARGET_NR_epoll_ctl 19
|
||||
#define TARGET_NR_epoll_create 20
|
||||
#define TARGET_NR_creat 21
|
||||
#define TARGET_NR_truncate 22
|
||||
#define TARGET_NR_ftruncate 23
|
||||
#define TARGET_NR_readv 24
|
||||
#define TARGET_NR_writev 25
|
||||
#define TARGET_NR_fsync 26
|
||||
#define TARGET_NR_fdatasync 27
|
||||
#define TARGET_NR_truncate64 28
|
||||
#define TARGET_NR_ftruncate64 29
|
||||
#define TARGET_NR_pread64 30
|
||||
#define TARGET_NR_pwrite64 31
|
||||
|
||||
#define TARGET_NR_link 32
|
||||
#define TARGET_NR_rename 33
|
||||
#define TARGET_NR_symlink 34
|
||||
#define TARGET_NR_readlink 35
|
||||
#define TARGET_NR_mknod 36
|
||||
#define TARGET_NR_pipe 37
|
||||
#define TARGET_NR_unlink 38
|
||||
#define TARGET_NR_rmdir 39
|
||||
|
||||
#define TARGET_NR_mkdir 40
|
||||
#define TARGET_NR_chdir 41
|
||||
#define TARGET_NR_fchdir 42
|
||||
#define TARGET_NR_getcwd 43
|
||||
|
||||
#define TARGET_NR_chmod 44
|
||||
#define TARGET_NR_chown 45
|
||||
#define TARGET_NR_stat 46
|
||||
#define TARGET_NR_stat64 47
|
||||
|
||||
#define TARGET_NR_lchown 48
|
||||
#define TARGET_NR_lstat 49
|
||||
#define TARGET_NR_lstat64 50
|
||||
#define TARGET_NR_available51 51
|
||||
|
||||
#define TARGET_NR_fchmod 52
|
||||
#define TARGET_NR_fchown 53
|
||||
#define TARGET_NR_fstat 54
|
||||
#define TARGET_NR_fstat64 55
|
||||
|
||||
#define TARGET_NR_flock 56
|
||||
#define TARGET_NR_access 57
|
||||
#define TARGET_NR_umask 58
|
||||
#define TARGET_NR_getdents 59
|
||||
#define TARGET_NR_getdents64 60
|
||||
#define TARGET_NR_fcntl64 61
|
||||
#define TARGET_NR_fallocate 62
|
||||
#define TARGET_NR_fadvise64_64 63
|
||||
#define TARGET_NR_utime 64 /* glibc 2.3.3 ?? */
|
||||
#define TARGET_NR_utimes 65
|
||||
#define TARGET_NR_ioctl 66
|
||||
#define TARGET_NR_fcntl 67
|
||||
|
||||
#define TARGET_NR_setxattr 68
|
||||
#define TARGET_NR_getxattr 69
|
||||
#define TARGET_NR_listxattr 70
|
||||
#define TARGET_NR_removexattr 71
|
||||
#define TARGET_NR_lsetxattr 72
|
||||
#define TARGET_NR_lgetxattr 73
|
||||
#define TARGET_NR_llistxattr 74
|
||||
#define TARGET_NR_lremovexattr 75
|
||||
#define TARGET_NR_fsetxattr 76
|
||||
#define TARGET_NR_fgetxattr 77
|
||||
#define TARGET_NR_flistxattr 78
|
||||
#define TARGET_NR_fremovexattr 79
|
||||
|
||||
/* File Map / Shared Memory Operations */
|
||||
|
||||
#define TARGET_NR_mmap2 80
|
||||
#define TARGET_NR_munmap 81
|
||||
#define TARGET_NR_mprotect 82
|
||||
#define TARGET_NR_brk 83
|
||||
#define TARGET_NR_mlock 84
|
||||
#define TARGET_NR_munlock 85
|
||||
#define TARGET_NR_mlockall 86
|
||||
#define TARGET_NR_munlockall 87
|
||||
#define TARGET_NR_mremap 88
|
||||
#define TARGET_NR_msync 89
|
||||
#define TARGET_NR_mincore 90
|
||||
#define TARGET_NR_madvise 91
|
||||
#define TARGET_NR_shmget 92
|
||||
#define TARGET_NR_shmat 93
|
||||
#define TARGET_NR_shmctl 94
|
||||
#define TARGET_NR_shmdt 95
|
||||
|
||||
/* Socket Operations */
|
||||
|
||||
#define TARGET_NR_socket 96
|
||||
#define TARGET_NR_setsockopt 97
|
||||
#define TARGET_NR_getsockopt 98
|
||||
#define TARGET_NR_shutdown 99
|
||||
|
||||
#define TARGET_NR_bind 100
|
||||
#define TARGET_NR_connect 101
|
||||
#define TARGET_NR_listen 102
|
||||
#define TARGET_NR_accept 103
|
||||
|
||||
#define TARGET_NR_getsockname 104
|
||||
#define TARGET_NR_getpeername 105
|
||||
#define TARGET_NR_sendmsg 106
|
||||
#define TARGET_NR_recvmsg 107
|
||||
#define TARGET_NR_send 108
|
||||
#define TARGET_NR_recv 109
|
||||
#define TARGET_NR_sendto 110
|
||||
#define TARGET_NR_recvfrom 111
|
||||
|
||||
#define TARGET_NR_socketpair 112
|
||||
#define TARGET_NR_sendfile 113
|
||||
#define TARGET_NR_sendfile64 114
|
||||
#define TARGET_NR_sendmmsg 115
|
||||
|
||||
/* Process Operations */
|
||||
|
||||
#define TARGET_NR_clone 116
|
||||
#define TARGET_NR_execve 117
|
||||
#define TARGET_NR_exit 118
|
||||
#define TARGET_NR_exit_group 119
|
||||
#define TARGET_NR_getpid 120
|
||||
#define TARGET_NR_wait4 121
|
||||
#define TARGET_NR_waitid 122
|
||||
#define TARGET_NR_kill 123
|
||||
#define TARGET_NR_tkill 124
|
||||
#define TARGET_NR_tgkill 125
|
||||
#define TARGET_NR_set_tid_address 126
|
||||
#define TARGET_NR_gettid 127
|
||||
#define TARGET_NR_setsid 128
|
||||
#define TARGET_NR_getsid 129
|
||||
#define TARGET_NR_prctl 130
|
||||
#define TARGET_NR_personality 131
|
||||
#define TARGET_NR_getpriority 132
|
||||
#define TARGET_NR_setpriority 133
|
||||
#define TARGET_NR_setitimer 134
|
||||
#define TARGET_NR_getitimer 135
|
||||
#define TARGET_NR_setuid 136
|
||||
#define TARGET_NR_getuid 137
|
||||
#define TARGET_NR_setgid 138
|
||||
#define TARGET_NR_getgid 139
|
||||
#define TARGET_NR_geteuid 140
|
||||
#define TARGET_NR_getegid 141
|
||||
#define TARGET_NR_setreuid 142
|
||||
#define TARGET_NR_setregid 143
|
||||
#define TARGET_NR_setresuid 144
|
||||
#define TARGET_NR_getresuid 145
|
||||
#define TARGET_NR_setresgid 146
|
||||
#define TARGET_NR_getresgid 147
|
||||
#define TARGET_NR_setpgid 148
|
||||
#define TARGET_NR_getpgid 149
|
||||
#define TARGET_NR_getppid 150
|
||||
#define TARGET_NR_getpgrp 151
|
||||
|
||||
#define TARGET_NR_reserved152 152 /* set_thread_area */
|
||||
#define TARGET_NR_reserved153 153 /* get_thread_area */
|
||||
#define TARGET_NR_times 154
|
||||
#define TARGET_NR_acct 155
|
||||
#define TARGET_NR_sched_setaffinity 156
|
||||
#define TARGET_NR_sched_getaffinity 157
|
||||
#define TARGET_NR_capget 158
|
||||
#define TARGET_NR_capset 159
|
||||
#define TARGET_NR_ptrace 160
|
||||
#define TARGET_NR_semtimedop 161
|
||||
#define TARGET_NR_semget 162
|
||||
#define TARGET_NR_semop 163
|
||||
#define TARGET_NR_semctl 164
|
||||
#define TARGET_NR_available165 165
|
||||
#define TARGET_NR_msgget 166
|
||||
#define TARGET_NR_msgsnd 167
|
||||
#define TARGET_NR_msgrcv 168
|
||||
#define TARGET_NR_msgctl 169
|
||||
#define TARGET_NR_available170 170
|
||||
|
||||
/* File System */
|
||||
|
||||
#define TARGET_NR_umount2 171
|
||||
#define TARGET_NR_mount 172
|
||||
#define TARGET_NR_swapon 173
|
||||
#define TARGET_NR_chroot 174
|
||||
#define TARGET_NR_pivot_root 175
|
||||
#define TARGET_NR_umount 176
|
||||
#define TARGET_NR_swapoff 177
|
||||
#define TARGET_NR_sync 178
|
||||
#define TARGET_NR_syncfs 179
|
||||
#define TARGET_NR_setfsuid 180
|
||||
#define TARGET_NR_setfsgid 181
|
||||
#define TARGET_NR_sysfs 182
|
||||
#define TARGET_NR_ustat 183
|
||||
#define TARGET_NR_statfs 184
|
||||
#define TARGET_NR_fstatfs 185
|
||||
#define TARGET_NR_statfs64 186
|
||||
#define TARGET_NR_fstatfs64 187
|
||||
|
||||
/* System */
|
||||
|
||||
#define TARGET_NR_setrlimit 188
|
||||
#define TARGET_NR_getrlimit 189
|
||||
#define TARGET_NR_getrusage 190
|
||||
#define TARGET_NR_futex 191
|
||||
#define TARGET_NR_gettimeofday 192
|
||||
#define TARGET_NR_settimeofday 193
|
||||
#define TARGET_NR_adjtimex 194
|
||||
#define TARGET_NR_nanosleep 195
|
||||
#define TARGET_NR_getgroups 196
|
||||
#define TARGET_NR_setgroups 197
|
||||
#define TARGET_NR_sethostname 198
|
||||
#define TARGET_NR_setdomainname 199
|
||||
#define TARGET_NR_syslog 200
|
||||
#define TARGET_NR_vhangup 201
|
||||
#define TARGET_NR_uselib 202
|
||||
#define TARGET_NR_reboot 203
|
||||
#define TARGET_NR_quotactl 204
|
||||
#define TARGET_NR_nfsservctl 205
|
||||
#define TARGET_NR__sysctl 206
|
||||
#define TARGET_NR_bdflush 207
|
||||
#define TARGET_NR_uname 208
|
||||
#define TARGET_NR_sysinfo 209
|
||||
#define TARGET_NR_init_module 210
|
||||
#define TARGET_NR_delete_module 211
|
||||
|
||||
#define TARGET_NR_sched_setparam 212
|
||||
#define TARGET_NR_sched_getparam 213
|
||||
#define TARGET_NR_sched_setscheduler 214
|
||||
#define TARGET_NR_sched_getscheduler 215
|
||||
#define TARGET_NR_sched_get_priority_max 216
|
||||
#define TARGET_NR_sched_get_priority_min 217
|
||||
#define TARGET_NR_sched_rr_get_interval 218
|
||||
#define TARGET_NR_sched_yield 219
|
||||
#define TARGET_NR_available222 222
|
||||
|
||||
/* Signal Handling */
|
||||
|
||||
#define TARGET_NR_restart_syscall 223
|
||||
#define TARGET_NR_sigaltstack 224
|
||||
#define TARGET_NR_rt_sigreturn 225
|
||||
#define TARGET_NR_rt_sigaction 226
|
||||
#define TARGET_NR_rt_sigprocmask 227
|
||||
#define TARGET_NR_rt_sigpending 228
|
||||
#define TARGET_NR_rt_sigtimedwait 229
|
||||
#define TARGET_NR_rt_sigqueueinfo 230
|
||||
#define TARGET_NR_rt_sigsuspend 231
|
||||
|
||||
/* Message */
|
||||
|
||||
#define TARGET_NR_mq_open 232
|
||||
#define TARGET_NR_mq_unlink 233
|
||||
#define TARGET_NR_mq_timedsend 234
|
||||
#define TARGET_NR_mq_timedreceive 235
|
||||
#define TARGET_NR_mq_notify 236
|
||||
#define TARGET_NR_mq_getsetattr 237
|
||||
#define TARGET_NR_available238 238
|
||||
|
||||
/* IO */
|
||||
|
||||
#define TARGET_NR_io_setup 239
|
||||
#define TARGET_NR_io_destroy 240
|
||||
#define TARGET_NR_io_submit 241
|
||||
#define TARGET_NR_io_getevents 242
|
||||
#define TARGET_NR_io_cancel 243
|
||||
#define TARGET_NR_clock_settime 244
|
||||
#define TARGET_NR_clock_gettime 245
|
||||
#define TARGET_NR_clock_getres 246
|
||||
#define TARGET_NR_clock_nanosleep 247
|
||||
|
||||
/* Timer */
|
||||
|
||||
#define TARGET_NR_timer_create 248
|
||||
#define TARGET_NR_timer_delete 249
|
||||
#define TARGET_NR_timer_settime 250
|
||||
#define TARGET_NR_timer_gettime 251
|
||||
#define TARGET_NR_timer_getoverrun 252
|
||||
|
||||
/* System */
|
||||
|
||||
#define TARGET_NR_reserved253 253
|
||||
#define TARGET_NR_lookup_dcookie 254
|
||||
#define TARGET_NR_available255 255
|
||||
#define TARGET_NR_add_key 256
|
||||
#define TARGET_NR_request_key 257
|
||||
#define TARGET_NR_keyctl 258
|
||||
#define TARGET_NR_available259 259
|
||||
|
||||
|
||||
#define TARGET_NR_readahead 260
|
||||
#define TARGET_NR_remap_file_pages 261
|
||||
#define TARGET_NR_migrate_pages 262
|
||||
#define TARGET_NR_mbind 263
|
||||
#define TARGET_NR_get_mempolicy 264
|
||||
#define TARGET_NR_set_mempolicy 265
|
||||
#define TARGET_NR_unshare 266
|
||||
#define TARGET_NR_move_pages 267
|
||||
#define TARGET_NR_splice 268
|
||||
#define TARGET_NR_tee 269
|
||||
#define TARGET_NR_vmsplice 270
|
||||
#define TARGET_NR_available271 271
|
||||
|
||||
#define TARGET_NR_pselect6 272
|
||||
#define TARGET_NR_ppoll 273
|
||||
#define TARGET_NR_epoll_pwait 274
|
||||
#define TARGET_NR_epoll_create1 275
|
||||
|
||||
#define TARGET_NR_inotify_init 276
|
||||
#define TARGET_NR_inotify_add_watch 277
|
||||
#define TARGET_NR_inotify_rm_watch 278
|
||||
#define TARGET_NR_inotify_init1 279
|
||||
|
||||
#define TARGET_NR_getcpu 280
|
||||
#define TARGET_NR_kexec_load 281
|
||||
|
||||
#define TARGET_NR_ioprio_set 282
|
||||
#define TARGET_NR_ioprio_get 283
|
||||
|
||||
#define TARGET_NR_set_robust_list 284
|
||||
#define TARGET_NR_get_robust_list 285
|
||||
#define TARGET_NR_available286 286
|
||||
#define TARGET_NR_available287 287
|
||||
|
||||
/* Relative File Operations */
|
||||
|
||||
#define TARGET_NR_openat 288
|
||||
#define TARGET_NR_mkdirat 289
|
||||
#define TARGET_NR_mknodat 290
|
||||
#define TARGET_NR_unlinkat 291
|
||||
#define TARGET_NR_renameat 292
|
||||
#define TARGET_NR_linkat 293
|
||||
#define TARGET_NR_symlinkat 294
|
||||
#define TARGET_NR_readlinkat 295
|
||||
#define TARGET_NR_utimensat 296
|
||||
#define TARGET_NR_fchownat 297
|
||||
#define TARGET_NR_futimesat 298
|
||||
#define TARGET_NR_fstatat64 299
|
||||
#define TARGET_NR_fchmodat 300
|
||||
#define TARGET_NR_faccessat 301
|
||||
#define TARGET_NR_available302 302
|
||||
#define TARGET_NR_available303 303
|
||||
|
||||
#define TARGET_NR_signalfd 304
|
||||
/* 305 was TARGET_NR_timerfd */
|
||||
#define TARGET_NR_eventfd 306
|
||||
#define TARGET_NR_recvmmsg 307
|
||||
|
||||
#define TARGET_NR_setns 308
|
||||
#define TARGET_NR_signalfd4 309
|
||||
#define TARGET_NR_dup3 310
|
||||
#define TARGET_NR_pipe2 311
|
||||
|
||||
#define TARGET_NR_timerfd_create 312
|
||||
#define TARGET_NR_timerfd_settime 313
|
||||
#define TARGET_NR_timerfd_gettime 314
|
||||
#define TARGET_NR_available315 315
|
||||
|
||||
#define TARGET_NR_eventfd2 316
|
||||
#define TARGET_NR_preadv 317
|
||||
#define TARGET_NR_pwritev 318
|
||||
#define TARGET_NR_available319 319
|
||||
|
||||
#define TARGET_NR_fanotify_init 320
|
||||
#define TARGET_NR_fanotify_mark 321
|
||||
#define TARGET_NR_process_vm_readv 322
|
||||
#define TARGET_NR_process_vm_writev 323
|
||||
|
||||
#define TARGET_NR_name_to_handle_at 324
|
||||
#define TARGET_NR_open_by_handle_at 325
|
||||
#define TARGET_NR_sync_file_range2 326
|
||||
#define TARGET_NR_perf_event_open 327
|
||||
|
||||
#define TARGET_NR_rt_tgsigqueueinfo 328
|
||||
#define TARGET_NR_clock_adjtime 329
|
||||
#define TARGET_NR_prlimit64 330
|
||||
#define TARGET_NR_kcmp 331
|
||||
|
||||
#define TARGET_NR_finit_module 332
|
||||
|
||||
#define TARGET_NR_accept4 333
|
||||
|
||||
#define TARGET_NR_sched_setattr 334
|
||||
#define TARGET_NR_sched_getattr 335
|
||||
|
||||
#define TARGET_NR_renameat2 336
|
||||
|
||||
#define TARGET_NR_seccomp 337
|
||||
#define TARGET_NR_getrandom 338
|
||||
#define TARGET_NR_memfd_create 339
|
||||
#define TARGET_NR_bpf 340
|
||||
#define TARGET_NR_execveat 341
|
||||
|
||||
#define TARGET_NR_userfaultfd 342
|
||||
#define TARGET_NR_membarrier 343
|
||||
#define TARGET_NR_mlock2 344
|
||||
#define TARGET_NR_copy_file_range 345
|
||||
#define TARGET_NR_preadv2 346
|
||||
#define TARGET_NR_pwritev2 347
|
||||
|
||||
#define TARGET_NR_pkey_mprotect 348
|
||||
#define TARGET_NR_pkey_alloc 349
|
||||
#define TARGET_NR_pkey_free 350
|
||||
|
||||
#define TARGET_NR_statx 351
|
||||
|
||||
#define TARGET_NR_syscall_count 352
|
||||
|
||||
#endif /* _XTENSA_UNISTD_H */
|
22
linux-user/xtensa/target_cpu.h
Normal file
22
linux-user/xtensa/target_cpu.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Xtensa-specific CPU ABI and functions for linux-user
|
||||
*/
|
||||
#ifndef XTENSA_TARGET_CPU_H
|
||||
#define XTENSA_TARGET_CPU_H
|
||||
|
||||
static inline void cpu_clone_regs(CPUXtensaState *env, target_ulong newsp)
|
||||
{
|
||||
if (newsp) {
|
||||
env->regs[1] = newsp;
|
||||
env->sregs[WINDOW_BASE] = 0;
|
||||
env->sregs[WINDOW_START] = 0x1;
|
||||
}
|
||||
env->regs[2] = 0;
|
||||
}
|
||||
|
||||
static inline void cpu_set_tls(CPUXtensaState *env, target_ulong newtls)
|
||||
{
|
||||
env->uregs[THREADPTR] = newtls;
|
||||
}
|
||||
|
||||
#endif
|
16
linux-user/xtensa/target_elf.h
Normal file
16
linux-user/xtensa/target_elf.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation, or (at your option) any
|
||||
* later version. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef XTENSA_TARGET_ELF_H
|
||||
#define XTENSA_TARGET_ELF_H
|
||||
|
||||
static inline const char *cpu_get_model(uint32_t eflags)
|
||||
{
|
||||
return XTENSA_DEFAULT_CPU_MODEL;
|
||||
}
|
||||
|
||||
#endif
|
28
linux-user/xtensa/target_signal.h
Normal file
28
linux-user/xtensa/target_signal.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef XTENSA_TARGET_SIGNAL_H
|
||||
#define XTENSA_TARGET_SIGNAL_H
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
/* this struct defines a stack used during syscall handling */
|
||||
|
||||
typedef struct target_sigaltstack {
|
||||
abi_ulong ss_sp;
|
||||
abi_int ss_flags;
|
||||
abi_ulong ss_size;
|
||||
} target_stack_t;
|
||||
|
||||
/*
|
||||
* sigaltstack controls
|
||||
*/
|
||||
#define TARGET_SS_ONSTACK 1
|
||||
#define TARGET_SS_DISABLE 2
|
||||
|
||||
#define TARGET_MINSIGSTKSZ 2048
|
||||
#define TARGET_SIGSTKSZ 8192
|
||||
|
||||
static inline abi_ulong get_sp_from_cpustate(CPUXtensaState *state)
|
||||
{
|
||||
return state->regs[1];
|
||||
}
|
||||
|
||||
#endif
|
28
linux-user/xtensa/target_structs.h
Normal file
28
linux-user/xtensa/target_structs.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef XTENSA_TARGET_STRUCTS_T
|
||||
#define XTENSA_TARGET_STRUCTS_T
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_uint mode; /* Read/write permission. */
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_int shm_segsz; /* size of segment in bytes */
|
||||
abi_long shm_atime; /* time of last shmat() */
|
||||
abi_long shm_dtime; /* time of last shmdt() */
|
||||
abi_long shm_ctime; /* time of last change by shmctl() */
|
||||
abi_ushort shm_cpid; /* pid of creator */
|
||||
abi_ushort shm_lpid; /* pid of last shmop */
|
||||
abi_ushort shm_nattch; /* number of current attaches */
|
||||
abi_ushort shm_unused; /* compatibility */
|
||||
abi_ulong __unused2;
|
||||
abi_ulong __unused3;
|
||||
};
|
||||
|
||||
#endif
|
49
linux-user/xtensa/target_syscall.h
Normal file
49
linux-user/xtensa/target_syscall.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
#ifndef XTENSA_TARGET_SYSCALL_H
|
||||
#define XTENSA_TARGET_SYSCALL_H
|
||||
|
||||
#define UNAME_MACHINE "xtensa"
|
||||
|
||||
#define UNAME_MINIMUM_RELEASE "3.19"
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
#define MMAP_SHIFT TARGET_PAGE_BITS
|
||||
|
||||
typedef uint32_t xtensa_reg_t;
|
||||
typedef struct {
|
||||
} xtregs_opt_t; /* TODO */
|
||||
|
||||
struct target_pt_regs {
|
||||
xtensa_reg_t pc; /* 4 */
|
||||
xtensa_reg_t ps; /* 8 */
|
||||
xtensa_reg_t depc; /* 12 */
|
||||
xtensa_reg_t exccause; /* 16 */
|
||||
xtensa_reg_t excvaddr; /* 20 */
|
||||
xtensa_reg_t debugcause; /* 24 */
|
||||
xtensa_reg_t wmask; /* 28 */
|
||||
xtensa_reg_t lbeg; /* 32 */
|
||||
xtensa_reg_t lend; /* 36 */
|
||||
xtensa_reg_t lcount; /* 40 */
|
||||
xtensa_reg_t sar; /* 44 */
|
||||
xtensa_reg_t windowbase; /* 48 */
|
||||
xtensa_reg_t windowstart; /* 52 */
|
||||
xtensa_reg_t syscall; /* 56 */
|
||||
xtensa_reg_t icountlevel; /* 60 */
|
||||
xtensa_reg_t scompare1; /* 64 */
|
||||
xtensa_reg_t threadptr; /* 68 */
|
||||
|
||||
/* Additional configurable registers that are used by the compiler. */
|
||||
xtregs_opt_t xtregs_opt;
|
||||
|
||||
/* Make sure the areg field is 16 bytes aligned. */
|
||||
int align[0] __attribute__ ((aligned(16)));
|
||||
|
||||
/* current register frame.
|
||||
* Note: The ESF for kernel exceptions ends after 16 registers!
|
||||
*/
|
||||
xtensa_reg_t areg[16];
|
||||
};
|
||||
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
|
||||
#endif
|
328
linux-user/xtensa/termbits.h
Normal file
328
linux-user/xtensa/termbits.h
Normal file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* include/asm-xtensa/termbits.h
|
||||
*
|
||||
* Copied from SH.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001 - 2005 Tensilica Inc.
|
||||
*/
|
||||
|
||||
#ifndef _XTENSA_TERMBITS_H
|
||||
#define _XTENSA_TERMBITS_H
|
||||
|
||||
#include <linux/posix_types.h>
|
||||
|
||||
typedef unsigned char cc_t;
|
||||
typedef unsigned int speed_t;
|
||||
typedef unsigned int tcflag_t;
|
||||
|
||||
#define TARGET_NCCS 19
|
||||
struct target_termios {
|
||||
tcflag_t c_iflag; /* input mode flags */
|
||||
tcflag_t c_oflag; /* output mode flags */
|
||||
tcflag_t c_cflag; /* control mode flags */
|
||||
tcflag_t c_lflag; /* local mode flags */
|
||||
cc_t c_line; /* line discipline */
|
||||
cc_t c_cc[TARGET_NCCS]; /* control characters */
|
||||
};
|
||||
|
||||
struct target_termios2 {
|
||||
tcflag_t c_iflag; /* input mode flags */
|
||||
tcflag_t c_oflag; /* output mode flags */
|
||||
tcflag_t c_cflag; /* control mode flags */
|
||||
tcflag_t c_lflag; /* local mode flags */
|
||||
cc_t c_line; /* line discipline */
|
||||
cc_t c_cc[TARGET_NCCS]; /* control characters */
|
||||
speed_t c_ispeed; /* input speed */
|
||||
speed_t c_ospeed; /* output speed */
|
||||
};
|
||||
|
||||
struct target_ktermios {
|
||||
tcflag_t c_iflag; /* input mode flags */
|
||||
tcflag_t c_oflag; /* output mode flags */
|
||||
tcflag_t c_cflag; /* control mode flags */
|
||||
tcflag_t c_lflag; /* local mode flags */
|
||||
cc_t c_line; /* line discipline */
|
||||
cc_t c_cc[TARGET_NCCS]; /* control characters */
|
||||
speed_t c_ispeed; /* input speed */
|
||||
speed_t c_ospeed; /* output speed */
|
||||
};
|
||||
|
||||
/* c_cc characters */
|
||||
|
||||
#define TARGET_VINTR 0
|
||||
#define TARGET_VQUIT 1
|
||||
#define TARGET_VERASE 2
|
||||
#define TARGET_VKILL 3
|
||||
#define TARGET_VEOF 4
|
||||
#define TARGET_VTIME 5
|
||||
#define TARGET_VMIN 6
|
||||
#define TARGET_VSWTC 7
|
||||
#define TARGET_VSTART 8
|
||||
#define TARGET_VSTOP 9
|
||||
#define TARGET_VSUSP 10
|
||||
#define TARGET_VEOL 11
|
||||
#define TARGET_VREPRINT 12
|
||||
#define TARGET_VDISCARD 13
|
||||
#define TARGET_VWERASE 14
|
||||
#define TARGET_VLNEXT 15
|
||||
#define TARGET_VEOL2 16
|
||||
|
||||
/* c_iflag bits */
|
||||
|
||||
#define TARGET_IGNBRK 0000001
|
||||
#define TARGET_BRKINT 0000002
|
||||
#define TARGET_IGNPAR 0000004
|
||||
#define TARGET_PARMRK 0000010
|
||||
#define TARGET_INPCK 0000020
|
||||
#define TARGET_ISTRIP 0000040
|
||||
#define TARGET_INLCR 0000100
|
||||
#define TARGET_IGNCR 0000200
|
||||
#define TARGET_ICRNL 0000400
|
||||
#define TARGET_IUCLC 0001000
|
||||
#define TARGET_IXON 0002000
|
||||
#define TARGET_IXANY 0004000
|
||||
#define TARGET_IXOFF 0010000
|
||||
#define TARGET_IMAXBEL 0020000
|
||||
#define TARGET_IUTF8 0040000
|
||||
|
||||
/* c_oflag bits */
|
||||
|
||||
#define TARGET_OPOST 0000001
|
||||
#define TARGET_OLCUC 0000002
|
||||
#define TARGET_ONLCR 0000004
|
||||
#define TARGET_OCRNL 0000010
|
||||
#define TARGET_ONOCR 0000020
|
||||
#define TARGET_ONLRET 0000040
|
||||
#define TARGET_OFILL 0000100
|
||||
#define TARGET_OFDEL 0000200
|
||||
#define TARGET_NLDLY 0000400
|
||||
#define TARGET_NL0 0000000
|
||||
#define TARGET_NL1 0000400
|
||||
#define TARGET_CRDLY 0003000
|
||||
#define TARGET_CR0 0000000
|
||||
#define TARGET_CR1 0001000
|
||||
#define TARGET_CR2 0002000
|
||||
#define TARGET_CR3 0003000
|
||||
#define TARGET_TABDLY 0014000
|
||||
#define TARGET_TAB0 0000000
|
||||
#define TARGET_TAB1 0004000
|
||||
#define TARGET_TAB2 0010000
|
||||
#define TARGET_TAB3 0014000
|
||||
#define TARGET_XTABS 0014000
|
||||
#define TARGET_BSDLY 0020000
|
||||
#define TARGET_BS0 0000000
|
||||
#define TARGET_BS1 0020000
|
||||
#define TARGET_VTDLY 0040000
|
||||
#define TARGET_VT0 0000000
|
||||
#define TARGET_VT1 0040000
|
||||
#define TARGET_FFDLY 0100000
|
||||
#define TARGET_FF0 0000000
|
||||
#define TARGET_FF1 0100000
|
||||
|
||||
/* c_cflag bit meaning */
|
||||
|
||||
#define TARGET_CBAUD 0010017
|
||||
#define TARGET_B0 0000000 /* hang up */
|
||||
#define TARGET_B50 0000001
|
||||
#define TARGET_B75 0000002
|
||||
#define TARGET_B110 0000003
|
||||
#define TARGET_B134 0000004
|
||||
#define TARGET_B150 0000005
|
||||
#define TARGET_B200 0000006
|
||||
#define TARGET_B300 0000007
|
||||
#define TARGET_B600 0000010
|
||||
#define TARGET_B1200 0000011
|
||||
#define TARGET_B1800 0000012
|
||||
#define TARGET_B2400 0000013
|
||||
#define TARGET_B4800 0000014
|
||||
#define TARGET_B9600 0000015
|
||||
#define TARGET_B19200 0000016
|
||||
#define TARGET_B38400 0000017
|
||||
#define TARGET_EXTA B19200
|
||||
#define TARGET_EXTB B38400
|
||||
#define TARGET_CSIZE 0000060
|
||||
#define TARGET_CS5 0000000
|
||||
#define TARGET_CS6 0000020
|
||||
#define TARGET_CS7 0000040
|
||||
#define TARGET_CS8 0000060
|
||||
#define TARGET_CSTOPB 0000100
|
||||
#define TARGET_CREAD 0000200
|
||||
#define TARGET_PARENB 0000400
|
||||
#define TARGET_PARODD 0001000
|
||||
#define TARGET_HUPCL 0002000
|
||||
#define TARGET_CLOCAL 0004000
|
||||
#define TARGET_CBAUDEX 0010000
|
||||
#define TARGET_BOTHER 0010000
|
||||
#define TARGET_B57600 0010001
|
||||
#define TARGET_B115200 0010002
|
||||
#define TARGET_B230400 0010003
|
||||
#define TARGET_B460800 0010004
|
||||
#define TARGET_B500000 0010005
|
||||
#define TARGET_B576000 0010006
|
||||
#define TARGET_B921600 0010007
|
||||
#define TARGET_B1000000 0010010
|
||||
#define TARGET_B1152000 0010011
|
||||
#define TARGET_B1500000 0010012
|
||||
#define TARGET_B2000000 0010013
|
||||
#define TARGET_B2500000 0010014
|
||||
#define TARGET_B3000000 0010015
|
||||
#define TARGET_B3500000 0010016
|
||||
#define TARGET_B4000000 0010017
|
||||
#define TARGET_CIBAUD 002003600000 /* input baud rate */
|
||||
#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */
|
||||
#define TARGET_CRTSCTS 020000000000 /* flow control */
|
||||
|
||||
#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
|
||||
|
||||
/* c_lflag bits */
|
||||
|
||||
#define TARGET_ISIG 0000001
|
||||
#define TARGET_ICANON 0000002
|
||||
#define TARGET_XCASE 0000004
|
||||
#define TARGET_ECHO 0000010
|
||||
#define TARGET_ECHOE 0000020
|
||||
#define TARGET_ECHOK 0000040
|
||||
#define TARGET_ECHONL 0000100
|
||||
#define TARGET_NOFLSH 0000200
|
||||
#define TARGET_TOSTOP 0000400
|
||||
#define TARGET_ECHOCTL 0001000
|
||||
#define TARGET_ECHOPRT 0002000
|
||||
#define TARGET_ECHOKE 0004000
|
||||
#define TARGET_FLUSHO 0010000
|
||||
#define TARGET_PENDIN 0040000
|
||||
#define TARGET_IEXTEN 0100000
|
||||
|
||||
/* tcflow() and TCXONC use these */
|
||||
|
||||
#define TARGET_TCOOFF 0
|
||||
#define TARGET_TCOON 1
|
||||
#define TARGET_TCIOFF 2
|
||||
#define TARGET_TCION 3
|
||||
|
||||
/* tcflush() and TCFLSH use these */
|
||||
|
||||
#define TARGET_TCIFLUSH 0
|
||||
#define TARGET_TCOFLUSH 1
|
||||
#define TARGET_TCIOFLUSH 2
|
||||
|
||||
/* tcsetattr uses these */
|
||||
|
||||
#define TARGET_TCSANOW 0
|
||||
#define TARGET_TCSADRAIN 1
|
||||
#define TARGET_TCSAFLUSH 2
|
||||
|
||||
/* from arch/xtensa/include/uapi/asm/ioctls.h */
|
||||
|
||||
#define TARGET_FIOCLEX _IO('f', 1)
|
||||
#define TARGET_FIONCLEX _IO('f', 2)
|
||||
#define TARGET_FIOASYNC _IOW('f', 125, int)
|
||||
#define TARGET_FIONBIO _IOW('f', 126, int)
|
||||
#define TARGET_FIONREAD _IOR('f', 127, int)
|
||||
#define TARGET_TIOCINQ FIONREAD
|
||||
#define TARGET_FIOQSIZE _IOR('f', 128, loff_t)
|
||||
|
||||
#define TARGET_TCGETS 0x5401
|
||||
#define TARGET_TCSETS 0x5402
|
||||
#define TARGET_TCSETSW 0x5403
|
||||
#define TARGET_TCSETSF 0x5404
|
||||
|
||||
#define TARGET_TCGETA 0x80127417 /* _IOR('t', 23, struct termio) */
|
||||
#define TARGET_TCSETA 0x40127418 /* _IOW('t', 24, struct termio) */
|
||||
#define TARGET_TCSETAW 0x40127419 /* _IOW('t', 25, struct termio) */
|
||||
#define TARGET_TCSETAF 0x4012741C /* _IOW('t', 28, struct termio) */
|
||||
|
||||
#define TARGET_TCSBRK _IO('t', 29)
|
||||
#define TARGET_TCXONC _IO('t', 30)
|
||||
#define TARGET_TCFLSH _IO('t', 31)
|
||||
|
||||
#define TARGET_TIOCSWINSZ 0x40087467 /* _IOW('t', 103, struct winsize) */
|
||||
#define TARGET_TIOCGWINSZ 0x80087468 /* _IOR('t', 104, struct winsize) */
|
||||
#define TARGET_TIOCSTART _IO('t', 110) /* start output, like ^Q */
|
||||
#define TARGET_TIOCSTOP _IO('t', 111) /* stop output, like ^S */
|
||||
#define TARGET_TIOCOUTQ _IOR('t', 115, int) /* output queue size */
|
||||
|
||||
#define TARGET_TIOCSPGRP _IOW('t', 118, int)
|
||||
#define TARGET_TIOCGPGRP _IOR('t', 119, int)
|
||||
|
||||
#define TARGET_TIOCEXCL _IO('T', 12)
|
||||
#define TARGET_TIOCNXCL _IO('T', 13)
|
||||
#define TARGET_TIOCSCTTY _IO('T', 14)
|
||||
|
||||
#define TARGET_TIOCSTI _IOW('T', 18, char)
|
||||
#define TARGET_TIOCMGET _IOR('T', 21, unsigned int)
|
||||
#define TARGET_TIOCMBIS _IOW('T', 22, unsigned int)
|
||||
#define TARGET_TIOCMBIC _IOW('T', 23, unsigned int)
|
||||
#define TARGET_TIOCMSET _IOW('T', 24, unsigned int)
|
||||
# define TARGET_TIOCM_LE 0x001
|
||||
# define TARGET_TIOCM_DTR 0x002
|
||||
# define TARGET_TIOCM_RTS 0x004
|
||||
# define TARGET_TIOCM_ST 0x008
|
||||
# define TARGET_TIOCM_SR 0x010
|
||||
# define TARGET_TIOCM_CTS 0x020
|
||||
# define TARGET_TIOCM_CAR 0x040
|
||||
# define TARGET_TIOCM_RNG 0x080
|
||||
# define TARGET_TIOCM_DSR 0x100
|
||||
# define TARGET_TIOCM_CD TIOCM_CAR
|
||||
# define TARGET_TIOCM_RI TIOCM_RNG
|
||||
|
||||
#define TARGET_TIOCGSOFTCAR _IOR('T', 25, unsigned int)
|
||||
#define TARGET_TIOCSSOFTCAR _IOW('T', 26, unsigned int)
|
||||
#define TARGET_TIOCLINUX _IOW('T', 28, char)
|
||||
#define TARGET_TIOCCONS _IO('T', 29)
|
||||
#define TARGET_TIOCGSERIAL 0x803C541E /*_IOR('T', 30, struct serial_struct)*/
|
||||
#define TARGET_TIOCSSERIAL 0x403C541F /*_IOW('T', 31, struct serial_struct)*/
|
||||
#define TARGET_TIOCPKT _IOW('T', 32, int)
|
||||
# define TARGET_TIOCPKT_DATA 0
|
||||
# define TARGET_TIOCPKT_FLUSHREAD 1
|
||||
# define TARGET_TIOCPKT_FLUSHWRITE 2
|
||||
# define TARGET_TIOCPKT_STOP 4
|
||||
# define TARGET_TIOCPKT_START 8
|
||||
# define TARGET_TIOCPKT_NOSTOP 16
|
||||
# define TARGET_TIOCPKT_DOSTOP 32
|
||||
# define TARGET_TIOCPKT_IOCTL 64
|
||||
|
||||
|
||||
#define TARGET_TIOCNOTTY _IO('T', 34)
|
||||
#define TARGET_TIOCSETD _IOW('T', 35, int)
|
||||
#define TARGET_TIOCGETD _IOR('T', 36, int)
|
||||
#define TARGET_TCSBRKP _IOW('T', 37, int) /* Needed for POSIX tcsendbreak()*/
|
||||
#define TARGET_TIOCSBRK _IO('T', 39) /* BSD compatibility */
|
||||
#define TARGET_TIOCCBRK _IO('T', 40) /* BSD compatibility */
|
||||
#define TARGET_TIOCGSID _IOR('T', 41, pid_t) /* Return the session ID of FD*/
|
||||
#define TARGET_TCGETS2 _IOR('T', 42, struct termios2)
|
||||
#define TARGET_TCSETS2 _IOW('T', 43, struct termios2)
|
||||
#define TARGET_TCSETSW2 _IOW('T', 44, struct termios2)
|
||||
#define TARGET_TCSETSF2 _IOW('T', 45, struct termios2)
|
||||
#define TARGET_TIOCGRS485 _IOR('T', 46, struct serial_rs485)
|
||||
#define TARGET_TIOCSRS485 _IOWR('T', 47, struct serial_rs485)
|
||||
#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
|
||||
#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
|
||||
#define TARGET_TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
||||
#define TARGET_TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
||||
#define TARGET_TIOCVHANGUP _IO('T', 0x37)
|
||||
#define TARGET_TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||
#define TARGET_TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||
#define TARGET_TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||
#define TARGET_TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
|
||||
|
||||
#define TARGET_TIOCSERCONFIG _IO('T', 83)
|
||||
#define TARGET_TIOCSERGWILD _IOR('T', 84, int)
|
||||
#define TARGET_TIOCSERSWILD _IOW('T', 85, int)
|
||||
#define TARGET_TIOCGLCKTRMIOS 0x5456
|
||||
#define TARGET_TIOCSLCKTRMIOS 0x5457
|
||||
#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
|
||||
#define TARGET_TIOCSERGETLSR _IOR('T', 89, unsigned int) /* Get line status reg. */
|
||||
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
|
||||
# define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
|
||||
#define TARGET_TIOCSERGETMULTI 0x80a8545a /* Get multiport config */
|
||||
/* _IOR('T', 90, struct serial_multiport_struct) */
|
||||
#define TARGET_TIOCSERSETMULTI 0x40a8545b /* Set multiport config */
|
||||
/* _IOW('T', 91, struct serial_multiport_struct) */
|
||||
|
||||
#define TARGET_TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */
|
||||
#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
|
||||
#endif /* _XTENSA_TERMBITS_H */
|
|
@ -1,10 +1,9 @@
|
|||
obj-y += xtensa-semi.o
|
||||
obj-y += core-dc232b.o
|
||||
obj-y += core-dc233c.o
|
||||
obj-y += core-de212.o
|
||||
obj-y += core-fsf.o
|
||||
obj-y += core-sample_controller.o
|
||||
obj-$(CONFIG_SOFTMMU) += monitor.o
|
||||
obj-$(CONFIG_SOFTMMU) += monitor.o xtensa-semi.o
|
||||
obj-y += xtensa-isa.o
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-y += gdbstub.o
|
||||
|
|
|
@ -45,9 +45,13 @@ static void xtensa_cpu_set_pc(CPUState *cs, vaddr value)
|
|||
|
||||
static bool xtensa_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
|
||||
return !cpu->env.runstall && cpu->env.pending_irq_level;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
|
@ -62,8 +66,16 @@ static void xtensa_cpu_reset(CPUState *s)
|
|||
env->exception_taken = 0;
|
||||
env->pc = env->config->exception_vector[EXC_RESET0 + env->static_vectors];
|
||||
env->sregs[LITBASE] &= ~1;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
env->sregs[PS] = xtensa_option_enabled(env->config,
|
||||
XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
|
||||
env->pending_irq_level = 0;
|
||||
#else
|
||||
env->sregs[PS] =
|
||||
(xtensa_option_enabled(env->config,
|
||||
XTENSA_OPTION_WINDOWED_REGISTER) ? PS_WOE : 0) |
|
||||
PS_UM | (3 << PS_RING_SHIFT);
|
||||
#endif
|
||||
env->sregs[VECBASE] = env->config->vecbase;
|
||||
env->sregs[IBREAKENABLE] = 0;
|
||||
env->sregs[MEMCTL] = MEMCTL_IL0EN & env->config->memctl_mask;
|
||||
|
@ -73,9 +85,10 @@ static void xtensa_cpu_reset(CPUState *s)
|
|||
env->sregs[CONFIGID0] = env->config->configid[0];
|
||||
env->sregs[CONFIGID1] = env->config->configid[1];
|
||||
|
||||
env->pending_irq_level = 0;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
reset_mmu(env);
|
||||
s->halted = env->runstall;
|
||||
#endif
|
||||
}
|
||||
|
||||
static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
|
||||
|
@ -104,11 +117,12 @@ static void xtensa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
|
|||
static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
XtensaCPU *cpu = XTENSA_CPU(dev);
|
||||
XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
xtensa_irq_init(&cpu->env);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
xtensa_irq_init(&XTENSA_CPU(dev)->env);
|
||||
#endif
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
|
@ -133,11 +147,13 @@ static void xtensa_cpu_initfn(Object *obj)
|
|||
cs->env_ptr = env;
|
||||
env->config = xcc->config;
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
env->address_space_er = g_malloc(sizeof(*env->address_space_er));
|
||||
env->system_er = g_malloc(sizeof(*env->system_er));
|
||||
memory_region_init_io(env->system_er, NULL, NULL, env, "er",
|
||||
UINT64_C(0x100000000));
|
||||
address_space_init(env->address_space_er, env->system_er, "ER");
|
||||
#endif
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_xtensa_cpu = {
|
||||
|
@ -166,7 +182,9 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
|
|||
cc->gdb_read_register = xtensa_cpu_gdb_read_register;
|
||||
cc->gdb_write_register = xtensa_cpu_gdb_write_register;
|
||||
cc->gdb_stop_before_watchpoint = true;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
cc->handle_mmu_fault = xtensa_cpu_handle_mmu_fault;
|
||||
#else
|
||||
cc->do_unaligned_access = xtensa_cpu_do_unaligned_access;
|
||||
cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
|
||||
cc->do_unassigned_access = xtensa_cpu_do_unassigned_access;
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#define ALIGNED_ONLY
|
||||
#define TARGET_LONG_BITS 32
|
||||
|
||||
/* Xtensa processors have a weak memory model */
|
||||
#define TCG_GUEST_DEFAULT_MO (0)
|
||||
|
||||
#define CPUArchState struct CPUXtensaState
|
||||
|
||||
#include "qemu-common.h"
|
||||
|
@ -41,7 +44,11 @@
|
|||
#define NB_MMU_MODES 4
|
||||
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 32
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 30
|
||||
#else
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#endif
|
||||
#define TARGET_PAGE_BITS 12
|
||||
|
||||
enum {
|
||||
|
@ -173,6 +180,7 @@ enum {
|
|||
|
||||
#define PS_OWB 0xf00
|
||||
#define PS_OWB_SHIFT 8
|
||||
#define PS_OWB_LEN 4
|
||||
|
||||
#define PS_CALLINC 0x30000
|
||||
#define PS_CALLINC_SHIFT 16
|
||||
|
@ -310,6 +318,7 @@ typedef struct xtensa_tlb {
|
|||
|
||||
typedef struct XtensaGdbReg {
|
||||
int targno;
|
||||
unsigned flags;
|
||||
int type;
|
||||
int group;
|
||||
unsigned size;
|
||||
|
@ -434,6 +443,7 @@ typedef struct CPUXtensaState {
|
|||
} fregs[16];
|
||||
float_status fp_status;
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE];
|
||||
xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE];
|
||||
unsigned autorefill_idx;
|
||||
|
@ -446,6 +456,7 @@ typedef struct CPUXtensaState {
|
|||
uint64_t time_base;
|
||||
uint64_t ccount_time;
|
||||
uint32_t ccount_base;
|
||||
#endif
|
||||
|
||||
int exception_taken;
|
||||
int yield_needed;
|
||||
|
@ -480,6 +491,9 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
|
|||
|
||||
#define ENV_OFFSET offsetof(XtensaCPU, env)
|
||||
|
||||
|
||||
int xtensa_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int size,
|
||||
int mmu_idx);
|
||||
void xtensa_cpu_do_interrupt(CPUState *cpu);
|
||||
bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
|
||||
void xtensa_cpu_do_unassigned_access(CPUState *cpu, hwaddr addr,
|
||||
|
@ -527,26 +541,9 @@ int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc);
|
|||
void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf);
|
||||
void xtensa_sync_window_from_phys(CPUXtensaState *env);
|
||||
void xtensa_sync_phys_from_window(CPUXtensaState *env);
|
||||
uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way);
|
||||
void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
|
||||
uint32_t *vpn, uint32_t wi, uint32_t *ei);
|
||||
int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
|
||||
uint32_t *pwi, uint32_t *pei, uint8_t *pring);
|
||||
void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
|
||||
xtensa_tlb_entry *entry, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
|
||||
void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
|
||||
int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
|
||||
uint32_t vaddr, int is_write, int mmu_idx,
|
||||
uint32_t *paddr, uint32_t *page_size, unsigned *access);
|
||||
void reset_mmu(CPUXtensaState *env);
|
||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env);
|
||||
void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta);
|
||||
void xtensa_restore_owb(CPUXtensaState *env);
|
||||
void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
|
||||
static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env)
|
||||
{
|
||||
return env->system_er;
|
||||
}
|
||||
|
||||
static inline void xtensa_select_static_vectors(CPUXtensaState *env,
|
||||
unsigned n)
|
||||
|
@ -600,6 +597,29 @@ static inline int xtensa_get_cring(const CPUXtensaState *env)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env,
|
||||
bool dtlb, uint32_t way);
|
||||
void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
|
||||
uint32_t *vpn, uint32_t wi, uint32_t *ei);
|
||||
int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
|
||||
uint32_t *pwi, uint32_t *pei, uint8_t *pring);
|
||||
void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
|
||||
xtensa_tlb_entry *entry, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
|
||||
void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
|
||||
int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
|
||||
uint32_t vaddr, int is_write, int mmu_idx,
|
||||
uint32_t *paddr, uint32_t *page_size, unsigned *access);
|
||||
void reset_mmu(CPUXtensaState *env);
|
||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env);
|
||||
|
||||
static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env)
|
||||
{
|
||||
return env->system_er;
|
||||
}
|
||||
|
||||
static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env,
|
||||
bool dtlb, unsigned wi, unsigned ei)
|
||||
{
|
||||
|
@ -607,6 +627,7 @@ static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env,
|
|||
env->dtlb[wi] + ei :
|
||||
env->itlb[wi] + ei;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
|
||||
{
|
||||
|
@ -619,6 +640,7 @@ static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
|
|||
#define MMU_MODE1_SUFFIX _ring1
|
||||
#define MMU_MODE2_SUFFIX _ring2
|
||||
#define MMU_MODE3_SUFFIX _ring3
|
||||
#define MMU_USER_IDX 3
|
||||
|
||||
static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch)
|
||||
{
|
||||
|
|
|
@ -28,9 +28,14 @@ int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
int num_regs = env->config->gdb_regmap.num_core_regs;
|
||||
#else
|
||||
int num_regs = env->config->gdb_regmap.num_regs;
|
||||
#endif
|
||||
unsigned i;
|
||||
|
||||
if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
|
||||
if (n < 0 || n >= num_regs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -81,8 +86,13 @@ int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||
CPUXtensaState *env = &cpu->env;
|
||||
uint32_t tmp;
|
||||
const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
int num_regs = env->config->gdb_regmap.num_core_regs;
|
||||
#else
|
||||
int num_regs = env->config->gdb_regmap.num_regs;
|
||||
#endif
|
||||
|
||||
if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
|
||||
if (n < 0 || n >= num_regs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,19 +88,31 @@ static void init_libisa(XtensaConfig *config)
|
|||
|
||||
void xtensa_finalize_config(XtensaConfig *config)
|
||||
{
|
||||
unsigned i, n = 0;
|
||||
|
||||
if (config->isa_internal) {
|
||||
init_libisa(config);
|
||||
}
|
||||
if (config->gdb_regmap.num_regs) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; config->gdb_regmap.reg[i].targno >= 0; ++i) {
|
||||
n += (config->gdb_regmap.reg[i].type != 6);
|
||||
if (config->gdb_regmap.num_regs == 0 ||
|
||||
config->gdb_regmap.num_core_regs == 0) {
|
||||
unsigned i;
|
||||
unsigned n_regs = 0;
|
||||
unsigned n_core_regs = 0;
|
||||
|
||||
for (i = 0; config->gdb_regmap.reg[i].targno >= 0; ++i) {
|
||||
if (config->gdb_regmap.reg[i].type != 6) {
|
||||
++n_regs;
|
||||
if ((config->gdb_regmap.reg[i].flags & 0x1) == 0) {
|
||||
++n_core_regs;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config->gdb_regmap.num_regs == 0) {
|
||||
config->gdb_regmap.num_regs = n_regs;
|
||||
}
|
||||
if (config->gdb_regmap.num_core_regs == 0) {
|
||||
config->gdb_regmap.num_core_regs = n_core_regs;
|
||||
}
|
||||
}
|
||||
config->gdb_regmap.num_regs = n;
|
||||
}
|
||||
|
||||
void xtensa_register_core(XtensaConfigList *node)
|
||||
|
@ -161,6 +173,7 @@ void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
|||
|
||||
hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
uint32_t paddr;
|
||||
uint32_t page_size;
|
||||
|
@ -175,8 +188,13 @@ hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
return paddr;
|
||||
}
|
||||
return ~0;
|
||||
#else
|
||||
return addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config,
|
||||
|
@ -286,6 +304,11 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
|
|||
}
|
||||
check_interrupts(env);
|
||||
}
|
||||
#else
|
||||
void xtensa_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||
{
|
||||
|
@ -297,6 +320,25 @@ bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
|
||||
int xtensa_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
|
||||
int mmu_idx)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
|
||||
qemu_log_mask(CPU_LOG_INT,
|
||||
"%s: rw = %d, address = 0x%08" VADDR_PRIx ", size = %d\n",
|
||||
__func__, rw, address, size);
|
||||
env->sregs[EXCVADDR] = address;
|
||||
env->sregs[EXCCAUSE] = rw ? STORE_PROHIBITED_CAUSE : LOAD_PROHIBITED_CAUSE;
|
||||
cs->exception_index = EXC_USER;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void reset_tlb_mmu_all_ways(CPUXtensaState *env,
|
||||
const xtensa_tlb *tlb, xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE])
|
||||
{
|
||||
|
@ -757,3 +799,4 @@ void xtensa_runstall(CPUXtensaState *env, bool runstall)
|
|||
cpu_reset_interrupt(cpu, CPU_INTERRUPT_HALT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -12,9 +12,12 @@ DEF_HELPER_1(restore_owb, void, env)
|
|||
DEF_HELPER_2(movsp, void, env, i32)
|
||||
DEF_HELPER_2(wsr_lbeg, void, env, i32)
|
||||
DEF_HELPER_2(wsr_lend, void, env, i32)
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
DEF_HELPER_1(simcall, void, env)
|
||||
#endif
|
||||
DEF_HELPER_1(dump_state, void, env)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
DEF_HELPER_3(waiti, void, env, i32, i32)
|
||||
DEF_HELPER_1(update_ccount, void, env)
|
||||
DEF_HELPER_2(wsr_ccount, void, env, i32)
|
||||
|
@ -35,6 +38,7 @@ DEF_HELPER_2(wsr_ibreakenable, void, env, i32)
|
|||
DEF_HELPER_3(wsr_ibreaka, void, env, i32, i32)
|
||||
DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32)
|
||||
DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32)
|
||||
#endif
|
||||
|
||||
DEF_HELPER_2(wur_fcr, void, env, i32)
|
||||
DEF_HELPER_FLAGS_1(abs_s, TCG_CALL_NO_RWG_SE, f32, f32)
|
||||
|
|
|
@ -36,6 +36,13 @@
|
|||
#include "qemu/timer.h"
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/* tb_invalidate_phys_range */
|
||||
#include "accel/tcg/translate-all.h"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
void xtensa_cpu_do_unaligned_access(CPUState *cs,
|
||||
vaddr addr, MMUAccessType access_type,
|
||||
int mmu_idx, uintptr_t retaddr)
|
||||
|
@ -102,6 +109,17 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
|
||||
{
|
||||
mmap_lock();
|
||||
tb_invalidate_phys_range(vaddr, vaddr + 1);
|
||||
mmap_unlock();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
|
@ -219,21 +237,21 @@ void xtensa_sync_phys_from_window(CPUXtensaState *env)
|
|||
copy_phys_from_window(env, env->sregs[WINDOW_BASE] * 4, 0, 16);
|
||||
}
|
||||
|
||||
static void rotate_window_abs(CPUXtensaState *env, uint32_t position)
|
||||
static void xtensa_rotate_window_abs(CPUXtensaState *env, uint32_t position)
|
||||
{
|
||||
xtensa_sync_phys_from_window(env);
|
||||
env->sregs[WINDOW_BASE] = windowbase_bound(position, env);
|
||||
xtensa_sync_window_from_phys(env);
|
||||
}
|
||||
|
||||
static void rotate_window(CPUXtensaState *env, uint32_t delta)
|
||||
void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta)
|
||||
{
|
||||
rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta);
|
||||
xtensa_rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta);
|
||||
}
|
||||
|
||||
void HELPER(wsr_windowbase)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
rotate_window_abs(env, v);
|
||||
xtensa_rotate_window_abs(env, v);
|
||||
}
|
||||
|
||||
void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
|
||||
|
@ -251,7 +269,7 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
|
|||
HELPER(window_check)(env, pc, callinc);
|
||||
}
|
||||
env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - imm;
|
||||
rotate_window(env, callinc);
|
||||
xtensa_rotate_window(env, callinc);
|
||||
env->sregs[WINDOW_START] |=
|
||||
windowstart_bit(env->sregs[WINDOW_BASE], env);
|
||||
}
|
||||
|
@ -266,7 +284,7 @@ void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w)
|
|||
|
||||
assert(n <= w);
|
||||
|
||||
rotate_window(env, n);
|
||||
xtensa_rotate_window(env, n);
|
||||
env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
|
||||
(windowbase << PS_OWB_SHIFT) | PS_EXCM;
|
||||
env->sregs[EPC1] = env->pc = pc;
|
||||
|
@ -311,7 +329,7 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
|
|||
|
||||
ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff);
|
||||
|
||||
rotate_window(env, -n);
|
||||
xtensa_rotate_window(env, -n);
|
||||
if (windowstart & windowstart_bit(env->sregs[WINDOW_BASE], env)) {
|
||||
env->sregs[WINDOW_START] &= ~windowstart_bit(owb, env);
|
||||
} else {
|
||||
|
@ -334,12 +352,17 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
|
|||
|
||||
void HELPER(rotw)(CPUXtensaState *env, uint32_t imm4)
|
||||
{
|
||||
rotate_window(env, imm4);
|
||||
xtensa_rotate_window(env, imm4);
|
||||
}
|
||||
|
||||
void xtensa_restore_owb(CPUXtensaState *env)
|
||||
{
|
||||
xtensa_rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT);
|
||||
}
|
||||
|
||||
void HELPER(restore_owb)(CPUXtensaState *env)
|
||||
{
|
||||
rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT);
|
||||
xtensa_restore_owb(env);
|
||||
}
|
||||
|
||||
void HELPER(movsp)(CPUXtensaState *env, uint32_t pc)
|
||||
|
@ -376,6 +399,8 @@ void HELPER(dump_state)(CPUXtensaState *env)
|
|||
cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
@ -888,6 +913,7 @@ void HELPER(wsr_dbreakc)(CPUXtensaState *env, uint32_t i, uint32_t v)
|
|||
}
|
||||
env->sregs[DBREAKC + i] = v;
|
||||
}
|
||||
#endif
|
||||
|
||||
void HELPER(wur_fcr)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
|
@ -1025,12 +1051,18 @@ void HELPER(ule_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
|||
|
||||
uint32_t HELPER(rer)(CPUXtensaState *env, uint32_t addr)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
return address_space_ldl(env->address_space_er, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HELPER(wer)(CPUXtensaState *env, uint32_t data, uint32_t addr)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
address_space_stl(env->address_space_er, addr, data,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -25,9 +25,14 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define XTREG(idx, ofs, bi, sz, al, no, flags, cp, typ, grp, name, \
|
||||
a1, a2, a3, a4, a5, a6) \
|
||||
{ .targno = (no), .type = (typ), .group = (grp), .size = (sz) },
|
||||
#define XTREG(idx, ofs, bi, sz, al, no, fl, cp, typ, grp, name, \
|
||||
a1, a2, a3, a4, a5, a6) { \
|
||||
.targno = (no), \
|
||||
.flags = (fl), \
|
||||
.type = (typ), \
|
||||
.group = (grp), \
|
||||
.size = (sz), \
|
||||
},
|
||||
#define XTREG_END { .targno = -1 },
|
||||
|
||||
#ifndef XCHAL_HAVE_DEPBITS
|
||||
|
|
|
@ -345,12 +345,14 @@ static void gen_debug_exception(DisasContext *dc, uint32_t cause)
|
|||
|
||||
static bool gen_check_privilege(DisasContext *dc)
|
||||
{
|
||||
if (dc->cring) {
|
||||
gen_exception_cause(dc, PRIVILEGED_CAUSE);
|
||||
dc->is_jmp = DISAS_UPDATE;
|
||||
return false;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (!dc->cring) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
gen_exception_cause(dc, PRIVILEGED_CAUSE);
|
||||
dc->is_jmp = DISAS_UPDATE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gen_check_cpenable(DisasContext *dc, unsigned cp)
|
||||
|
@ -498,6 +500,7 @@ static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static bool gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
|
||||
{
|
||||
if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
|
||||
|
@ -519,14 +522,17 @@ static bool gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
|
|||
tcg_gen_andi_i32(d, d, 0xfffffffc);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
|
||||
{
|
||||
static bool (* const rsr_handler[256])(DisasContext *dc,
|
||||
TCGv_i32 d, uint32_t sr) = {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
[CCOUNT] = gen_rsr_ccount,
|
||||
[INTSET] = gen_rsr_ccount,
|
||||
[PTEVADDR] = gen_rsr_ptevaddr,
|
||||
#endif
|
||||
};
|
||||
|
||||
if (rsr_handler[sr]) {
|
||||
|
@ -582,6 +588,7 @@ static bool gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static bool gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
|
||||
{
|
||||
gen_helper_wsr_windowbase(cpu_env, v);
|
||||
|
@ -797,6 +804,11 @@ static bool gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static void gen_check_interrupts(DisasContext *dc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
|
||||
{
|
||||
|
@ -808,6 +820,7 @@ static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
|
|||
[BR] = gen_wsr_br,
|
||||
[LITBASE] = gen_wsr_litbase,
|
||||
[ACCHI] = gen_wsr_acchi,
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
[WINDOW_BASE] = gen_wsr_windowbase,
|
||||
[WINDOW_START] = gen_wsr_windowstart,
|
||||
[PTEVADDR] = gen_wsr_ptevaddr,
|
||||
|
@ -834,6 +847,7 @@ static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
|
|||
[CCOMPARE] = gen_wsr_ccompare,
|
||||
[CCOMPARE + 1] = gen_wsr_ccompare,
|
||||
[CCOMPARE + 2] = gen_wsr_ccompare,
|
||||
#endif
|
||||
};
|
||||
|
||||
if (wsr_handler[sr]) {
|
||||
|
@ -878,6 +892,7 @@ static void gen_load_store_alignment(DisasContext *dc, int shift,
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static void gen_waiti(DisasContext *dc, uint32_t imm4)
|
||||
{
|
||||
TCGv_i32 pc = tcg_const_i32(dc->next_pc);
|
||||
|
@ -894,6 +909,7 @@ static void gen_waiti(DisasContext *dc, uint32_t imm4)
|
|||
tcg_temp_free(intlevel);
|
||||
gen_jumpi_check_loop_end(dc, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool gen_window_check1(DisasContext *dc, unsigned r1)
|
||||
{
|
||||
|
@ -1215,11 +1231,17 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
|
|||
(i % 4) == 3 ? '\n' : ' ');
|
||||
}
|
||||
|
||||
xtensa_sync_phys_from_window(env);
|
||||
cpu_fprintf(f, "\n");
|
||||
|
||||
for (i = 0; i < env->config->nareg; ++i) {
|
||||
cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
|
||||
(i % 4) == 3 ? '\n' : ' ');
|
||||
cpu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]);
|
||||
if (i % 4 == 3) {
|
||||
bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0;
|
||||
bool cw = env->sregs[WINDOW_BASE] == i / 4;
|
||||
|
||||
cpu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
|
||||
}
|
||||
}
|
||||
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
|
||||
|
@ -1590,12 +1612,14 @@ static void translate_icache(DisasContext *dc, const uint32_t arg[],
|
|||
{
|
||||
if ((!par[0] || gen_check_privilege(dc)) &&
|
||||
gen_window_check1(dc, arg[0]) && par[1]) {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
TCGv_i32 addr = tcg_temp_new_i32();
|
||||
|
||||
tcg_gen_movi_i32(cpu_pc, dc->pc);
|
||||
tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
|
||||
gen_helper_itlb_hit_test(cpu_env, addr);
|
||||
tcg_temp_free(addr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1604,12 +1628,14 @@ static void translate_itlb(DisasContext *dc, const uint32_t arg[],
|
|||
{
|
||||
if (gen_check_privilege(dc) &&
|
||||
gen_window_check1(dc, arg[0])) {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
TCGv_i32 dtlb = tcg_const_i32(par[0]);
|
||||
|
||||
gen_helper_itlb(cpu_env, cpu_R[arg[0]], dtlb);
|
||||
/* This could change memory mapping, so exit tb */
|
||||
gen_jumpi_check_loop_end(dc, -1);
|
||||
tcg_temp_free(dtlb);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1658,9 +1684,15 @@ static void translate_ldst(DisasContext *dc, const uint32_t arg[],
|
|||
gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]);
|
||||
}
|
||||
if (par[2]) {
|
||||
if (par[1]) {
|
||||
tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
|
||||
}
|
||||
tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
|
||||
} else {
|
||||
tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
|
||||
if (par[1]) {
|
||||
tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL);
|
||||
}
|
||||
}
|
||||
tcg_temp_free(addr);
|
||||
}
|
||||
|
@ -1817,6 +1849,12 @@ static void translate_mac16(DisasContext *dc, const uint32_t arg[],
|
|||
}
|
||||
}
|
||||
|
||||
static void translate_memw(DisasContext *dc, const uint32_t arg[],
|
||||
const uint32_t par[])
|
||||
{
|
||||
tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
|
||||
}
|
||||
|
||||
static void translate_minmax(DisasContext *dc, const uint32_t arg[],
|
||||
const uint32_t par[])
|
||||
{
|
||||
|
@ -1967,11 +2005,13 @@ static void translate_ptlb(DisasContext *dc, const uint32_t arg[],
|
|||
{
|
||||
if (gen_check_privilege(dc) &&
|
||||
gen_window_check2(dc, arg[0], arg[1])) {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
TCGv_i32 dtlb = tcg_const_i32(par[0]);
|
||||
|
||||
tcg_gen_movi_i32(cpu_pc, dc->pc);
|
||||
gen_helper_ptlb(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
|
||||
tcg_temp_free(dtlb);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2155,8 +2195,10 @@ static void translate_rtlb(DisasContext *dc, const uint32_t arg[],
|
|||
{
|
||||
static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
|
||||
TCGv_i32 a2) = {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
gen_helper_rtlb0,
|
||||
gen_helper_rtlb1,
|
||||
#endif
|
||||
};
|
||||
|
||||
if (gen_check_privilege(dc) &&
|
||||
|
@ -2187,29 +2229,33 @@ static void translate_setb_expstate(DisasContext *dc, const uint32_t arg[],
|
|||
tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
|
||||
{
|
||||
}
|
||||
#else
|
||||
static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
|
||||
{
|
||||
TCGv_i32 tpc = tcg_const_i32(dc->pc);
|
||||
|
||||
gen_helper_check_atomctl(cpu_env, tpc, addr);
|
||||
tcg_temp_free(tpc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void translate_s32c1i(DisasContext *dc, const uint32_t arg[],
|
||||
const uint32_t par[])
|
||||
{
|
||||
if (gen_window_check2(dc, arg[0], arg[1])) {
|
||||
TCGLabel *label = gen_new_label();
|
||||
TCGv_i32 tmp = tcg_temp_local_new_i32();
|
||||
TCGv_i32 addr = tcg_temp_local_new_i32();
|
||||
TCGv_i32 tpc;
|
||||
|
||||
tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
|
||||
tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
|
||||
gen_load_store_alignment(dc, 2, addr, true);
|
||||
|
||||
tpc = tcg_const_i32(dc->pc);
|
||||
gen_helper_check_atomctl(cpu_env, tpc, addr);
|
||||
tcg_gen_qemu_ld32u(cpu_R[arg[0]], addr, dc->cring);
|
||||
tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[arg[0]],
|
||||
cpu_SR[SCOMPARE1], label);
|
||||
|
||||
tcg_gen_qemu_st32(tmp, addr, dc->cring);
|
||||
|
||||
gen_set_label(label);
|
||||
tcg_temp_free(tpc);
|
||||
gen_check_atomctl(dc, addr);
|
||||
tcg_gen_atomic_cmpxchg_i32(cpu_R[arg[0]], addr, cpu_SR[SCOMPARE1],
|
||||
tmp, dc->cring, MO_32);
|
||||
tcg_temp_free(addr);
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
|
@ -2261,11 +2307,14 @@ static void translate_sext(DisasContext *dc, const uint32_t arg[],
|
|||
static void translate_simcall(DisasContext *dc, const uint32_t arg[],
|
||||
const uint32_t par[])
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (semihosting_enabled()) {
|
||||
if (gen_check_privilege(dc)) {
|
||||
gen_helper_simcall(cpu_env);
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
|
||||
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
|
||||
}
|
||||
|
@ -2448,7 +2497,9 @@ static void translate_waiti(DisasContext *dc, const uint32_t arg[],
|
|||
const uint32_t par[])
|
||||
{
|
||||
if (gen_check_privilege(dc)) {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
gen_waiti(dc, arg[0]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2457,12 +2508,14 @@ static void translate_wtlb(DisasContext *dc, const uint32_t arg[],
|
|||
{
|
||||
if (gen_check_privilege(dc) &&
|
||||
gen_window_check2(dc, arg[0], arg[1])) {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
TCGv_i32 dtlb = tcg_const_i32(par[0]);
|
||||
|
||||
gen_helper_wtlb(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]], dtlb);
|
||||
/* This could change memory mapping, so exit tb */
|
||||
gen_jumpi_check_loop_end(dc, -1);
|
||||
tcg_temp_free(dtlb);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2822,7 +2875,7 @@ static const XtensaOpcodeOps core_ops[] = {
|
|||
.translate = translate_extui,
|
||||
}, {
|
||||
.name = "extw",
|
||||
.translate = translate_nop,
|
||||
.translate = translate_memw,
|
||||
}, {
|
||||
.name = "hwwdtlba",
|
||||
.translate = translate_ill,
|
||||
|
@ -2939,7 +2992,7 @@ static const XtensaOpcodeOps core_ops[] = {
|
|||
.par = (const uint32_t[]){TCG_COND_GEU},
|
||||
}, {
|
||||
.name = "memw",
|
||||
.translate = translate_nop,
|
||||
.translate = translate_memw,
|
||||
}, {
|
||||
.name = "min",
|
||||
.translate = translate_minmax,
|
||||
|
|
Loading…
Reference in a new issue