|  | /* | 
|  | * Copyright (c) 2022, Commonwealth Scientific and Industrial Research | 
|  | * Organisation (CSIRO) ABN 41 687 119 230. | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | #include <string.h> | 
|  | #include <zephyr/kernel.h> | 
|  | #include <zephyr/arch/common/semihost.h> | 
|  |  | 
|  | struct semihost_poll_in_args { | 
|  | long zero; | 
|  | } __packed; | 
|  |  | 
|  | struct semihost_open_args { | 
|  | const char *path; | 
|  | long mode; | 
|  | long path_len; | 
|  | } __packed; | 
|  |  | 
|  | struct semihost_close_args { | 
|  | long fd; | 
|  | } __packed; | 
|  |  | 
|  | struct semihost_flen_args { | 
|  | long fd; | 
|  | } __packed; | 
|  |  | 
|  | struct semihost_seek_args { | 
|  | long fd; | 
|  | long offset; | 
|  | } __packed; | 
|  |  | 
|  | struct semihost_read_args { | 
|  | long fd; | 
|  | char *buf; | 
|  | long len; | 
|  | } __packed; | 
|  |  | 
|  | struct semihost_write_args { | 
|  | long fd; | 
|  | const char *buf; | 
|  | long len; | 
|  | } __packed; | 
|  |  | 
|  | char semihost_poll_in(void) | 
|  | { | 
|  | struct semihost_poll_in_args args = { | 
|  | .zero = 0 | 
|  | }; | 
|  |  | 
|  | return (char)semihost_exec(SEMIHOST_READC, &args); | 
|  | } | 
|  |  | 
|  | void semihost_poll_out(char c) | 
|  | { | 
|  | /* WRITEC takes a pointer directly to the character */ | 
|  | (void)semihost_exec(SEMIHOST_WRITEC, &c); | 
|  | } | 
|  |  | 
|  | long semihost_open(const char *path, long mode) | 
|  | { | 
|  | struct semihost_open_args args = { | 
|  | .path = path, | 
|  | .mode = mode, | 
|  | .path_len = strlen(path) | 
|  | }; | 
|  |  | 
|  | return semihost_exec(SEMIHOST_OPEN, &args); | 
|  | } | 
|  |  | 
|  | long semihost_close(long fd) | 
|  | { | 
|  | struct semihost_close_args args = { | 
|  | .fd = fd | 
|  | }; | 
|  |  | 
|  | return semihost_exec(SEMIHOST_CLOSE, &args); | 
|  | } | 
|  |  | 
|  | long semihost_flen(long fd) | 
|  | { | 
|  | struct semihost_flen_args args = { | 
|  | .fd = fd | 
|  | }; | 
|  |  | 
|  | return semihost_exec(SEMIHOST_FLEN, &args); | 
|  | } | 
|  |  | 
|  | long semihost_seek(long fd, long offset) | 
|  | { | 
|  | struct semihost_seek_args args = { | 
|  | .fd = fd, | 
|  | .offset = offset | 
|  | }; | 
|  |  | 
|  | return semihost_exec(SEMIHOST_SEEK, &args); | 
|  | } | 
|  |  | 
|  | long semihost_read(long fd, void *buf, long len) | 
|  | { | 
|  | struct semihost_read_args args = { | 
|  | .fd = fd, | 
|  | .buf = buf, | 
|  | .len = len | 
|  | }; | 
|  | long ret; | 
|  |  | 
|  | ret = semihost_exec(SEMIHOST_READ, &args); | 
|  | /* EOF condition */ | 
|  | if (ret == len) { | 
|  | ret = -EIO; | 
|  | } | 
|  | /* All bytes read */ | 
|  | else if (ret == 0) { | 
|  | ret = len; | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | long semihost_write(long fd, const void *buf, long len) | 
|  | { | 
|  | struct semihost_write_args args = { | 
|  | .fd = fd, | 
|  | .buf = buf, | 
|  | .len = len | 
|  | }; | 
|  |  | 
|  | return semihost_exec(SEMIHOST_WRITE, &args); | 
|  | } |