semihostingfs.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. #include <common.h>
  7. #include <fs.h>
  8. #include <malloc.h>
  9. #include <os.h>
  10. #include <semihosting.h>
  11. #include <semihostingfs.h>
  12. int smh_fs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info)
  13. {
  14. /*
  15. * Only accept a NULL struct blk_desc for the semihosting, which is when
  16. * hostfs interface is used
  17. */
  18. return !!rbdd;
  19. }
  20. static int smh_fs_read_at(const char *filename, loff_t pos, void *buffer,
  21. loff_t maxsize, loff_t *actread)
  22. {
  23. long fd, size, ret;
  24. fd = smh_open(filename, MODE_READ | MODE_BINARY);
  25. if (fd < 0)
  26. return fd;
  27. ret = smh_seek(fd, pos);
  28. if (ret < 0) {
  29. smh_close(fd);
  30. return ret;
  31. }
  32. if (!maxsize) {
  33. size = smh_flen(fd);
  34. if (ret < 0) {
  35. smh_close(fd);
  36. return size;
  37. }
  38. maxsize = size;
  39. }
  40. size = smh_read(fd, buffer, maxsize);
  41. smh_close(fd);
  42. if (size < 0)
  43. return size;
  44. *actread = size;
  45. return 0;
  46. }
  47. static int smh_fs_write_at(const char *filename, loff_t pos, void *buffer,
  48. loff_t towrite, loff_t *actwrite)
  49. {
  50. long fd, size, ret;
  51. /* Try to open existing file */
  52. fd = smh_open(filename, MODE_READ | MODE_BINARY | MODE_PLUS);
  53. if (fd < 0)
  54. /* Create new file */
  55. fd = smh_open(filename, MODE_WRITE | MODE_BINARY);
  56. if (fd < 0)
  57. return fd;
  58. ret = smh_seek(fd, pos);
  59. if (ret < 0) {
  60. smh_close(fd);
  61. return ret;
  62. }
  63. ret = smh_write(fd, buffer, towrite, &size);
  64. smh_close(fd);
  65. *actwrite = size;
  66. return ret;
  67. }
  68. int smh_fs_size(const char *filename, loff_t *result)
  69. {
  70. long fd, size;
  71. fd = smh_open(filename, MODE_READ | MODE_BINARY);
  72. if (fd < 0)
  73. return fd;
  74. size = smh_flen(fd);
  75. smh_close(fd);
  76. if (size < 0)
  77. return size;
  78. *result = size;
  79. return 0;
  80. }
  81. int smh_fs_read(const char *filename, void *buf, loff_t offset, loff_t len,
  82. loff_t *actread)
  83. {
  84. int ret;
  85. ret = smh_fs_read_at(filename, offset, buf, len, actread);
  86. if (ret)
  87. printf("** Unable to read file %s **\n", filename);
  88. return ret;
  89. }
  90. int smh_fs_write(const char *filename, void *buf, loff_t offset,
  91. loff_t len, loff_t *actwrite)
  92. {
  93. int ret;
  94. ret = smh_fs_write_at(filename, offset, buf, len, actwrite);
  95. if (ret)
  96. printf("** Unable to write file %s **\n", filename);
  97. return ret;
  98. }