[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support
From: |
Mike Frysinger |
Subject: |
[Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support |
Date: |
Mon, 17 Jun 2013 03:16:21 -0400 |
Signed-off-by: Mike Frysinger <address@hidden>
---
default-configs/bfin-linux-user.mak | 1 +
linux-user/bfin/syscall.h | 59 ++++++
linux-user/bfin/syscall_nr.h | 389 ++++++++++++++++++++++++++++++++++++
linux-user/bfin/target_flat.h | 92 +++++++++
linux-user/bfin/target_sigcontext.h | 61 ++++++
linux-user/bfin/target_signal.h | 31 +++
linux-user/bfin/termbits.h | 227 +++++++++++++++++++++
linux-user/elfload.c | 47 +++++
linux-user/main.c | 160 +++++++++++++++
linux-user/qemu.h | 4 +
linux-user/signal.c | 225 +++++++++++++++++++++
linux-user/syscall.c | 3 +-
linux-user/syscall_defs.h | 65 +++++-
linux-user/target_ucontext.h | 14 ++
14 files changed, 1375 insertions(+), 3 deletions(-)
create mode 100644 default-configs/bfin-linux-user.mak
create mode 100644 linux-user/bfin/syscall.h
create mode 100644 linux-user/bfin/syscall_nr.h
create mode 100644 linux-user/bfin/target_flat.h
create mode 100644 linux-user/bfin/target_sigcontext.h
create mode 100644 linux-user/bfin/target_signal.h
create mode 100644 linux-user/bfin/termbits.h
create mode 100644 linux-user/target_ucontext.h
diff --git a/default-configs/bfin-linux-user.mak
b/default-configs/bfin-linux-user.mak
new file mode 100644
index 0000000..5f7aefb
--- /dev/null
+++ b/default-configs/bfin-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for bfin-linux-user
diff --git a/linux-user/bfin/syscall.h b/linux-user/bfin/syscall.h
new file mode 100644
index 0000000..892ee75
--- /dev/null
+++ b/linux-user/bfin/syscall.h
@@ -0,0 +1,59 @@
+struct target_pt_regs {
+ abi_ulong orig_pc;
+ abi_ulong ipend;
+ abi_ulong seqstat;
+ abi_ulong rete;
+ abi_ulong retn;
+ abi_ulong retx;
+ abi_ulong pc; /* PC == RETI */
+ abi_ulong rets;
+ abi_ulong reserved; /* Used as scratch during system calls
*/
+ abi_ulong astat;
+ abi_ulong lb1;
+ abi_ulong lb0;
+ abi_ulong lt1;
+ abi_ulong lt0;
+ abi_ulong lc1;
+ abi_ulong lc0;
+ abi_ulong a1w;
+ abi_ulong a1x;
+ abi_ulong a0w;
+ abi_ulong a0x;
+ abi_ulong b3;
+ abi_ulong b2;
+ abi_ulong b1;
+ abi_ulong b0;
+ abi_ulong l3;
+ abi_ulong l2;
+ abi_ulong l1;
+ abi_ulong l0;
+ abi_ulong m3;
+ abi_ulong m2;
+ abi_ulong m1;
+ abi_ulong m0;
+ abi_ulong i3;
+ abi_ulong i2;
+ abi_ulong i1;
+ abi_ulong i0;
+ abi_ulong usp;
+ abi_ulong fp;
+ abi_ulong p5;
+ abi_ulong p4;
+ abi_ulong p3;
+ abi_ulong p2;
+ abi_ulong p1;
+ abi_ulong p0;
+ abi_ulong r7;
+ abi_ulong r6;
+ abi_ulong r5;
+ abi_ulong r4;
+ abi_ulong r3;
+ abi_ulong r2;
+ abi_ulong r1;
+ abi_ulong r0;
+ abi_ulong orig_r0;
+ abi_ulong orig_p0;
+ abi_ulong syscfg;
+};
+
+#define UNAME_MACHINE "blackfin"
diff --git a/linux-user/bfin/syscall_nr.h b/linux-user/bfin/syscall_nr.h
new file mode 100644
index 0000000..52ec628
--- /dev/null
+++ b/linux-user/bfin/syscall_nr.h
@@ -0,0 +1,389 @@
+/*
+ * This file contains the system call numbers.
+ */
+#define TARGET_NR_restart_syscall 0
+#define TARGET_NR_exit 1
+#define TARGET_NR_fork 2
+#define TARGET_NR_read 3
+#define TARGET_NR_write 4
+#define TARGET_NR_open 5
+#define TARGET_NR_close 6
+ /* 7 TARGET_NR_waitpid obsolete */
+#define TARGET_NR_creat 8
+#define TARGET_NR_link 9
+#define TARGET_NR_unlink 10
+#define TARGET_NR_execve 11
+#define TARGET_NR_chdir 12
+#define TARGET_NR_time 13
+#define TARGET_NR_mknod 14
+#define TARGET_NR_chmod 15
+#define TARGET_NR_chown 16
+ /* 17 TARGET_NR_break obsolete */
+ /* 18 TARGET_NR_oldstat obsolete */
+#define TARGET_NR_lseek 19
+#define TARGET_NR_getpid 20
+#define TARGET_NR_mount 21
+ /* 22 TARGET_NR_umount obsolete */
+#define TARGET_NR_setuid 23
+#define TARGET_NR_getuid 24
+#define TARGET_NR_stime 25
+#define TARGET_NR_ptrace 26
+#define TARGET_NR_alarm 27
+ /* 28 TARGET_NR_oldfstat obsolete */
+#define TARGET_NR_pause 29
+ /* 30 TARGET_NR_utime obsolete */
+ /* 31 TARGET_NR_stty obsolete */
+ /* 32 TARGET_NR_gtty obsolete */
+#define TARGET_NR_access 33
+#define TARGET_NR_nice 34
+ /* 35 TARGET_NR_ftime obsolete */
+#define TARGET_NR_sync 36
+#define TARGET_NR_kill 37
+#define TARGET_NR_rename 38
+#define TARGET_NR_mkdir 39
+#define TARGET_NR_rmdir 40
+#define TARGET_NR_dup 41
+#define TARGET_NR_pipe 42
+#define TARGET_NR_times 43
+ /* 44 TARGET_NR_prof obsolete */
+#define TARGET_NR_brk 45
+#define TARGET_NR_setgid 46
+#define TARGET_NR_getgid 47
+ /* 48 TARGET_NR_signal obsolete */
+#define TARGET_NR_geteuid 49
+#define TARGET_NR_getegid 50
+#define TARGET_NR_acct 51
+#define TARGET_NR_umount2 52
+ /* 53 TARGET_NR_lock obsolete */
+#define TARGET_NR_ioctl 54
+#define TARGET_NR_fcntl 55
+ /* 56 TARGET_NR_mpx obsolete */
+#define TARGET_NR_setpgid 57
+ /* 58 TARGET_NR_ulimit obsolete */
+ /* 59 TARGET_NR_oldolduname obsolete */
+#define TARGET_NR_umask 60
+#define TARGET_NR_chroot 61
+#define TARGET_NR_ustat 62
+#define TARGET_NR_dup2 63
+#define TARGET_NR_getppid 64
+#define TARGET_NR_getpgrp 65
+#define TARGET_NR_setsid 66
+ /* 67 TARGET_NR_sigaction obsolete */
+#define TARGET_NR_sgetmask 68
+#define TARGET_NR_ssetmask 69
+#define TARGET_NR_setreuid 70
+#define TARGET_NR_setregid 71
+ /* 72 TARGET_NR_sigsuspend obsolete */
+ /* 73 TARGET_NR_sigpending obsolete */
+#define TARGET_NR_sethostname 74
+#define TARGET_NR_setrlimit 75
+ /* 76 TARGET_NR_old_getrlimit obsolete */
+#define TARGET_NR_getrusage 77
+#define TARGET_NR_gettimeofday 78
+#define TARGET_NR_settimeofday 79
+#define TARGET_NR_getgroups 80
+#define TARGET_NR_setgroups 81
+ /* 82 TARGET_NR_select obsolete */
+#define TARGET_NR_symlink 83
+ /* 84 TARGET_NR_oldlstat obsolete */
+#define TARGET_NR_readlink 85
+ /* 86 TARGET_NR_uselib obsolete */
+ /* 87 TARGET_NR_swapon obsolete */
+#define TARGET_NR_reboot 88
+ /* 89 TARGET_NR_readdir obsolete */
+ /* 90 TARGET_NR_mmap obsolete */
+#define TARGET_NR_munmap 91
+#define TARGET_NR_truncate 92
+#define TARGET_NR_ftruncate 93
+#define TARGET_NR_fchmod 94
+#define TARGET_NR_fchown 95
+#define TARGET_NR_getpriority 96
+#define TARGET_NR_setpriority 97
+ /* 98 TARGET_NR_profil obsolete */
+#define TARGET_NR_statfs 99
+#define TARGET_NR_fstatfs 100
+ /* 101 TARGET_NR_ioperm */
+ /* 102 TARGET_NR_socketcall obsolete */
+#define TARGET_NR_syslog 103
+#define TARGET_NR_setitimer 104
+#define TARGET_NR_getitimer 105
+#define TARGET_NR_stat 106
+#define TARGET_NR_lstat 107
+#define TARGET_NR_fstat 108
+ /* 109 TARGET_NR_olduname obsolete */
+ /* 110 TARGET_NR_iopl obsolete */
+#define TARGET_NR_vhangup 111
+ /* 112 TARGET_NR_idle obsolete */
+ /* 113 TARGET_NR_vm86old */
+#define TARGET_NR_wait4 114
+ /* 115 TARGET_NR_swapoff obsolete */
+#define TARGET_NR_sysinfo 116
+ /* 117 TARGET_NR_ipc oboslete */
+#define TARGET_NR_fsync 118
+ /* 119 TARGET_NR_sigreturn obsolete */
+#define TARGET_NR_clone 120
+#define TARGET_NR_setdomainname 121
+#define TARGET_NR_uname 122
+ /* 123 TARGET_NR_modify_ldt obsolete */
+#define TARGET_NR_adjtimex 124
+#define TARGET_NR_mprotect 125
+ /* 126 TARGET_NR_sigprocmask obsolete */
+ /* 127 TARGET_NR_create_module obsolete */
+#define TARGET_NR_init_module 128
+#define TARGET_NR_delete_module 129
+ /* 130 TARGET_NR_get_kernel_syms obsolete */
+#define TARGET_NR_quotactl 131
+#define TARGET_NR_getpgid 132
+#define TARGET_NR_fchdir 133
+#define TARGET_NR_bdflush 134
+ /* 135 was sysfs */
+#define TARGET_NR_personality 136
+ /* 137 TARGET_NR_afs_syscall */
+#define TARGET_NR_setfsuid 138
+#define TARGET_NR_setfsgid 139
+#define TARGET_NR__llseek 140
+#define TARGET_NR_getdents 141
+ /* 142 TARGET_NR__newselect obsolete */
+#define TARGET_NR_flock 143
+ /* 144 TARGET_NR_msync obsolete */
+#define TARGET_NR_readv 145
+#define TARGET_NR_writev 146
+#define TARGET_NR_getsid 147
+#define TARGET_NR_fdatasync 148
+#define TARGET_NR__sysctl 149
+ /* 150 TARGET_NR_mlock */
+ /* 151 TARGET_NR_munlock */
+ /* 152 TARGET_NR_mlockall */
+ /* 153 TARGET_NR_munlockall */
+#define TARGET_NR_sched_setparam 154
+#define TARGET_NR_sched_getparam 155
+#define TARGET_NR_sched_setscheduler 156
+#define TARGET_NR_sched_getscheduler 157
+#define TARGET_NR_sched_yield 158
+#define TARGET_NR_sched_get_priority_max 159
+#define TARGET_NR_sched_get_priority_min 160
+#define TARGET_NR_sched_rr_get_interval 161
+#define TARGET_NR_nanosleep 162
+#define TARGET_NR_mremap 163
+#define TARGET_NR_setresuid 164
+#define TARGET_NR_getresuid 165
+ /* 166 TARGET_NR_vm86 */
+ /* 167 TARGET_NR_query_module */
+ /* 168 TARGET_NR_poll */
+#define TARGET_NR_nfsservctl 169
+#define TARGET_NR_setresgid 170
+#define TARGET_NR_getresgid 171
+#define TARGET_NR_prctl 172
+#define TARGET_NR_rt_sigreturn 173
+#define TARGET_NR_rt_sigaction 174
+#define TARGET_NR_rt_sigprocmask 175
+#define TARGET_NR_rt_sigpending 176
+#define TARGET_NR_rt_sigtimedwait 177
+#define TARGET_NR_rt_sigqueueinfo 178
+#define TARGET_NR_rt_sigsuspend 179
+#define TARGET_NR_pread 180
+#define TARGET_NR_pwrite 181
+#define TARGET_NR_lchown 182
+#define TARGET_NR_getcwd 183
+#define TARGET_NR_capget 184
+#define TARGET_NR_capset 185
+#define TARGET_NR_sigaltstack 186
+#define TARGET_NR_sendfile 187
+ /* 188 TARGET_NR_getpmsg */
+ /* 189 TARGET_NR_putpmsg */
+#define TARGET_NR_vfork 190
+#define TARGET_NR_getrlimit 191
+#define TARGET_NR_mmap2 192 /* xxx: this is mmap2 !? */
+#define TARGET_NR_truncate64 193
+#define TARGET_NR_ftruncate64 194
+#define TARGET_NR_stat64 195
+#define TARGET_NR_lstat64 196
+#define TARGET_NR_fstat64 197
+#define TARGET_NR_chown32 198
+#define TARGET_NR_getuid32 199
+#define TARGET_NR_getgid32 200
+#define TARGET_NR_geteuid32 201
+#define TARGET_NR_getegid32 202
+#define TARGET_NR_setreuid32 203
+#define TARGET_NR_setregid32 204
+#define TARGET_NR_getgroups32 205
+#define TARGET_NR_setgroups32 206
+#define TARGET_NR_fchown32 207
+#define TARGET_NR_setresuid32 208
+#define TARGET_NR_getresuid32 209
+#define TARGET_NR_setresgid32 210
+#define TARGET_NR_getresgid32 211
+#define TARGET_NR_lchown32 212
+#define TARGET_NR_setuid32 213
+#define TARGET_NR_setgid32 214
+#define TARGET_NR_setfsuid32 215
+#define TARGET_NR_setfsgid32 216
+#define TARGET_NR_pivot_root 217
+ /* 218 TARGET_NR_mincore */
+ /* 219 TARGET_NR_madvise */
+#define TARGET_NR_getdents64 220
+#define TARGET_NR_fcntl64 221
+ /* 222 reserved for TUX */
+ /* 223 reserved for TUX */
+#define TARGET_NR_gettid 224
+#define TARGET_NR_readahead 225
+#define TARGET_NR_setxattr 226
+#define TARGET_NR_lsetxattr 227
+#define TARGET_NR_fsetxattr 228
+#define TARGET_NR_getxattr 229
+#define TARGET_NR_lgetxattr 230
+#define TARGET_NR_fgetxattr 231
+#define TARGET_NR_listxattr 232
+#define TARGET_NR_llistxattr 233
+#define TARGET_NR_flistxattr 234
+#define TARGET_NR_removexattr 235
+#define TARGET_NR_lremovexattr 236
+#define TARGET_NR_fremovexattr 237
+#define TARGET_NR_tkill 238
+#define TARGET_NR_sendfile64 239
+#define TARGET_NR_futex 240
+#define TARGET_NR_sched_setaffinity 241
+#define TARGET_NR_sched_getaffinity 242
+ /* 243 TARGET_NR_set_thread_area */
+ /* 244 TARGET_NR_get_thread_area */
+#define TARGET_NR_io_setup 245
+#define TARGET_NR_io_destroy 246
+#define TARGET_NR_io_getevents 247
+#define TARGET_NR_io_submit 248
+#define TARGET_NR_io_cancel 249
+ /* 250 TARGET_NR_alloc_hugepages */
+ /* 251 TARGET_NR_free_hugepages */
+#define TARGET_NR_exit_group 252
+#define TARGET_NR_lookup_dcookie 253
+#define TARGET_NR_bfin_spinlock 254
+
+#define TARGET_NR_epoll_create 255
+#define TARGET_NR_epoll_ctl 256
+#define TARGET_NR_epoll_wait 257
+ /* 258 TARGET_NR_remap_file_pages */
+#define TARGET_NR_set_tid_address 259
+#define TARGET_NR_timer_create 260
+#define TARGET_NR_timer_settime 261
+#define TARGET_NR_timer_gettime 262
+#define TARGET_NR_timer_getoverrun 263
+#define TARGET_NR_timer_delete 264
+#define TARGET_NR_clock_settime 265
+#define TARGET_NR_clock_gettime 266
+#define TARGET_NR_clock_getres 267
+#define TARGET_NR_clock_nanosleep 268
+#define TARGET_NR_statfs64 269
+#define TARGET_NR_fstatfs64 270
+#define TARGET_NR_tgkill 271
+#define TARGET_NR_utimes 272
+#define TARGET_NR_fadvise64_64 273
+ /* 274 TARGET_NR_vserver */
+ /* 275 TARGET_NR_mbind */
+ /* 276 TARGET_NR_get_mempolicy */
+ /* 277 TARGET_NR_set_mempolicy */
+#define TARGET_NR_mq_open 278
+#define TARGET_NR_mq_unlink 279
+#define TARGET_NR_mq_timedsend 280
+#define TARGET_NR_mq_timedreceive 281
+#define TARGET_NR_mq_notify 282
+#define TARGET_NR_mq_getsetattr 283
+#define TARGET_NR_kexec_load 284
+#define TARGET_NR_waitid 285
+#define TARGET_NR_add_key 286
+#define TARGET_NR_request_key 287
+#define TARGET_NR_keyctl 288
+#define TARGET_NR_ioprio_set 289
+#define TARGET_NR_ioprio_get 290
+#define TARGET_NR_inotify_init 291
+#define TARGET_NR_inotify_add_watch 292
+#define TARGET_NR_inotify_rm_watch 293
+ /* 294 TARGET_NR_migrate_pages */
+#define TARGET_NR_openat 295
+#define TARGET_NR_mkdirat 296
+#define TARGET_NR_mknodat 297
+#define TARGET_NR_fchownat 298
+#define TARGET_NR_futimesat 299
+#define TARGET_NR_fstatat64 300
+#define TARGET_NR_unlinkat 301
+#define TARGET_NR_renameat 302
+#define TARGET_NR_linkat 303
+#define TARGET_NR_symlinkat 304
+#define TARGET_NR_readlinkat 305
+#define TARGET_NR_fchmodat 306
+#define TARGET_NR_faccessat 307
+#define TARGET_NR_pselect6 308
+#define TARGET_NR_ppoll 309
+#define TARGET_NR_unshare 310
+
+/* Blackfin private syscalls */
+#define TARGET_NR_sram_alloc 311
+#define TARGET_NR_sram_free 312
+#define TARGET_NR_dma_memcpy 313
+
+/* socket syscalls */
+#define TARGET_NR_accept 314
+#define TARGET_NR_bind 315
+#define TARGET_NR_connect 316
+#define TARGET_NR_getpeername 317
+#define TARGET_NR_getsockname 318
+#define TARGET_NR_getsockopt 319
+#define TARGET_NR_listen 320
+#define TARGET_NR_recv 321
+#define TARGET_NR_recvfrom 322
+#define TARGET_NR_recvmsg 323
+#define TARGET_NR_send 324
+#define TARGET_NR_sendmsg 325
+#define TARGET_NR_sendto 326
+#define TARGET_NR_setsockopt 327
+#define TARGET_NR_shutdown 328
+#define TARGET_NR_socket 329
+#define TARGET_NR_socketpair 330
+
+/* sysv ipc syscalls */
+#define TARGET_NR_semctl 331
+#define TARGET_NR_semget 332
+#define TARGET_NR_semop 333
+#define TARGET_NR_msgctl 334
+#define TARGET_NR_msgget 335
+#define TARGET_NR_msgrcv 336
+#define TARGET_NR_msgsnd 337
+#define TARGET_NR_shmat 338
+#define TARGET_NR_shmctl 339
+#define TARGET_NR_shmdt 340
+#define TARGET_NR_shmget 341
+
+#define TARGET_NR_splice 342
+#define TARGET_NR_sync_file_range 343
+#define TARGET_NR_tee 344
+#define TARGET_NR_vmsplice 345
+
+#define TARGET_NR_epoll_pwait 346
+#define TARGET_NR_utimensat 347
+#define TARGET_NR_signalfd 348
+#define TARGET_NR_timerfd_create 349
+#define TARGET_NR_eventfd 350
+#define TARGET_NR_pread64 351
+#define TARGET_NR_pwrite64 352
+#define TARGET_NR_fadvise64 353
+#define TARGET_NR_set_robust_list 354
+#define TARGET_NR_get_robust_list 355
+#define TARGET_NR_fallocate 356
+#define TARGET_NR_semtimedop 357
+#define TARGET_NR_timerfd_settime 358
+#define TARGET_NR_timerfd_gettime 359
+#define TARGET_NR_signalfd4 360
+#define TARGET_NR_eventfd2 361
+#define TARGET_NR_epoll_create1 362
+#define TARGET_NR_dup3 363
+#define TARGET_NR_pipe2 364
+#define TARGET_NR_inotify_init1 365
+#define TARGET_NR_preadv 366
+#define TARGET_NR_pwritev 367
+#define TARGET_NR_rt_tgsigqueueinfo 368
+#define TARGET_NR_perf_event_open 369
+#define TARGET_NR_recvmmsg 370
+#define TARGET_NR_fanotify_init 371
+#define TARGET_NR_fanotify_mark 372
+#define TARGET_NR_prlimit64 373
+#define TARGET_NR_cacheflush 374
+
+#define TARGET_NR_syscall 375
diff --git a/linux-user/bfin/target_flat.h b/linux-user/bfin/target_flat.h
new file mode 100644
index 0000000..c694a6a
--- /dev/null
+++ b/linux-user/bfin/target_flat.h
@@ -0,0 +1,92 @@
+/*
+ * uClinux flat-format executables
+ *
+ * Copyright 2003-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2
+ */
+
+#define FLAT_BFIN_RELOC_TYPE_16_BIT 0
+#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
+#define FLAT_BFIN_RELOC_TYPE_32_BIT 2
+
+#define flat_argvp_envp_on_stack() 0
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_old_ram_flag(flag) (flag)
+#define flat_get_relocate_addr(relval) ((relval) & 0x03ffffff)
+
+static inline int flat_set_persistent(abi_ulong relval, abi_ulong *persistent)
+{
+ int type = (relval >> 26) & 7;
+ if (type == 3) {
+ *persistent = relval << 16;
+ return 1;
+ }
+ return 0;
+}
+
+static abi_ulong
+flat_get_addr_from_rp(abi_ulong ul_ptr, abi_ulong relval, abi_ulong flags,
abi_ulong *persistent)
+{
+ int type = (relval >> 26) & 7;
+ abi_ulong val;
+
+#ifdef DEBUG
+ printf("%s:%i: ptr:%8x relval:%8x type:%x flags:%x persistent:%x",
+ __func__, __LINE__, ul_ptr, relval, type, flags, *persistent);
+#endif
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT:
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+ if (get_user_u16(val, ul_ptr)) {
+ fprintf(stderr, "BINFMT_FLAT: unable to read reloc at %#x\n",
ul_ptr);
+ abort();
+ }
+ val += *persistent;
+ break;
+ case FLAT_BFIN_RELOC_TYPE_32_BIT:
+ if (get_user_u32(val, ul_ptr)) {
+ fprintf(stderr, "BINFMT_FLAT: unable to read reloc at %#x\n",
ul_ptr);
+ abort();
+ }
+ break;
+ default:
+ fprintf(stderr, "BINFMT_FLAT: Unknown relocation type %x\n", type);
+ abort();
+ break;
+ }
+#ifdef DEBUG
+ printf(" val:%x\n", val);
+#endif
+
+ /*
+ * Stack-relative relocs contain the offset into the stack, we
+ * have to add the stack's start address here and return 1 from
+ * flat_addr_absolute to prevent the normal address calculations
+ */
+ if (relval & (1 << 29)) {
+ fprintf(stderr, "BINFMT_FLAT: stack relocs not supported\n");
+ abort();
+ /*return val + current->mm->context.end_brk;*/
+ }
+
+ if ((flags & FLAT_FLAG_GOTPIC) == 0)
+ val = ntohl(val);
+
+ return val;
+}
+
+static int
+flat_put_addr_at_rp(abi_ulong ptr, abi_ulong addr, abi_ulong relval)
+{
+ int type = (relval >> 26) & 7;
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT: return put_user_u16(addr, ptr);
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT: return put_user_u16(addr >> 16, ptr);
+ case FLAT_BFIN_RELOC_TYPE_32_BIT: return put_user_u32(addr, ptr);
+ }
+
+ abort();
+}
diff --git a/linux-user/bfin/target_sigcontext.h
b/linux-user/bfin/target_sigcontext.h
new file mode 100644
index 0000000..10d61e2
--- /dev/null
+++ b/linux-user/bfin/target_sigcontext.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef TARGET_SIGCONTEXT_H
+#define TARGET_SIGCONTEXT_H
+
+/* Add new entries at the end of the structure only. */
+struct target_sigcontext {
+ abi_ulong sc_r0;
+ abi_ulong sc_r1;
+ abi_ulong sc_r2;
+ abi_ulong sc_r3;
+ abi_ulong sc_r4;
+ abi_ulong sc_r5;
+ abi_ulong sc_r6;
+ abi_ulong sc_r7;
+ abi_ulong sc_p0;
+ abi_ulong sc_p1;
+ abi_ulong sc_p2;
+ abi_ulong sc_p3;
+ abi_ulong sc_p4;
+ abi_ulong sc_p5;
+ abi_ulong sc_usp;
+ abi_ulong sc_a0w;
+ abi_ulong sc_a1w;
+ abi_ulong sc_a0x;
+ abi_ulong sc_a1x;
+ abi_ulong sc_astat;
+ abi_ulong sc_rets;
+ abi_ulong sc_pc;
+ abi_ulong sc_retx;
+ abi_ulong sc_fp;
+ abi_ulong sc_i0;
+ abi_ulong sc_i1;
+ abi_ulong sc_i2;
+ abi_ulong sc_i3;
+ abi_ulong sc_m0;
+ abi_ulong sc_m1;
+ abi_ulong sc_m2;
+ abi_ulong sc_m3;
+ abi_ulong sc_l0;
+ abi_ulong sc_l1;
+ abi_ulong sc_l2;
+ abi_ulong sc_l3;
+ abi_ulong sc_b0;
+ abi_ulong sc_b1;
+ abi_ulong sc_b2;
+ abi_ulong sc_b3;
+ abi_ulong sc_lc0;
+ abi_ulong sc_lc1;
+ abi_ulong sc_lt0;
+ abi_ulong sc_lt1;
+ abi_ulong sc_lb0;
+ abi_ulong sc_lb1;
+ abi_ulong sc_seqstat;
+};
+
+#endif
diff --git a/linux-user/bfin/target_signal.h b/linux-user/bfin/target_signal.h
new file mode 100644
index 0000000..7367c0a
--- /dev/null
+++ b/linux-user/bfin/target_signal.h
@@ -0,0 +1,31 @@
+#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_long 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(CPUArchState *env)
+{
+ return env->spreg;
+}
+
+#define TARGET_SIGRETURN_STUB 0x400
+
+#endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/bfin/termbits.h b/linux-user/bfin/termbits.h
new file mode 100644
index 0000000..5c5fa01
--- /dev/null
+++ b/linux-user/bfin/termbits.h
@@ -0,0 +1,227 @@
+/* from asm/termbits.h */
+/* NOTE: exactly the same as i386 */
+
+#define TARGET_NCCS 19
+
+struct target_termios {
+ uint32_t c_iflag; /* input mode flags */
+ uint32_t c_oflag; /* output mode flags */
+ uint32_t c_cflag; /* control mode flags */
+ uint32_t c_lflag; /* local mode flags */
+ uint8_t c_line; /* line discipline */
+ uint8_t 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_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 (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, uint32_t) /* Get Pty
Number (of pty-mux device) */
+#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int32_t) /* 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 */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ddef23e..b09e33e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -979,6 +979,48 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
const CPUM68KState *e
#endif
+#ifdef TARGET_BFIN
+
+#define ELF_START_MMAP 0x00000000
+
+#define elf_check_arch(x) ( (x) == EM_BLACKFIN )
+#define elf_is_fdpic(e) ( (e)->e_flags & EF_BFIN_FDPIC )
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_BLACKFIN
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+{
+ if (infop->personality == PER_LINUX_FDPIC) {
+ if (infop->other_info) {
+ /* dynamic */
+ regs->p0 = tswapl(infop->loadmap_addr);
+ regs->p1 = tswapl(infop->other_info->loadmap_addr);
+ regs->p2 = tswapl(infop->other_info->pt_dynamic_addr);
+ } else {
+ /* static */
+ regs->p0 = tswapl(infop->loadmap_addr);
+ regs->p1 = 0;
+ regs->p2 = tswapl(infop->pt_dynamic_addr);
+ }
+ regs->r7 = 0;
+ } else if (infop->start_code == 0) {
+ /* Must be bare metal ELF ... */
+ infop->personality = PER_MASK;
+ }
+ regs->pc = tswapl(infop->entry);
+ regs->usp = tswapl(infop->start_stack);
+}
+
+#define ELF_EXEC_PAGESIZE 4096
+
+/* See linux kernel: arch/blackfin/include/asm/elf.h. */
+#define ELF_NREG 40
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+#endif
+
#ifdef TARGET_ALPHA
#define ELF_START_MMAP (0x30000000000ULL)
@@ -1677,6 +1719,11 @@ static void load_elf_image(const char *image_name, int
image_fd,
address does not conflict with MMAP_MIN_ADDR or the
QEMU application itself. */
probe_guest_base(image_name, loaddr, hiaddr);
+#ifdef TARGET_BFIN
+ /* Make space for the fixed code region */
+ if (elf_is_fdpic(ehdr) && load_addr < 0x1000)
+ load_addr += 0x1000;
+#endif
}
load_bias = load_addr - loaddr;
diff --git a/linux-user/main.c b/linux-user/main.c
index b97b8cf..bb5d032 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2795,6 +2795,115 @@ void cpu_loop(CPUM68KState *env)
}
#endif /* TARGET_M68K */
+#ifdef TARGET_BFIN
+
+#include "disas/disas.h"
+
+void cpu_loop(CPUArchState *env)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+ int trapnr, gdbsig;
+ target_siginfo_t info;
+
+ for (;;) {
+ cpu_exec_start(cs);
+ trapnr = cpu_exec(env);
+ cpu_exec_end(cs);
+ gdbsig = 0;
+
+ switch (trapnr) {
+ case EXCP_SYSCALL:
+ env->pc += 2;
+ env->dreg[0] = do_syscall(env,
+ env->preg[0],
+ env->dreg[0],
+ env->dreg[1],
+ env->dreg[2],
+ env->dreg[3],
+ env->dreg[4],
+ env->dreg[5], 0, 0);
+ break;
+ case EXCP_INTERRUPT:
+ /* just indicate that signals should be handled asap */
+ break;
+ case EXCP_DEBUG:
+ /* XXX: does this handle hwloops ? */
+ /*env->pc += 2;*/
+ /* EMUEXCPT signals debugger only if attached; NOP otherwise */
+ gdbsig = TARGET_SIGTRAP;
+ break;
+ case EXCP_SOFT_BP:
+ {
+ int sig = gdb_handlesig(env, 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_HLT:
+ do_syscall(env, TARGET_NR_exit, 0, 0, 0, 0, 0, 0, 0, 0);
+ break;
+ case EXCP_ABORT:
+ do_syscall(env, TARGET_NR_exit, 1, 0, 0, 0, 0, 0, 0, 0);
+ break;
+ case EXCP_DBGA:
+ fprintf(stderr, "qemu: DBGA failed\n");
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGABRT;
+ break;
+ case EXCP_UNDEF_INST:
+ fprintf(stderr, "qemu: unhandled insn @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ gdbsig = TARGET_SIGILL;
+ break;
+ case EXCP_DCPLB_VIOLATE:
+ fprintf(stderr, "qemu: memory violation @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGSEGV;
+ break;
+ case EXCP_ILL_SUPV:
+ fprintf(stderr, "qemu: supervisor mode required @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ gdbsig = TARGET_SIGILL;
+ break;
+ case EXCP_MISALIG_INST:
+ fprintf(stderr, "qemu: unaligned insn fetch @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGSEGV;
+ break;
+ case EXCP_DATA_MISALGIN:
+ fprintf(stderr, "qemu: unaligned data fetch @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGSEGV;
+ break;
+ default:
+ fprintf(stderr, "qemu: unhandled CPU exception %#x - aborting\n",
+ trapnr);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGILL;
+ break;
+ }
+
+ if (gdbsig) {
+ gdb_handlesig(env, gdbsig);
+ /* XXX: should we let people continue if gdb handles the signal ?
*/
+ if (gdbsig != TARGET_SIGTRAP) {
+ exit(1);
+ }
+ }
+
+ process_pending_signals(env);
+ }
+}
+
+#endif
+
#ifdef TARGET_ALPHA
static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
{
@@ -4013,6 +4122,57 @@ int main(int argc, char **argv, char **envp)
}
env->pc = regs->pc;
}
+#elif defined(TARGET_BFIN)
+ {
+ env->personality = info->personality;
+ env->dreg[0] = regs->r0;
+ env->dreg[1] = regs->r1;
+ env->dreg[2] = regs->r2;
+ env->dreg[3] = regs->r3;
+ env->dreg[4] = regs->r4;
+ env->dreg[5] = regs->r5;
+ env->dreg[6] = regs->r6;
+ env->dreg[7] = regs->r7;
+ env->preg[0] = regs->p0;
+ env->preg[1] = regs->p1;
+ env->preg[2] = regs->p2;
+ env->preg[3] = regs->p3;
+ env->preg[4] = regs->p4;
+ env->preg[5] = regs->p5;
+ env->spreg = regs->usp;
+ env->fpreg = regs->fp;
+ env->uspreg = regs->usp;
+ env->breg[0] = regs->b0;
+ env->breg[1] = regs->b1;
+ env->breg[2] = regs->b2;
+ env->breg[3] = regs->b3;
+ env->lreg[0] = regs->l0;
+ env->lreg[1] = regs->l1;
+ env->lreg[2] = regs->l2;
+ env->lreg[3] = regs->l3;
+ env->mreg[0] = regs->m0;
+ env->mreg[1] = regs->m1;
+ env->mreg[2] = regs->m2;
+ env->mreg[3] = regs->m3;
+ env->ireg[0] = regs->i0;
+ env->ireg[1] = regs->i1;
+ env->ireg[2] = regs->i2;
+ env->ireg[3] = regs->i3;
+ env->lcreg[0] = regs->lc0;
+ env->ltreg[0] = regs->lt0;
+ env->lbreg[0] = regs->lb0;
+ env->lcreg[1] = regs->lc1;
+ env->ltreg[1] = regs->lt1;
+ env->lbreg[1] = regs->lb1;
+ env->areg[0] = ((uint64_t)regs->a0x << 32) | regs->a0w;
+ env->areg[1] = ((uint64_t)regs->a1x << 32) | regs->a1w;
+ env->rets = regs->rets;
+ env->rete = regs->rete;
+ env->retn = regs->retn;
+ env->retx = regs->retx;
+ env->pc = regs->pc;
+ bfin_astat_write(env, regs->astat);
+ }
#elif defined(TARGET_ALPHA)
{
int i;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index b10e957..819f268 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -26,6 +26,10 @@
#define THREAD
#endif
+#ifdef TARGET_BFIN
+#define CONFIG_USE_FDPIC
+#endif
+
/* This struct is used to hold certain information about the image.
* Basically, it replicates in user space what would be certain
* task_struct fields in the kernel
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 5da8452..6e2d613 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5353,6 +5353,231 @@ long do_rt_sigreturn(CPUAlphaState *env)
force_sig(TARGET_SIGSEGV);
}
+#elif defined(TARGET_BFIN)
+
+#include "target_sigcontext.h"
+#include "target_ucontext.h"
+
+struct target_rt_sigframe {
+ int32_t sig;
+ abi_ulong pinfo;
+ abi_ulong puc;
+ /* This is no longer needed by the kernel, but unfortunately userspace
+ * code expects it to be there. */
+ char retcode[8];
+ target_siginfo_t info;
+ struct target_ucontext uc;
+};
+
+struct fdpic_func_descriptor {
+ abi_ulong text;
+ abi_ulong GOT;
+};
+
+#define rreg dreg
+
+static inline int
+target_rt_restore_sigcontext(CPUArchState *env, struct target_sigcontext *sc,
long *ret)
+{
+ uint32_t reg;
+ int err = 0;
+
+#define RESTORE2(e, x) err |= __get_user(env->e, &sc->sc_##x)
+#define RESTOREA(r, i) RESTORE2(r##reg[i], r##i)
+#define RESTORE(x) RESTORE2(x, x)
+
+ /* restore passed registers */
+ RESTOREA(r, 0); RESTOREA(r, 1); RESTOREA(r, 2); RESTOREA(r, 3);
+ RESTOREA(r, 4); RESTOREA(r, 5); RESTOREA(r, 6); RESTOREA(r, 7);
+ RESTOREA(p, 0); RESTOREA(p, 1); RESTOREA(p, 2); RESTOREA(p, 3);
+ RESTOREA(p, 4); RESTOREA(p, 5);
+ RESTORE2(spreg, usp);
+ err |= __get_user(reg, &sc->sc_a0x);
+ env->areg[0] = reg;
+ err |= __get_user(reg, &sc->sc_a0w);
+ env->areg[0] = (env->areg[0] << 32) | reg;
+ err |= __get_user(reg, &sc->sc_a1x);
+ env->areg[1] = reg;
+ err |= __get_user(reg, &sc->sc_a1w);
+ env->areg[1] = (env->areg[1] << 32) | reg;
+ err |= __get_user(reg, &sc->sc_astat);
+ bfin_astat_write(env, reg);
+ RESTORE(rets);
+ RESTORE(pc);
+ RESTORE(retx);
+ RESTORE2(fpreg, fp);
+ RESTOREA(i, 0); RESTOREA(i, 1); RESTOREA(i, 2); RESTOREA(i, 3);
+ RESTOREA(m, 0); RESTOREA(m, 1); RESTOREA(m, 2); RESTOREA(m, 3);
+ RESTOREA(l, 0); RESTOREA(l, 1); RESTOREA(l, 2); RESTOREA(l, 3);
+ RESTOREA(b, 0); RESTOREA(b, 1); RESTOREA(b, 2); RESTOREA(b, 3);
+ RESTOREA(lc, 0); RESTOREA(lc, 1);
+ RESTOREA(lt, 0); RESTOREA(lt, 1);
+ RESTOREA(lb, 0); RESTOREA(lb, 1);
+ RESTORE(seqstat);
+
+ *ret = env->dreg[0];
+ return err;
+}
+
+static inline int
+target_rt_setup_sigcontext(struct target_sigcontext *sc, CPUArchState *env)
+{
+ int err = 0;
+
+#define SETUP2(e, x) err |= __put_user(env->e, &sc->sc_##x)
+#define SETUPA(r, i) SETUP2(r##reg[i], r##i)
+#define SETUP(x) SETUP2(x, x)
+
+ SETUPA(r, 0); SETUPA(r, 1); SETUPA(r, 2); SETUPA(r, 3);
+ SETUPA(r, 4); SETUPA(r, 5); SETUPA(r, 6); SETUPA(r, 7);
+ SETUPA(p, 0); SETUPA(p, 1); SETUPA(p, 2); SETUPA(p, 3);
+ SETUPA(p, 4); SETUPA(p, 5);
+ SETUP2(spreg, usp);
+ err |= __put_user((uint32_t)env->areg[0], &sc->sc_a0w);
+ err |= __put_user((uint32_t)env->areg[1], &sc->sc_a1w);
+ err |= __put_user((uint32_t)(env->areg[0] >> 32), &sc->sc_a0x);
+ err |= __put_user((uint32_t)(env->areg[1] >> 32), &sc->sc_a1x);
+ err |= __put_user(bfin_astat_read(env), &sc->sc_astat);
+ SETUP(rets);
+ SETUP(pc);
+ SETUP(retx);
+ SETUP2(fpreg, fp);
+ SETUPA(i, 0); SETUPA(i, 1); SETUPA(i, 2); SETUPA(i, 3);
+ SETUPA(m, 0); SETUPA(m, 1); SETUPA(m, 2); SETUPA(m, 3);
+ SETUPA(l, 0); SETUPA(l, 1); SETUPA(l, 2); SETUPA(l, 3);
+ SETUPA(b, 0); SETUPA(b, 1); SETUPA(b, 2); SETUPA(b, 3);
+ SETUPA(lc, 0); SETUPA(lc, 1);
+ SETUPA(lt, 0); SETUPA(lt, 1);
+ SETUPA(lb, 0); SETUPA(lb, 1);
+ SETUP(seqstat);
+
+ return err;
+}
+
+#undef rreg
+
+static inline abi_ulong
+get_sigframe(struct target_sigaction *ka, CPUArchState *env, size_t frame_size)
+{
+ abi_ulong usp;
+
+ /* Default to using normal stack. */
+ usp = env->spreg;
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(usp) == 0)) {
+ usp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ }
+
+ return ((usp - frame_size) & -8UL);
+}
+
+static void setup_rt_frame(int sig, struct target_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPUArchState *env)
+{
+ struct target_rt_sigframe *frame;
+ abi_ulong frame_addr;
+ abi_ulong info_addr;
+ abi_ulong uc_addr;
+ int err = 0;
+ int i;
+
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+ goto give_sigsegv;
+
+ err |= __put_user(sig, &frame->sig);
+
+ info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
+ err |= __put_user(info_addr, &frame->pinfo);
+ uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
+ err |= __put_user(uc_addr, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.tuc_flags);
+ err |= __put_user(0, &frame->uc.tuc_link);
+ err |= __put_user(target_sigaltstack_used.ss_sp,
&frame->uc.tuc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(env->spreg), &frame->uc.tuc_stack.ss_flags);
+ err |= __put_user(target_sigaltstack_used.ss_size,
&frame->uc.tuc_stack.ss_size);
+ err |= target_rt_setup_sigcontext(&frame->uc.tuc_mcontext, env);
+
+ for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+ if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
+ goto give_sigsegv;
+ }
+
+ if (err)
+ goto give_sigsegv;
+
+ /* Set up registers for signal handler */
+ env->spreg = frame_addr;
+ if (env->personality & 0x0080000/*FDPIC_FUNCPTRS*/) {
+ struct fdpic_func_descriptor *funcptr;
+ if (!lock_user_struct(VERIFY_READ, funcptr, ka->_sa_handler, 1))
+ goto give_sigsegv;
+ __get_user(env->pc, &funcptr->text);
+ __get_user(env->preg[3], &funcptr->GOT);
+ unlock_user_struct(funcptr, ka->_sa_handler, 0);
+ } else
+ env->pc = ka->_sa_handler;
+ env->rets = TARGET_SIGRETURN_STUB;
+
+ env->dreg[0] = frame->sig;
+ env->dreg[1] = info_addr;
+ env->dreg[2] = uc_addr;
+
+ unlock_user_struct(frame, frame_addr, 1);
+ return;
+
+ give_sigsegv:
+ unlock_user_struct(frame, frame_addr, 1);
+ force_sig(TARGET_SIGSEGV);
+}
+
+static void setup_frame(int sig, struct target_sigaction *ka,
+ target_sigset_t *set, CPUArchState *env)
+{
+ target_siginfo_t info;
+ setup_rt_frame(sig, ka, &info, set, env);
+}
+
+long do_sigreturn(CPUArchState *env)
+{
+ fprintf(stderr, "do_sigreturn: not implemented\n");
+ return -TARGET_ENOSYS;
+}
+
+/* NB: This version should work for any arch ... */
+long do_rt_sigreturn(CPUArchState *env)
+{
+ long ret;
+ abi_ulong frame_addr = env->spreg;
+ struct target_rt_sigframe *frame;
+ sigset_t host_set;
+
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+ goto badframe;
+
+ target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
+ sigprocmask(SIG_SETMASK, &host_set, NULL);
+
+ if (target_rt_restore_sigcontext(env, &frame->uc.tuc_mcontext, &ret))
+ 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 ret;
+
+ badframe:
+ unlock_user_struct(frame, frame_addr, 0);
+ force_sig(TARGET_SIGSEGV);
+ return 0;
+}
+
#else
static void setup_frame(int sig, struct target_sigaction *ka,
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cdd0c28..a9dce35 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7444,7 +7444,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_sigaltstack:
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
- defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
|| \
+ defined(TARGET_BFIN)
ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState
*)cpu_env));
break;
#else
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 92c01a9..362cd2d 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -63,7 +63,7 @@
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
|| defined(TARGET_M68K) || defined(TARGET_CRIS) ||
defined(TARGET_UNICORE32) \
- || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ || defined(TARGET_S390X) || defined(TARGET_OPENRISC) ||
defined(TARGET_BFIN)
#define TARGET_IOC_SIZEBITS 14
#define TARGET_IOC_DIRBITS 2
@@ -327,7 +327,7 @@ int do_sigaction(int sig, const struct target_sigaction
*act,
|| defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \
|| defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
|| defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \
- || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ || defined(TARGET_S390X) || defined(TARGET_OPENRISC) ||
defined(TARGET_BFIN)
#if defined(TARGET_SPARC)
#define TARGET_SA_NOCLDSTOP 8u
@@ -1689,6 +1689,67 @@ struct target_stat64 {
int64_t st_blocks;
};
+#elif defined(TARGET_BFIN)
+
+struct target_stat {
+ uint16_t st_dev;
+ uint16_t __pad1;
+ abi_ulong st_ino;
+ uint16_t st_mode;
+ uint16_t st_nlink;
+ uint16_t st_uid;
+ uint16_t st_gid;
+ uint16_t st_rdev;
+ uint16_t __pad2;
+ abi_ulong st_size;
+ abi_ulong st_blksize;
+ abi_ulong st_blocks;
+ abi_ulong target_st_atime;
+ abi_ulong __unused1;
+ abi_ulong target_st_mtime;
+ abi_ulong __unused2;
+ abi_ulong target_st_ctime;
+ abi_ulong __unused3;
+ abi_ulong __unused4;
+ abi_ulong __unused5;
+} __attribute__((packed));
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct target_stat64 {
+ uint64_t st_dev;
+ unsigned char __pad1[4];
+
+#define STAT64_HAS_BROKEN_ST_INO 1
+ abi_ulong __st_ino;
+
+ uint32_t st_mode;
+ uint32_t st_nlink;
+
+ abi_ulong st_uid;
+ abi_ulong st_gid;
+
+ uint64_t st_rdev;
+ unsigned char __pad2[4];
+
+ int64_t st_size;
+ abi_ulong st_blksize;
+
+ int64_t st_blocks; /* Number 512-byte blocks allocated. */
+
+ 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;
+
+ uint64_t st_ino;
+} __attribute__((packed));
+
#elif defined(TARGET_ALPHA)
struct target_stat {
diff --git a/linux-user/target_ucontext.h b/linux-user/target_ucontext.h
new file mode 100644
index 0000000..49706b4
--- /dev/null
+++ b/linux-user/target_ucontext.h
@@ -0,0 +1,14 @@
+/* This is the asm-generic/ucontext.h version */
+
+#ifndef TARGET_UCONTEXT_H
+#define TARGET_UCONTEXT_H
+
+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; /* mask last for extensibility */
+};
+
+#endif
--
1.8.2.1
- [Qemu-devel] [PATCH 0/5] Initial Blackfin support (linux-user only), Mike Frysinger, 2013/06/17
- [Qemu-devel] [PATCH 1/5] Blackfin: add disassembler support, Mike Frysinger, 2013/06/17
- [Qemu-devel] [PATCH 2/5] Blackfin: initial port, Mike Frysinger, 2013/06/17
- [Qemu-devel] [PATCH 5/5] linux-user: add support for Blackfin syscalls, Mike Frysinger, 2013/06/17
- [Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support,
Mike Frysinger <=
- [Qemu-devel] [PATCH 4/5] Blackfin: add test suite, Mike Frysinger, 2013/06/17
- Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port, Richard Henderson, 2013/06/25
- Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port, Eric Blake, 2013/06/28
- Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port, Andreas Färber, 2013/06/28