1 /*
2 * Copyright (c) 2022, Commonwealth Scientific and Industrial Research
3 * Organisation (CSIRO) ABN 41 687 119 230.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <string.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/arch/common/semihost.h>
11
12 struct semihost_poll_in_args {
13 long zero;
14 } __packed;
15
16 struct semihost_open_args {
17 const char *path;
18 long mode;
19 long path_len;
20 } __packed;
21
22 struct semihost_close_args {
23 long fd;
24 } __packed;
25
26 struct semihost_flen_args {
27 long fd;
28 } __packed;
29
30 struct semihost_seek_args {
31 long fd;
32 long offset;
33 } __packed;
34
35 struct semihost_read_args {
36 long fd;
37 char *buf;
38 long len;
39 } __packed;
40
41 struct semihost_write_args {
42 long fd;
43 const char *buf;
44 long len;
45 } __packed;
46
semihost_poll_in(void)47 char semihost_poll_in(void)
48 {
49 struct semihost_poll_in_args args = {
50 .zero = 0
51 };
52
53 return (char)semihost_exec(SEMIHOST_READC, &args);
54 }
55
semihost_poll_out(char c)56 void semihost_poll_out(char c)
57 {
58 /* WRITEC takes a pointer directly to the character */
59 (void)semihost_exec(SEMIHOST_WRITEC, &c);
60 }
61
semihost_open(const char * path,long mode)62 long semihost_open(const char *path, long mode)
63 {
64 struct semihost_open_args args = {
65 .path = path,
66 .mode = mode,
67 .path_len = strlen(path)
68 };
69
70 return semihost_exec(SEMIHOST_OPEN, &args);
71 }
72
semihost_close(long fd)73 long semihost_close(long fd)
74 {
75 struct semihost_close_args args = {
76 .fd = fd
77 };
78
79 return semihost_exec(SEMIHOST_CLOSE, &args);
80 }
81
semihost_flen(long fd)82 long semihost_flen(long fd)
83 {
84 struct semihost_flen_args args = {
85 .fd = fd
86 };
87
88 return semihost_exec(SEMIHOST_FLEN, &args);
89 }
90
semihost_seek(long fd,long offset)91 long semihost_seek(long fd, long offset)
92 {
93 struct semihost_seek_args args = {
94 .fd = fd,
95 .offset = offset
96 };
97
98 return semihost_exec(SEMIHOST_SEEK, &args);
99 }
100
semihost_read(long fd,void * buf,long len)101 long semihost_read(long fd, void *buf, long len)
102 {
103 struct semihost_read_args args = {
104 .fd = fd,
105 .buf = buf,
106 .len = len
107 };
108 long ret;
109
110 ret = semihost_exec(SEMIHOST_READ, &args);
111 /* EOF condition */
112 if (ret == len) {
113 ret = -EIO;
114 }
115 /* All bytes read */
116 else if (ret == 0) {
117 ret = len;
118 }
119 return ret;
120 }
121
semihost_write(long fd,const void * buf,long len)122 long semihost_write(long fd, const void *buf, long len)
123 {
124 struct semihost_write_args args = {
125 .fd = fd,
126 .buf = buf,
127 .len = len
128 };
129
130 return semihost_exec(SEMIHOST_WRITE, &args);
131 }
132