/* * TOPPERS PROJECT Home Network Working Group Software * * Copyright (C) 2020 Cores Co., Ltd. Japan * * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー * スコード中に含まれていること. * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 * の無保証規定を掲載すること. * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ * と. * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 * 作権表示,この利用条件および下記の無保証規定を掲載すること. * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに * 報告すること. * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを * 免責すること. * * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ * の責任を負わない. * * @(#) $Id$ */ #include "shellif.h" #include "target_syssvc.h" #include "kernel_cfg.h" extern int shellcmd_exit_code; extern jmp_buf shellcmd_exit; void shell_abort() { shellcmd_exit_code = -1; longjmp(shellcmd_exit, 1); } void shell_exit(int exitcd) { shellcmd_exit_code = exitcd; longjmp(shellcmd_exit, 1); } void shell_exit_group(int exitcd) { shellcmd_exit_code = exitcd; longjmp(shellcmd_exit, 1); } const struct utsname host_name = { "TOPPERS/ASP3", TARGET_NAME, "3.5.0", "3.5.0", TARGET_NAME, "toppers.jp" }; int shell_uname(struct utsname *uts) { memcpy(uts, &host_name, sizeof(host_name)); return 0; } int shell_clock_getres(clockid_t clk_id, struct timespec *res) { if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC)) return -EINVAL; memset(&res->tv_sec, 0xFF, sizeof(res->tv_sec)); res->tv_nsec = 0; return 0; } int shell_clock_gettime(clockid_t clk_id, struct timespec *tp) { SYSTIM now = 0; if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC)) return -EINVAL; get_tim(&now); tp->tv_sec = now / 1000000; tp->tv_nsec = (now % 1000000) * 1000; return 0; } int shell_clock_settime(clockid_t clk_id, const struct timespec *tp) { if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC)) return -EINVAL; SYSTIM time; ER ret; time = (tp->tv_sec * 1000000ll) + (tp->tv_nsec / 1000ll); ret = set_tim(time); if (ret != E_OK) { return -EPERM; } return 0; } sigset_t g_sigmask; int shell_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old) { if (old != NULL) memcpy(old, &g_sigmask, sizeof(sigset_t)); switch (how) { case SIG_BLOCK: for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) { g_sigmask.__bits[i] |= set->__bits[i]; } break; case SIG_UNBLOCK: for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) { g_sigmask.__bits[i] &= ~set->__bits[i]; } break; case SIG_SETMASK: memcpy(&g_sigmask, set, sizeof(sigset_t)); break; default: return -EINVAL; } return 0; } // musl-1.1.18\src\internal\ksigaction.h struct k_sigaction { void(*handler)(int); unsigned long flags; void(*restorer)(void); unsigned mask[2]; }; struct k_sigaction sigtable[7]; int shell_sigaction(int sig, const struct k_sigaction *restrict sa, struct k_sigaction *restrict old, size_t size) { struct k_sigaction *sat; switch(sig){ case SIGALRM: sat = &sigtable[0]; break; case SIGFPE: sat = &sigtable[1]; break; case SIGILL: sat = &sigtable[2]; break; case SIGSEGV: sat = &sigtable[3]; break; case SIGBUS: sat = &sigtable[4]; break; case SIGABRT: sat = &sigtable[5]; break; case SIGPIPE: sat = &sigtable[6]; break; default: return -EINVAL; } if (old != NULL) memcpy(old, sat, offsetof(struct k_sigaction, mask) + size); memcpy(sat, sa, offsetof(struct k_sigaction, mask) + size); return 0; } int shell_madvise(void *a, size_t b, int c) { return 0; } int shell_gettid() { ID tskid; ER ret; ret = get_tid(&tskid); if (ret != E_OK) return -1; return tskid; } int shell_tkill(int tid, int sig) { if ((tid == SHELLCMD_TASK) && (sig == SIGABRT)) { shell_abort(); } no_implement("tkill"); return -1; } int shell_kill(int pid, int sig) { DebugBreak(); return -1; } int shell_gettimeofday(struct timeval *tv, void *tzvp) { SYSTIM time; if (!tv) return 0; get_tim(&time); tv->tv_sec = time / 1000000; tv->tv_usec = time - (tv->tv_sec * 1000000); return 0; } int shell_nanosleep(const struct timespec *req, struct timespec *rem) { ER ret; TMO tmo; SYSTIM prev, now, diff; if ((req == NULL) || (req->tv_nsec < 0) || (req->tv_nsec >= 1000000000)) return -EINVAL; get_tim(&prev); tmo = req->tv_sec * 1000000 + req->tv_nsec / 1000; ret = tslp_tsk(tmo); if (ret == E_OK) { if (rem != NULL) { get_tim(&now); diff = now - prev; rem->tv_sec = diff / 1000000ll; rem->tv_nsec = (diff - (rem->tv_sec * 1000000ll)) * 1000ll; } return 0; } else if (ret == E_TMOUT) { if (rem != NULL) { rem->tv_sec = 0; rem->tv_nsec = 0; } return 0; } return -EFAULT; } ssize_t shell_getrandom(void *buf, size_t buflen, unsigned int flags) { SYSTIM now; int32_t i; int *output = (int *)buf; size_t sz = buflen / 4; get_tim(&now); srand(now); for (i = 0; i < sz; i++) output[i] = rand(); for (i = 4 * sz; i < buflen; i++) ((char *)buf)[i] = rand(); return buflen; } extern uint32_t __CmdBase; extern uint32_t __CmdLimit; void *shell_brk(void *addr) { if (addr == 0) { return (void *)((intptr_t)&__CmdBase + 0x40000); } if ((addr >= (intptr_t)&__CmdBase + 0x40000) && (addr < &__CmdLimit)) { return addr; } return (void *)-1; } void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset) { if (fd != -1) return -EINVAL; if ((length >= 0) && (length <= (intptr_t)&__CmdLimit - ((intptr_t)&__CmdBase + 0x40000))) { return &__CmdBase + 0x40000; } return (void *)-1; } int shell_mprotect(void *addr, size_t len, int prot) { //if ((addr >= (intptr_t)&__CmdBase + 0x40000) && ((intptr_t)addr + len < &__CmdLimit)) { return 0; //} //return -1; }