2 #include <cyg/io/flash.h>
4 #include CYGHWR_MEMORY_LAYOUT_H
10 ///////////////////////////////////////////////////////////////////////////////////////////////
14 #define CE_RAM_BASE CYGMEM_REGION_ram
15 #define CE_RAM_SIZE CYGMEM_REGION_ram_SIZE
16 #define CE_RAM_END (CE_RAM_BASE + CE_RAM_SIZE)
17 #define CE_WINCE_VRAM_BASE 0x80000000
18 #define CE_FIX_ADDRESS(a) (((a) - CE_WINCE_VRAM_BASE) + CE_RAM_BASE)
20 #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
21 extern void *flash_start, *flash_end;
23 static inline int is_rom_addr(void *addr)
25 return addr >= flash_start && addr <= flash_end;
28 #define is_rom_addr(p) 0
31 static inline int is_ram_addr(unsigned long addr)
33 return addr >= CE_RAM_BASE && addr < CE_RAM_END;
36 // Bin image parse states
37 #define CE_PS_RTI_ADDR 0
38 #define CE_PS_RTI_LEN 1
39 #define CE_PS_E_ADDR 2
41 #define CE_PS_E_CHKSUM 4
42 #define CE_PS_E_DATA 5
45 #define CE_MIN(a, b) (((a) < (b)) ? (a) : (b))
46 #define CE_MAX(a, b) (((a) > (b)) ? (a) : (b))
50 #define STRMAC(s) _STRMAC(s)
52 ///////////////////////////////////////////////////////////////////////////////////////////////
55 unsigned long rtiPhysAddr;
56 unsigned long rtiPhysLen;
57 unsigned long ePhysAddr;
58 unsigned long ePhysLen;
59 unsigned long eChkSum;
61 unsigned long eEntryPoint;
62 unsigned long eRamStart;
63 unsigned long eRamLen;
64 unsigned long eDrvGlb;
66 unsigned char parseState;
67 unsigned long parseChkSum;
69 unsigned char *parsePtr;
78 edbg_os_config_data edbgConfig;
84 struct sockaddr_in locAddr;
85 struct sockaddr_in srvAddrSend;
86 struct sockaddr_in srvAddrRecv;
87 bool gotJumpingRequest;
89 unsigned short blockNum;
91 unsigned char data[516];
94 ///////////////////////////////////////////////////////////////////////////////////////////////
96 #ifdef CYGPKG_REDBOOT_NETWORKING
102 #ifdef CYGPKG_HAL_ARM_XSCALE_TRITON270_EQT32
103 #include <cyg/hal/hal_triton270.h>
107 ///////////////////////////////////////////////////////////////////////////////////////////////
110 void ce_init_bin(ce_bin *bin, unsigned char *dataBuffer);
111 int ce_parse_bin(ce_bin *bin);
112 bool ce_lookup_ep_bin(ce_bin *bin);
113 void ce_prepare_run_bin(ce_bin *bin);
114 void ce_run_bin(ce_bin *bin);
116 #ifdef CYGPKG_REDBOOT_NETWORKING
117 // Redboot network based routines
118 void ce_shell(int argc, char *argv[]);
119 void ce_init_download_link(ce_net *net, ce_bin *bin, struct sockaddr_in *host_addr, bool verbose);
120 void ce_init_edbg_link(ce_net *net);
121 int ce_send_frame(ce_net *net);
122 int ce_recv_frame(ce_net *net, int timeout);
123 int ce_send_bootme(ce_net *net);
124 int ce_send_write_ack(ce_net *net);
125 int ce_process_download(ce_net *net, ce_bin *bin);
126 void ce_process_edbg(ce_net *net, ce_bin *bin);
130 ///////////////////////////////////////////////////////////////////////////////////////////////
133 #ifdef CYGPKG_REDBOOT_NETWORKING
134 // Redboot network based commands
137 "Set up a connection to the CE host PC over TCP/IP and download the run-time image",
138 "[-v] [-t <timeout>] [-h <host>]",
143 ///////////////////////////////////////////////////////////////////////////////////////////////
146 bool ce_bin_load(void *image, int imglen)
148 ce_init_bin(&g_bin, image);
150 g_bin.dataLen = imglen;
152 if (ce_parse_bin(&g_bin) == CE_PR_EOF) {
153 ce_prepare_run_bin(&g_bin);
160 bool ce_is_bin_image(void *image, int imglen)
162 if (imglen < CE_BIN_SIGN_LEN) {
163 diag_printf("Not a valid CE image: image size %u shorter than minimum %u\n",
164 imglen, CE_BIN_SIGN_LEN);
167 if (is_rom_addr(image)) {
168 unsigned char sign_buf[CE_BIN_SIGN_LEN];
171 if (flash_read(image, sign_buf,
172 CE_BIN_SIGN_LEN, &err_addr) != FLASH_ERR_OK) {
175 return memcmp(sign_buf, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0;
177 return memcmp(image, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0;
180 void ce_bin_init_parser()
182 // No buffer address by now, will be specified
183 // later by the ce_bin_parse_next routine
184 ce_init_bin(&g_bin, NULL);
187 int ce_bin_parse_next(void *parseBuffer, int len)
191 g_bin.data = (unsigned char*)parseBuffer;
193 rc = ce_parse_bin(&g_bin);
195 if (rc == CE_PR_EOF) {
196 ce_prepare_run_bin(&g_bin);
202 void ce_init_bin(ce_bin *bin, unsigned char *dataBuffer)
204 memset(bin, 0, sizeof(ce_bin));
206 bin->data = dataBuffer;
207 bin->parseState = CE_PS_RTI_ADDR;
208 bin->parsePtr = (unsigned char*)&bin->rtiPhysAddr;
211 int ce_parse_bin(ce_bin *bin)
213 unsigned char *pbData = bin->data;
214 int pbLen = bin->dataLen;
218 if (bin->binLen == 0) {
219 // Check for the .BIN signature first
220 if (!ce_is_bin_image(pbData, pbLen)) {
221 diag_printf("** Error: Invalid or corrupted .BIN image!\n");
226 diag_printf("Loading Windows CE .BIN image ...\n");
229 pbLen -= CE_BIN_SIGN_LEN;
230 pbData += CE_BIN_SIGN_LEN;
234 switch (bin->parseState) {
241 copyLen = CE_MIN(sizeof(unsigned int) - bin->parseLen, pbLen);
243 if (is_rom_addr(pbData)) {
246 if (flash_read(pbData, &bin->parsePtr[bin->parseLen],
247 copyLen, &err_addr) != FLASH_ERR_OK) {
251 memcpy(&bin->parsePtr[bin->parseLen], pbData, copyLen);
253 bin->parseLen += copyLen;
257 if (bin->parseLen == sizeof(unsigned int)) {
258 if (bin->parseState == CE_PS_RTI_ADDR) {
259 bin->rtiPhysAddr = CE_FIX_ADDRESS(bin->rtiPhysAddr);
260 if (!is_ram_addr(bin->rtiPhysAddr)) {
261 diag_printf("Invalid address %08lx in CE_PS_RTI_ADDR section\n",
265 } else if (bin->parseState == CE_PS_E_ADDR) {
266 if (bin->ePhysAddr) {
267 bin->ePhysAddr = CE_FIX_ADDRESS(bin->ePhysAddr);
268 if (!is_ram_addr(bin->ePhysAddr)) {
269 diag_printf("Invalid address %08lx in CE_PS_E_ADDR section\n",
278 bin->parsePtr += sizeof(unsigned int);
279 if (bin->parseState == CE_PS_E_DATA) {
280 if (bin->ePhysAddr) {
281 bin->parsePtr = (unsigned char*)(bin->ePhysAddr);
282 bin->parseChkSum = 0;
294 if (bin->ePhysAddr) {
295 copyLen = CE_MIN(bin->ePhysLen - bin->parseLen, pbLen);
296 bin->parseLen += copyLen;
298 if (is_rom_addr(pbData)) {
301 if (flash_read(pbData, bin->parsePtr,
302 copyLen, &err_addr) != FLASH_ERR_OK) {
307 bin->parseChkSum += *bin->parsePtr++;
311 bin->parseChkSum += *pbData;
312 *bin->parsePtr ++ = *pbData ++;
315 if (bin->parseLen == bin->ePhysLen) {
316 diag_printf("Section [%02d]: address 0x%08lX, size 0x%08lX, checksum %s\n",
320 (bin->eChkSum == bin->parseChkSum) ? "ok" : "fail");
322 if (bin->eChkSum != bin->parseChkSum) {
325 diag_printf("Error: Checksum error, corrupted .BIN file!\n");
333 bin->parseState = CE_PS_E_ADDR;
335 bin->parsePtr = (unsigned char*)(&bin->ePhysAddr);
351 if (!ce_lookup_ep_bin(bin)) {
352 diag_printf("** Error: entry point not found!\n");
359 diag_printf("Entry point: 0x%08lX, address range: 0x%08lX-0x%08lX\n",
362 bin->rtiPhysAddr + bin->rtiPhysLen);
369 bin->binLen += bin->dataLen;
374 bool ce_lookup_ep_bin(ce_bin *bin)
377 ce_toc_entry *tentry;
381 // Check image Table Of Contents (TOC) signature
382 if (*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE) {
383 // Error: Did not find image TOC signature!
389 // Lookup entry point
390 header = (ce_rom_hdr*)CE_FIX_ADDRESS(*(unsigned int*)(bin->rtiPhysAddr +
391 ROM_SIGNATURE_OFFSET +
392 sizeof(unsigned int)));
393 tentry = (ce_toc_entry*)(header + 1);
395 for (i = 0; i < header->nummods; i ++) {
396 // Look for 'nk.exe' module
397 if (strcmp((char*)CE_FIX_ADDRESS(tentry[ i ].fileName), "nk.exe") == 0) {
398 // Save entry point and RAM addresses
400 e32 = (e32_rom*)CE_FIX_ADDRESS(tentry[ i ].e32Offset);
402 bin->eEntryPoint = CE_FIX_ADDRESS(tentry[ i ].loadOffset) +
404 bin->eRamStart = CE_FIX_ADDRESS(header->ramStart);
405 bin->eRamLen = header->ramEnd - header->ramStart;
407 // Save driver_globals address
408 // Must follow RAM section in CE config.bib file
412 // RAM 80900000 03200000 RAM
413 // DRV_GLB 83B00000 00001000 RESERVED
416 bin->eDrvGlb = CE_FIX_ADDRESS(header->ramEnd) -
417 sizeof(ce_driver_globals);
422 // Error: Did not find 'nk.exe' module
427 void setup_drv_globals(ce_driver_globals *drv_glb)
429 diag_printf("%s %p\n", __FUNCTION__, drv_glb);
431 // Fill out driver globals
432 memset(drv_glb, 0, sizeof(ce_driver_globals));
435 drv_glb->signature = DRV_GLB_SIGNATURE;
440 #ifdef CYGPKG_REDBOOT_NETWORKING
441 // Local ethernet MAC address
442 memcpy(drv_glb->macAddr, __local_enet_addr, sizeof(__local_enet_addr));
445 memcpy(&drv_glb->ipAddr, __local_ip_addr, sizeof(__local_ip_addr));
448 memcpy(&drv_glb->ipMask, __local_ip_mask, sizeof(__local_ip_mask));
451 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
453 memcpy(&drv_glb->ipGate, __local_ip_gate, sizeof(__local_ip_gate));
458 #if WINCE_ALTERNATE_ARG_BASE
459 void setup_alt_drv_globals(ce_alt_driver_globals *alt_drv_glb)
461 diag_printf("%s %p\n", __FUNCTION__, alt_drv_glb);
462 // Fill out driver globals
463 memset(alt_drv_glb, 0, sizeof(ce_alt_driver_globals));
465 alt_drv_glb->header.signature = ALT_DRV_GLB_SIGNATURE;
466 alt_drv_glb->header.oalVersion = 1;
467 alt_drv_glb->header.bspVersion = 1;
469 alt_drv_glb->kitl.flags = 0;
470 diag_sprintf(alt_drv_glb->deviceId, "Triton");
472 #ifdef CYGPKG_REDBOOT_NETWORKING
473 memcpy(&alt_drv_glb->kitl.mac[0], __local_enet_addr, sizeof(__local_enet_addr));
474 diag_sprintf(alt_drv_glb->deviceId, "Triton%02X", __local_enet_addr[5]);
477 memcpy(&alt_drv_glb->kitl.ipAddress, __local_ip_addr, sizeof(__local_ip_addr));
480 memcpy(&alt_drv_glb->kitl.ipMask, __local_ip_mask, sizeof(__local_ip_mask));
483 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
485 memcpy(&alt_drv_glb->kitl.ipRoute, __local_ip_gate, sizeof(__local_ip_gate));
490 #define setup_alt_drv_globals(x) CYG_EMPTY_STATEMENT
493 void ce_prepare_run_bin(ce_bin *bin)
495 ce_driver_globals *drv_glb;
497 diag_printf("%s\n", __FUNCTION__);
499 #if WINCE_ALTERNATE_ARG_BASE
500 ce_alt_driver_globals *alt_drv_glb = &_KARO_CECFG_START;
501 char *karo_magic = &_KARO_MAGIC[0];
502 unsigned long *karo_structure_size = &_KARO_STRUCT_SIZE;
504 memcpy(karo_magic, "KARO_CE6", sizeof(_KARO_MAGIC));
505 *karo_structure_size = sizeof(ce_alt_driver_globals);
507 // Clear os RAM area (if needed)
508 if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
509 diag_printf("Preparing clean boot ... ");
510 memset((void *)bin->eRamStart, 0, bin->eRamLen);
514 // Prepare driver globals (if needed)
516 drv_glb = (ce_driver_globals *)bin->eDrvGlb;
518 setup_drv_globals(drv_glb);
519 setup_alt_drv_globals(alt_drv_glb);
521 // EDBG services config
522 memcpy(&drv_glb->edbgConfig, &bin->edbgConfig, sizeof(bin->edbgConfig));
525 // Update global RedBoot entry point address
526 // to use with go/run commands
527 entry_address = bin->eEntryPoint;
530 void ce_run_bin(ce_bin *bin)
532 char *argv[] = { "go" };
534 diag_printf("Launching Windows CE ...\n");
536 // Call GO command direcly
540 // Extract version from CYGDAT_REDBOOT_CUSTOM_VERSION macro
541 // Works with versions like 'v2', 'v2.1', '2', '2.1', '2a', '2.1a'
543 void ce_redboot_version(unsigned int *vhigh, unsigned int *vlow)
545 char *pver = ""STRMAC(CYGDAT_REDBOOT_CUSTOM_VERSION);
554 p = pver + strlen(pver) - 1;
557 if (*p >= '0' && *p <= '9') {
558 *ver += ((*p - '0') * pow);
560 } else if (*p == '.') {
573 ///////////////////////////////////////////////////////////////////////////////////////////////
574 // Redboot network based routines
576 #ifdef CYGPKG_REDBOOT_NETWORKING
577 void ce_load(int argc, char *argv[])
579 struct option_info opts[3];
580 bool verbose, use_timeout;
581 int timeout, recv_timeout, ret;
584 struct sockaddr_in host_ip_addr;
586 // Prepare for command line scan
589 init_opts(&opts[0], 'v', false, OPTION_ARG_TYPE_FLG, (void *)&verbose, NULL,
590 "verbose operation");
593 init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_NUM, (void *)&timeout, &use_timeout,
594 "<timeout> - max wait time (#sec) for the connection");
597 init_opts(&opts[2], 'h', true, OPTION_ARG_TYPE_STR, (void *)&host_name, NULL,
598 "<host> - host name or IP address");
600 if (!scan_opts(argc, argv, 1, opts, 3, NULL, 0, "")) {
601 diag_printf("CELOAD - Invalid option specified\n");
605 // Check host IP address (if specified)
606 memset(&host_ip_addr, 0, sizeof(host_ip_addr));
608 if (!_gethostbyname(host_name, (in_addr_t*)&host_ip_addr)) {
609 diag_printf("CELOAD - Invalid host name: %s\n", host_name);
614 // Initialize download link
616 ce_init_download_link(&g_net, &g_bin, &host_ip_addr, verbose);
628 diag_printf("CELOAD - Canceled, timeout\n");
633 if (_rb_gets(&ctemp, 1, 1) == _GETS_CTRLC) {
634 diag_printf("CELOAD - canceled by user\n");
639 if (ce_send_bootme(&g_net)) {
640 diag_printf("CELOAD - error while sending BOOTME request\n");
646 diag_printf("Waiting for connection, timeout %d sec\n",
649 diag_printf("Waiting for connection, enter ^C to abort\n");
654 // Try to receive frame
656 if (ce_recv_frame(&g_net, recv_timeout)) {
657 // Process received data
659 ret = ce_process_download(&g_net, &g_bin);
661 if (ret != CE_PR_MORE) {
664 } else if (use_timeout) {
665 timeout -= recv_timeout;
670 // Try to receive edbg commands from host
671 ce_init_edbg_link(&g_net);
674 diag_printf("Waiting for EDBG commands ...\n");
677 while (ce_recv_frame(&g_net, 3)) {
678 ce_process_edbg(&g_net, &g_bin);
681 // Prepare WinCE image for execution
682 ce_prepare_run_bin(&g_bin);
684 // Launch WinCE, if necessary
685 if (g_net.gotJumpingRequest) {
691 void ce_init_download_link(ce_net *net, ce_bin *bin, struct sockaddr_in *host_addr, bool verbose)
693 // Initialize EDBG link for download
695 memset(net, 0, sizeof(ce_net));
697 net->locAddr.sin_family = AF_INET;
698 memcpy(&net->locAddr.sin_addr, __local_ip_addr, sizeof(__local_ip_addr));
699 net->locAddr.sin_port = htons(EDBG_DOWNLOAD_PORT);
701 net->srvAddrSend.sin_family = AF_INET;
702 net->srvAddrSend.sin_port = htons(EDBG_DOWNLOAD_PORT);
704 net->srvAddrRecv.sin_family = AF_INET;
705 net->srvAddrRecv.sin_port = 0;
707 if (host_addr->sin_addr.s_addr) {
708 // Use specified host address ...
710 net->srvAddrSend.sin_addr = host_addr->sin_addr;
711 net->srvAddrRecv.sin_addr = host_addr->sin_addr;
713 // ... or use default server address
715 net->srvAddrSend.sin_addr = my_bootp_info.bp_siaddr;
716 net->srvAddrRecv.sin_addr = my_bootp_info.bp_siaddr;
719 net->verbose = verbose;
721 // Initialize .BIN parser
723 // net->data + 0 -> Command
724 // net->data + 2 -> Block number
725 // net->data + 4 -> Block data
727 ce_init_bin(bin, net->data + 4);
730 void ce_init_edbg_link(ce_net *net)
732 // Initialize EDBG link for commands
734 net->locAddr.sin_port = htons(EDBG_DOWNLOAD_PORT);
735 net->srvAddrSend.sin_port = htons(EDBG_DOWNLOAD_PORT);
736 net->srvAddrRecv.sin_port = 0;
740 int ce_send_frame(ce_net *net)
744 return __udp_sendto(net->data, net->dataLen, &net->srvAddrSend, &net->locAddr);
747 int ce_recv_frame(ce_net *net, int timeout)
749 struct timeval timeo;
753 timeo.tv_sec = timeout;
756 // Receive UDP packet
758 net->dataLen = __udp_recvfrom(net->data, sizeof(net->data), &net->srvAddrRecv,
759 &net->locAddr, &timeo);
761 if (net->dataLen < 0) {
762 // Error! No data available
769 int ce_send_bootme(ce_net *net)
772 edbg_bootme_data *data;
773 unsigned int verHigh, verLow;
775 // Fill out BOOTME packet
776 memset(net->data, 0, BOOTME_PKT_SIZE);
778 header = (eth_dbg_hdr*)net->data;
779 data = (edbg_bootme_data*)header->data;
781 header->id = EDBG_ID;
782 header->service = EDBG_SVC_ADMIN;
783 header->flags = EDBG_FL_FROM_DEV;
784 header->seqNum = net->secNum ++;
785 header->cmd = EDBG_CMD_BOOTME;
787 // Get RedBoot version
788 ce_redboot_version(&verHigh, &verLow);
790 data->versionMajor = verHigh;
791 data->versionMinor = verLow;
792 data->cpuId = EDBG_CPU_TYPE_ARM;
793 data->bootmeVer = EDBG_CURRENT_BOOTME_VERSION;
795 data->downloadPort = 0;
798 memcpy(data->macAddr, __local_enet_addr, sizeof(__local_enet_addr));
799 memcpy(&data->ipAddr, __local_ip_addr, sizeof(__local_ip_addr));
801 // Device name string (NULL terminated). Should include
802 // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc)
804 // We will use lower MAC address segment to create device name
805 // eg. MAC '00-0C-C6-69-09-05', device name 'Triton05'
807 strcpy(data->platformId, "Triton");
808 diag_sprintf(data->deviceName, "%s%02X", data->platformId, __local_enet_addr[5]);
810 diag_printf("header->id: %08X\r\n", header->id);
811 diag_printf("header->service: %08X\r\n", header->service);
812 diag_printf("header->flags: %08X\r\n", header->flags);
813 diag_printf("header->seqNum: %08X\r\n", header->seqNum);
814 diag_printf("header->cmd: %08X\r\n\r\n", header->cmd);
816 diag_printf("data->versionMajor: %08X\r\n", data->versionMajor);
817 diag_printf("data->versionMinor: %08X\r\n", data->versionMinor);
818 diag_printf("data->cpuId: %08X\r\n", data->cpuId);
819 diag_printf("data->bootmeVer: %08X\r\n", data->bootmeVer);
820 diag_printf("data->bootFlags: %08X\r\n", data->bootFlags);
821 diag_printf("data->svcPort: %08X\r\n\r\n", data->svcPort);
823 diag_printf("data->macAddr: %02X-%02X-%02X-%02X-%02X-%02X-%02X\r\n",
824 (data->macAddr[0] >> 0) & 0xFF,
825 (data->macAddr[0] >> 8) & 0xFF,
826 (data->macAddr[1] >> 0) & 0xFF,
827 (data->macAddr[1] >> 8) & 0xFF,
828 (data->macAddr[2] >> 0) & 0xFF,
829 (data->macAddr[2] >> 8) & 0xFF);
831 diag_printf("data->ipAddr: %d.%d.%d.%d\r\n",
832 (data->ipAddr >> 0) & 0xFF,
833 (data->ipAddr >> 8) & 0xFF,
834 (data->ipAddr >> 16) & 0xFF,
835 (data->ipAddr >> 24) & 0xFF);
837 diag_printf("data->platformId: %s\r\n", data->platformId);
838 diag_printf("data->deviceName: %s\r\n", data->deviceName);
840 // Some diag output ...
842 diag_printf("Sending BOOTME request [%d] to %s\n",
844 inet_ntoa((in_addr_t *)&net->srvAddrSend));
848 net->dataLen = BOOTME_PKT_SIZE;
850 return ce_send_frame(net);
853 int ce_send_write_ack(ce_net *net)
855 unsigned short *wdata = (unsigned short*)net->data;
857 wdata[ 0 ] = htons(EDBG_CMD_WRITE_ACK);
858 wdata[ 1 ] = htons(net->blockNum);
862 return ce_send_frame(net);
865 int ce_process_download(ce_net *net, ce_bin *bin)
867 int ret = CE_PR_MORE;
869 if (net->dataLen >= 2) {
870 switch (ntohs(*(unsigned short*)net->data)) {
871 case EDBG_CMD_WRITE_REQ:
873 // Check file name for WRITE request
874 // CE EShell uses "boot.bin" file name
876 /*diag_printf(">>>>>>>> First Frame, IP: %s, port: %d\n",
877 inet_ntoa((in_addr_t *)&net->srvAddrRecv),
878 net->srvAddrRecv.sin_port);*/
879 if (strncmp((char*)(net->data + 2), "boot.bin", 8) == 0) {
882 diag_printf("Locked Down download link, IP: %s, port: %d\n",
883 inet_ntoa((in_addr_t *)&net->srvAddrRecv),
884 net->srvAddrRecv.sin_port);
887 // Lock down EShell download link
888 net->locAddr.sin_port = htons(EDBG_DOWNLOAD_PORT + 1);
889 net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
890 net->srvAddrSend.sin_addr = net->srvAddrRecv.sin_addr;
894 net->srvAddrRecv.sin_port = 0;
899 ce_send_write_ack(net);
903 // LW: is it really intended to fall thru in case of net->link != 0 ?
906 bin->dataLen = net->dataLen - 4;
908 // Parse next block of .bin file
909 ret = ce_parse_bin(bin);
911 // Request next block
912 if (ret != CE_PR_ERROR) {
915 ce_send_write_ack(net);
918 case EDBG_CMD_READ_REQ:
919 // Read requests are not supported
923 // Error condition on the host side
924 diag_printf("Error: unknown error on the host side\n");
935 void ce_process_edbg(ce_net *net, ce_bin *bin)
939 if (net->dataLen < sizeof(eth_dbg_hdr)) {
942 net->srvAddrRecv.sin_port = 0;
946 header = (eth_dbg_hdr*)net->data;
948 if (header->id != EDBG_ID) {
951 net->srvAddrRecv.sin_port = 0;
955 if (header->service != EDBG_SVC_ADMIN) {
965 diag_printf("Locked Down EDBG service link, IP: %s, port: %d\n",
966 inet_ntoa((in_addr_t *)&net->srvAddrRecv),
967 net->srvAddrRecv.sin_port);
970 // Lock down EDBG link
972 net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
976 switch (header->cmd) {
977 case EDBG_CMD_JUMPIMG:
978 net->gotJumpingRequest = true;
981 diag_printf("Received JUMPING command\n");
983 // Just pass through and copy CONFIG structure
984 case EDBG_CMD_OS_CONFIG:
985 // Copy config structure
986 memcpy(&bin->edbgConfig, header->data, sizeof(edbg_os_config_data));
988 diag_printf("Received CONFIG command\n");
989 if (bin->edbgConfig.flags & EDBG_FL_DBGMSG) {
990 diag_printf("--> Enabling DBGMSG service, IP: %d.%d.%d.%d, port: %d\n",
991 (bin->edbgConfig.dbgMsgIPAddr >> 0) & 0xFF,
992 (bin->edbgConfig.dbgMsgIPAddr >> 8) & 0xFF,
993 (bin->edbgConfig.dbgMsgIPAddr >> 16) & 0xFF,
994 (bin->edbgConfig.dbgMsgIPAddr >> 24) & 0xFF,
995 (int)bin->edbgConfig.dbgMsgPort);
997 if (bin->edbgConfig.flags & EDBG_FL_PPSH) {
998 diag_printf("--> Enabling PPSH service, IP: %d.%d.%d.%d, port: %d\n",
999 (bin->edbgConfig.ppshIPAddr >> 0) & 0xFF,
1000 (bin->edbgConfig.ppshIPAddr >> 8) & 0xFF,
1001 (bin->edbgConfig.ppshIPAddr >> 16) & 0xFF,
1002 (bin->edbgConfig.ppshIPAddr >> 24) & 0xFF,
1003 (int)bin->edbgConfig.ppshPort);
1005 if (bin->edbgConfig.flags & EDBG_FL_KDBG) {
1006 diag_printf("--> Enabling KDBG service, IP: %d.%d.%d.%d, port: %d\n",
1007 (bin->edbgConfig.kdbgIPAddr >> 0) & 0xFF,
1008 (bin->edbgConfig.kdbgIPAddr >> 8) & 0xFF,
1009 (bin->edbgConfig.kdbgIPAddr >> 16) & 0xFF,
1010 (bin->edbgConfig.kdbgIPAddr >> 24) & 0xFF,
1011 (int)bin->edbgConfig.kdbgPort);
1013 if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
1014 diag_printf("--> Force clean boot\n");
1020 diag_printf("Received unknown command: %08X\n", header->cmd);
1026 header->flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
1027 net->dataLen = EDBG_DATA_OFFSET;