/* * SPDX-License-Identifier: BSD-3-Clause * * Copyright © 2023 Keith Packard * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _NIOS2_SEMIHOST_H_ #define _NIOS2_SEMIHOST_H_ #include <stdio.h> #include <errno.h> #include <endian.h> #include <sys/types.h> #include <sys/stat.h> #define HOSTED_EXIT 0 #define HOSTED_INIT_SIM 1 #define HOSTED_OPEN 2 #define HOSTED_CLOSE 3 #define HOSTED_READ 4 #define HOSTED_WRITE 5 #define HOSTED_LSEEK 6 #define HOSTED_RENAME 7 #define HOSTED_UNLINK 8 #define HOSTED_STAT 9 #define HOSTED_FSTAT 10 #define HOSTED_GETTIMEOFDAY 11 #define HOSTED_ISATTY 12 #define HOSTED_SYSTEM 13 #define GDB_O_RDONLY 0 #define GDB_O_WRONLY 1 #define GDB_O_RDWR 2 #define GDB_O_APPEND 8 #define GDB_O_CREAT 0x200 #define GDB_O_TRUNC 0x400 #define GDB_O_EXCL 0x800 typedef uint32_t my_mode_t; typedef uint32_t my_time_t; struct nios2_stat { uint32_t my_dev; /* device */ uint32_t my_ino; /* inode */ my_mode_t my_mode; /* protection */ uint32_t my_nlink; /* number of hard links */ uint32_t my_uid; /* user ID of owner */ uint32_t my_gid; /* group ID of owner */ uint32_t my_rdev; /* device type (if inode device) */ uint64_t my_size; /* total size, in bytes */ uint64_t my_blksize; /* blocksize for filesystem I/O */ uint64_t my_blocks; /* number of blocks allocated */ my_time_t my_atime; /* time of last access */ my_time_t my_mtime; /* time of last modification */ my_time_t my_ctime; /* time of last change */ }; static inline copy_stat(struct stat *restrict statbuf, struct nios2_stat *nios2_stat) { statbuf->st_dev = be32toh(nios2_stat->my_dev); statbuf->st_ino = be32toh(nios2_stat->my_ino); statbuf->st_mode = be32toh(nios2_stat->my_mode); statbuf->st_nlink = be32toh(nios2_stat->my_nlink); statbuf->st_uid = be32toh(nios2_stat->my_uid); statbuf->st_gid = be32toh(nios2_stat->my_gid); statbuf->st_rdev = be32toh(nios2_stat->my_rdev); statbuf->st_size = be32toh(nios2_stat->my_size); statbuf->st_blksize = be32toh(nios2_stat->my_blksize); statbuf->st_blocks = be32toh(nios2_stat->my_blocks); statbuf->st_atime = be32toh(nios2_stat->my_atime); statbuf->st_mtime = be32toh(nios2_stat->my_mtime); statbuf->st_ctime = be32toh(nios2_stat->my_ctime); } struct nios2_semihost { uintptr_t args[4]; }; intptr_t nios2_semihost(int func, struct nios2_semihost *args); static inline intptr_t nios2_semihost1_immediate(int func, uintptr_t arg0) { return nios2_semihost(func, (struct nios2_semihost *) arg0); }; static inline intptr_t nios2_semihost1(int func, uintptr_t arg0) { struct nios2_semihost args; intptr_t ret; args.args[0] = arg0; nios2_semihost(func, &args); ret = args.args[0]; if (ret < 0) errno = args.args[1]; return ret; }; static inline intptr_t nios2_semihost2(int func, uintptr_t arg0, uintptr_t arg1) { struct nios2_semihost args; intptr_t ret; args.args[0] = arg0; args.args[1] = arg1; nios2_semihost(func, &args); ret = args.args[0]; if (ret < 0) errno = args.args[1]; return ret; }; static inline intptr_t nios2_semihost3(int func, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2) { struct nios2_semihost args; intptr_t ret; args.args[0] = arg0; args.args[1] = arg1; args.args[2] = arg2; nios2_semihost(func, &args); ret = args.args[0]; if (ret < 0) errno = args.args[1]; return ret; }; static inline uint64_t nios2_semihost4_64(int func, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3) { struct nios2_semihost args; uint64_t ret; args.args[0] = arg0; args.args[1] = arg1; args.args[2] = arg2; args.args[3] = arg3; nios2_semihost(func, &args); ret = ((uint64_t) args.args[0] << 32) | args.args[1]; if ((int64_t) ret < 0) errno = args.args[2]; return ret; }; static inline intptr_t nios2_semihost4(int func, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3) { struct nios2_semihost args; intptr_t ret; args.args[0] = arg0; args.args[1] = arg1; args.args[2] = arg2; args.args[3] = arg3; nios2_semihost(func, &args); ret = args.args[0]; if (ret < 0) errno = args.args[1]; return ret; }; #endif /* _NIOS2_SEMIHOST_H_ */