/* * TOPPERS ECHONET Lite Communication Middleware * * Copyright (C) 2017 Cores Co., Ltd. Japan * * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー * スコード中に含まれていること. * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 * の無保証規定を掲載すること. * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ * と. * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 * 作権表示,この利用条件および下記の無保証規定を掲載すること. * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに * 報告すること. * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを * 免責すること. * * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ * の責任を負わない. * * @(#) $Id$ */ #define _CRT_NO_TIME_T #include "../../musl-1.1.18/include/bits/syscall.h" #include "shellif.h" #include #include "MBRZA1H.h" void *thread_area; void *tid_address; // https://os.mbed.com/users/dkato/code/FlashAccess/#652a093cf264 void flash_access_cache_control(void) { unsigned int assoc; /* ==== Cleaning and invalidation of the L1 data cache ==== */ __v7_all_cache(2); __DSB(); /* ==== Cleaning and invalidation of the L2 cache ==== */ if (PL310->AUX_CNT & (1<<16)) { assoc = 16; } else { assoc = 8; } PL310->INV_WAY = (1 << assoc) - 1; while(PL310->INV_WAY & ((1 << assoc) - 1)); // poll invalidate PL310->CACHE_SYNC = 0x0; /* ==== Invalidate all TLB entries ==== */ __ca9u_inv_tlb_all(); /* ==== Invalidate the L1 instruction cache ==== */ __v7_inv_icache_all(); __DSB(); __ISB(); } void no_implement(const char *text) { syslog(LOG_ERROR, text); asm("bkpt #0"); } static long __syscall(struct regs_t *r) { long ret = -ENOSYS; shellif_into(); switch (r->n) { case SYS__llseek: return shell_llseek(r->a, (((off_t)r->b) << 32) + (off_t)r->c, (off_t *)r->d, r->e); case SYS__newselect: ret = shell_select(r->a, (fd_set *)r->b, (fd_set *)r->c, (fd_set *)r->d, (struct timeval *)r->e); break; case SYS_accept: ret = shell_accept(r->a, (struct sockaddr *)r->b, (socklen_t *)r->c); break; case SYS_access: ret = shell_access((const char *)r->a, r->b); break; case SYS_acct: no_implement("acct\n"); break; case SYS_adjtimex: no_implement("adjtimex\n"); break; #ifdef SYS_arch_prctl case SYS_arch_prctl: no_implement("arch_prctl\n"); break; #endif case SYS_bind: ret = shell_bind(r->a, (const struct sockaddr *)r->b, (socklen_t)r->c); break; case SYS_brk: ret = (long)shell_brk((void *)r->a); break; #ifdef SYS_cachectl case SYS_cachectl: no_implement("cachectl\n"); break; #endif #ifdef SYS_cacheflush case SYS_cacheflush: no_implement("cacheflush\n"); break; #endif case SYS_capget: no_implement("capget\n"); break; case SYS_capset: no_implement("capset\n"); break; case SYS_chdir: ret = shell_chdir((const char *)r->a); break; case SYS_chmod: ret = shell_chmod((const char *)r->a, (mode_t)r->b); break; case SYS_chown32: no_implement("chown\n"); break; case SYS_chroot: ret = shell_chroot((const char *)r->a); break; case SYS_clock_adjtime: no_implement("clock_adjtime\n"); break; case SYS_clock_getres: ret = shell_clock_getres((clockid_t)r->a, (struct timespec *)r->b); break; case SYS_clock_gettime: ret = shell_clock_gettime((clockid_t)r->a, (struct timespec *)r->b); break; case SYS_clock_nanosleep: no_implement("clock_nanosleep\n"); break; case SYS_clock_settime: ret = shell_clock_settime((clockid_t)r->a, (const struct timespec *)r->b); break; case SYS_clone: no_implement("clone\n"); break; case SYS_close: ret = shell_close(r->a); break; case SYS_connect: ret = shell_connect(r->a, (const struct sockaddr *)r->b, (socklen_t)r->c); break; case SYS_delete_module: no_implement("delete_module\n"); break; case SYS_dup: no_implement("dup\n"); break; case SYS_dup2: no_implement("dup2\n"); break; case SYS_dup3: no_implement("dup3\n"); break; case SYS_epoll_create: no_implement("epoll_create\n"); break; case SYS_epoll_create1: no_implement("epoll_create1\n"); break; case SYS_epoll_ctl: no_implement("epoll_ctl\n"); break; case SYS_epoll_pwait: no_implement("epoll_pwait\n"); break; case SYS_epoll_wait: no_implement("epoll_wait\n"); break; case SYS_eventfd: no_implement("eventfd\n"); break; case SYS_eventfd2: no_implement("eventfd2\n"); break; case SYS_execve: no_implement("execve\n"); break; case SYS_exit: shell_exit(r->a); ret = 0; break; case SYS_exit_group: shell_exit_group(r->a); ret = 0; break; case SYS_faccessat: no_implement("faccessat\n"); break; case SYS_fadvise64_64: no_implement("fadvise64_64\n"); break; case SYS_fallocate: no_implement("fallocate\n"); break; case SYS_fanotify_init: no_implement("fanotify_init\n"); break; case SYS_fanotify_mark: no_implement("fanotify_mark\n"); break; case SYS_fchdir: no_implement("fchdir\n"); break; case SYS_fchmod: no_implement("fchmod\n"); break; case SYS_fchmodat: no_implement("fchmodat\n"); break; case SYS_fchown32: no_implement("fchown\n"); break; case SYS_fchownat: no_implement("fchownat\n"); break; case SYS_fcntl64: ret = shell_fcntl((int)r->a, (int)r->b, (void *)r->c); break; case SYS_fdatasync: no_implement("fdatasync\n"); break; case SYS_fgetxattr: no_implement("fgetxattr\n"); break; case SYS_flistxattr: no_implement("flistxattr\n"); break; case SYS_flock: no_implement("flock\n"); break; case SYS_fork: no_implement("fork\n"); break; case SYS_fremovexattr: no_implement("fremovexattr\n"); break; case SYS_fsetxattr: no_implement("fsetxattr\n"); break; case SYS_fstat64: ret = shell_fstat((int)r->a, (struct stat *)r->b); break; case SYS_fstatat64: no_implement("fstatat64\n"); break; case SYS_fstatfs: no_implement("fstatfs\n"); break; case SYS_fstatfs64: no_implement("fstatfs64\n"); break; case SYS_fsync: ret = shell_fsync(r->a); break; case SYS_ftruncate64: ret = shell_ftruncate((int)r->a, (((off_t)r->b) << 32) + (off_t)r->c); break; case SYS_futex: no_implement("futex\n"); break; case SYS_futimesat: no_implement("futimesat\n"); break; case SYS_getcpu: no_implement("getcpu\n"); break; case SYS_getcwd: ret = (long)shell_getcwd((char *)r->a, (size_t)r->b); break; case SYS_getdents64: ret = shell_getdents((int)r->a, (struct dirent *)r->b, (size_t)r->c); // TODO break; case SYS_getegid32: no_implement("getegid\n"); break; case SYS_geteuid32: no_implement("geteuid\n"); break; case SYS_getgid32: no_implement("getgid\n"); break; case SYS_getgroups32: no_implement("getgroups\n"); break; case SYS_getitimer: no_implement("getitimer\n"); break; case SYS_getpgid: no_implement("getpgid\n"); break; case SYS_getpid: ret = shell_getpid(); break; case SYS_getppid: no_implement("getppid\n"); break; case SYS_getpriority: no_implement("getpriority\n"); break; case SYS_getresgid32: no_implement("getresgid\n"); break; case SYS_getresuid32: no_implement("getresuid\n"); break; #ifdef SYS_getrlimit case SYS_getrlimit: no_implement("getrlimit\n"); break; #endif case SYS_getrusage: no_implement("getrusage\n"); break; case SYS_getsid: no_implement("getsid\n"); break; case SYS_getsockopt: ret = shell_getsockopt(r->a, r->b, r->c, (void *)r->d, (socklen_t *)r->e); break; case SYS_gettid: no_implement("gettid\n"); break; case SYS_gettimeofday: ret = shell_gettimeofday((struct timeval *)r->a, (void *)r->b); break; case SYS_getuid32: no_implement("getuid\n"); break; case SYS_getxattr: no_implement("getxattr\n"); break; case SYS_init_module: no_implement("init_module\n"); break; case SYS_inotify_add_watch: no_implement("inotify_add_watch\n"); break; case SYS_inotify_init: no_implement("inotify_init\n"); break; case SYS_inotify_init1: no_implement("inotify_init1\n"); break; case SYS_inotify_rm_watch: no_implement("inotify_rm_watch\n"); break; case SYS_ioctl: ret = shell_ioctl((int)r->a, (int)r->b, (void *)r->c); break; #ifdef SYS_ioperm case SYS_ioperm: no_implement("ioperm\n"); break; #endif #ifdef SYS_iopl case SYS_iopl: no_implement("iopl\n"); break; #endif #ifdef SYS_ipc case SYS_ipc: no_implement("ipc\n"); break; #endif #ifdef SYS_ipc case SYS_ipc: no_implement("ipc\n"); break; #endif case SYS_kill: ret = shell_kill(r->a, r->b); break; case SYS_lchown32: no_implement("lchown\n"); break; case SYS_lgetxattr: no_implement("lgetxattr\n"); break; case SYS_link: ret = shell_link((const char *)r->a, (const char *)r->b); break; case SYS_linkat: no_implement("linkat\n"); break; case SYS_listen: ret = shell_listen(r->a, r->b); break; case SYS_listxattr: no_implement("listxattr\n"); break; case SYS_llistxattr: no_implement("llistxattr\n"); break; case SYS_lremovexattr: no_implement("lremovexattr\n"); break; case SYS_lsetxattr: no_implement("lsetxattr\n"); break; case SYS_lstat64: ret = shell_lstat((const char *__restrict)r->a, (struct stat *__restrict)r->b); break; case SYS_madvise: ret = shell_madvise((void *)r->a, (size_t)r->b, (int)r->c); // TODO break; case SYS_mincore: no_implement("mincore\n"); break; case SYS_mkdir: ret = shell_mkdir((const char *)r->a, (mode_t)r->b); break; case SYS_mkdirat: no_implement("mkdirat\n"); break; case SYS_mknod: no_implement("mknod\n"); break; case SYS_mknodat: no_implement("mknodat\n"); break; case SYS_mlock: no_implement("mlock\n"); break; case SYS_mlockall: no_implement("mlockall\n"); break; case SYS_mmap2: ret = (int)shell_mmap2((void *)r->a, (size_t)r->b, r->c, r->d, r->e, (off_t)r->f); break; case SYS_mount: no_implement("mount\n"); break; case SYS_mprotect: return shell_mprotect((void *)r->a, (size_t)r->b, r->c); break; case SYS_mq_getsetattr: no_implement("mq_getsetattr\n"); break; case SYS_mq_notify: no_implement("mq_notify\n"); break; case SYS_mq_open: no_implement("mq_open\n"); break; case SYS_mq_timedreceive: no_implement("mq_timedreceive\n"); break; case SYS_mq_timedsend: no_implement("mq_timedsend\n"); break; case SYS_mq_unlink: no_implement("mq_unlink\n"); break; case SYS_mremap: no_implement("mremap\n"); break; case SYS_msgctl: no_implement("msgctl\n"); break; case SYS_msgget: no_implement("msgget\n"); break; case SYS_msgrcv: no_implement("msgrcv\n"); break; case SYS_msgsnd: no_implement("msgsnd\n"); break; case SYS_msync: no_implement("msync\n"); break; case SYS_munlock: no_implement("munlock\n"); break; case SYS_munlockall: no_implement("munlockall\n"); break; case SYS_munmap: no_implement("munmap\n"); break; case SYS_nanosleep: no_implement("nanosleep\n"); break; case SYS_nice: no_implement("nice\n"); break; case SYS_open: ret = shell_open((const char *)r->a, (int)r->b, (void *)r->c); break; case SYS_openat: no_implement("openat\n"); break; case SYS_pause: no_implement("pause\n"); break; case SYS_personality: no_implement("personality\n"); break; case SYS_pipe: no_implement("pipe\n"); break; case SYS_pipe2: no_implement("pipe2\n"); break; case SYS_pivot_root: no_implement("pivot_root\n"); break; case SYS_poll: ret = shell_poll((struct pollfd *)r->a, (nfds_t)r->b, (int)r->c); break; case SYS_ppoll: no_implement("ppoll\n"); break; case SYS_prctl: no_implement("prctl\n"); break; case SYS_pread64: no_implement("pread64\n"); break; case SYS_preadv: no_implement("preadv\n"); break; case SYS_prlimit64: no_implement("prlimit64\n"); break; case SYS_process_vm_readv: no_implement("process_vm_readv\n"); break; case SYS_process_vm_writev: no_implement("process_vm_writev\n"); break; case SYS_pselect6: no_implement("pselect6\n"); break; case SYS_ptrace: no_implement("ptrace\n"); break; case SYS_pwrite64: no_implement("pwrite64\n"); break; case SYS_pwritev: no_implement("pwritev\n"); break; case SYS_quotactl: no_implement("quotactl\n"); break; case SYS_read: ret = shell_read((int)r->a, (void *)r->b, (size_t)r->c); break; case SYS_readahead: no_implement("readahead\n"); break; case SYS_readlink: no_implement("readlink\n"); break; case SYS_readlinkat: no_implement("readlinkat\n"); break; case SYS_readv: ret = shell_readv((int)r->a, (const struct iovec *)r->b, (int)r->c); break; case SYS_recv: ret = shell_recv(r->a, (void *)r->b, (size_t)r->c, r->d); break; case SYS_recvfrom: if (r->e == 0) ret = shell_recv(r->a, (void *)r->b, (size_t)r->c, r->d); else ret = shell_recvfrom(r->a, (void *)r->b, (size_t)r->c, r->d, (struct sockaddr *)r->e, (socklen_t *)r->f); break; case SYS_recvmsg: ret = shell_recvmsg(r->a, (struct msghdr *)r->b, (size_t)r->c); break; case SYS_reboot: no_implement("reboot\n"); break; case SYS_recvmmsg: no_implement("recvmmsg\n"); break; case SYS_remap_file_pages: no_implement("remap_file_pages\n"); break; case SYS_removexattr: no_implement("removexattr\n"); break; case SYS_rename: ret = shell_rename((const char *)r->a, (const char *)r->b); break; case SYS_renameat: no_implement("renameat\n"); break; case SYS_rmdir: ret = shell_rmdir((const char *)r->a); break; case SYS_rt_sigaction: ret = shell_sigaction(r->a, (const struct sigaction *)r->b, (struct sigaction *)r->c); break; case SYS_rt_sigpending: no_implement("rt_sigpending\n"); break; case SYS_rt_sigprocmask: ret = shell_sigprocmask(r->a, (const sigset_t *)r->b, (sigset_t *)r->c); break; case SYS_rt_sigqueueinfo: no_implement("rt_sigqueueinfo\n"); break; case SYS_rt_sigsuspend: no_implement("rt_sigsuspend\n"); break; case SYS_rt_sigtimedwait: no_implement("rt_sigtimedwait\n"); break; case SYS_send: ret = shell_send(r->a, (const void *)r->b, (size_t)r->c, r->d); break; case SYS_sendmsg: ret = shell_sendmsg(r->a, (const struct msghdr *)r->b, (size_t)r->c); break; case SYS_sendto: if (r->e == 0) ret = shell_send(r->a, (const void *)r->b, (size_t)r->c, r->d); else ret = shell_sendto(r->a, (const void *)r->b, (size_t)r->c, r->d, (const struct sockaddr *)r->e, (socklen_t)r->f); break; case SYS_setsockopt: ret = shell_setsockopt(r->a, r->b, r->c, (const void *)r->d, (socklen_t)r->e); break; case SYS_shutdown: ret = shell_shutdown(r->a, r->b); break; case SYS_sched_get_priority_max: no_implement("sched_get_priority_max\n"); break; case SYS_sched_get_priority_min: no_implement("sched_get_priority_min\n"); break; case SYS_sched_getaffinity: no_implement("sched_getaffinity\n"); break; case SYS_sched_getparam: no_implement("sched_getparam\n"); break; case SYS_sched_getscheduler: no_implement("sched_getscheduler\n"); break; case SYS_sched_rr_get_interval: no_implement("sched_rr_get_interval\n"); break; case SYS_sched_setaffinity: no_implement("sched_setaffinity\n"); break; case SYS_sched_setparam: no_implement("sched_setparam\n"); break; case SYS_sched_setscheduler: no_implement("sched_setscheduler\n"); break; case SYS_sched_yield: no_implement("sched_yield\n"); break; case SYS_semctl: no_implement("semctl\n"); break; case SYS_semget: no_implement("semget\n"); break; case SYS_semop: no_implement("semop\n"); break; case SYS_semtimedop: no_implement("semtimedop\n"); break; case SYS_sendfile64: no_implement("sendfile\n"); break; case SYS_sendmmsg: no_implement("sendmmsg\n"); break; case SYS_set_robust_list: no_implement("set_robust_list\n"); break; #ifdef SYS_set_thread_area case SYS_set_thread_area: thread_area = (void *)r->a; __asm__ __volatile__ ( "mcr p15,0,%0,c13,c0,3" :: "r"(thread_area) ); ret = 0; break; #endif case SYS_set_tid_address: tid_address = (void *)r->a; ret = 0; break; case SYS_setdomainname: no_implement("setdomainname\n"); break; case SYS_setfsgid32: no_implement("setfsgid\n"); break; case SYS_setfsuid32: no_implement("setfsuid\n"); break; case SYS_setgroups32: no_implement("setgroups\n"); break; case SYS_sethostname: no_implement("sethostname\n"); break; case SYS_setitimer: no_implement("setitimer\n"); break; case SYS_setns: no_implement("setns\n"); break; case SYS_setpgid: no_implement("setpgid\n"); break; case SYS_setpriority: no_implement("setpriority\n"); break; case SYS_setrlimit: no_implement("setrlimit\n"); break; case SYS_setsid: no_implement("setsid\n"); break; case SYS_settimeofday: no_implement("settimeofday\n"); break; case SYS_setxattr: no_implement("setxattr\n"); break; case SYS_shmat: no_implement("shmat\n"); break; case SYS_shmctl: no_implement("shmctl\n"); break; case SYS_shmdt: no_implement("shmdt\n"); break; case SYS_shmget: no_implement("shmget\n"); break; case SYS_sigaltstack: no_implement("sigaltstack\n"); break; case SYS_signalfd: no_implement("signalfd\n"); break; case SYS_signalfd4: no_implement("signalfd4\n"); break; case SYS_socket: ret = shell_socket(r->a, r->b, r->c); break; case SYS_splice: no_implement("splice\n"); break; case SYS_stat64: ret = shell_stat((const char *)r->a, (struct stat *)r->b); break; case SYS_statfs64: no_implement("statfs64\n"); break; case SYS_swapoff: no_implement("swapoff\n"); break; case SYS_swapon: no_implement("swapon\n"); break; case SYS_symlink: no_implement("symlink\n"); break; case SYS_symlinkat: no_implement("symlinkat\n"); break; case SYS_sync: no_implement("sync\n"); break; #ifdef SYS_sync_file_range case SYS_sync_file_range: no_implement("sync_file_range\n"); break; #endif case SYS_sync_file_range2: no_implement("sync_file_range2\n"); break; case SYS_syncfs: no_implement("syncfs\n"); break; case SYS_sysinfo: no_implement("sysinfo\n"); break; case SYS_syslog: no_implement("syslog\n"); break; case SYS_tee: no_implement("tee\n"); break; case SYS_tgkill: no_implement("tgkill\n"); break; case SYS_timer_create: no_implement("timer_create\n"); break; case SYS_timer_delete: no_implement("timer_delete\n"); break; case SYS_timer_getoverrun: no_implement("timer_getoverrun\n"); break; case SYS_timer_gettime: no_implement("timer_gettime\n"); break; case SYS_timer_settime: no_implement("timer_settime\n"); break; case SYS_timerfd_create: no_implement("timerfd_create\n"); break; case SYS_timerfd_gettime: no_implement("timerfd_gettime\n"); break; case SYS_timerfd_settime: no_implement("timerfd_settime\n"); break; case SYS_times: no_implement("times\n"); break; case SYS_tkill: no_implement("tkill\n"); break; case SYS_truncate64: no_implement("truncate\n"); break; case SYS_ugetrlimit: no_implement("ugetrlimit\n"); break; case SYS_umask: no_implement("umask\n"); break; case SYS_umount2: no_implement("umount2\n"); break; case SYS_uname: ret = shell_uname((struct utsname *)r->a); break; case SYS_unlink: ret = shell_unlink((const char *)r->a); break; case SYS_unlinkat: no_implement("unlinkat\n"); break; case SYS_unshare: no_implement("unshare\n"); break; case SYS_utimensat: no_implement("utimensat\n"); break; case SYS_utimes: no_implement("utimes\n"); break; case SYS_vhangup: no_implement("vhangup\n"); break; case SYS_vmsplice: no_implement("vmsplice\n"); break; case SYS_wait4: no_implement("wait4\n"); break; case SYS_waitid: no_implement("waitid\n"); break; case SYS_write: ret = shell_write((int)r->a, (const void *)r->b, (size_t)r->c); break; case SYS_writev: ret = shell_writev((int)r->a, (const struct iovec *)r->b, (size_t)r->c); break; default: switch (r->n) { case 0xf0002: flash_access_cache_control(); ret = 0; break; case 0xf0005: // __set_thread_area thread_area = (void *)r->a; __asm__ __volatile__ ( "mcr p15,0,%0,c13,c0,3" :: "r"(thread_area) ); ret = 0; break; default: asm("bkpt #0"); break; } break; } shellif_outof(); return ret; } void __attribute__((naked)) __syscall_cp_asm() { register long sp asm("sp"); asm("push {r0, r1, r2, r3, r4, r5, r7, r12, lr}"); __syscall((struct regs_t *)sp); asm("add sp, sp, #4"); asm("pop {r1, r2, r3, r4, r5, r7, r12, pc}"); } /* * スーパバイザコール */ void __attribute__((naked)) _kernel_svc_handler(void) { register long r0 asm("r0"); asm("srsfd #0x13!"); asm("stmfd sp!, {r0-r3,r12,lr}"); asm("mrs r0, spsr"); asm("tst r0, #0x20"); asm("ldrneh r0, [lr,#-2]"); asm("bicne r0, r0, #0xFF00"); asm("ldreq r0, [lr,#-4]"); asm("biceq r0, r0, #0xFF000000"); switch (r0){ case 0: asm("str %0, [sp,#0x18]" :: "r"(__syscall_cp_asm)); break; case 1: asm("str %0, [sp,#0x18]" :: "r"(__mbedcall_cp_asm)); break; } asm("ldmfd sp!, {r0-r3,r12,lr}"); asm("rfefd sp!"); }