]> Git Repo - u-boot.git/blame - common/spl/spl_ymodem.c
Restore patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"
[u-boot.git] / common / spl / spl_ymodem.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
24de357a
MP
2/*
3 * (C) Copyright 2000-2004
4 * Wolfgang Denk, DENX Software Engineering, [email protected].
5 *
6 * (C) Copyright 2011
7 * Texas Instruments, <www.ti.com>
8 *
9 * Matt Porter <[email protected]>
24de357a 10 */
0c670fc1 11#include <gzip.h>
4d72caa5 12#include <image.h>
f7ae49fc 13#include <log.h>
47f7bcae 14#include <spl.h>
24de357a 15#include <xyzModem.h>
b08c8c48 16#include <linux/libfdt.h>
24de357a
MP
17
18#define BUF_SIZE 1024
19
fa715193
LV
20/*
21 * Information required to load image using ymodem.
22 *
23 * @image_read: Now of bytes read from the image.
24 * @buf: pointer to the previous read block.
25 */
26struct ymodem_fit_info {
27 int image_read;
28 char *buf;
29};
30
24de357a
MP
31static int getcymodem(void) {
32 if (tstc())
c670aeee 33 return (getchar());
24de357a
MP
34 return -1;
35}
36
fa715193
LV
37static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
38 ulong size, void *addr)
39{
095764e3 40 int res, err, buf_offset;
fa715193
LV
41 struct ymodem_fit_info *info = load->priv;
42 char *buf = info->buf;
c1335e2c 43 ulong copy_size = size;
fa715193
LV
44
45 while (info->image_read < offset) {
46 res = xyzModem_stream_read(buf, BUF_SIZE, &err);
47 if (res <= 0)
9d6ee3e2
AD
48 break;
49
fa715193
LV
50 info->image_read += res;
51 }
52
53 if (info->image_read > offset) {
54 res = info->image_read - offset;
095764e3
LV
55 if (info->image_read % BUF_SIZE)
56 buf_offset = (info->image_read % BUF_SIZE);
57 else
58 buf_offset = BUF_SIZE;
c1335e2c
VR
59
60 if (res > copy_size) {
61 memcpy(addr, &buf[buf_offset - res], copy_size);
62 goto done;
63 }
095764e3 64 memcpy(addr, &buf[buf_offset - res], res);
fa715193 65 addr = addr + res;
c1335e2c 66 copy_size -= res;
fa715193
LV
67 }
68
69 while (info->image_read < offset + size) {
70 res = xyzModem_stream_read(buf, BUF_SIZE, &err);
71 if (res <= 0)
9d6ee3e2 72 break;
fa715193 73
fa715193 74 info->image_read += res;
c1335e2c
VR
75 if (res > copy_size) {
76 memcpy(addr, buf, copy_size);
77 goto done;
78 }
79 memcpy(addr, buf, res);
fa715193 80 addr += res;
c1335e2c 81 copy_size -= res;
fa715193
LV
82 }
83
c1335e2c 84done:
fa715193
LV
85 return size;
86}
87
e413033d
AD
88int spl_ymodem_load_image(struct spl_image_info *spl_image,
89 struct spl_boot_device *bootdev)
24de357a 90{
92e5cb80 91 ulong size = 0;
24de357a
MP
92 int err;
93 int res;
94 int ret;
95 connection_info_t info;
96 char buf[BUF_SIZE];
f3543e69 97 struct legacy_img_hdr *ih = NULL;
24de357a
MP
98 ulong addr = 0;
99
100 info.mode = xyzModem_ymodem;
101 ret = xyzModem_stream_open(&info, &err);
fa715193
LV
102 if (ret) {
103 printf("spl: ymodem err - %s\n", xyzModem_error(err));
104 return ret;
105 }
106
107 res = xyzModem_stream_read(buf, BUF_SIZE, &err);
108 if (res <= 0)
109 goto end_stream;
110
792dd570 111 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) &&
f3543e69 112 image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) {
792dd570 113 addr = CONFIG_SYS_LOAD_ADDR;
f3543e69 114 ih = (struct legacy_img_hdr *)addr;
792dd570
MV
115
116 memcpy((void *)addr, buf, res);
117 size += res;
118 addr += res;
119
120 while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
121 memcpy((void *)addr, buf, res);
122 size += res;
123 addr += res;
124 }
125
2e0429bc 126 ret = spl_parse_image_header(spl_image, bootdev, ih);
792dd570
MV
127 if (ret)
128 return ret;
129 } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
f3543e69 130 image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) {
fa715193
LV
131 struct spl_load_info load;
132 struct ymodem_fit_info info;
133
134 debug("Found FIT\n");
fa715193 135 load.priv = (void *)&info;
5271e359 136 spl_set_bl_len(&load, 1);
fa715193
LV
137 info.buf = buf;
138 info.image_read = BUF_SIZE;
139 load.read = ymodem_read_fit;
f4d7d859 140 ret = spl_load_simple_fit(spl_image, &load, 0, (void *)buf);
fa715193 141 size = info.image_read;
24de357a 142
fa715193
LV
143 while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0)
144 size += res;
145 } else {
f3543e69 146 ih = (struct legacy_img_hdr *)buf;
2e0429bc 147 ret = spl_parse_image_header(spl_image, bootdev, ih);
fa715193 148 if (ret)
6d8dbe48 149 goto end_stream;
92e5cb80
MV
150#ifdef CONFIG_SPL_GZIP
151 if (ih->ih_comp == IH_COMP_GZIP)
152 addr = CONFIG_SYS_LOAD_ADDR;
153 else
154#endif
155 addr = spl_image->load_addr;
fa715193 156 memcpy((void *)addr, buf, res);
f3543e69 157 ih = (struct legacy_img_hdr *)addr;
fa715193
LV
158 size += res;
159 addr += res;
160
161 while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
162 memcpy((void *)addr, buf, res);
24de357a
MP
163 size += res;
164 addr += res;
24de357a 165 }
24de357a
MP
166 }
167
fa715193 168end_stream:
24de357a
MP
169 xyzModem_stream_close(&err);
170 xyzModem_stream_terminate(false, &getcymodem);
171
92e5cb80 172 printf("Loaded %lu bytes\n", size);
6d8dbe48 173
d574c19b
MV
174#ifdef CONFIG_SPL_GZIP
175 if (!(IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
f3543e69 176 image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) &&
d574c19b
MV
177 (ih->ih_comp == IH_COMP_GZIP)) {
178 if (gunzip((void *)(spl_image->load_addr + sizeof(*ih)),
179 CONFIG_SYS_BOOTM_LEN,
180 (void *)(CONFIG_SYS_LOAD_ADDR + sizeof(*ih)),
181 &size)) {
182 puts("Uncompressing error\n");
183 return -EIO;
184 }
185 }
186#endif
187
6d8dbe48 188 return ret;
24de357a 189}
ebc4ef61 190SPL_LOAD_IMAGE_METHOD("UART", 0, BOOT_DEVICE_UART, spl_ymodem_load_image);
This page took 0.321862 seconds and 4 git commands to generate.