tizen 2.4 release
[kernel/u-boot-tm1.git] / modem_boot / packet.c
1 #include <config.h>
2 #include <common.h>
3 #include <linux/types.h>
4 #include <asm/arch/bits.h>
5 #include <linux/string.h>
6 #include <android_bootimg.h>
7 #include <linux/mtd/mtd.h>
8 #include <linux/mtd/nand.h>
9 #include <nand.h>
10 #include <android_boot.h>
11 #include <environment.h>
12 #include <jffs2/jffs2.h>
13 #include <boot_mode.h>
14 #include <malloc.h>
15 #include "cmd_def.h"
16 #include "packet.h"
17
18 //#define __DEBUG__
19
20 #ifdef __DEBUG__
21 #define boot_debug printf
22 #else
23 #define boot_debug 
24 #endif
25
26 typedef enum _DL_PACKET_TYPE{
27         BSL_UART_PACKET,
28         BSL_SPI_PACKET
29 }BSL_PACKET_E;
30
31 #define SPI_PORT        0
32
33 #ifndef __SPI_MODE__
34 #define hs_channel_write        sdio_channel_write
35 #define hs_channel_read         sdio_channel_read
36 #else
37 #define hs_channel_write        SPI_channel_write
38 #define hs_channel_read         SPI_channel_read
39 #endif
40 #define TEST_LENGTH  (1024*60)
41 char    test_buffer[TEST_LENGTH]={0};
42
43 extern int hs_channel_write(unsigned char *buffer,int len);
44 extern int hs_channel_read(unsigned char *buffer,int len);
45 extern int uart_write(char *buffer,int size);
46 extern int uart_read(char *buffer,int size);
47 extern void req_clk_init(void);
48 static unsigned long send_buffer[1024*8+64]={0};
49
50 /******************************************************************************
51 **  Description:    This function scan the data in src buffer ,add 0x7e as begin
52 **                  and end of src,at the same time replace 0x7E,0x7D with rules
53 **                  below: 
54 **                        0x7e is replaced by 0x7d and 0x5e;
55 **                        0x7D is replace 0x7d and 0x5d
56 **                  the translated data will be save in dest buffer
57 **  Author:         jiayong.yang
58 **  parameter:      dest is buffer result of process
59 **                  src is buffer where data is saved
60 **                  size is size of src data. 
61 ******************************************************************************/
62 static int translate_packet(char *dest,char *src,int size)
63 {
64         int i;
65         int translated_size = 0;
66         
67         dest[translated_size++] = 0x7E;
68         
69         for(i=0;i<size;i++){
70                 if(src[i] == 0x7E){
71                         dest[translated_size++] = 0x7D;
72                         dest[translated_size++] = 0x5E;
73                 } else if(src[i] == 0x7D) {
74                         dest[translated_size++] = 0x7D;
75                         dest[translated_size++] = 0x5D;                 
76                 } else 
77                         dest[translated_size++] = src[i];
78         }       
79         dest[translated_size++] = 0x7E;
80         return translated_size; 
81 }
82 /******************************************************************************
83 **  Description:    This function scan the data in src buffer ,add 0x7e as begin
84 **                  and end of src,at the same time replace 0x7E,0x7D with rules
85 **                  below: 
86 **                        0x7e is replaced by 0x7d and 0x5e;
87 **                        0x7D is replace 0x7d and 0x5d
88 **                  the translated data will be save in dest buffer
89 **  Author:         jiayong.yang
90 **  parameter:      dest is buffer result of process
91 **                  src is buffer where data is saved
92 **                  size is size of src data. 
93 ******************************************************************************/
94 static int untranslate_packet(char *dest,char *src,int size)
95 {
96         int i;
97         int translated_size = 0;
98         int status = 0;
99         for(i=0;i<size;i++){
100                 switch(status){
101                         case 0:
102                                 if(src[i] == 0x7e)
103                                         status = 1;
104                         break;
105                         case 1:
106                                 if(src[i] != 0x7e)
107                                 {
108                                         status = 2;
109                                         dest[translated_size++] = src[i];
110                                 }
111                         break;
112                         case 2:
113                                 if(src[i] == 0x7E){
114                                         unsigned short crc;
115                                         crc = crc_16_l_calc((char const *)dest,translated_size-2);
116                                         return translated_size;
117                                 }else if(dest[translated_size-1] == 0x7D){
118                                         if(src[i] == 0x5E){
119                                                 dest[translated_size-1] = 0x7E;
120                                         } else if(src[i] == 0x5D) {
121                                                 dest[translated_size-1] = 0x7D;
122                                         }
123                                 }else {
124                                         dest[translated_size++] = src[i];
125                                 }
126                         break;
127                 }
128         }
129         return translated_size;
130 }
131 /******************************************************************************
132 **  Description:    This function setup the download protocol packet
133 **  Author:         jiayong.yang
134 **  parameter:      msg : msg type
135 **                  buffer: where packet is saved
136 **                  data_size: length of message body
137 **                  packet_type: UART message or SPI message. 
138 ******************************************************************************/
139 static int setup_packet(CMD_TYPE msg,char *buffer,int offset,int data_size,BSL_PACKET_E packet_type)
140 {
141         struct pkt_header_tag *head;
142         int length = sizeof(struct pkt_header_tag)+data_size;
143         int total_size = 0;
144         unsigned short crc16;
145         
146         head = (struct pkt_header_tag *)&buffer[4];
147         switch(msg)
148         {
149                 case BSL_CMD_CONNECT:
150                         if(packet_type==BSL_UART_PACKET){
151                                 head->type = cpu2be16((unsigned short)msg);
152                                 head->length = cpu2be16((unsigned short)data_size);
153                                 *((unsigned short *)&buffer[length+4]) = 0;
154                                 total_size = length + 2;
155                         }else{
156
157                                 *((unsigned short *)&buffer[0]) = data_size;
158                                 *((unsigned short *)&buffer[2]) = (unsigned short)msg;
159                                 *((unsigned int *)&buffer[8]) = 0;
160                                 *((unsigned short *)&buffer[4]) = boot_checksum((const unsigned char *)buffer+offset,data_size);
161                                 *((unsigned short *)&buffer[6]) = boot_checksum((const unsigned char *)buffer,6);
162                                 
163                                 total_size = 12;
164                         }
165                 break;
166                 case BSL_CMD_START_DATA:
167                         if(packet_type==BSL_UART_PACKET){
168                                 head->type = cpu2be16((unsigned short)msg);
169                                 head->length = cpu2be16((unsigned short)data_size);
170                                 crc16 = crc_16_l_calc((char const *)head,length);
171                                 *((unsigned short *)&buffer[length+4]) = cpu2be16(crc16);
172                                 total_size = length + 2;
173                         }else{
174
175                                 *((unsigned short *)&buffer[0]) =  data_size;
176                                 *((unsigned short *)&buffer[2]) = (unsigned short)msg;
177                                 *((unsigned short *)&buffer[4]) = boot_checksum((const unsigned char *)buffer+offset,data_size);
178                                 *((unsigned short *)&buffer[6]) = boot_checksum((const unsigned char *)buffer,6);
179                                 total_size = data_size + 8;
180                         }
181                 break;
182                 case BSL_CMD_MIDST_DATA:
183                         if(packet_type==BSL_UART_PACKET){
184                                 head->type =  cpu2be16(((unsigned short)msg));
185                                 head->length = cpu2be16(((unsigned short)data_size));
186                                 crc16 = crc_16_l_calc((char const *)head,length);
187                                 *((unsigned short *)&buffer[length+4]) = cpu2be16(crc16);
188                                 total_size = length + 2;
189                         }else{
190                                 if(data_size == 0)
191                                         *((unsigned short *)&buffer[0]) =  4;
192                                 else
193                                         *((unsigned short *)&buffer[0]) =  data_size;
194                                 *((unsigned short *)&buffer[2]) = (unsigned short)msg;
195                                 *((unsigned short *)&buffer[4]) = boot_checksum((const unsigned char *)(buffer+offset),data_size);
196                                 *((unsigned short *)&buffer[6]) = boot_checksum((const unsigned char *)buffer,6);
197                                 total_size = data_size + 8;
198                         }               
199                 break;
200                 case BSL_CMD_END_DATA:
201                         if(packet_type==BSL_UART_PACKET){
202                                 head->type =  cpu2be16((unsigned short)msg);
203                                 head->length = cpu2be16((unsigned short)data_size);
204                                 crc16 = crc_16_l_calc((char const *)head,length);
205                                 *((unsigned short *)&buffer[length+4]) = cpu2be16(crc16);
206                                 total_size = length + 2;
207                         }else{
208
209                                 *((unsigned short *)&buffer[0]) =  data_size;
210                                 *((unsigned short *)&buffer[2]) = (unsigned short)msg;
211                                 *((unsigned int *)&buffer[8]) = 0;
212                                 *((unsigned short *)&buffer[4]) = boot_checksum((const unsigned char *)(buffer+offset),data_size);
213                                 *((unsigned short *)&buffer[6]) = boot_checksum((const unsigned char *)buffer,6);
214                                 
215                                 total_size = 12;
216                         }               
217                 break;  
218                 case BSL_CMD_EXEC_DATA:
219                         if(packet_type==BSL_UART_PACKET){
220                                 head->type =  cpu2be16((unsigned short)msg);
221                                 head->length = cpu2be16((unsigned short)data_size);
222                                 crc16 = crc_16_l_calc((char const *)head,length);
223                                 *((unsigned short *)&buffer[length+4]) = cpu2be16(crc16);
224                                 total_size = length + 2;
225                         }else{
226
227                                 *((unsigned short *)&buffer[0]) =  data_size;
228                                 *((unsigned short *)&buffer[2]) = (unsigned short)msg;
229                                 *((unsigned short *)&buffer[4]) = boot_checksum((const unsigned char *)(buffer+offset),data_size);
230                                 *((unsigned short *)&buffer[6]) = boot_checksum((const unsigned char *)buffer,6);
231                                 total_size = data_size + 8;
232                         }                
233                 break;
234                 case BSL_CMD_SWITCH_MODE:
235                         if(packet_type==BSL_UART_PACKET){
236                                 head->type =  cpu2be16((unsigned short)msg);
237                                 head->length = cpu2be16((unsigned short)data_size);
238                                 crc16 = frm_chk((const unsigned short *)head,length);
239                                 *((unsigned short *)&buffer[length+4]) = (crc16);
240                                 total_size = length + 2;
241                         }else{
242
243                                 *((unsigned short *)&buffer[0]) =  4;
244                                 *((unsigned short *)&buffer[2]) = (unsigned short)msg;
245                                 *((unsigned short *)&buffer[4]) = boot_checksum((const unsigned char *)(buffer+offset),data_size);
246                                 *((unsigned short *)&buffer[6]) = boot_checksum((const unsigned char *)buffer,6);
247                                 *((unsigned int *)&buffer[8]) = 0;
248                                 total_size = 12;
249                         }
250                 break;
251                 default:
252                 break;                                  
253         }
254         return total_size;
255 }
256 /******************************************************************************
257 **  Description:    This function setup connect message by uart
258 **  Author:         jiayong.yang
259 **  parameter:      none 
260 ******************************************************************************/
261 int  uart_send_connect_message(void)
262 {
263         char raw_buffer[32] = {0};
264         char *data= raw_buffer;
265         int size;
266         int translated_size;
267         int offset;
268         int retval;
269         struct pkt_header_tag head;
270         
271         size = setup_packet(BSL_CMD_CONNECT,raw_buffer,8,0,BSL_UART_PACKET);
272         translated_size = translate_packet((char *)send_buffer,(char *)&raw_buffer[4],size);
273         retval = uart_write((char *)send_buffer,translated_size);
274         if(retval > 0)
275         {
276                 size = 8;
277                 offset = 0;
278                 do{
279                         retval = uart_read((char *)&raw_buffer[offset],size);
280                         if(retval > 0)
281                         {
282                                 offset += retval;
283                                 size -= retval;
284                         } else {
285                                 break;
286                         }
287                 }while(size!=0);
288         }
289         if(retval > 0){
290                 data = (char *)send_buffer;     
291                 retval = untranslate_packet(data,(char *)raw_buffer,offset);    
292                 head.type = (data[0]<<8)|data[1];
293                 if(head.type == BSL_REP_ACK)
294                         return 0;
295         } 
296         printf("Modem connect failed\n");
297         return -1;
298 }
299 /******************************************************************************
300 **  Description:    This function setup data start message by uart
301 **  Author:         jiayong.yang
302 **  parameter:      size : size of image to be sent
303 **                  addr : address where image to be saved in MODEM 
304 ******************************************************************************/
305 int  uart_send_start_message(int size,unsigned long addr)
306 {
307         char raw_buffer[32] = {0};
308         char *data = raw_buffer;
309         int translated_size;
310         int offset;
311         int retval;
312         struct pkt_header_tag head;
313         
314         *(unsigned long *)&raw_buffer[8] = cpu2be32(addr);
315         *(unsigned long *)&raw_buffer[12] = cpu2be32(size);
316         size = setup_packet(BSL_CMD_START_DATA,raw_buffer,8,8,BSL_UART_PACKET);
317         translated_size = translate_packet((char *)send_buffer,(char *)&raw_buffer[4],size);
318         retval = uart_write((char *)send_buffer,translated_size);
319
320         if(retval > 0)
321         {
322                 size = 8;
323                 offset = 0;
324                 do{
325                         retval = uart_read((char *)&raw_buffer[offset],size);
326                         if(retval > 0)
327                         {
328                                 offset += retval;
329                                 size -= retval;
330                         } else {
331                                 break;
332                         }
333                 }while(size!=0);
334         }
335         if(retval > 0){
336                 data = (char *)send_buffer;
337                 untranslate_packet(data,(char *)raw_buffer,offset);
338                 head.type = (data[0]<<8)|data[1];
339                 
340                 if(head.type == BSL_REP_ACK)
341                         return 0;
342         } 
343         printf("\nData START failed\n");
344         return -1;
345 }
346 /******************************************************************************
347 **  Description:    This function setup data end message by uart
348 **  Author:         jiayong.yang
349 **  parameter:      none 
350 ******************************************************************************/
351 int  uart_send_end_message(void)
352 {
353         char raw_buffer[32] = {0};
354         char *data = raw_buffer;
355         int size;
356         int translated_size;
357         int offset;
358         int retval;
359         struct pkt_header_tag head;
360         
361         size = setup_packet(BSL_CMD_END_DATA,raw_buffer,8,0,BSL_UART_PACKET);
362         translated_size = translate_packet((char *)send_buffer,(char *)&raw_buffer[4],size);
363         retval = uart_write((char *)send_buffer,translated_size);
364
365         if(retval >0)
366         {
367                 size = 8;
368                 offset = 0;
369                 do{
370                         retval = uart_read((char *)&raw_buffer[offset],size);
371                         if(retval > 0)
372                         {
373                                 offset += retval;
374                                 size -= retval;
375                         } else {
376                                 break;
377                         }
378                 }while(size!=0);
379         }
380         if(retval > 0){
381                 data = (char *)send_buffer;
382                 untranslate_packet(data,(char *)raw_buffer,offset);
383                 head.type = (data[0]<<8)|data[1];
384                 if(head.type == BSL_REP_ACK)
385                         return 0;
386         } 
387         printf("\nData START failed\n");
388         return -1;
389 }
390 /******************************************************************************
391 **  Description:    This function setup data message by uart
392 **  Author:         jiayong.yang
393 **  parameter:      none 
394 ******************************************************************************/
395 int  uart_send_data_message(char *buffer,int data_size)
396 {
397         char raw_buffer[32] = {0};
398         char    uart_buffer[300]={0};
399         char *data = raw_buffer;
400         int size;
401         int translated_size;
402         int offset;
403         int retval;
404         struct pkt_header_tag head;
405         
406         memcpy(&uart_buffer[8],buffer,data_size);       
407         size = setup_packet(BSL_CMD_MIDST_DATA,uart_buffer,8,data_size,BSL_UART_PACKET);
408         translated_size = translate_packet((char *)send_buffer,(char *)&uart_buffer[4],size);
409         retval = uart_write((char *)send_buffer,translated_size);
410
411         if(retval >0)
412         {
413                 size = 8;
414                 offset = 0;
415                 do{
416                         retval = uart_read((char *)&raw_buffer[offset],size);
417                         if(retval > 0)
418                         {
419                                 offset += retval;
420                                 size -= retval;
421                         } else {
422                                 break;
423                         }
424                 }while(size!=0);
425         }
426         if(retval > 0){
427                 data = (char *)send_buffer;
428                 untranslate_packet(data,(char *)raw_buffer,offset);
429                 head.type = (data[0]<<8)|data[1];
430                 
431                 if(head.type == BSL_REP_ACK){
432                         printf(".");
433                         return 0;
434                 } else {
435                         printf("E");
436                 }
437         } 
438         return -1;
439 }
440 /******************************************************************************
441 **  Description:    This function setup execute message by uart
442 **  Author:         jiayong.yang
443 **  parameter:      addr: address MODEM start to run.
444 ******************************************************************************/
445 int  uart_send_exec_message(unsigned long addr)
446 {
447         char raw_buffer[32] = {0};
448         char *data = raw_buffer;
449         int size;
450         int translated_size;
451         int offset;
452         int retval;
453         struct pkt_header_tag head;
454         
455         *(unsigned long *)&raw_buffer[8] = cpu2be32(addr);
456         size = setup_packet(BSL_CMD_EXEC_DATA,raw_buffer,8,4,BSL_UART_PACKET);
457         translated_size = translate_packet((char *)send_buffer,(char *)&raw_buffer[4],size);
458         retval = uart_write((char *)send_buffer,translated_size);
459
460         if(retval >0)
461         {
462                 size = 8;
463                 offset = 0;
464                 do{
465                         retval = uart_read((char *)&raw_buffer[offset],size);
466                         if(retval >= 0)
467                         {
468                                 offset += retval;
469                                 size -= retval;
470                         } else {
471                                 break;
472                         }
473                 }while(size!=0);
474         }
475         if(retval > 0){
476                 data = (char *)send_buffer;
477                 untranslate_packet(data,(char *)raw_buffer,offset);
478                 head.type = (data[0]<<8)|data[1];
479                 
480                 if(head.type == BSL_REP_ACK)
481                         return 0;
482         } 
483         printf("FDL failed to run!!!");
484         return -1;
485 }
486 /******************************************************************************
487 **  Description:    This function change the transfer  to SPI bus
488 **  Author:         jiayong.yang
489 **  parameter:      none
490 ******************************************************************************/
491 int  uart_send_change_spi_mode_message(void)
492 {
493         char raw_buffer[32] = {0};
494         char *data = raw_buffer;
495         int size;
496         int translated_size;
497         int offset;
498         int retval;
499         struct pkt_header_tag head;
500         
501         size = setup_packet(BSL_CMD_SWITCH_MODE,raw_buffer,8,0,BSL_UART_PACKET);
502         translated_size = translate_packet((char *)send_buffer,(char *)&raw_buffer[4],size);
503         retval = uart_write((char *)send_buffer,translated_size);
504
505         if(retval >0)
506         {
507                 size = 8;
508                 offset = 0;
509                 do{
510                         retval = uart_read((char *)&raw_buffer[offset],size);
511                         if(retval > 0)
512                         {
513                                 offset += retval;
514                                 size -= retval;
515                         } else {
516                                 break;
517                         }
518                 }while(size!=0);
519         }
520         if(retval > 0){
521                 data = (char *)send_buffer;
522                 untranslate_packet(data,(char *)raw_buffer,offset);
523                 head.type = (data[0]<<8)|data[1];
524                 
525                 if(head.type == BSL_REP_ACK)
526                         return 0;
527                 
528         }
529         printf("ChangeMode failed\n");
530         return -1;
531 }
532 /******************************************************************************
533 **  Description:    This function send data start message by SPI
534 **  Author:         jiayong.yang
535 **  parameter:      img_address : address where image to be saved in MODEM
536 **                  img_size :  size of image to be sent
537 ******************************************************************************/
538 #define SPI_ACK_SIZE    8
539 int hs_channel_send_start_message(unsigned long img_address,unsigned long img_size)
540 {
541         unsigned char read_buffer[16]={0};
542         unsigned char buffer[32]={0};
543         unsigned long data_size = 8;
544         struct pkt_header_tag *head;
545         unsigned long data_offset=8;
546         unsigned long *data = (unsigned long *)buffer;
547         int status;
548
549         data[2] = cpu2be32(img_address);
550         data[3] = cpu2be32(img_size);
551         setup_packet(BSL_CMD_START_DATA,buffer,data_offset,data_size,BSL_SPI_PACKET);
552         hs_channel_write(buffer,8);
553         hs_channel_write(buffer+data_offset,data_size);
554         hs_channel_read(read_buffer,SPI_ACK_SIZE);
555         head = (struct pkt_header_tag *)read_buffer;
556         if(cpu2be16(head->type) == BSL_REP_ACK);
557                 return 0;
558         printf("data start failed\n");
559         return -1;
560 }
561 /******************************************************************************
562 **  Description:    This function send data message by SPI
563 **  Author:         jiayong.yang
564 **  parameter:      buffer: address of data to be sent
565 **                  data_size :  size of data to be sent
566 ******************************************************************************/
567 int hs_channel_send_data_message(char *buffer,int data_size)
568 {
569         unsigned char read_buffer[16]={0};
570         struct pkt_header_tag *head;
571         unsigned long data_offset=8;
572         unsigned long *data;
573         int status;
574         int address = (int)send_buffer;
575  
576         address += 64;
577
578         address = address/32*32;
579         address -= 8;
580         data = (unsigned long *)address;
581         memcpy((char *)data+data_offset,buffer,data_size);
582         setup_packet(BSL_CMD_MIDST_DATA,data,data_offset,data_size,BSL_SPI_PACKET);
583  
584         hs_channel_write(data,8);
585         hs_channel_write((char *)data+data_offset,data_size);
586         hs_channel_read(read_buffer,SPI_ACK_SIZE);
587
588         head = (struct pkt_header_tag *)read_buffer;
589
590         if(cpu2be16(head->type) == BSL_REP_ACK){
591         //      printf(".");
592                 return 0;
593         }
594         printf("E");
595         return -1;
596                 
597 }
598 /******************************************************************************
599 **  Description:    This function send data end message by SPI
600 **  Author:         jiayong.yang
601 **  parameter:      none
602 ******************************************************************************/
603 int hs_channel_send_data_end(void)
604 {
605         unsigned char read_buffer[16]={0};
606         unsigned char buffer[16]={0};
607         unsigned long data_size = 4;
608         unsigned long *data = (unsigned long *)buffer;
609         struct pkt_header_tag *head;
610         unsigned long data_offset=8;
611         int status;
612
613         setup_packet(BSL_CMD_END_DATA,buffer,data_offset,data_size,BSL_SPI_PACKET);
614         hs_channel_write(buffer,8);
615         hs_channel_write(buffer+data_offset,data_size);
616         hs_channel_read(read_buffer,SPI_ACK_SIZE);
617
618         head = (struct pkt_header_tag *)read_buffer;
619         if(cpu2be16(head->type) == BSL_REP_ACK)
620                 return 0;
621         printf("data end failed 0x%x\n",cpu2be16(head->type));
622         return -1;
623 }
624 /******************************************************************************
625 **  Description:    This function setup execute message by SPI
626 **  Author:         jiayong.yang
627 **  parameter:      img_address : where modem start to run
628 ******************************************************************************/
629 int hs_channel_send_exec(unsigned long address)
630 {
631         unsigned char read_buffer[16]={0};
632         unsigned char buffer[16]={0};
633         unsigned long data_size = 4;
634         unsigned long *data = (unsigned long *)buffer;
635         struct pkt_header_tag *head;
636         unsigned long data_offset=8;
637         int status;
638
639         data[2] = cpu2be32(address);
640                 
641         setup_packet(BSL_CMD_EXEC_DATA,buffer,data_offset,data_size,BSL_SPI_PACKET);
642
643         hs_channel_write(buffer,8);
644         hs_channel_write(buffer+data_offset,data_size);
645         hs_channel_read(read_buffer,SPI_ACK_SIZE);
646
647         head = (struct pkt_header_tag *)read_buffer;
648         if(cpu2be16(head->type) == BSL_REP_ACK)
649                 return 0;
650         printf("MODEM run failed...\n");
651         return -1;
652 }
653 /******************************************************************************
654 **  Description:    This function download modem images by SPI
655 **  Author:         jiayong.yang
656 **  parameter:      none
657 ******************************************************************************/
658 struct modem_image_info {
659         unsigned long *buffer;
660         int image_size;
661         unsigned long address;
662 };
663 struct modem_image_info download_images_info[]={
664 #if 1
665         {
666                 0x00480000,
667                 0x00020000,
668                 0x02100000,
669         },
670 #endif
671         {
672                 0x00020000,         //source address in AP memory
673                 0x00200000,     //image size, dsp
674                 0x00020000,     //dest address in CP memory
675         },
676         {
677                 0x004a0000,
678                 0x00040000,
679                 0x02120000,
680         },
681         {
682                 0x004E0000,
683                 0x00008000,
684                 0x02160000,
685         },
686         {
687                 0x01600000,
688                 0x009F8000,    //cp image
689                 0x00400000,
690         },
691 };
692 void hs_download_image(struct modem_image_info *info)
693 {
694         extern unsigned long get_timer_masked(void);
695         unsigned long *img_data=NULL;
696         int ret,i;
697         int packet_count = 0;
698         int left=0;
699         int send_len = 0;
700
701         printf("\nDload MODEM image: size = 0x%08x, address = 0x%08x\n",info->image_size,info->address);
702         hs_channel_send_start_message(info->address,info->image_size);
703         img_data = info->buffer;
704         printf("\nstart_time = %dms\n",(unsigned int)get_timer_masked());
705         left = info->image_size;
706         packet_count = (info->image_size+TEST_LENGTH-1)/TEST_LENGTH;
707         for(i=0;i<packet_count;){
708                 if(left > TEST_LENGTH)
709                         send_len = TEST_LENGTH;
710                 else
711                         send_len = left;
712                 left -= send_len;
713                 ret = hs_channel_send_data_message(img_data,(int)send_len);
714                 if(ret == 0){
715                         img_data += (send_len/4);
716                         i++;
717                 } else {
718                         while(1);
719                 }
720         }
721         printf("\nend_time = %dms\n",(unsigned int)get_timer_masked());
722 }
723 void hs_download_proc(void)
724 {
725         
726         int i,j = 0;
727
728         j = sizeof(download_images_info)/sizeof(download_images_info[0]);
729         for(i=0;i<j;i++)
730                 hs_download_image(&download_images_info[i]);
731         hs_channel_send_exec(0x400000);
732 }