]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - common/spl/spl_ymodem.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2000-2004
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7 * Texas Instruments, <www.ti.com>
9 * Matt Porter <mporter@ti.com>
17 #include <asm/u-boot.h>
18 #include <linux/libfdt.h>
23 * Information required to load image using ymodem.
25 * @image_read: Now of bytes read from the image.
26 * @buf: pointer to the previous read block.
28 struct ymodem_fit_info
{
33 static int getcymodem(void) {
39 static ulong
ymodem_read_fit(struct spl_load_info
*load
, ulong offset
,
40 ulong size
, void *addr
)
42 int res
, err
, buf_offset
;
43 struct ymodem_fit_info
*info
= load
->priv
;
44 char *buf
= info
->buf
;
45 ulong copy_size
= size
;
47 while (info
->image_read
< offset
) {
48 res
= xyzModem_stream_read(buf
, BUF_SIZE
, &err
);
52 info
->image_read
+= res
;
55 if (info
->image_read
> offset
) {
56 res
= info
->image_read
- offset
;
57 if (info
->image_read
% BUF_SIZE
)
58 buf_offset
= (info
->image_read
% BUF_SIZE
);
60 buf_offset
= BUF_SIZE
;
62 if (res
> copy_size
) {
63 memcpy(addr
, &buf
[buf_offset
- res
], copy_size
);
66 memcpy(addr
, &buf
[buf_offset
- res
], res
);
71 while (info
->image_read
< offset
+ size
) {
72 res
= xyzModem_stream_read(buf
, BUF_SIZE
, &err
);
76 info
->image_read
+= res
;
77 if (res
> copy_size
) {
78 memcpy(addr
, buf
, copy_size
);
81 memcpy(addr
, buf
, res
);
90 int spl_ymodem_load_image(struct spl_image_info
*spl_image
,
91 struct spl_boot_device
*bootdev
)
97 connection_info_t info
;
99 struct legacy_img_hdr
*ih
= NULL
;
102 info
.mode
= xyzModem_ymodem
;
103 ret
= xyzModem_stream_open(&info
, &err
);
105 printf("spl: ymodem err - %s\n", xyzModem_error(err
));
109 res
= xyzModem_stream_read(buf
, BUF_SIZE
, &err
);
113 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL
) &&
114 image_get_magic((struct legacy_img_hdr
*)buf
) == FDT_MAGIC
) {
115 addr
= CONFIG_SYS_LOAD_ADDR
;
116 ih
= (struct legacy_img_hdr
*)addr
;
118 memcpy((void *)addr
, buf
, res
);
122 while ((res
= xyzModem_stream_read(buf
, BUF_SIZE
, &err
)) > 0) {
123 memcpy((void *)addr
, buf
, res
);
128 ret
= spl_parse_image_header(spl_image
, bootdev
, ih
);
131 } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT
) &&
132 image_get_magic((struct legacy_img_hdr
*)buf
) == FDT_MAGIC
) {
133 struct spl_load_info load
;
134 struct ymodem_fit_info info
;
136 debug("Found FIT\n");
137 load
.priv
= (void *)&info
;
138 load
.filename
= NULL
;
141 info
.image_read
= BUF_SIZE
;
142 load
.read
= ymodem_read_fit
;
143 ret
= spl_load_simple_fit(spl_image
, &load
, 0, (void *)buf
);
144 size
= info
.image_read
;
146 while ((res
= xyzModem_stream_read(buf
, BUF_SIZE
, &err
)) > 0)
149 ih
= (struct legacy_img_hdr
*)buf
;
150 ret
= spl_parse_image_header(spl_image
, bootdev
, ih
);
153 #ifdef CONFIG_SPL_GZIP
154 if (ih
->ih_comp
== IH_COMP_GZIP
)
155 addr
= CONFIG_SYS_LOAD_ADDR
;
158 addr
= spl_image
->load_addr
;
159 memcpy((void *)addr
, buf
, res
);
160 ih
= (struct legacy_img_hdr
*)addr
;
164 while ((res
= xyzModem_stream_read(buf
, BUF_SIZE
, &err
)) > 0) {
165 memcpy((void *)addr
, buf
, res
);
172 xyzModem_stream_close(&err
);
173 xyzModem_stream_terminate(false, &getcymodem
);
175 printf("Loaded %lu bytes\n", size
);
177 #ifdef CONFIG_SPL_GZIP
178 if (!(IS_ENABLED(CONFIG_SPL_LOAD_FIT
) &&
179 image_get_magic((struct legacy_img_hdr
*)buf
) == FDT_MAGIC
) &&
180 (ih
->ih_comp
== IH_COMP_GZIP
)) {
181 if (gunzip((void *)(spl_image
->load_addr
+ sizeof(*ih
)),
182 CONFIG_SYS_BOOTM_LEN
,
183 (void *)(CONFIG_SYS_LOAD_ADDR
+ sizeof(*ih
)),
185 puts("Uncompressing error\n");
193 SPL_LOAD_IMAGE_METHOD("UART", 0, BOOT_DEVICE_UART
, spl_ymodem_load_image
);