:)
[platform/kernel/u-boot.git] / fs / semihostingfs.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2022, Sean Anderson <sean.anderson@seco.com>
4  * Copyright (c) 2012, Google Inc.
5  */
6
7 #include <common.h>
8 #include <fs.h>
9 #include <malloc.h>
10 #include <os.h>
11 #include <semihosting.h>
12 #include <semihostingfs.h>
13
14 int smh_fs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info)
15 {
16         /*
17          * Only accept a NULL struct blk_desc for the semihosting, which is when
18          * hostfs interface is used
19          */
20         return !!rbdd;
21 }
22
23 static int smh_fs_read_at(const char *filename, loff_t pos, void *buffer,
24                           loff_t maxsize, loff_t *actread)
25 {
26         long fd, size, ret;
27
28         fd = smh_open(filename, MODE_READ | MODE_BINARY);
29         if (fd < 0)
30                 return fd;
31         ret = smh_seek(fd, pos);
32         if (ret < 0) {
33                 smh_close(fd);
34                 return ret;
35         }
36         if (!maxsize) {
37                 size = smh_flen(fd);
38                 if (ret < 0) {
39                         smh_close(fd);
40                         return size;
41                 }
42
43                 maxsize = size;
44         }
45
46         size = smh_read(fd, buffer, maxsize);
47         smh_close(fd);
48         if (size < 0)
49                 return size;
50
51         *actread = size;
52         return 0;
53 }
54
55 static int smh_fs_write_at(const char *filename, loff_t pos, void *buffer,
56                            loff_t towrite, loff_t *actwrite)
57 {
58         long fd, size, ret;
59
60         fd = smh_open(filename, MODE_READ | MODE_BINARY | MODE_PLUS);
61         if (fd < 0)
62                 return fd;
63         ret = smh_seek(fd, pos);
64         if (ret < 0) {
65                 smh_close(fd);
66                 return ret;
67         }
68
69         ret = smh_write(fd, buffer, towrite, &size);
70         smh_close(fd);
71         *actwrite = size;
72         return ret;
73 }
74
75 int smh_fs_size(const char *filename, loff_t *result)
76 {
77         long fd, size;
78
79         fd = smh_open(filename, MODE_READ | MODE_BINARY);
80         if (fd < 0)
81                 return fd;
82
83         size = smh_flen(fd);
84         smh_close(fd);
85
86         if (size < 0)
87                 return size;
88
89         *result = size;
90         return 0;
91 }
92
93 int smh_fs_read(const char *filename, void *buf, loff_t offset, loff_t len,
94                 loff_t *actread)
95 {
96         int ret;
97
98         ret = smh_fs_read_at(filename, offset, buf, len, actread);
99         if (ret)
100                 printf("** Unable to read file %s **\n", filename);
101
102         return ret;
103 }
104
105 int smh_fs_write(const char *filename, void *buf, loff_t offset,
106                  loff_t len, loff_t *actwrite)
107 {
108         int ret;
109
110         ret = smh_fs_write_at(filename, offset, buf, len, actwrite);
111         if (ret)
112                 printf("** Unable to write file %s **\n", filename);
113
114         return ret;
115 }