ARM queue:
* aarch64 preparation patchset (excluding the defconfigs, so this doesn't actually enable the new targets yet) * minor bugfixes and cleanups * disable "-cpu any" in system emulation mode * fix ARMv7M stack alignment on reset -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABCAAGBQJSL2jzAAoJEDwlJe0UNgzesqIP/0pn2qoSv6BXSjVHAlbGvOtC n4ZF6Aeoc+S9vvWbKk/2mCGNyf2ewokVCrekMSjWeD4i0WQwLPAIbwZ4RTmketCt KqJQQ2JrFQyu5xTlooc4NrAuO8XllEtFIdIl/Aob9HyZvlNQR+l81GP0LqipiTLz Dto1Cxack8BpOopy8hxBnR4xcE3yz9e+9b2P7iONJ4TYzs7vheu0j4qMOZtNyw/T mf7yKrv+YzvlbJJgM3tK9sgBShtGqyxgW6YO5OHrsM/D/9wc+ML6k3iMpf7Sr2RF 1/P0xUZBkaXht3ZDBU/EOG5Gi+AqoPS2K/Quu/NFADn7dpV+qAeukiCHnhhCtPHc AbSl6oaHjpfEPC7JaORIdzu8+GAIhT6fWP4MNa0bkWtatGh3OXJvMboalu1jtARE DCpTvA4pRyjJ8WFO/CYASxeeFeZX7DYCy4RYklSk7cbQ5xH9n2Jq3g/92y+07KnQ bZYpP57Lor8p2bHenr8p9V/dIlIKTgQkcgqIumNSSrIBU4NCVb2G566kfTSKZy4S Alq/dmWs3oxmidviz8HT0aX6tVJgFU2rkIVE4nCZjCH/0fQYU7NVfMshFNLar8zQ lCe1K7Yiv+u6W/bgUIG3AM1GVbsb8X2YKNTEUXOls54Jzjep3lQrsoVCaaQLgaI5 Cz+uCGX+4x4Pe9h6XWDk =oraU -----END PGP SIGNATURE----- Merge remote-tracking branch 'pmaydell/tags/pull-target-arm-20130910' into staging ARM queue: * aarch64 preparation patchset (excluding the defconfigs, so this doesn't actually enable the new targets yet) * minor bugfixes and cleanups * disable "-cpu any" in system emulation mode * fix ARMv7M stack alignment on reset # gpg: Signature made Tue 10 Sep 2013 01:46:11 PM CDT using RSA key ID 14360CDE # gpg: Can't check signature: public key not found # By Alexander Graf (13) and others # Via Peter Maydell * pmaydell/tags/pull-target-arm-20130910: (28 commits) configure: Add handling code for AArch64 targets linux-user: Add AArch64 support linux-user: Allow targets to specify a minimum uname release linux-user: Add AArch64 termbits.h definitions linux-user: Implement cpu_set_tls() and cpu_clone_regs() for AArch64 linux-user: Make sure NWFPE code is 32 bit ARM only linux-user: Add signal handling for AArch64 linux-user: Fix up AArch64 syscall handlers linux-user: Add syscall number definitions for AArch64 linux-user: Add cpu loop for AArch64 linux-user: Don't treat AArch64 cpu names specially target-arm: Add AArch64 gdbstub support target-arm: Add AArch64 translation stub target-arm: Prepare translation for AArch64 code target-arm: Disable 32 bit CPUs in 64 bit linux-user builds target-arm: Add new AArch64CPUInfo base class and subclasses target-arm: Pass DisasContext* to gen_set_pc_im() target-arm: Fix target_ulong/uint32_t confusions target-arm: Export cpu_env target-arm: Extract the disas struct to a header file ... Message-id: 1378839142-7726-1-git-send-email-peter.maydell@linaro.org Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
This commit is contained in:
commit
2d1fe1873a
7
configure
vendored
7
configure
vendored
@ -2550,7 +2550,7 @@ fi
|
||||
fdt_required=no
|
||||
for target in $target_list; do
|
||||
case $target in
|
||||
arm*-softmmu|ppc*-softmmu|microblaze*-softmmu)
|
||||
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu)
|
||||
fdt_required=yes
|
||||
;;
|
||||
esac
|
||||
@ -4366,6 +4366,11 @@ case "$target_name" in
|
||||
bflt="yes"
|
||||
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
|
||||
;;
|
||||
aarch64)
|
||||
TARGET_BASE_ARCH=arm
|
||||
bflt="yes"
|
||||
gdb_xml_files="aarch64-core.xml"
|
||||
;;
|
||||
cris)
|
||||
;;
|
||||
lm32)
|
||||
|
46
gdb-xml/aarch64-core.xml
Normal file
46
gdb-xml/aarch64-core.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2009-2012 Free Software Foundation, Inc.
|
||||
Contributed by ARM Ltd.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.aarch64.core">
|
||||
<reg name="x0" bitsize="64"/>
|
||||
<reg name="x1" bitsize="64"/>
|
||||
<reg name="x2" bitsize="64"/>
|
||||
<reg name="x3" bitsize="64"/>
|
||||
<reg name="x4" bitsize="64"/>
|
||||
<reg name="x5" bitsize="64"/>
|
||||
<reg name="x6" bitsize="64"/>
|
||||
<reg name="x7" bitsize="64"/>
|
||||
<reg name="x8" bitsize="64"/>
|
||||
<reg name="x9" bitsize="64"/>
|
||||
<reg name="x10" bitsize="64"/>
|
||||
<reg name="x11" bitsize="64"/>
|
||||
<reg name="x12" bitsize="64"/>
|
||||
<reg name="x13" bitsize="64"/>
|
||||
<reg name="x14" bitsize="64"/>
|
||||
<reg name="x15" bitsize="64"/>
|
||||
<reg name="x16" bitsize="64"/>
|
||||
<reg name="x17" bitsize="64"/>
|
||||
<reg name="x18" bitsize="64"/>
|
||||
<reg name="x19" bitsize="64"/>
|
||||
<reg name="x20" bitsize="64"/>
|
||||
<reg name="x21" bitsize="64"/>
|
||||
<reg name="x22" bitsize="64"/>
|
||||
<reg name="x23" bitsize="64"/>
|
||||
<reg name="x24" bitsize="64"/>
|
||||
<reg name="x25" bitsize="64"/>
|
||||
<reg name="x26" bitsize="64"/>
|
||||
<reg name="x27" bitsize="64"/>
|
||||
<reg name="x28" bitsize="64"/>
|
||||
<reg name="x29" bitsize="64"/>
|
||||
<reg name="x30" bitsize="64"/>
|
||||
<reg name="sp" bitsize="64" type="data_ptr"/>
|
||||
|
||||
<reg name="pc" bitsize="64" type="code_ptr"/>
|
||||
<reg name="cpsr" bitsize="32"/>
|
||||
</feature>
|
@ -94,23 +94,21 @@ static const VMStateDescription vmstate_pl110 = {
|
||||
static const unsigned char pl110_id[] =
|
||||
{ 0x10, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
|
||||
|
||||
/* The Arm documentation (DDI0224C) says the CLDC on the Versatile board
|
||||
has a different ID. However Linux only looks for the normal ID. */
|
||||
#if 0
|
||||
static const unsigned char pl110_versatile_id[] =
|
||||
{ 0x93, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
|
||||
#else
|
||||
#define pl110_versatile_id pl110_id
|
||||
#endif
|
||||
|
||||
static const unsigned char pl111_id[] = {
|
||||
0x11, 0x11, 0x24, 0x00, 0x0d, 0xf0, 0x05, 0xb1
|
||||
};
|
||||
|
||||
|
||||
/* Indexed by pl110_version */
|
||||
static const unsigned char *idregs[] = {
|
||||
pl110_id,
|
||||
pl110_versatile_id,
|
||||
/* The ARM documentation (DDI0224C) says the CLCDC on the Versatile board
|
||||
* has a different ID (0x93, 0x10, 0x04, 0x00, ...). However the hardware
|
||||
* itself has the same ID values as a stock PL110, and guests (in
|
||||
* particular Linux) rely on this. We emulate what the hardware does,
|
||||
* rather than what the docs claim it ought to do.
|
||||
*/
|
||||
pl110_id,
|
||||
pl111_id
|
||||
};
|
||||
|
||||
|
@ -14,10 +14,6 @@
|
||||
#define ABI_LLONG_ALIGNMENT 2
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_ARM
|
||||
#define ABI_LLONG_ALIGNMENT 4
|
||||
#endif
|
||||
|
||||
#ifndef ABI_SHORT_ALIGNMENT
|
||||
#define ABI_SHORT_ALIGNMENT 2
|
||||
#endif
|
||||
|
9
linux-user/aarch64/syscall.h
Normal file
9
linux-user/aarch64/syscall.h
Normal file
@ -0,0 +1,9 @@
|
||||
struct target_pt_regs {
|
||||
uint64_t regs[31];
|
||||
uint64_t sp;
|
||||
uint64_t pc;
|
||||
uint64_t pstate;
|
||||
};
|
||||
|
||||
#define UNAME_MACHINE "aarch64"
|
||||
#define UNAME_MINIMUM_RELEASE "3.8.0"
|
323
linux-user/aarch64/syscall_nr.h
Normal file
323
linux-user/aarch64/syscall_nr.h
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* This file contains the system call numbers.
|
||||
*/
|
||||
|
||||
#define TARGET_NR_io_setup 0
|
||||
#define TARGET_NR_io_destroy 1
|
||||
#define TARGET_NR_io_submit 2
|
||||
#define TARGET_NR_io_cancel 3
|
||||
#define TARGET_NR_io_getevents 4
|
||||
#define TARGET_NR_setxattr 5
|
||||
#define TARGET_NR_lsetxattr 6
|
||||
#define TARGET_NR_fsetxattr 7
|
||||
#define TARGET_NR_getxattr 8
|
||||
#define TARGET_NR_lgetxattr 9
|
||||
#define TARGET_NR_fgetxattr 10
|
||||
#define TARGET_NR_listxattr 11
|
||||
#define TARGET_NR_llistxattr 12
|
||||
#define TARGET_NR_flistxattr 13
|
||||
#define TARGET_NR_removexattr 14
|
||||
#define TARGET_NR_lremovexattr 15
|
||||
#define TARGET_NR_fremovexattr 16
|
||||
#define TARGET_NR_getcwd 17
|
||||
#define TARGET_NR_lookup_dcookie 18
|
||||
#define TARGET_NR_eventfd2 19
|
||||
#define TARGET_NR_epoll_create1 20
|
||||
#define TARGET_NR_epoll_ctl 21
|
||||
#define TARGET_NR_epoll_pwait 22
|
||||
#define TARGET_NR_dup 23
|
||||
#define TARGET_NR_dup3 24
|
||||
#define TARGET_NR_fcntl 25
|
||||
#define TARGET_NR_inotify_init1 26
|
||||
#define TARGET_NR_inotify_add_watch 27
|
||||
#define TARGET_NR_inotify_rm_watch 28
|
||||
#define TARGET_NR_ioctl 29
|
||||
#define TARGET_NR_ioprio_set 30
|
||||
#define TARGET_NR_ioprio_get 31
|
||||
#define TARGET_NR_flock 32
|
||||
#define TARGET_NR_mknodat 33
|
||||
#define TARGET_NR_mkdirat 34
|
||||
#define TARGET_NR_unlinkat 35
|
||||
#define TARGET_NR_symlinkat 36
|
||||
#define TARGET_NR_linkat 37
|
||||
#define TARGET_NR_renameat 38
|
||||
#define TARGET_NR_umount2 39
|
||||
#define TARGET_NR_mount 40
|
||||
#define TARGET_NR_pivot_root 41
|
||||
#define TARGET_NR_nfsservctl 42
|
||||
#define TARGET_NR_statfs 43
|
||||
#define TARGET_NR_fstatfs 44
|
||||
#define TARGET_NR_truncate 45
|
||||
#define TARGET_NR_ftruncate 46
|
||||
#define TARGET_NR_fallocate 47
|
||||
#define TARGET_NR_faccessat 48
|
||||
#define TARGET_NR_chdir 49
|
||||
#define TARGET_NR_fchdir 50
|
||||
#define TARGET_NR_chroot 51
|
||||
#define TARGET_NR_fchmod 52
|
||||
#define TARGET_NR_fchmodat 53
|
||||
#define TARGET_NR_fchownat 54
|
||||
#define TARGET_NR_fchown 55
|
||||
#define TARGET_NR_openat 56
|
||||
#define TARGET_NR_close 57
|
||||
#define TARGET_NR_vhangup 58
|
||||
#define TARGET_NR_pipe2 59
|
||||
#define TARGET_NR_quotactl 60
|
||||
#define TARGET_NR_getdents64 61
|
||||
#define TARGET_NR_lseek 62
|
||||
#define TARGET_NR_read 63
|
||||
#define TARGET_NR_write 64
|
||||
#define TARGET_NR_readv 65
|
||||
#define TARGET_NR_writev 66
|
||||
#define TARGET_NR_pread64 67
|
||||
#define TARGET_NR_pwrite64 68
|
||||
#define TARGET_NR_preadv 69
|
||||
#define TARGET_NR_pwritev 70
|
||||
#define TARGET_NR_sendfile 71
|
||||
#define TARGET_NR_pselect6 72
|
||||
#define TARGET_NR_ppoll 73
|
||||
#define TARGET_NR_signalfd4 74
|
||||
#define TARGET_NR_vmsplice 75
|
||||
#define TARGET_NR_splice 76
|
||||
#define TARGET_NR_tee 77
|
||||
#define TARGET_NR_readlinkat 78
|
||||
#define TARGET_NR_fstatat64 79
|
||||
#define TARGET_NR_fstat 80
|
||||
#define TARGET_NR_sync 81
|
||||
#define TARGET_NR_fsync 82
|
||||
#define TARGET_NR_fdatasync 83
|
||||
#define TARGET_NR_sync_file_range2 84
|
||||
/* #define TARGET_NR_sync_file_range 84 */
|
||||
#define TARGET_NR_timerfd_create 85
|
||||
#define TARGET_NR_timerfd_settime 86
|
||||
#define TARGET_NR_timerfd_gettime 87
|
||||
#define TARGET_NR_utimensat 88
|
||||
#define TARGET_NR_acct 89
|
||||
#define TARGET_NR_capget 90
|
||||
#define TARGET_NR_capset 91
|
||||
#define TARGET_NR_personality 92
|
||||
#define TARGET_NR_exit 93
|
||||
#define TARGET_NR_exit_group 94
|
||||
#define TARGET_NR_waitid 95
|
||||
#define TARGET_NR_set_tid_address 96
|
||||
#define TARGET_NR_unshare 97
|
||||
#define TARGET_NR_futex 98
|
||||
#define TARGET_NR_set_robust_list 99
|
||||
#define TARGET_NR_get_robust_list 100
|
||||
#define TARGET_NR_nanosleep 101
|
||||
#define TARGET_NR_getitimer 102
|
||||
#define TARGET_NR_setitimer 103
|
||||
#define TARGET_NR_kexec_load 104
|
||||
#define TARGET_NR_init_module 105
|
||||
#define TARGET_NR_delete_module 106
|
||||
#define TARGET_NR_timer_create 107
|
||||
#define TARGET_NR_timer_gettime 108
|
||||
#define TARGET_NR_timer_getoverrun 109
|
||||
#define TARGET_NR_timer_settime 110
|
||||
#define TARGET_NR_timer_delete 111
|
||||
#define TARGET_NR_clock_settime 112
|
||||
#define TARGET_NR_clock_gettime 113
|
||||
#define TARGET_NR_clock_getres 114
|
||||
#define TARGET_NR_clock_nanosleep 115
|
||||
#define TARGET_NR_syslog 116
|
||||
#define TARGET_NR_ptrace 117
|
||||
#define TARGET_NR_sched_setparam 118
|
||||
#define TARGET_NR_sched_setscheduler 119
|
||||
#define TARGET_NR_sched_getscheduler 120
|
||||
#define TARGET_NR_sched_getparam 121
|
||||
#define TARGET_NR_sched_setaffinity 122
|
||||
#define TARGET_NR_sched_getaffinity 123
|
||||
#define TARGET_NR_sched_yield 124
|
||||
#define TARGET_NR_sched_get_priority_max 125
|
||||
#define TARGET_NR_sched_get_priority_min 126
|
||||
#define TARGET_NR_sched_rr_get_interval 127
|
||||
#define TARGET_NR_restart_syscall 128
|
||||
#define TARGET_NR_kill 129
|
||||
#define TARGET_NR_tkill 130
|
||||
#define TARGET_NR_tgkill 131
|
||||
#define TARGET_NR_sigaltstack 132
|
||||
#define TARGET_NR_rt_sigsuspend 133
|
||||
#define TARGET_NR_rt_sigaction 134
|
||||
#define TARGET_NR_rt_sigprocmask 135
|
||||
#define TARGET_NR_rt_sigpending 136
|
||||
#define TARGET_NR_rt_sigtimedwait 137
|
||||
#define TARGET_NR_rt_sigqueueinfo 138
|
||||
#define TARGET_NR_rt_sigreturn 139
|
||||
#define TARGET_NR_setpriority 140
|
||||
#define TARGET_NR_getpriority 141
|
||||
#define TARGET_NR_reboot 142
|
||||
#define TARGET_NR_setregid 143
|
||||
#define TARGET_NR_setgid 144
|
||||
#define TARGET_NR_setreuid 145
|
||||
#define TARGET_NR_setuid 146
|
||||
#define TARGET_NR_setresuid 147
|
||||
#define TARGET_NR_getresuid 148
|
||||
#define TARGET_NR_setresgid 149
|
||||
#define TARGET_NR_getresgid 150
|
||||
#define TARGET_NR_setfsuid 151
|
||||
#define TARGET_NR_setfsgid 152
|
||||
#define TARGET_NR_times 153
|
||||
#define TARGET_NR_setpgid 154
|
||||
#define TARGET_NR_getpgid 155
|
||||
#define TARGET_NR_getsid 156
|
||||
#define TARGET_NR_setsid 157
|
||||
#define TARGET_NR_getgroups 158
|
||||
#define TARGET_NR_setgroups 159
|
||||
#define TARGET_NR_uname 160
|
||||
#define TARGET_NR_sethostname 161
|
||||
#define TARGET_NR_setdomainname 162
|
||||
#define TARGET_NR_getrlimit 163
|
||||
#define TARGET_NR_setrlimit 164
|
||||
#define TARGET_NR_getrusage 165
|
||||
#define TARGET_NR_umask 166
|
||||
#define TARGET_NR_prctl 167
|
||||
#define TARGET_NR_getcpu 168
|
||||
#define TARGET_NR_gettimeofday 169
|
||||
#define TARGET_NR_settimeofday 170
|
||||
#define TARGET_NR_adjtimex 171
|
||||
#define TARGET_NR_getpid 172
|
||||
#define TARGET_NR_getppid 173
|
||||
#define TARGET_NR_getuid 174
|
||||
#define TARGET_NR_geteuid 175
|
||||
#define TARGET_NR_getgid 176
|
||||
#define TARGET_NR_getegid 177
|
||||
#define TARGET_NR_gettid 178
|
||||
#define TARGET_NR_sysinfo 179
|
||||
#define TARGET_NR_mq_open 180
|
||||
#define TARGET_NR_mq_unlink 181
|
||||
#define TARGET_NR_mq_timedsend 182
|
||||
#define TARGET_NR_mq_timedreceive 183
|
||||
#define TARGET_NR_mq_notify 184
|
||||
#define TARGET_NR_mq_getsetattr 185
|
||||
#define TARGET_NR_msgget 186
|
||||
#define TARGET_NR_msgctl 187
|
||||
#define TARGET_NR_msgrcv 188
|
||||
#define TARGET_NR_msgsnd 189
|
||||
#define TARGET_NR_semget 190
|
||||
#define TARGET_NR_semctl 191
|
||||
#define TARGET_NR_semtimedop 192
|
||||
#define TARGET_NR_semop 193
|
||||
#define TARGET_NR_shmget 194
|
||||
#define TARGET_NR_shmctl 195
|
||||
#define TARGET_NR_shmat 196
|
||||
#define TARGET_NR_shmdt 197
|
||||
#define TARGET_NR_socket 198
|
||||
#define TARGET_NR_socketpair 199
|
||||
#define TARGET_NR_bind 200
|
||||
#define TARGET_NR_listen 201
|
||||
#define TARGET_NR_accept 202
|
||||
#define TARGET_NR_connect 203
|
||||
#define TARGET_NR_getsockname 204
|
||||
#define TARGET_NR_getpeername 205
|
||||
#define TARGET_NR_sendto 206
|
||||
#define TARGET_NR_recvfrom 207
|
||||
#define TARGET_NR_setsockopt 208
|
||||
#define TARGET_NR_getsockopt 209
|
||||
#define TARGET_NR_shutdown 210
|
||||
#define TARGET_NR_sendmsg 211
|
||||
#define TARGET_NR_recvmsg 212
|
||||
#define TARGET_NR_readahead 213
|
||||
#define TARGET_NR_brk 214
|
||||
#define TARGET_NR_munmap 215
|
||||
#define TARGET_NR_mremap 216
|
||||
#define TARGET_NR_add_key 217
|
||||
#define TARGET_NR_request_key 218
|
||||
#define TARGET_NR_keyctl 219
|
||||
#define TARGET_NR_clone 220
|
||||
#define TARGET_NR_execve 221
|
||||
#define TARGET_NR_mmap 222
|
||||
#define TARGET_NR_fadvise64 223
|
||||
#define TARGET_NR_swapon 224
|
||||
#define TARGET_NR_swapoff 225
|
||||
#define TARGET_NR_mprotect 226
|
||||
#define TARGET_NR_msync 227
|
||||
#define TARGET_NR_mlock 228
|
||||
#define TARGET_NR_munlock 229
|
||||
#define TARGET_NR_mlockall 230
|
||||
#define TARGET_NR_munlockall 231
|
||||
#define TARGET_NR_mincore 232
|
||||
#define TARGET_NR_madvise 233
|
||||
#define TARGET_NR_remap_file_pages 234
|
||||
#define TARGET_NR_mbind 235
|
||||
#define TARGET_NR_get_mempolicy 236
|
||||
#define TARGET_NR_set_mempolicy 237
|
||||
#define TARGET_NR_migrate_pages 238
|
||||
#define TARGET_NR_move_pages 239
|
||||
#define TARGET_NR_rt_tgsigqueueinfo 240
|
||||
#define TARGET_NR_perf_event_open 241
|
||||
#define TARGET_NR_accept4 242
|
||||
#define TARGET_NR_recvmmsg 243
|
||||
#define TARGET_NR_arch_specific_syscall 244
|
||||
#define TARGET_NR_wait4 260
|
||||
#define TARGET_NR_prlimit64 261
|
||||
#define TARGET_NR_fanotify_init 262
|
||||
#define TARGET_NR_fanotify_mark 263
|
||||
#define TARGET_NR_name_to_handle_at 264
|
||||
#define TARGET_NR_open_by_handle_at 265
|
||||
#define TARGET_NR_clock_adjtime 266
|
||||
#define TARGET_NR_syncfs 267
|
||||
#define TARGET_NR_setns 268
|
||||
#define TARGET_NR_sendmmsg 269
|
||||
#define TARGET_NR_process_vm_readv 270
|
||||
#define TARGET_NR_process_vm_writev 271
|
||||
#define TARGET_NR_kcmp 272
|
||||
#define TARGET_NR_finit_module 273
|
||||
#define TARGET_NR_open 1024
|
||||
#define TARGET_NR_link 1025
|
||||
#define TARGET_NR_unlink 1026
|
||||
#define TARGET_NR_mknod 1027
|
||||
#define TARGET_NR_chmod 1028
|
||||
#define TARGET_NR_chown 1029
|
||||
#define TARGET_NR_mkdir 1030
|
||||
#define TARGET_NR_rmdir 1031
|
||||
#define TARGET_NR_lchown 1032
|
||||
#define TARGET_NR_access 1033
|
||||
#define TARGET_NR_rename 1034
|
||||
#define TARGET_NR_readlink 1035
|
||||
#define TARGET_NR_symlink 1036
|
||||
#define TARGET_NR_utimes 1037
|
||||
#define TARGET_NR_stat 1038
|
||||
#define TARGET_NR_lstat 1039
|
||||
#define TARGET_NR_pipe 1040
|
||||
#define TARGET_NR_dup2 1041
|
||||
#define TARGET_NR_epoll_create 1042
|
||||
#define TARGET_NR_inotify_init 1043
|
||||
#define TARGET_NR_eventfd 1044
|
||||
#define TARGET_NR_signalfd 1045
|
||||
#define TARGET_NR_sendfile64 1046
|
||||
#define TARGET_NR_ftruncate64 1047
|
||||
#define TARGET_NR_truncate64 1048
|
||||
#define TARGET_NR_stat64 1049
|
||||
#define TARGET_NR_lstat64 1050
|
||||
#define TARGET_NR_fstat64 1051
|
||||
#define TARGET_NR_fcntl64 1052
|
||||
/* #define TARGET_NR_fadvise64 1053 */
|
||||
#define TARGET_NR_newfstatat 1054
|
||||
#define TARGET_NR_fstatfs64 1055
|
||||
#define TARGET_NR_statfs64 1056
|
||||
#define TARGET_NR_lseek64 1057
|
||||
#define TARGET_NR_mmap64 1058
|
||||
#define TARGET_NR_alarm 1059
|
||||
#define TARGET_NR_getpgrp 1060
|
||||
#define TARGET_NR_pause 1061
|
||||
#define TARGET_NR_time 1062
|
||||
#define TARGET_NR_utime 1063
|
||||
#define TARGET_NR_creat 1064
|
||||
#define TARGET_NR_getdents 1065
|
||||
#define TARGET_NR_futimesat 1066
|
||||
#define TARGET_NR_select 1067
|
||||
#define TARGET_NR_poll 1068
|
||||
#define TARGET_NR_epoll_wait 1069
|
||||
#define TARGET_NR_ustat 1070
|
||||
#define TARGET_NR_vfork 1071
|
||||
#define TARGET_NR_oldwait4 1072
|
||||
#define TARGET_NR_recv 1073
|
||||
#define TARGET_NR_send 1074
|
||||
#define TARGET_NR_bdflush 1075
|
||||
#define TARGET_NR_umount 1076
|
||||
#define TARGET_NR_uselib 1077
|
||||
#define TARGET_NR__sysctl 1078
|
||||
#define TARGET_NR_fork 1079
|
||||
#define TARGET_NR_syscalls (__NR_fork+1)
|
||||
|
||||
#define TARGET_NR_sigreturn 1999
|
35
linux-user/aarch64/target_cpu.h
Normal file
35
linux-user/aarch64/target_cpu.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* ARM AArch64 specific CPU ABI and functions for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef TARGET_CPU_H
|
||||
#define TARGET_CPU_H
|
||||
|
||||
static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
|
||||
{
|
||||
if (newsp) {
|
||||
env->xregs[31] = newsp;
|
||||
}
|
||||
env->xregs[0] = 0;
|
||||
}
|
||||
|
||||
static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
|
||||
{
|
||||
env->sr.tpidr_el0 = newtls;
|
||||
}
|
||||
|
||||
#endif
|
29
linux-user/aarch64/target_signal.h
Normal file
29
linux-user/aarch64/target_signal.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef TARGET_SIGNAL_H
|
||||
#define 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(CPUARMState *state)
|
||||
{
|
||||
return state->xregs[31];
|
||||
}
|
||||
|
||||
#endif /* TARGET_SIGNAL_H */
|
220
linux-user/aarch64/termbits.h
Normal file
220
linux-user/aarch64/termbits.h
Normal file
@ -0,0 +1,220 @@
|
||||
/* from asm/termbits.h */
|
||||
/* NOTE: exactly the same as i386 */
|
||||
|
||||
#define TARGET_NCCS 19
|
||||
|
||||
struct target_termios {
|
||||
unsigned int c_iflag; /* input mode flags */
|
||||
unsigned int c_oflag; /* output mode flags */
|
||||
unsigned int c_cflag; /* control mode flags */
|
||||
unsigned int c_lflag; /* local mode flags */
|
||||
unsigned char c_line; /* line discipline */
|
||||
unsigned char c_cc[TARGET_NCCS]; /* control characters */
|
||||
};
|
||||
|
||||
/* 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_B57600 0010001
|
||||
#define TARGET_B115200 0010002
|
||||
#define TARGET_B230400 0010003
|
||||
#define TARGET_B460800 0010004
|
||||
#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */
|
||||
#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */
|
||||
#define TARGET_CRTSCTS 020000000000 /* flow control */
|
||||
|
||||
/* 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
|
||||
|
||||
/* c_cc character offsets */
|
||||
#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
|
||||
|
||||
/* ioctls */
|
||||
|
||||
#define TARGET_TCGETS 0x5401
|
||||
#define TARGET_TCSETS 0x5402
|
||||
#define TARGET_TCSETSW 0x5403
|
||||
#define TARGET_TCSETSF 0x5404
|
||||
#define TARGET_TCGETA 0x5405
|
||||
#define TARGET_TCSETA 0x5406
|
||||
#define TARGET_TCSETAW 0x5407
|
||||
#define TARGET_TCSETAF 0x5408
|
||||
#define TARGET_TCSBRK 0x5409
|
||||
#define TARGET_TCXONC 0x540A
|
||||
#define TARGET_TCFLSH 0x540B
|
||||
|
||||
#define TARGET_TIOCEXCL 0x540C
|
||||
#define TARGET_TIOCNXCL 0x540D
|
||||
#define TARGET_TIOCSCTTY 0x540E
|
||||
#define TARGET_TIOCGPGRP 0x540F
|
||||
#define TARGET_TIOCSPGRP 0x5410
|
||||
#define TARGET_TIOCOUTQ 0x5411
|
||||
#define TARGET_TIOCSTI 0x5412
|
||||
#define TARGET_TIOCGWINSZ 0x5413
|
||||
#define TARGET_TIOCSWINSZ 0x5414
|
||||
#define TARGET_TIOCMGET 0x5415
|
||||
#define TARGET_TIOCMBIS 0x5416
|
||||
#define TARGET_TIOCMBIC 0x5417
|
||||
#define TARGET_TIOCMSET 0x5418
|
||||
#define TARGET_TIOCGSOFTCAR 0x5419
|
||||
#define TARGET_TIOCSSOFTCAR 0x541A
|
||||
#define TARGET_FIONREAD 0x541B
|
||||
#define TARGET_TIOCINQ TARGET_FIONREAD
|
||||
#define TARGET_TIOCLINUX 0x541C
|
||||
#define TARGET_TIOCCONS 0x541D
|
||||
#define TARGET_TIOCGSERIAL 0x541E
|
||||
#define TARGET_TIOCSSERIAL 0x541F
|
||||
#define TARGET_TIOCPKT 0x5420
|
||||
#define TARGET_FIONBIO 0x5421
|
||||
#define TARGET_TIOCNOTTY 0x5422
|
||||
#define TARGET_TIOCSETD 0x5423
|
||||
#define TARGET_TIOCGETD 0x5424
|
||||
#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
|
||||
#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */
|
||||
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
|
||||
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
|
||||
#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
|
||||
#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int)
|
||||
/* Get Pty Number (of pty-mux device) */
|
||||
#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int)
|
||||
/* Lock/unlock Pty */
|
||||
|
||||
#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
|
||||
#define TARGET_FIOCLEX 0x5451
|
||||
#define TARGET_FIOASYNC 0x5452
|
||||
#define TARGET_TIOCSERCONFIG 0x5453
|
||||
#define TARGET_TIOCSERGWILD 0x5454
|
||||
#define TARGET_TIOCSERSWILD 0x5455
|
||||
#define TARGET_TIOCGLCKTRMIOS 0x5456
|
||||
#define TARGET_TIOCSLCKTRMIOS 0x5457
|
||||
#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
|
||||
#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */
|
||||
#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */
|
||||
#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
|
||||
|
||||
#define TARGET_TIOCMIWAIT 0x545C
|
||||
/* wait for a change on serial input line(s) */
|
||||
#define TARGET_TIOCGICOUNT 0x545D
|
||||
/* read serial port inline interrupt counts */
|
||||
#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
|
||||
#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
|
||||
|
||||
/* Used for packet mode */
|
||||
#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_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
|
@ -30,7 +30,8 @@
|
||||
* return here */
|
||||
const char *cpu_to_uname_machine(void *cpu_env)
|
||||
{
|
||||
#ifdef TARGET_ARM
|
||||
#if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
|
||||
|
||||
/* utsname machine name on linux arm is CPU arch name + endianness, e.g.
|
||||
* armv7l; to get a list of CPU arch names from the linux source, use:
|
||||
* grep arch_name: -A1 linux/arch/arm/mm/proc-*.S
|
||||
|
@ -269,16 +269,26 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
|
||||
#define elf_check_arch(x) ( (x) == EM_ARM )
|
||||
#define elf_check_arch(x) ((x) == ELF_MACHINE)
|
||||
|
||||
#define ELF_ARCH ELF_MACHINE
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#else
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_ARCH EM_ARM
|
||||
#endif
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *regs,
|
||||
struct image_info *infop)
|
||||
{
|
||||
abi_long stack = infop->start_stack;
|
||||
memset(regs, 0, sizeof(*regs));
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
regs->pc = infop->entry & ~0x3ULL;
|
||||
regs->sp = stack;
|
||||
#else
|
||||
regs->ARM_cpsr = 0x10;
|
||||
if (infop->entry & 1)
|
||||
regs->ARM_cpsr |= CPSR_T;
|
||||
@ -292,6 +302,7 @@ static inline void init_thread(struct target_pt_regs *regs,
|
||||
/* For uClinux PIC binaries. */
|
||||
/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
|
||||
regs->ARM_r10 = infop->start_data;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ELF_NREG 18
|
||||
|
@ -449,6 +449,9 @@ void cpu_loop(CPUX86State *env)
|
||||
__r; \
|
||||
})
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
/* Commpage handling -- there is no commpage for AArch64 */
|
||||
|
||||
/*
|
||||
* See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
|
||||
* Input:
|
||||
@ -582,6 +585,7 @@ do_kernel_trap(CPUARMState *env)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_strex(CPUARMState *env)
|
||||
{
|
||||
@ -661,6 +665,7 @@ done:
|
||||
return segv;
|
||||
}
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
void cpu_loop(CPUARMState *env)
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
@ -873,6 +878,83 @@ void cpu_loop(CPUARMState *env)
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* AArch64 main loop */
|
||||
void cpu_loop(CPUARMState *env)
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
int trapnr, sig;
|
||||
target_siginfo_t info;
|
||||
uint32_t addr;
|
||||
|
||||
for (;;) {
|
||||
cpu_exec_start(cs);
|
||||
trapnr = cpu_arm_exec(env);
|
||||
cpu_exec_end(cs);
|
||||
|
||||
switch (trapnr) {
|
||||
case EXCP_SWI:
|
||||
env->xregs[0] = do_syscall(env,
|
||||
env->xregs[8],
|
||||
env->xregs[0],
|
||||
env->xregs[1],
|
||||
env->xregs[2],
|
||||
env->xregs[3],
|
||||
env->xregs[4],
|
||||
env->xregs[5],
|
||||
0, 0);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_UDEF:
|
||||
info.si_signo = SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case EXCP_PREFETCH_ABORT:
|
||||
addr = env->cp15.c6_insn;
|
||||
goto do_segv;
|
||||
case EXCP_DATA_ABORT:
|
||||
addr = env->cp15.c6_data;
|
||||
do_segv:
|
||||
info.si_signo = SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = addr;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
case EXCP_BKPT:
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig) {
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_STREX:
|
||||
if (do_strex(env)) {
|
||||
addr = env->cp15.c6_data;
|
||||
goto do_segv;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
||||
trapnr);
|
||||
cpu_dump_state(cs, stderr, fprintf, 0);
|
||||
abort();
|
||||
}
|
||||
process_pending_signals(env);
|
||||
}
|
||||
}
|
||||
#endif /* ndef TARGET_ABI32 */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_UNICORE32
|
||||
@ -3594,6 +3676,8 @@ int main(int argc, char **argv, char **envp)
|
||||
/* Scan interp_prefix dir for replacement files. */
|
||||
init_paths(interp_prefix);
|
||||
|
||||
init_qemu_uname_release();
|
||||
|
||||
if (cpu_model == NULL) {
|
||||
#if defined(TARGET_I386)
|
||||
#ifdef TARGET_X86_64
|
||||
@ -3884,6 +3968,22 @@ int main(int argc, char **argv, char **envp)
|
||||
cpu_x86_load_seg(env, R_FS, 0);
|
||||
cpu_x86_load_seg(env, R_GS, 0);
|
||||
#endif
|
||||
#elif defined(TARGET_AARCH64)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
|
||||
fprintf(stderr,
|
||||
"The selected ARM CPU does not support 64 bit mode\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
env->xregs[i] = regs->regs[i];
|
||||
}
|
||||
env->pc = regs->pc;
|
||||
env->xregs[31] = regs->sp;
|
||||
}
|
||||
#elif defined(TARGET_ARM)
|
||||
{
|
||||
int i;
|
||||
|
@ -74,7 +74,7 @@ struct vm86_saved_state {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_ARM
|
||||
#if defined(TARGET_ARM) && defined(TARGET_ABI32)
|
||||
/* FPU emulator */
|
||||
#include "nwfpe/fpa11.h"
|
||||
#endif
|
||||
@ -98,8 +98,10 @@ struct emulated_sigtable {
|
||||
typedef struct TaskState {
|
||||
pid_t ts_tid; /* tid (or pid) of this task */
|
||||
#ifdef TARGET_ARM
|
||||
# ifdef TARGET_ABI32
|
||||
/* FPA state */
|
||||
FPA11 fpa;
|
||||
# endif
|
||||
int swi_errno;
|
||||
#endif
|
||||
#ifdef TARGET_UNICORE32
|
||||
@ -195,6 +197,7 @@ extern THREAD CPUState *thread_cpu;
|
||||
void cpu_loop(CPUArchState *env);
|
||||
char *target_strerror(int err);
|
||||
int get_osversion(void);
|
||||
void init_qemu_uname_release(void);
|
||||
void fork_start(void);
|
||||
void fork_end(int child);
|
||||
|
||||
|
@ -1092,6 +1092,266 @@ badframe:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_AARCH64)
|
||||
|
||||
struct target_sigcontext {
|
||||
uint64_t fault_address;
|
||||
/* AArch64 registers */
|
||||
uint64_t regs[31];
|
||||
uint64_t sp;
|
||||
uint64_t pc;
|
||||
uint64_t pstate;
|
||||
/* 4K reserved for FP/SIMD state and future expansion */
|
||||
char __reserved[4096] __attribute__((__aligned__(16)));
|
||||
};
|
||||
|
||||
struct target_ucontext {
|
||||
abi_ulong tuc_flags;
|
||||
abi_ulong tuc_link;
|
||||
target_stack_t tuc_stack;
|
||||
target_sigset_t tuc_sigmask;
|
||||
/* glibc uses a 1024-bit sigset_t */
|
||||
char __unused[1024 / 8 - sizeof(target_sigset_t)];
|
||||
/* last for future expansion */
|
||||
struct target_sigcontext tuc_mcontext;
|
||||
};
|
||||
|
||||
/*
|
||||
* Header to be used at the beginning of structures extending the user
|
||||
* context. Such structures must be placed after the rt_sigframe on the stack
|
||||
* and be 16-byte aligned. The last structure must be a dummy one with the
|
||||
* magic and size set to 0.
|
||||
*/
|
||||
struct target_aarch64_ctx {
|
||||
uint32_t magic;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
#define TARGET_FPSIMD_MAGIC 0x46508001
|
||||
|
||||
struct target_fpsimd_context {
|
||||
struct target_aarch64_ctx head;
|
||||
uint32_t fpsr;
|
||||
uint32_t fpcr;
|
||||
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
|
||||
};
|
||||
|
||||
/*
|
||||
* Auxiliary context saved in the sigcontext.__reserved array. Not exported to
|
||||
* user space as it will change with the addition of new context. User space
|
||||
* should check the magic/size information.
|
||||
*/
|
||||
struct target_aux_context {
|
||||
struct target_fpsimd_context fpsimd;
|
||||
/* additional context to be added before "end" */
|
||||
struct target_aarch64_ctx end;
|
||||
};
|
||||
|
||||
struct target_rt_sigframe {
|
||||
struct target_siginfo info;
|
||||
struct target_ucontext uc;
|
||||
uint64_t fp;
|
||||
uint64_t lr;
|
||||
uint32_t tramp[2];
|
||||
};
|
||||
|
||||
static int target_setup_sigframe(struct target_rt_sigframe *sf,
|
||||
CPUARMState *env, target_sigset_t *set)
|
||||
{
|
||||
int i;
|
||||
struct target_aux_context *aux =
|
||||
(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
|
||||
|
||||
/* set up the stack frame for unwinding */
|
||||
__put_user(env->xregs[29], &sf->fp);
|
||||
__put_user(env->xregs[30], &sf->lr);
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
__put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
|
||||
}
|
||||
__put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
|
||||
__put_user(env->pc, &sf->uc.tuc_mcontext.pc);
|
||||
__put_user(env->pstate, &sf->uc.tuc_mcontext.pstate);
|
||||
|
||||
__put_user(/*current->thread.fault_address*/ 0,
|
||||
&sf->uc.tuc_mcontext.fault_address);
|
||||
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
__put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
__put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
|
||||
__put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
|
||||
#else
|
||||
__put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
|
||||
__put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
|
||||
#endif
|
||||
}
|
||||
__put_user(/*env->fpsr*/0, &aux->fpsimd.fpsr);
|
||||
__put_user(/*env->fpcr*/0, &aux->fpsimd.fpcr);
|
||||
__put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
|
||||
__put_user(sizeof(struct target_fpsimd_context),
|
||||
&aux->fpsimd.head.size);
|
||||
|
||||
/* set the "end" magic */
|
||||
__put_user(0, &aux->end.magic);
|
||||
__put_user(0, &aux->end.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int target_restore_sigframe(CPUARMState *env,
|
||||
struct target_rt_sigframe *sf)
|
||||
{
|
||||
sigset_t set;
|
||||
int i;
|
||||
struct target_aux_context *aux =
|
||||
(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
|
||||
uint32_t magic, size;
|
||||
|
||||
target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
|
||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
__get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
|
||||
}
|
||||
|
||||
__get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
|
||||
__get_user(env->pc, &sf->uc.tuc_mcontext.pc);
|
||||
__get_user(env->pstate, &sf->uc.tuc_mcontext.pstate);
|
||||
|
||||
__get_user(magic, &aux->fpsimd.head.magic);
|
||||
__get_user(size, &aux->fpsimd.head.size);
|
||||
|
||||
if (magic != TARGET_FPSIMD_MAGIC
|
||||
|| size != sizeof(struct target_fpsimd_context)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32 * 2; i++) {
|
||||
__get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
|
||||
{
|
||||
abi_ulong sp;
|
||||
|
||||
sp = env->xregs[31];
|
||||
|
||||
/*
|
||||
* This is the X/Open sanctioned signal stack switching.
|
||||
*/
|
||||
if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
|
||||
sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
static void target_setup_frame(int usig, struct target_sigaction *ka,
|
||||
target_siginfo_t *info, target_sigset_t *set,
|
||||
CPUARMState *env)
|
||||
{
|
||||
struct target_rt_sigframe *frame;
|
||||
abi_ulong frame_addr;
|
||||
|
||||
frame_addr = get_sigframe(ka, env);
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
__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->xregs[31]),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
target_setup_sigframe(frame, env, set);
|
||||
/* mov x8,#__NR_rt_sigreturn; svc #0 */
|
||||
__put_user(0xd2801168, &frame->tramp[0]);
|
||||
__put_user(0xd4000001, &frame->tramp[1]);
|
||||
env->xregs[0] = usig;
|
||||
env->xregs[31] = frame_addr;
|
||||
env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
|
||||
env->pc = ka->_sa_handler;
|
||||
env->xregs[30] = env->xregs[31] +
|
||||
offsetof(struct target_rt_sigframe, tramp);
|
||||
if (info) {
|
||||
if (copy_siginfo_to_user(&frame->info, info)) {
|
||||
goto give_sigsegv;
|
||||
}
|
||||
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
|
||||
env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
|
||||
}
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
target_siginfo_t *info, target_sigset_t *set,
|
||||
CPUARMState *env)
|
||||
{
|
||||
target_setup_frame(sig, ka, info, set, env);
|
||||
}
|
||||
|
||||
static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
target_sigset_t *set, CPUARMState *env)
|
||||
{
|
||||
target_setup_frame(sig, ka, 0, set, env);
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUARMState *env)
|
||||
{
|
||||
struct target_rt_sigframe *frame;
|
||||
abi_ulong frame_addr = env->xregs[31];
|
||||
|
||||
if (frame_addr & 15) {
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (target_restore_sigframe(env, frame)) {
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return env->xregs[0];
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUARMState *env)
|
||||
{
|
||||
return do_rt_sigreturn(env);
|
||||
}
|
||||
|
||||
#elif defined(TARGET_ARM)
|
||||
|
||||
struct target_sigcontext {
|
||||
|
@ -4737,7 +4737,7 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
|
||||
abi_ulong target_addr,
|
||||
struct stat *host_st)
|
||||
{
|
||||
#ifdef TARGET_ARM
|
||||
#if defined(TARGET_ARM) && defined(TARGET_ABI32)
|
||||
if (((CPUARMState *)cpu_env)->eabi) {
|
||||
struct target_eabi_stat64 *target_st;
|
||||
|
||||
@ -4863,21 +4863,13 @@ int host_to_target_waitstatus(int status)
|
||||
return status;
|
||||
}
|
||||
|
||||
int get_osversion(void)
|
||||
static int relstr_to_int(const char *s)
|
||||
{
|
||||
static int osversion;
|
||||
struct new_utsname buf;
|
||||
const char *s;
|
||||
/* Convert a uname release string like "2.6.18" to an integer
|
||||
* of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
|
||||
*/
|
||||
int i, n, tmp;
|
||||
if (osversion)
|
||||
return osversion;
|
||||
if (qemu_uname_release && *qemu_uname_release) {
|
||||
s = qemu_uname_release;
|
||||
} else {
|
||||
if (sys_uname(&buf))
|
||||
return 0;
|
||||
s = buf.release;
|
||||
}
|
||||
|
||||
tmp = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
n = 0;
|
||||
@ -4887,13 +4879,55 @@ int get_osversion(void)
|
||||
s++;
|
||||
}
|
||||
tmp = (tmp << 8) + n;
|
||||
if (*s == '.')
|
||||
if (*s == '.') {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
osversion = tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int get_osversion(void)
|
||||
{
|
||||
static int osversion;
|
||||
struct new_utsname buf;
|
||||
const char *s;
|
||||
|
||||
if (osversion)
|
||||
return osversion;
|
||||
if (qemu_uname_release && *qemu_uname_release) {
|
||||
s = qemu_uname_release;
|
||||
} else {
|
||||
if (sys_uname(&buf))
|
||||
return 0;
|
||||
s = buf.release;
|
||||
}
|
||||
osversion = relstr_to_int(s);
|
||||
return osversion;
|
||||
}
|
||||
|
||||
void init_qemu_uname_release(void)
|
||||
{
|
||||
/* Initialize qemu_uname_release for later use.
|
||||
* If the host kernel is too old and the user hasn't asked for
|
||||
* a specific fake version number, we might want to fake a minimum
|
||||
* target kernel version.
|
||||
*/
|
||||
#ifdef UNAME_MINIMUM_RELEASE
|
||||
struct new_utsname buf;
|
||||
|
||||
if (qemu_uname_release && *qemu_uname_release) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sys_uname(&buf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
|
||||
qemu_uname_release = UNAME_MINIMUM_RELEASE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int open_self_maps(void *cpu_env, int fd)
|
||||
{
|
||||
@ -6381,7 +6415,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
#endif
|
||||
#ifdef TARGET_NR_mmap
|
||||
case TARGET_NR_mmap:
|
||||
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
|
||||
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
|
||||
(defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
|
||||
defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
|
||||
|| defined(TARGET_S390X)
|
||||
{
|
||||
|
@ -1137,7 +1137,8 @@ struct target_winsize {
|
||||
#define TARGET_MAP_UNINITIALIZED 0x4000000 /* for anonymous mmap, memory could be uninitialized */
|
||||
#endif
|
||||
|
||||
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) \
|
||||
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) \
|
||||
|| (defined(TARGET_ARM) && defined(TARGET_ABI32)) \
|
||||
|| defined(TARGET_CRIS) || defined(TARGET_UNICORE32)
|
||||
struct target_stat {
|
||||
unsigned short st_dev;
|
||||
@ -1835,6 +1836,28 @@ struct target_stat {
|
||||
abi_long st_blocks;
|
||||
abi_ulong __unused[3];
|
||||
};
|
||||
#elif defined(TARGET_AARCH64)
|
||||
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_ulong _pad1;
|
||||
abi_long st_size;
|
||||
int st_blksize;
|
||||
int __pad2;
|
||||
abi_long st_blocks;
|
||||
abi_long target_st_atime;
|
||||
abi_ulong target_st_atime_nsec;
|
||||
abi_long target_st_mtime;
|
||||
abi_ulong target_st_mtime_nsec;
|
||||
abi_long target_st_ctime;
|
||||
abi_ulong target_st_ctime_nsec;
|
||||
unsigned int __unused[2];
|
||||
};
|
||||
#elif defined(TARGET_OPENRISC)
|
||||
|
||||
/* These are the asm-generic versions of the stat and stat64 structures */
|
||||
@ -1943,7 +1966,8 @@ struct target_statfs64 {
|
||||
uint32_t f_spare[6];
|
||||
};
|
||||
#elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \
|
||||
defined(TARGET_SPARC64)) && !defined(TARGET_ABI32)
|
||||
defined(TARGET_SPARC64) || defined(TARGET_AARCH64)) && \
|
||||
!defined(TARGET_ABI32)
|
||||
struct target_statfs {
|
||||
abi_long f_type;
|
||||
abi_long f_bsize;
|
||||
|
@ -5,3 +5,4 @@ obj-$(CONFIG_NO_KVM) += kvm-stub.o
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-y += neon_helper.o iwmmxt_helper.o
|
||||
obj-y += gdbstub.o
|
||||
obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o gdbstub64.o
|
||||
|
@ -130,6 +130,18 @@ typedef struct ARMCPU {
|
||||
uint32_t reset_auxcr;
|
||||
} ARMCPU;
|
||||
|
||||
#define TYPE_AARCH64_CPU "aarch64-cpu"
|
||||
#define AARCH64_CPU_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(AArch64CPUClass, (klass), TYPE_AARCH64_CPU)
|
||||
#define AARCH64_CPU_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(AArch64CPUClass, (obj), TYPE_AArch64_CPU)
|
||||
|
||||
typedef struct AArch64CPUClass {
|
||||
/*< private >*/
|
||||
ARMCPUClass parent_class;
|
||||
/*< public >*/
|
||||
} AArch64CPUClass;
|
||||
|
||||
static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
|
||||
{
|
||||
return container_of(env, ARMCPU, env);
|
||||
@ -161,4 +173,11 @@ int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
void arm_gt_ptimer_cb(void *opaque);
|
||||
void arm_gt_vtimer_cb(void *opaque);
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
fprintf_function cpu_fprintf, int flags);
|
||||
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -84,6 +84,11 @@ static void arm_cpu_reset(CPUState *s)
|
||||
env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
|
||||
}
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
|
||||
/* 64 bit CPUs always start in 64 bit mode */
|
||||
env->aarch64 = 1;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
env->uncached_cpsr = ARM_CPU_MODE_USR;
|
||||
/* For user mode we must enable access to coprocessors */
|
||||
@ -108,7 +113,7 @@ static void arm_cpu_reset(CPUState *s)
|
||||
modified flash and reset itself. However images
|
||||
loaded via -kernel have not been copied yet, so load the
|
||||
values directly from there. */
|
||||
env->regs[13] = ldl_p(rom);
|
||||
env->regs[13] = ldl_p(rom) & 0xFFFFFFFC;
|
||||
pc = ldl_p(rom + 4);
|
||||
env->thumb = pc & 1;
|
||||
env->regs[15] = pc & ~1;
|
||||
@ -288,8 +293,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
acc->parent_realize(dev, errp);
|
||||
}
|
||||
|
||||
/* CPU models */
|
||||
|
||||
static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
@ -309,6 +312,9 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
|
||||
return oc;
|
||||
}
|
||||
|
||||
/* CPU models. These are not needed for the AArch64 linux-user build. */
|
||||
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
|
||||
|
||||
static void arm926_initfn(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
@ -822,6 +828,7 @@ static void pxa270c5_initfn(Object *obj)
|
||||
cpu->reset_sctlr = 0x00000078;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static void arm_any_initfn(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
@ -832,8 +839,14 @@ static void arm_any_initfn(Object *obj)
|
||||
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V7MP);
|
||||
#ifdef TARGET_AARCH64
|
||||
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
|
||||
#endif
|
||||
cpu->midr = 0xffffffff;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */
|
||||
|
||||
typedef struct ARMCPUInfo {
|
||||
const char *name;
|
||||
@ -842,6 +855,7 @@ typedef struct ARMCPUInfo {
|
||||
} ARMCPUInfo;
|
||||
|
||||
static const ARMCPUInfo arm_cpus[] = {
|
||||
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
|
||||
{ .name = "arm926", .initfn = arm926_initfn },
|
||||
{ .name = "arm946", .initfn = arm946_initfn },
|
||||
{ .name = "arm1026", .initfn = arm1026_initfn },
|
||||
@ -874,7 +888,10 @@ static const ARMCPUInfo arm_cpus[] = {
|
||||
{ .name = "pxa270-b1", .initfn = pxa270b1_initfn },
|
||||
{ .name = "pxa270-c0", .initfn = pxa270c0_initfn },
|
||||
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
{ .name = "any", .initfn = arm_any_initfn },
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
170
target-arm/cpu.h
170
target-arm/cpu.h
@ -19,13 +19,19 @@
|
||||
#ifndef CPU_ARM_H
|
||||
#define CPU_ARM_H
|
||||
|
||||
#define TARGET_LONG_BITS 32
|
||||
#include "config.h"
|
||||
|
||||
#define ELF_MACHINE EM_ARM
|
||||
#if defined(TARGET_AARCH64)
|
||||
/* AArch64 definitions */
|
||||
# define TARGET_LONG_BITS 64
|
||||
# define ELF_MACHINE EM_AARCH64
|
||||
#else
|
||||
# define TARGET_LONG_BITS 32
|
||||
# define ELF_MACHINE EM_ARM
|
||||
#endif
|
||||
|
||||
#define CPUArchState struct CPUARMState
|
||||
|
||||
#include "config.h"
|
||||
#include "qemu-common.h"
|
||||
#include "exec/cpu-defs.h"
|
||||
|
||||
@ -97,6 +103,20 @@ typedef struct ARMGenericTimer {
|
||||
typedef struct CPUARMState {
|
||||
/* Regs for current mode. */
|
||||
uint32_t regs[16];
|
||||
|
||||
/* 32/64 switch only happens when taking and returning from
|
||||
* exceptions so the overlap semantics are taken care of then
|
||||
* instead of having a complicated union.
|
||||
*/
|
||||
/* Regs for A64 mode. */
|
||||
uint64_t xregs[32];
|
||||
uint64_t pc;
|
||||
/* TODO: pstate doesn't correspond to an architectural register;
|
||||
* it would be better modelled as the underlying fields.
|
||||
*/
|
||||
uint32_t pstate;
|
||||
uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
|
||||
|
||||
/* Frequently accessed CPSR bits are stored separately for efficiency.
|
||||
This contains all the other bits. Use cpsr_{read,write} to access
|
||||
the whole CPSR. */
|
||||
@ -175,6 +195,11 @@ typedef struct CPUARMState {
|
||||
uint32_t c15_power_control; /* power control */
|
||||
} cp15;
|
||||
|
||||
/* System registers (AArch64) */
|
||||
struct {
|
||||
uint64_t tpidr_el0;
|
||||
} sr;
|
||||
|
||||
struct {
|
||||
uint32_t other_sp;
|
||||
uint32_t vecbase;
|
||||
@ -191,7 +216,22 @@ typedef struct CPUARMState {
|
||||
|
||||
/* VFP coprocessor state. */
|
||||
struct {
|
||||
float64 regs[32];
|
||||
/* VFP/Neon register state. Note that the mapping between S, D and Q
|
||||
* views of the register bank differs between AArch64 and AArch32:
|
||||
* In AArch32:
|
||||
* Qn = regs[2n+1]:regs[2n]
|
||||
* Dn = regs[n]
|
||||
* Sn = regs[n/2] bits 31..0 for even n, and bits 63..32 for odd n
|
||||
* (and regs[32] to regs[63] are inaccessible)
|
||||
* In AArch64:
|
||||
* Qn = regs[2n+1]:regs[2n]
|
||||
* Dn = regs[2n]
|
||||
* Sn = regs[2n] bits 31..0
|
||||
* This corresponds to the architecturally defined mapping between
|
||||
* the two execution states, and means we do not need to explicitly
|
||||
* map these registers when changing states.
|
||||
*/
|
||||
float64 regs[64];
|
||||
|
||||
uint32_t xregs[16];
|
||||
/* We store these fpcsr fields separately for convenience. */
|
||||
@ -261,6 +301,20 @@ int bank_number(int mode);
|
||||
void switch_mode(CPUARMState *, int);
|
||||
uint32_t do_arm_semihosting(CPUARMState *env);
|
||||
|
||||
static inline bool is_a64(CPUARMState *env)
|
||||
{
|
||||
return env->aarch64;
|
||||
}
|
||||
|
||||
#define PSTATE_N_SHIFT 3
|
||||
#define PSTATE_N (1 << PSTATE_N_SHIFT)
|
||||
#define PSTATE_Z_SHIFT 2
|
||||
#define PSTATE_Z (1 << PSTATE_Z_SHIFT)
|
||||
#define PSTATE_C_SHIFT 1
|
||||
#define PSTATE_C (1 << PSTATE_C_SHIFT)
|
||||
#define PSTATE_V_SHIFT 0
|
||||
#define PSTATE_V (1 << PSTATE_V_SHIFT)
|
||||
|
||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
|
||||
signal handlers to inform the virtual CPU of exceptions. non zero
|
||||
is returned if the signal was handled by the virtual CPU. */
|
||||
@ -270,22 +324,22 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
|
||||
int mmu_idx);
|
||||
#define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
|
||||
|
||||
#define CPSR_M (0x1f)
|
||||
#define CPSR_T (1 << 5)
|
||||
#define CPSR_F (1 << 6)
|
||||
#define CPSR_I (1 << 7)
|
||||
#define CPSR_A (1 << 8)
|
||||
#define CPSR_E (1 << 9)
|
||||
#define CPSR_IT_2_7 (0xfc00)
|
||||
#define CPSR_GE (0xf << 16)
|
||||
#define CPSR_RESERVED (0xf << 20)
|
||||
#define CPSR_J (1 << 24)
|
||||
#define CPSR_IT_0_1 (3 << 25)
|
||||
#define CPSR_Q (1 << 27)
|
||||
#define CPSR_V (1 << 28)
|
||||
#define CPSR_C (1 << 29)
|
||||
#define CPSR_Z (1 << 30)
|
||||
#define CPSR_N (1 << 31)
|
||||
#define CPSR_M (0x1fU)
|
||||
#define CPSR_T (1U << 5)
|
||||
#define CPSR_F (1U << 6)
|
||||
#define CPSR_I (1U << 7)
|
||||
#define CPSR_A (1U << 8)
|
||||
#define CPSR_E (1U << 9)
|
||||
#define CPSR_IT_2_7 (0xfc00U)
|
||||
#define CPSR_GE (0xfU << 16)
|
||||
#define CPSR_RESERVED (0xfU << 20)
|
||||
#define CPSR_J (1U << 24)
|
||||
#define CPSR_IT_0_1 (3U << 25)
|
||||
#define CPSR_Q (1U << 27)
|
||||
#define CPSR_V (1U << 28)
|
||||
#define CPSR_C (1U << 29)
|
||||
#define CPSR_Z (1U << 30)
|
||||
#define CPSR_N (1U << 31)
|
||||
#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V)
|
||||
|
||||
#define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7)
|
||||
@ -409,6 +463,7 @@ enum arm_features {
|
||||
ARM_FEATURE_PXN, /* has Privileged Execute Never bit */
|
||||
ARM_FEATURE_LPAE, /* has Large Physical Address Extension */
|
||||
ARM_FEATURE_V8,
|
||||
ARM_FEATURE_AARCH64, /* supports 64 bit mode */
|
||||
};
|
||||
|
||||
static inline int arm_feature(CPUARMState *env, int feature)
|
||||
@ -729,8 +784,13 @@ bool write_cpustate_to_list(ARMCPU *cpu);
|
||||
#define TARGET_PAGE_BITS 10
|
||||
#endif
|
||||
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 40
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#if defined(TARGET_AARCH64)
|
||||
# define TARGET_PHYS_ADDR_SPACE_BITS 48
|
||||
# define TARGET_VIRT_ADDR_SPACE_BITS 64
|
||||
#else
|
||||
# define TARGET_PHYS_ADDR_SPACE_BITS 40
|
||||
# define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#endif
|
||||
|
||||
static inline CPUARMState *cpu_init(const char *cpu_model)
|
||||
{
|
||||
@ -757,7 +817,13 @@ static inline int cpu_mmu_index (CPUARMState *env)
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
/* Bit usage in the TB flags field: */
|
||||
/* Bit usage in the TB flags field: bit 31 indicates whether we are
|
||||
* in 32 or 64 bit mode. The meaning of the other bits depends on that.
|
||||
*/
|
||||
#define ARM_TBFLAG_AARCH64_STATE_SHIFT 31
|
||||
#define ARM_TBFLAG_AARCH64_STATE_MASK (1U << ARM_TBFLAG_AARCH64_STATE_SHIFT)
|
||||
|
||||
/* Bit usage when in AArch32 state: */
|
||||
#define ARM_TBFLAG_THUMB_SHIFT 0
|
||||
#define ARM_TBFLAG_THUMB_MASK (1 << ARM_TBFLAG_THUMB_SHIFT)
|
||||
#define ARM_TBFLAG_VECLEN_SHIFT 1
|
||||
@ -772,9 +838,12 @@ static inline int cpu_mmu_index (CPUARMState *env)
|
||||
#define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
|
||||
#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
|
||||
#define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
|
||||
/* Bits 31..17 are currently unused. */
|
||||
|
||||
/* Bit usage when in AArch64 state: currently no bits defined */
|
||||
|
||||
/* some convenience accessor macros */
|
||||
#define ARM_TBFLAG_AARCH64_STATE(F) \
|
||||
(((F) & ARM_TBFLAG_AARCH64_STATE_MASK) >> ARM_TBFLAG_AARCH64_STATE_SHIFT)
|
||||
#define ARM_TBFLAG_THUMB(F) \
|
||||
(((F) & ARM_TBFLAG_THUMB_MASK) >> ARM_TBFLAG_THUMB_SHIFT)
|
||||
#define ARM_TBFLAG_VECLEN(F) \
|
||||
@ -793,25 +862,31 @@ static inline int cpu_mmu_index (CPUARMState *env)
|
||||
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, int *flags)
|
||||
{
|
||||
int privmode;
|
||||
*pc = env->regs[15];
|
||||
*cs_base = 0;
|
||||
*flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
|
||||
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
|
||||
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
|
||||
| (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
|
||||
| (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
|
||||
if (arm_feature(env, ARM_FEATURE_M)) {
|
||||
privmode = !((env->v7m.exception == 0) && (env->v7m.control & 1));
|
||||
if (is_a64(env)) {
|
||||
*pc = env->pc;
|
||||
*flags = ARM_TBFLAG_AARCH64_STATE_MASK;
|
||||
} else {
|
||||
privmode = (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR;
|
||||
}
|
||||
if (privmode) {
|
||||
*flags |= ARM_TBFLAG_PRIV_MASK;
|
||||
}
|
||||
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
|
||||
*flags |= ARM_TBFLAG_VFPEN_MASK;
|
||||
int privmode;
|
||||
*pc = env->regs[15];
|
||||
*flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
|
||||
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
|
||||
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
|
||||
| (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
|
||||
| (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
|
||||
if (arm_feature(env, ARM_FEATURE_M)) {
|
||||
privmode = !((env->v7m.exception == 0) && (env->v7m.control & 1));
|
||||
} else {
|
||||
privmode = (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR;
|
||||
}
|
||||
if (privmode) {
|
||||
*flags |= ARM_TBFLAG_PRIV_MASK;
|
||||
}
|
||||
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
|
||||
*flags |= ARM_TBFLAG_VFPEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
*cs_base = 0;
|
||||
}
|
||||
|
||||
static inline bool cpu_has_work(CPUState *cpu)
|
||||
@ -822,8 +897,17 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||
|
||||
#include "exec/exec-all.h"
|
||||
|
||||
static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
|
||||
{
|
||||
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
|
||||
env->pc = tb->pc;
|
||||
} else {
|
||||
env->regs[15] = tb->pc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load an instruction and return it in the standard little-endian order */
|
||||
static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
|
||||
static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr,
|
||||
bool do_swap)
|
||||
{
|
||||
uint32_t insn = cpu_ldl_code(env, addr);
|
||||
@ -834,7 +918,7 @@ static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
|
||||
}
|
||||
|
||||
/* Ditto, for a halfword (Thumb) instruction */
|
||||
static inline uint16_t arm_lduw_code(CPUARMState *env, uint32_t addr,
|
||||
static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr,
|
||||
bool do_swap)
|
||||
{
|
||||
uint16_t insn = cpu_lduw_code(env, addr);
|
||||
|
118
target-arm/cpu64.c
Normal file
118
target-arm/cpu64.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* QEMU AArch64 CPU
|
||||
*
|
||||
* Copyright (c) 2013 Linaro Ltd
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see
|
||||
* <http://www.gnu.org/licenses/gpl-2.0.html>
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "qemu-common.h"
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#include "hw/loader.h"
|
||||
#endif
|
||||
#include "hw/arm/arm.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
|
||||
static inline void set_feature(CPUARMState *env, int feature)
|
||||
{
|
||||
env->features |= 1ULL << feature;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static void aarch64_any_initfn(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8);
|
||||
set_feature(&cpu->env, ARM_FEATURE_VFP4);
|
||||
set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
|
||||
set_feature(&cpu->env, ARM_FEATURE_NEON);
|
||||
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V7MP);
|
||||
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct ARMCPUInfo {
|
||||
const char *name;
|
||||
void (*initfn)(Object *obj);
|
||||
void (*class_init)(ObjectClass *oc, void *data);
|
||||
} ARMCPUInfo;
|
||||
|
||||
static const ARMCPUInfo aarch64_cpus[] = {
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
{ .name = "any", .initfn = aarch64_any_initfn },
|
||||
#endif
|
||||
};
|
||||
|
||||
static void aarch64_cpu_initfn(Object *obj)
|
||||
{
|
||||
}
|
||||
|
||||
static void aarch64_cpu_finalizefn(Object *obj)
|
||||
{
|
||||
}
|
||||
|
||||
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(oc);
|
||||
|
||||
cc->dump_state = aarch64_cpu_dump_state;
|
||||
cc->gdb_read_register = aarch64_cpu_gdb_read_register;
|
||||
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
|
||||
cc->gdb_num_core_regs = 34;
|
||||
cc->gdb_core_xml_file = "aarch64-core.xml";
|
||||
}
|
||||
|
||||
static void aarch64_cpu_register(const ARMCPUInfo *info)
|
||||
{
|
||||
TypeInfo type_info = {
|
||||
.parent = TYPE_AARCH64_CPU,
|
||||
.instance_size = sizeof(ARMCPU),
|
||||
.instance_init = info->initfn,
|
||||
.class_size = sizeof(ARMCPUClass),
|
||||
.class_init = info->class_init,
|
||||
};
|
||||
|
||||
type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
|
||||
type_register(&type_info);
|
||||
g_free((void *)type_info.name);
|
||||
}
|
||||
|
||||
static const TypeInfo aarch64_cpu_type_info = {
|
||||
.name = TYPE_AARCH64_CPU,
|
||||
.parent = TYPE_ARM_CPU,
|
||||
.instance_size = sizeof(ARMCPU),
|
||||
.instance_init = aarch64_cpu_initfn,
|
||||
.instance_finalize = aarch64_cpu_finalizefn,
|
||||
.abstract = true,
|
||||
.class_size = sizeof(AArch64CPUClass),
|
||||
.class_init = aarch64_cpu_class_init,
|
||||
};
|
||||
|
||||
static void aarch64_cpu_register_types(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
type_register_static(&aarch64_cpu_type_info);
|
||||
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); i++) {
|
||||
aarch64_cpu_register(&aarch64_cpus[i]);
|
||||
}
|
||||
}
|
||||
|
||||
type_init(aarch64_cpu_register_types)
|
73
target-arm/gdbstub64.c
Normal file
73
target-arm/gdbstub64.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* ARM gdb server stub: AArch64 specific functions.
|
||||
*
|
||||
* Copyright (c) 2013 SUSE LINUX Products GmbH
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "qemu-common.h"
|
||||
#include "exec/gdbstub.h"
|
||||
|
||||
int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
|
||||
if (n < 31) {
|
||||
/* Core integer register. */
|
||||
return gdb_get_reg64(mem_buf, env->xregs[n]);
|
||||
}
|
||||
switch (n) {
|
||||
case 31:
|
||||
return gdb_get_reg64(mem_buf, env->xregs[31]);
|
||||
break;
|
||||
case 32:
|
||||
return gdb_get_reg64(mem_buf, env->pc);
|
||||
break;
|
||||
case 33:
|
||||
return gdb_get_reg32(mem_buf, env->pstate);
|
||||
}
|
||||
/* Unknown register. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
uint64_t tmp;
|
||||
|
||||
tmp = ldq_p(mem_buf);
|
||||
|
||||
if (n < 31) {
|
||||
/* Core integer register. */
|
||||
env->xregs[n] = tmp;
|
||||
return 8;
|
||||
}
|
||||
switch (n) {
|
||||
case 31:
|
||||
env->xregs[31] = tmp;
|
||||
return 8;
|
||||
case 32:
|
||||
env->pc = tmp;
|
||||
return 8;
|
||||
case 33:
|
||||
/* CPSR */
|
||||
env->pstate = tmp;
|
||||
return 4;
|
||||
}
|
||||
/* Unknown register. */
|
||||
return 0;
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
#include "exec/gdbstub.h"
|
||||
#include "helper.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "sysemu/arch_init.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu/bitops.h"
|
||||
|
||||
@ -972,7 +973,7 @@ static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
static inline bool extended_addresses_enabled(CPUARMState *env)
|
||||
{
|
||||
return arm_feature(env, ARM_FEATURE_LPAE)
|
||||
&& (env->cp15.c2_control & (1 << 31));
|
||||
&& (env->cp15.c2_control & (1U << 31));
|
||||
}
|
||||
|
||||
static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
@ -1385,7 +1386,7 @@ static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
* so these bits always RAZ.
|
||||
*/
|
||||
if (arm_feature(env, ARM_FEATURE_V7MP)) {
|
||||
mpidr |= (1 << 31);
|
||||
mpidr |= (1U << 31);
|
||||
/* Cores which are uniprocessor (non-coherent)
|
||||
* but still implement the MP extensions set
|
||||
* bit 30. (For instance, A9UP.) However we do
|
||||
@ -1829,6 +1830,37 @@ void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
||||
g_slist_free(list);
|
||||
}
|
||||
|
||||
static void arm_cpu_add_definition(gpointer data, gpointer user_data)
|
||||
{
|
||||
ObjectClass *oc = data;
|
||||
CpuDefinitionInfoList **cpu_list = user_data;
|
||||
CpuDefinitionInfoList *entry;
|
||||
CpuDefinitionInfo *info;
|
||||
const char *typename;
|
||||
|
||||
typename = object_class_get_name(oc);
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->name = g_strndup(typename,
|
||||
strlen(typename) - strlen("-" TYPE_ARM_CPU));
|
||||
|
||||
entry = g_malloc0(sizeof(*entry));
|
||||
entry->value = info;
|
||||
entry->next = *cpu_list;
|
||||
*cpu_list = entry;
|
||||
}
|
||||
|
||||
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
||||
{
|
||||
CpuDefinitionInfoList *cpu_list = NULL;
|
||||
GSList *list;
|
||||
|
||||
list = object_class_get_list(TYPE_ARM_CPU, false);
|
||||
g_slist_foreach(list, arm_cpu_add_definition, &cpu_list);
|
||||
g_slist_free(list);
|
||||
|
||||
return cpu_list;
|
||||
}
|
||||
|
||||
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
||||
const ARMCPRegInfo *r, void *opaque)
|
||||
{
|
||||
|
@ -37,11 +37,11 @@ static const VMStateInfo vmstate_fpscr = {
|
||||
|
||||
static const VMStateDescription vmstate_vfp = {
|
||||
.name = "cpu/vfp",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.minimum_version_id_old = 2,
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 3,
|
||||
.minimum_version_id_old = 3,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 32),
|
||||
VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 64),
|
||||
/* The xregs array is a little awkward because element 1 (FPSCR)
|
||||
* requires a specific accessor, so we have to split it up in
|
||||
* the vmstate:
|
||||
|
139
target-arm/translate-a64.c
Normal file
139
target-arm/translate-a64.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* AArch64 translation
|
||||
*
|
||||
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "tcg-op.h"
|
||||
#include "qemu/log.h"
|
||||
#include "translate.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
||||
#include "helper.h"
|
||||
#define GEN_HELPER 1
|
||||
#include "helper.h"
|
||||
|
||||
static TCGv_i64 cpu_X[32];
|
||||
static TCGv_i64 cpu_pc;
|
||||
static TCGv_i32 pstate;
|
||||
|
||||
static const char *regnames[] = {
|
||||
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
|
||||
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
|
||||
"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
|
||||
"x24", "x25", "x26", "x27", "x28", "x29", "lr", "sp"
|
||||
};
|
||||
|
||||
/* initialize TCG globals. */
|
||||
void a64_translate_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
|
||||
offsetof(CPUARMState, pc),
|
||||
"pc");
|
||||
for (i = 0; i < 32; i++) {
|
||||
cpu_X[i] = tcg_global_mem_new_i64(TCG_AREG0,
|
||||
offsetof(CPUARMState, xregs[i]),
|
||||
regnames[i]);
|
||||
}
|
||||
|
||||
pstate = tcg_global_mem_new_i32(TCG_AREG0,
|
||||
offsetof(CPUARMState, pstate),
|
||||
"pstate");
|
||||
}
|
||||
|
||||
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
fprintf_function cpu_fprintf, int flags)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
int i;
|
||||
|
||||
cpu_fprintf(f, "PC=%016"PRIx64" SP=%016"PRIx64"\n",
|
||||
env->pc, env->xregs[31]);
|
||||
for (i = 0; i < 31; i++) {
|
||||
cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
|
||||
if ((i % 4) == 3) {
|
||||
cpu_fprintf(f, "\n");
|
||||
} else {
|
||||
cpu_fprintf(f, " ");
|
||||
}
|
||||
}
|
||||
cpu_fprintf(f, "PSTATE=%c%c%c%c\n",
|
||||
env->pstate & PSTATE_N ? 'n' : '.',
|
||||
env->pstate & PSTATE_Z ? 'z' : '.',
|
||||
env->pstate & PSTATE_C ? 'c' : '.',
|
||||
env->pstate & PSTATE_V ? 'v' : '.');
|
||||
cpu_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
void gen_a64_set_pc_im(uint64_t val)
|
||||
{
|
||||
tcg_gen_movi_i64(cpu_pc, val);
|
||||
}
|
||||
|
||||
static void gen_exception(int excp)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_temp_new_i32();
|
||||
tcg_gen_movi_i32(tmp, excp);
|
||||
gen_helper_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
static void gen_exception_insn(DisasContext *s, int offset, int excp)
|
||||
{
|
||||
gen_a64_set_pc_im(s->pc - offset);
|
||||
gen_exception(excp);
|
||||
s->is_jmp = DISAS_JUMP;
|
||||
}
|
||||
|
||||
static void real_unallocated_encoding(DisasContext *s)
|
||||
{
|
||||
fprintf(stderr, "Unknown instruction: %#x\n", s->insn);
|
||||
gen_exception_insn(s, 4, EXCP_UDEF);
|
||||
}
|
||||
|
||||
#define unallocated_encoding(s) do { \
|
||||
fprintf(stderr, "unallocated encoding at line: %d\n", __LINE__); \
|
||||
real_unallocated_encoding(s); \
|
||||
} while (0)
|
||||
|
||||
void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
||||
{
|
||||
uint32_t insn;
|
||||
|
||||
insn = arm_ldl_code(env, s->pc, s->bswap_code);
|
||||
s->insn = insn;
|
||||
s->pc += 4;
|
||||
|
||||
switch ((insn >> 24) & 0x1f) {
|
||||
default:
|
||||
unallocated_encoding(s);
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(s->singlestep_enabled) && (s->is_jmp == DISAS_TB_JUMP)) {
|
||||
/* go through the main loop for single step */
|
||||
s->is_jmp = DISAS_JUMP;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
49
target-arm/translate.h
Normal file
49
target-arm/translate.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef TARGET_ARM_TRANSLATE_H
|
||||
#define TARGET_ARM_TRANSLATE_H
|
||||
|
||||
/* internal defines */
|
||||
typedef struct DisasContext {
|
||||
target_ulong pc;
|
||||
uint32_t insn;
|
||||
int is_jmp;
|
||||
/* Nonzero if this instruction has been conditionally skipped. */
|
||||
int condjmp;
|
||||
/* The label that will be jumped to when the instruction is skipped. */
|
||||
int condlabel;
|
||||
/* Thumb-2 conditional execution bits. */
|
||||
int condexec_mask;
|
||||
int condexec_cond;
|
||||
struct TranslationBlock *tb;
|
||||
int singlestep_enabled;
|
||||
int thumb;
|
||||
int bswap_code;
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
int user;
|
||||
#endif
|
||||
int vfp_enabled;
|
||||
int vec_len;
|
||||
int vec_stride;
|
||||
int aarch64;
|
||||
} DisasContext;
|
||||
|
||||
extern TCGv_ptr cpu_env;
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
void a64_translate_init(void);
|
||||
void disas_a64_insn(CPUARMState *env, DisasContext *s);
|
||||
void gen_a64_set_pc_im(uint64_t val);
|
||||
#else
|
||||
static inline void a64_translate_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void gen_a64_set_pc_im(uint64_t val)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TARGET_ARM_TRANSLATE_H */
|
Loading…
Reference in New Issue
Block a user