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 14int 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 23static 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 55static 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 79int 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 97int 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 109int 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} 120