blob: 9e98959b6be75d0bec77f5270ea60560ff8dfe2c [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*******************************************************************************
2 * Copyright (C) 2016, ZIXC Corporation.
3 *
4 * File Name:cmd_set.c
5 * File Mark:
6 * Description:
7 * Others:
8 * Version: 1.0
9 * Author: zangxiaofeng
10 * Date: 2013-6-8
11 * History 1:
12 * Date:
13 * Version:
14 * Author:
15 * Modification:
16 * History 2:
17 ********************************************************************************/
18/****************************************************************************
19* Include files
20****************************************************************************/
21#include <common.h>
22#include <command.h>
23#include <net.h>
24#include <jffs2/load_kernel.h>
25#include <nand.h>
26#include <linux/mtd/spi-nor.h>
27#include <linux/mtd/nor_spifc.h>
28
29#include "downloader_config.h"
30#include "downloader_nand.h"
31#include "downloader_serial.h"
32#include "errno.h"
33#include "boot_mode.h"
34
35
36#define ZLOAD_PARTITION_SIZE 0x3000
37
38
39/****************************************************************************
40* Global Function Prototypes
41****************************************************************************/
42extern partition_table_t * g_partition_table;
43int set_partitions(unsigned int size);
44partition_entry_t * get_partitions(const char *partname, partition_table_t *table);
45
46partition_table_t * g_partition_table_dl = NULL;
47
48extern char *tsp_console_buffer;
49extern struct fsl_qspi spi_nor_flash;
50
51
52/*******************************************************************************
53 * Function:do_set
54 * Description:
55 * Parameters:
56 * Input:
57 *
58 * Output:
59 *
60 * Returns:
61 *
62 *
63 * Others:
64 ********************************************************************************/
65int do_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
66{
67
68 char *par = NULL;
69 unsigned int size = 0;
70 unsigned int ret = 0;
71
72 if(argc<3)
73 {
74 return cmd_usage(cmdtp);
75 }
76 par = argv[1];
77 size = (unsigned int)simple_strtoul (argv[2], NULL, 16);
78
79 if(strcmp(par,"partitions") == 0)
80 {
81 sprintf(tsp_console_buffer,"OKAY RECV_TABLES");
82 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
83 ret = set_partitions(size);
84 return ret;
85 }
86 else
87 {
88 sprintf(tsp_console_buffer,"FAIL COMMAND ERROR");
89 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
90 return -1;
91 }
92
93
94}
95U_BOOT_CMD(
96 set, CONFIG_SYS_MAXARGS, 0, do_set,
97 "set : set [module] [size]",
98 ""
99);
100
101/*******************************************************************************
102 * Function:set_partitions
103 * Description:
104 * Parameters:
105 * Input:
106 *
107 * Output:
108 *
109 * Returns:
110 *
111 *
112 * Others:
113 ********************************************************************************/
114 int set_partitions(unsigned int size)
115{
116 partition_entry_t *part_nvr = NULL;
117 partition_entry_t *part_nvr_dl = NULL;
118 partition_table_t *table_dl = NULL;
119 char *table_new = (char*)(CONFIG_USB_DMA_BUF_ADDR); /*USB DMA BUFFER*/
120
121 /* UE´ÓPC»ñÈ¡·ÖÇø±í */
122 downloader_serial_read_actuallen((char *)table_new, size);
123 table_dl = (partition_table_t *)table_new;
124
125 g_partition_table_dl = kzalloc(4096, GFP_KERNEL);
126 if(g_partition_table_dl == NULL)
127 {
128 printf("set_partitions kzalloc failed.\n");
129 return -1;
130 }
131
132 memcpy(g_partition_table_dl,table_dl,size);
133 if(table_dl->magic != PARTITION_MAGIC)
134 {
135 sprintf(tsp_console_buffer,"FAIL INVALID_PARTITION_TABLE");
136 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
137 return -1;
138 }
139
140 /* ·ÖÇø±íÆ¥Åä»òûÓзÖÇø±í */
141 if(memcmp( g_partition_table, table_dl, sizeof(partition_table_t))==0
142 || g_partition_table->magic != PARTITION_MAGIC)
143 {
144 g_partition_table = g_partition_table_dl;
145 sprintf(tsp_console_buffer,"OKAY");
146 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
147 return 0;
148 }
149 else
150 {
151 /* UE´ÓPC»ñÈ¡NV·ÖÇøÐÅÏ¢ */
152 part_nvr_dl = get_partitions("nvrofs", table_dl);
153 if(part_nvr_dl == NULL)
154 {
155 printf("pc part nvrofs get failed.\n");
156 return -1;
157 }
158
159 /* ´ÓUEµÄNAND¶ÁÈ¡NV·ÖÇøÐÅÏ¢ */
160 part_nvr = get_partitions("nvrofs", g_partition_table);
161 if(part_nvr == NULL)
162 {
163 printf("part_nvrofs get failed.\n");
164 sprintf(tsp_console_buffer,"FAIL UNACCEPTABLE_PARTITION_CHANGE");
165 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
166 return -1;
167 }
168
169 if((part_nvr->part_offset == part_nvr_dl->part_offset)
170 &&(part_nvr->part_size == part_nvr_dl->part_size))
171 {
172 sprintf(tsp_console_buffer,"FAIL ACCEPTABLE_PARTITION_CHANGE");
173 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
174 return 0;
175 }
176 else
177 {
178 sprintf(tsp_console_buffer,"FAIL UNACCEPTABLE_PARTITION_CHANGE");
179 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
180 return -1;
181 }
182 }
183}
184
185/*******************************************************************************
186 * Function:get_partitions
187 * Description:
188 * Parameters:
189 * Input:
190 *
191 * Output:
192 *
193 * Returns:
194 *
195 *
196 * Others:
197 ********************************************************************************/
198 partition_entry_t * get_partitions(const char *partname, partition_table_t *table)
199{
200
201 partition_entry_t *entry = &table->table[0];
202 uint32_t entry_nums = table->entrys;
203 while( entry_nums-- )
204 {
205 if ( strcmp((const char *)entry->part_name,partname) == 0 )
206 return entry;
207 entry++;
208 }
209 return NULL;
210}
211
212/*******************************************************************************
213 * Function:set_nand_dlflag
214 * Description: open or close USB DL PORT, based on nand
215 * dl on :open DL port ; dl off :close DL port
216 * Parameters:
217 * Input:
218 *
219 * Output:
220 *
221 * Returns:
222 *
223 *
224 * Others:
225 ********************************************************************************/
226 int set_nand_dlflag( char * sign)
227{
228 char value = 0;
229 int bootflag = 0;
230 int times = 0;
231 int i =0;
232 int ret = 0;
233 struct erase_info ei;
234 nand_info_t *nand = &nand_info[nand_curr_device];
235
236 u_char *buffer = kzalloc(6*(nand->writesize + nand->oobsize),GFP_KERNEL);
237 u_char *p_buffer = buffer;
238
239 if( buffer == NULL )
240 return 1;
241
242 times = 12*1024/nand->writesize;
243 for(i=0;i<times;i++)
244 {
245 nand_read_page_with_ecc(nand,
246 ((loff_t)i*nand->writesize),
247 0,
248 p_buffer);
249 p_buffer += nand->writesize;
250 }
251
252 if (strcmp((const char *)sign,"on") == 0)
253 {
254 bootflag = 0x00;
255 memset(&value, bootflag, 1);
256 }
257 else if (strcmp((const char *)sign,"off") == 0)
258 {
259 bootflag = 0x5a;
260 memset(&value, bootflag, 1);
261 }
262 memcpy(buffer+2, &value, 1);
263
264 memset(&ei, 0, sizeof(struct erase_info));
265 ei.mtd = nand;
266 ei.addr = (uint64_t)(0);
267 ei.len = (uint64_t)nand->erasesize;
268 ret = nand->erase(nand, &ei); /*²Á³ýµÚÒ»¿é*/
269
270 p_buffer = buffer;
271
272 for(i=0;i<times;i++)
273 {
274 nand_write_page_with_ecc(nand, ((loff_t)i*nand->writesize), p_buffer);
275 p_buffer += nand->writesize;
276 }
277
278 sprintf(tsp_console_buffer,"DL OKAY");
279 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
280
281 kfree(buffer);
282
283 return 0;
284
285}
286
287
288/*******************************************************************************
289 * Function:set_nor_dlflag
290 * Description: open or close USB DL PORT, based on nand
291 * dl on :open DL port ; dl off :close DL port
292 * Parameters:
293 * Input:
294 *
295 * Output:
296 *
297 * Returns:
298 *
299 *
300 * Others:
301 ********************************************************************************/
302 int set_nor_dlflag(char *sign)
303{
304 int ret = 0;
305 char value = 0;
306 int bootflag = 0;
307 uint32_t load_addr = 0x0;
308 uint32_t size_read = ZLOAD_PARTITION_SIZE;
309 uint32_t size_write = ZLOAD_PARTITION_SIZE;
310 struct fsl_qspi *nor = &spi_nor_flash;
311 u_char *buffer = kzalloc(ZLOAD_PARTITION_SIZE,GFP_KERNEL);
312
313 if(buffer == NULL)
314 {
315 return -1;
316 }
317
318 ret = nand_read(&(nor->nor[0].mtd), load_addr, &size_read, buffer);
319 if(ret != 0)
320 {
321 printf("nand_read error.\n");
322 return -1;
323 }
324
325 if (strcmp((const char *)sign,"on") == 0)
326 {
327 bootflag = 0x00;
328 memset(&value, bootflag, 1);
329 }
330 else if (strcmp((const char *)sign,"off") == 0)
331 {
332 bootflag = 0x5a;
333 memset(&value, bootflag, 1);
334 }
335 memcpy(buffer+2, &value, 1);
336
337 ret = nand_erase(&(nor->nor[0].mtd), load_addr, nor->nor[0].mtd.erasesize);
338 if(ret != 0)
339 {
340 printf("nand_erase error.\n");
341 return -1;
342 }
343
344 ret = nand_write(&(nor->nor[0].mtd), load_addr, &size_write, buffer);
345 if(ret != 0)
346 {
347 printf("nand_write error.\n");
348 return -1;
349 }
350
351 sprintf(tsp_console_buffer,"DL OKAY");
352 downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
353
354 kfree(buffer);
355
356 return 0;
357}
358
359
360/*******************************************************************************
361 * Function:do_dlflag
362 * Description: open or close USB DL PORT,
363 * dl on :open DL port ; dl off :close DL port
364 * Parameters:
365 * Input:
366 *
367 * Output:
368 *
369 * Returns:
370 *
371 *
372 * Others:
373 ********************************************************************************/
374int do_dlflag(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
375{
376 int ret = 0;
377 u_char *sign = NULL;
378 int type = 0;
379
380 if(argc<2)
381 {
382 return cmd_usage(cmdtp);
383 }
384 sign = argv[1];
385 type = read_boot_flashtype();
386
387 if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
388 {
389 ret = set_nand_dlflag(sign);
390 }
391 else if(type == IF_TYPE_NOR)
392 {
393 ret = set_nor_dlflag(sign);
394 }
395
396 if(ret != 0)
397 {
398 return -1;
399 }
400
401 return 0;
402
403}
404U_BOOT_CMD(
405 dl, CONFIG_SYS_MAXARGS, 0, do_dlflag,
406 "dl : dl [sign]",
407 ""
408);