blob: 1950ef26aab11498d812ec7c6079bc6a55cc212f [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*******************************************************************************
2 * Copyright (C) 2016, ZIXC Corporation.
3 *
4 * File Name:cmd_dl_mmc.c
5 * File Mark:
6 * Description: download or upload bin from eMMC,compat with SD
7 * Others:
8 * Version: 1.0
9 * Author: zangxiaofeng
10 * Date: 2014-1-13
11 * History 1:
12 * Date:
13 * Version:
14 * Author:
15 * Modification:
16 * History 2:
17 ********************************************************************************/
18
19
20
21/****************************************************************************
22* Include files
23****************************************************************************/
24#include <common.h>
25#include <command.h>
26#include <net.h>
27#include <jffs2/load_kernel.h>
28#include "downloader_config.h"
29#include "downloader_nand.h"
30#include "downloader_serial.h"
31#include "errno.h"
32
33#include <mmc.h>
34
35extern partition_table_t * g_partition_table_dl;
36extern int downloader_readline (char * buffer);
37extern int downloader_mmc_erase(partition_entry_t * part, uint partEraseSize);
38extern char *tsp_console_buffer;
39
40/*******************************************************************************
41 * Function:do_mmc_write
42 * Description:
43 * Parameters:
44 * Input:
45 *
46 * Output:
47 *
48 * Returns:
49 *
50 *
51 * Others:
52 ********************************************************************************/
53int do_mmc_write(partition_entry_t *part, char *par , unsigned int offset,unsigned int size )
54{
55 char *ack = tsp_console_buffer;
56 unsigned int offset_par = offset;
57 unsigned int leftWriteLength = 0;
58 unsigned int curWriteLength = 0;
59#ifdef CONFIG_LOAD_CRC
60
61 unsigned long crc = 0;
62 unsigned long crc1 = 0;
63#endif
64 int ret = 0;
65 int zload_len = 8192;
66
67 nand_info_t *nand = NULL;
68
69 if(part==NULL)
70 {
71 sprintf(ack,"FAIL INVALID PARTITION");
72 downloader_serial_write(ack, strlen(ack)+1);
73 return EINVAL; /* Invalid argument */
74 }
75
76 if((size==0)||(size>part->part_size))
77 {
78 sprintf(ack,"FAIL INVALID LENGTH");
79 downloader_serial_write(ack, strlen(ack)+1);
80 return EINVAL; /* Invalid argument */
81 }
82 leftWriteLength = size;
83 ret = downloader_mmc_erase( part, part->part_size);
84 while(leftWriteLength>0)
85 {
86 curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
87#ifdef CONFIG_LOAD_CRC
88 sprintf(ack,"DATACRC %08x",curWriteLength);
89#else
90 sprintf(ack,"DATA %08x",curWriteLength);
91#endif
92 downloader_serial_write(ack, strlen(ack)+1);
93#ifdef CONFIG_LOAD_CRC
94 downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength+4);
95 crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,curWriteLength);
96 memcpy((unsigned char *)(&crc1),(unsigned char*)(DOWNLOADER_BUFFER_BASE+curWriteLength),4);
97 //printf("CRC_calc= %x,CRC_rec=%x \n",crc,crc1);
98 if(crc != crc1)
99 {
100 sprintf(ack,"FAIL CRC ERROR");
101 downloader_serial_write(ack, strlen(ack)+1);
102 return ENOSYS; /* Function not implemented */
103 }
104#else
105 downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
106#endif
107 if(memcmp(par,"zloader",7) == 0) /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
108 {
109 memcpy((char *)(DOWNLOADER_BUFFER_BASE+4096),g_partition_table_dl,4096);
110 ret = mmc_write( nand,(loff_t)(part->part_offset + offset_par) , &zload_len, (unsigned char *)DOWNLOADER_BUFFER_BASE, 0);
111 }
112 else
113 {
114 ret = mmc_write( nand,(loff_t)(part->part_offset + offset_par) , &curWriteLength, (unsigned char *)DOWNLOADER_BUFFER_BASE, 0);
115 }
116
117 if(ret)
118 {
119 sprintf(ack,"FAIL MMC WRITE %d,%d,ret = %d",offset_par,curWriteLength,ret);
120 downloader_serial_write(ack, strlen(ack)+1);
121 return ENOSYS; /* Function not implemented */
122 }
123 leftWriteLength -= curWriteLength;
124 offset_par += curWriteLength;
125 }
126 sprintf(ack,"OKAY");
127 downloader_serial_write(ack, strlen(ack)+1);
128 return 0;
129}
130
131/*******************************************************************************
132 * Function:do_mmc_read
133 * Description:
134 * Parameters:
135 * Input:
136 *
137 * Output:
138 *
139 * Returns:
140 *
141 *
142 * Others:
143 ********************************************************************************/
144int do_mmc_read(partition_entry_t *part, char *par , unsigned int offset,unsigned int size )
145{
146 char *rx_buffer = tsp_console_buffer;
147 char *ack = tsp_console_buffer;
148 unsigned int offset_par = offset;
149 unsigned int leftReadLength = 0;
150 unsigned int curReadLength = 0;
151#ifdef CONFIG_LOAD_CRC
152 unsigned long crc = 0;
153#endif
154 int ret = 0;
155 nand_info_t *nand = NULL;
156
157 if(part == NULL)
158 {
159 sprintf(ack,"FAIL INVALID PARTITION");
160 downloader_serial_write(ack, strlen(ack)+1);
161 return EINVAL; /* Invalid argument */
162 }
163 if((size == 0)||(size>part->part_size))
164 {
165 sprintf(ack,"FAIL INVALID LENGTH");
166 downloader_serial_write(ack, strlen(ack)+1);
167 return EINVAL; /* Invalid argument */
168 }
169 leftReadLength = size;
170#ifdef CONFIG_LOAD_CRC
171 sprintf(ack,"DATACRC %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
172#else
173 sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
174#endif
175 downloader_serial_write(ack, strlen(ack)+1);
176
177 while(leftReadLength>0)
178 {
179 curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
180 downloader_readline(rx_buffer);
181 if(memcmp(rx_buffer,"OKAY",4)==0)
182 {
183 ret = mmc_read( nand,(loff_t)(part->part_offset+offset_par), &curReadLength, (unsigned char *)DOWNLOADER_BUFFER_BASE);
184 if(ret)
185 {
186 sprintf(ack,"FAIL MMC READ %d,%d, ret = %d",offset_par,curReadLength,ret);
187 downloader_serial_write(ack, strlen(ack)+1);
188 return ENOSYS; /* Function not implemented */
189 }
190 //printf("start to upload LEN=%d \n",curReadLength);
191#ifdef CONFIG_LOAD_CRC
192 crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,curReadLength);
193 memcpy((unsigned char*)(DOWNLOADER_BUFFER_BASE+curReadLength),(unsigned char *)(&crc),4);
194 downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength+4);
195#else
196 downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength);
197#endif
198 //downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength);
199
200 }
201 else
202 {
203 sprintf(ack,"FAIL COMMAND ERROR");
204 downloader_serial_write(ack, strlen(ack)+1);
205 return EBADRQC; /* Invalid request code */
206 }
207 leftReadLength -= curReadLength;
208 offset_par += curReadLength;
209 }
210
211 downloader_readline(rx_buffer);
212 if(memcmp(rx_buffer,"OKAY",4)==0)
213 {
214 return 0;
215 }
216 else
217 {
218 sprintf(ack,"FAIL COMMAND ERROR");
219 downloader_serial_write(ack, strlen(ack)+1);
220 return -1;
221 }
222}
223
224
225/*******************************************************************************
226 * Function:downloader_mmc_erase
227 * Description:erase mmc partition
228 * Parameters:
229 * Input:partEraseSize: must be multiple of 512KBytes
230 * part:part information,offset and size must be multiple of 512KBytes
231 * Output:
232 *
233 * Returns:
234 *
235 *
236 * Others:
237 ********************************************************************************/
238
239int downloader_mmc_erase(partition_entry_t * part, uint partEraseSize)
240{
241 unsigned int blksize = 512;
242 int ret = 0;
243
244 if(part == NULL )
245 {
246 return -1;
247 }
248 ret = mmc_erase( (u64)part->part_offset, (lbaint_t)partEraseSize/blksize);
249
250 return ret;
251}
252/*******************************************************************************
253 * Function:do_mmc_eraseall
254 * Description:erase all mmc partitions
255 * Parameters:
256 * Input:
257 * Output:
258 *
259 * Returns:
260 *
261 *
262 * Others:
263 ********************************************************************************/
264
265int downloader_mmc_eraseall(void)
266{
267
268 int ret = 0;
269 partition_entry_t *entry = &g_partition_table->table[0];
270 uint32_t entry_nums = g_partition_table->entrys;
271
272 while( entry_nums-- )
273 {
274 if ( strcmp((const char *)entry->part_name, "ddr") == 0 \
275 ||strcmp((const char *)entry->part_name, "raw") == 0)
276 {
277 entry++;
278 continue;
279 }
280 ret = downloader_mmc_erase(entry,entry->part_size);
281 entry++;
282 }
283 return ret;
284
285}
286/*******************************************************************************
287 * Function:do_mmc_eraseauto
288 * Description:erase mmc except nvr
289 * Parameters:
290 * Input:
291 * Output:
292 *
293 * Returns:
294 *
295 *
296 * Others:
297 ********************************************************************************/
298int downloader_mmc_eraseauto(void)
299{
300 int ret = 0;
301 partition_entry_t *entry = &g_partition_table->table[0];
302 uint32_t entry_nums = g_partition_table->entrys;
303
304 while( entry_nums-- )
305 {
306 if (strcmp((const char *)entry->part_name, "nvro") == 0||\
307 strcmp((const char *)entry->part_name, "ddr") == 0 \
308 ||strcmp((const char *)entry->part_name, "raw") == 0)
309 {
310 entry++;
311 continue;
312 }
313 ret = downloader_mmc_erase(entry,entry->part_size);
314 entry++;
315 }
316 return ret;
317}
318
319
320/*
321 ******************************************************************************
322 * Function:set_mmc_dlflag
323 * Description: open or close USB DL PORT, based on mmc
324 * dl on :open DL port ; dl off :close DL port
325 * Parameters:
326 * Input:
327 *
328 * Output:
329 *
330 * Returns:
331 *
332 *
333 * Others:
334 *******************************************************************************
335 */
336int set_mmc_dlflag( char * sign)
337{
338 int ret = 0;
339 char value = 0;
340 int bootflag = 0;
341 int size = 8192;
342
343 u_char *buffer = kzalloc(0x3000,GFP_KERNEL);
344 if( buffer == NULL )
345 return -1;
346
347 if (strcmp((const char *)sign,"on") == 0)
348 {
349 bootflag = 0x00;
350 memset(&value, bootflag, 1);
351 }
352 else if (strcmp((const char *)sign,"off") == 0)
353 {
354 bootflag = 0x5a;
355 memset(&value, bootflag, 1);
356 }
357 memcpy(buffer+2, &value, 1);
358 ret = mmc_write( 0, 0, &size,buffer, 0);
359
360 sprintf(tsp_console_buffer,"DL OKAY");
361 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
362
363 kfree(buffer);
364 return 0;
365
366}
367
368
369