1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
4 */
5
6 #include <image.h>
7 #include <log.h>
8 #include <semihosting.h>
9 #include <spl.h>
10 #include <spl_load.h>
11
smh_fit_read(struct spl_load_info * load,ulong file_offset,ulong size,void * buf)12 static ulong smh_fit_read(struct spl_load_info *load, ulong file_offset,
13 ulong size, void *buf)
14 {
15 long fd = *(long *)load->priv;
16 ulong ret;
17
18 if (smh_seek(fd, file_offset))
19 return 0;
20
21 ret = smh_read(fd, buf, size);
22 return ret < 0 ? 0 : ret;
23 }
24
spl_smh_load_image(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)25 static int spl_smh_load_image(struct spl_image_info *spl_image,
26 struct spl_boot_device *bootdev)
27 {
28 const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME;
29 int ret;
30 long fd, len;
31 struct spl_load_info load;
32
33 fd = smh_open(filename, MODE_READ | MODE_BINARY);
34 if (fd < 0) {
35 log_debug("could not open %s: %ld\n", filename, fd);
36 return fd;
37 }
38
39 ret = smh_flen(fd);
40 if (ret < 0) {
41 log_debug("could not get length of image: %d\n", ret);
42 goto out;
43 }
44 len = ret;
45
46 spl_load_init(&load, smh_fit_read, &fd, 1);
47 ret = spl_load(spl_image, bootdev, &load, len, 0);
48 if (ret)
49 log_debug("could not read %s: %d\n", filename, ret);
50 out:
51 smh_close(fd);
52 return ret;
53 }
54 SPL_LOAD_IMAGE_METHOD("SEMIHOSTING", 0, BOOT_DEVICE_SMH, spl_smh_load_image);
55