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>
10 #include <android_boot.h>
11 #include <environment.h>
12 #include <jffs2/jffs2.h>
13 #include <boot_mode.h>
21 #define boot_debug printf
26 typedef enum _DL_PACKET_TYPE{
34 #define hs_channel_write sdio_channel_write
35 #define hs_channel_read sdio_channel_read
37 #define hs_channel_write SPI_channel_write
38 #define hs_channel_read SPI_channel_read
40 #define TEST_LENGTH (1024*60)
41 char test_buffer[TEST_LENGTH]={0};
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};
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
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)
65 int translated_size = 0;
67 dest[translated_size++] = 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;
77 dest[translated_size++] = src[i];
79 dest[translated_size++] = 0x7E;
80 return translated_size;
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
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)
97 int translated_size = 0;
109 dest[translated_size++] = src[i];
115 crc = crc_16_l_calc((char const *)dest,translated_size-2);
116 return translated_size;
117 }else if(dest[translated_size-1] == 0x7D){
119 dest[translated_size-1] = 0x7E;
120 } else if(src[i] == 0x5D) {
121 dest[translated_size-1] = 0x7D;
124 dest[translated_size++] = src[i];
129 return translated_size;
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)
141 struct pkt_header_tag *head;
142 int length = sizeof(struct pkt_header_tag)+data_size;
144 unsigned short crc16;
146 head = (struct pkt_header_tag *)&buffer[4];
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;
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);
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;
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;
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;
191 *((unsigned short *)&buffer[0]) = 4;
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;
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;
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);
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;
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;
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;
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;
256 /******************************************************************************
257 ** Description: This function setup connect message by uart
258 ** Author: jiayong.yang
260 ******************************************************************************/
261 int uart_send_connect_message(void)
263 char raw_buffer[32] = {0};
264 char *data= raw_buffer;
269 struct pkt_header_tag head;
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);
279 retval = uart_read((char *)&raw_buffer[offset],size);
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)
296 printf("Modem connect failed\n");
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)
307 char raw_buffer[32] = {0};
308 char *data = raw_buffer;
312 struct pkt_header_tag head;
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);
325 retval = uart_read((char *)&raw_buffer[offset],size);
336 data = (char *)send_buffer;
337 untranslate_packet(data,(char *)raw_buffer,offset);
338 head.type = (data[0]<<8)|data[1];
340 if(head.type == BSL_REP_ACK)
343 printf("\nData START failed\n");
346 /******************************************************************************
347 ** Description: This function setup data end message by uart
348 ** Author: jiayong.yang
350 ******************************************************************************/
351 int uart_send_end_message(void)
353 char raw_buffer[32] = {0};
354 char *data = raw_buffer;
359 struct pkt_header_tag head;
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);
370 retval = uart_read((char *)&raw_buffer[offset],size);
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)
387 printf("\nData START failed\n");
390 /******************************************************************************
391 ** Description: This function setup data message by uart
392 ** Author: jiayong.yang
394 ******************************************************************************/
395 int uart_send_data_message(char *buffer,int data_size)
397 char raw_buffer[32] = {0};
398 char uart_buffer[300]={0};
399 char *data = raw_buffer;
404 struct pkt_header_tag head;
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);
416 retval = uart_read((char *)&raw_buffer[offset],size);
427 data = (char *)send_buffer;
428 untranslate_packet(data,(char *)raw_buffer,offset);
429 head.type = (data[0]<<8)|data[1];
431 if(head.type == BSL_REP_ACK){
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)
447 char raw_buffer[32] = {0};
448 char *data = raw_buffer;
453 struct pkt_header_tag head;
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);
465 retval = uart_read((char *)&raw_buffer[offset],size);
476 data = (char *)send_buffer;
477 untranslate_packet(data,(char *)raw_buffer,offset);
478 head.type = (data[0]<<8)|data[1];
480 if(head.type == BSL_REP_ACK)
483 printf("FDL failed to run!!!");
486 /******************************************************************************
487 ** Description: This function change the transfer to SPI bus
488 ** Author: jiayong.yang
490 ******************************************************************************/
491 int uart_send_change_spi_mode_message(void)
493 char raw_buffer[32] = {0};
494 char *data = raw_buffer;
499 struct pkt_header_tag head;
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);
510 retval = uart_read((char *)&raw_buffer[offset],size);
521 data = (char *)send_buffer;
522 untranslate_packet(data,(char *)raw_buffer,offset);
523 head.type = (data[0]<<8)|data[1];
525 if(head.type == BSL_REP_ACK)
529 printf("ChangeMode failed\n");
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)
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;
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);
558 printf("data start failed\n");
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)
569 unsigned char read_buffer[16]={0};
570 struct pkt_header_tag *head;
571 unsigned long data_offset=8;
574 int address = (int)send_buffer;
578 address = address/32*32;
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);
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);
588 head = (struct pkt_header_tag *)read_buffer;
590 if(cpu2be16(head->type) == BSL_REP_ACK){
598 /******************************************************************************
599 ** Description: This function send data end message by SPI
600 ** Author: jiayong.yang
602 ******************************************************************************/
603 int hs_channel_send_data_end(void)
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;
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);
618 head = (struct pkt_header_tag *)read_buffer;
619 if(cpu2be16(head->type) == BSL_REP_ACK)
621 printf("data end failed 0x%x\n",cpu2be16(head->type));
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)
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;
639 data[2] = cpu2be32(address);
641 setup_packet(BSL_CMD_EXEC_DATA,buffer,data_offset,data_size,BSL_SPI_PACKET);
643 hs_channel_write(buffer,8);
644 hs_channel_write(buffer+data_offset,data_size);
645 hs_channel_read(read_buffer,SPI_ACK_SIZE);
647 head = (struct pkt_header_tag *)read_buffer;
648 if(cpu2be16(head->type) == BSL_REP_ACK)
650 printf("MODEM run failed...\n");
653 /******************************************************************************
654 ** Description: This function download modem images by SPI
655 ** Author: jiayong.yang
657 ******************************************************************************/
658 struct modem_image_info {
659 unsigned long *buffer;
661 unsigned long address;
663 struct modem_image_info download_images_info[]={
672 0x00020000, //source address in AP memory
673 0x00200000, //image size, dsp
674 0x00020000, //dest address in CP memory
688 0x009F8000, //cp image
692 void hs_download_image(struct modem_image_info *info)
694 extern unsigned long get_timer_masked(void);
695 unsigned long *img_data=NULL;
697 int packet_count = 0;
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;
713 ret = hs_channel_send_data_message(img_data,(int)send_len);
715 img_data += (send_len/4);
721 printf("\nend_time = %dms\n",(unsigned int)get_timer_masked());
723 void hs_download_proc(void)
728 j = sizeof(download_images_info)/sizeof(download_images_info[0]);
730 hs_download_image(&download_images_info[i]);
731 hs_channel_send_exec(0x400000);