Prepare v2023.10
[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         /* Try to open existing file */
61         fd = smh_open(filename, MODE_READ | MODE_BINARY | MODE_PLUS);
62         if (fd < 0)
63                 /* Create new file */
64                 fd = smh_open(filename, MODE_WRITE | MODE_BINARY);
65         if (fd < 0)
66                 return fd;
67         ret = smh_seek(fd, pos);
68         if (ret < 0) {
69                 smh_close(fd);
70                 return ret;
71         }
72
73         ret = smh_write(fd, buffer, towrite, &size);
74         smh_close(fd);
75         *actwrite = size;
76         return ret;
77 }
78
79 int smh_fs_size(const char *filename, loff_t *result)
80 {
81         long fd, size;
82
83         fd = smh_open(filename, MODE_READ | MODE_BINARY);
84         if (fd < 0)
85                 return fd;
86
87         size = smh_flen(fd);
88         smh_close(fd);
89
90         if (size < 0)
91                 return size;
92
93         *result = size;
94         return 0;
95 }
96
97 int smh_fs_read(const char *filename, void *buf, loff_t offset, loff_t len,
98                 loff_t *actread)
99 {
100         int ret;
101
102         ret = smh_fs_read_at(filename, offset, buf, len, actread);
103         if (ret)
104                 printf("** Unable to read file %s **\n", filename);
105
106         return ret;
107 }
108
109 int smh_fs_write(const char *filename, void *buf, loff_t offset,
110                  loff_t len, loff_t *actwrite)
111 {
112         int ret;
113
114         ret = smh_fs_write_at(filename, offset, buf, len, actwrite);
115         if (ret)
116                 printf("** Unable to write file %s **\n", filename);
117
118         return ret;
119 }