blob: 5b5e842a11b1eb70169dd3b14d1b316bdbab170d [file] [log] [blame]
Sean Anderson8e1c9fe2022-03-22 16:59:19 -04001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
4 */
5
6#include <common.h>
7#include <image.h>
8#include <log.h>
9#include <semihosting.h>
10#include <spl.h>
11
12static int smh_read_full(long fd, void *memp, size_t len)
13{
14 long read;
15
16 read = smh_read(fd, memp, len);
17 if (read < 0)
18 return read;
19 if (read != len)
20 return -EIO;
21 return 0;
22}
23
24static int spl_smh_load_image(struct spl_image_info *spl_image,
25 struct spl_boot_device *bootdev)
26{
27 const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME;
28 int ret;
29 long fd, len;
Simon Glassf3543e62022-09-06 20:26:52 -060030 struct legacy_img_hdr *header =
Sean Anderson8e1c9fe2022-03-22 16:59:19 -040031 spl_get_load_buffer(-sizeof(*header), sizeof(*header));
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
Simon Glassf3543e62022-09-06 20:26:52 -060046 ret = smh_read_full(fd, header, sizeof(struct legacy_img_hdr));
Sean Anderson8e1c9fe2022-03-22 16:59:19 -040047 if (ret) {
48 log_debug("could not read image header: %d\n", ret);
49 goto out;
50 }
51
52 ret = spl_parse_image_header(spl_image, bootdev, header);
53 if (ret) {
54 log_debug("failed to parse image header: %d\n", ret);
55 goto out;
56 }
57
58 ret = smh_seek(fd, 0);
59 if (ret) {
60 log_debug("could not seek to start of image: %d\n", ret);
61 goto out;
62 }
63
64 ret = smh_read_full(fd, (void *)spl_image->load_addr, len);
65 if (ret)
66 log_debug("could not read %s: %d\n", filename, ret);
67out:
68 smh_close(fd);
69 return ret;
70}
71SPL_LOAD_IMAGE_METHOD("SEMIHOSTING", 0, BOOT_DEVICE_SMH, spl_smh_load_image);