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) {
324 diag_printf("Error: Checksum error, corrupted .BIN file!\n");
325 diag_printf("checksum calculated: 0x%08lx from file: 0x%08lx\n",
326 bin->parseChkSum, bin->eChkSum);
332 bin->parseState = CE_PS_E_ADDR;
334 bin->parsePtr = (unsigned char*)(&bin->ePhysAddr);
350 if (!ce_lookup_ep_bin(bin)) {
351 diag_printf("** Error: entry point not found!\n");
358 diag_printf("Entry point: 0x%08lX, address range: 0x%08lX-0x%08lX\n",
361 bin->rtiPhysAddr + bin->rtiPhysLen);
368 bin->binLen += bin->dataLen;
373 bool ce_lookup_ep_bin(ce_bin *bin)
376 ce_toc_entry *tentry;
380 // Check image Table Of Contents (TOC) signature
381 if (*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE) {
382 // Error: Did not find image TOC signature!
388 // Lookup entry point
389 header = (ce_rom_hdr*)CE_FIX_ADDRESS(*(unsigned int*)(bin->rtiPhysAddr +
390 ROM_SIGNATURE_OFFSET +
391 sizeof(unsigned int)));
392 tentry = (ce_toc_entry*)(header + 1);
394 for (i = 0; i < header->nummods; i++) {
395 // Look for 'nk.exe' module
396 if (strcmp((char*)CE_FIX_ADDRESS(tentry[ i ].fileName), "nk.exe") == 0) {
397 // Save entry point and RAM addresses
399 e32 = (e32_rom*)CE_FIX_ADDRESS(tentry[ i ].e32Offset);
401 bin->eEntryPoint = CE_FIX_ADDRESS(tentry[ i ].loadOffset) +
403 bin->eRamStart = CE_FIX_ADDRESS(header->ramStart);
404 bin->eRamLen = header->ramEnd - header->ramStart;
406 // Save driver_globals address
407 // Must follow RAM section in CE config.bib file
411 // RAM 80900000 03200000 RAM
412 // DRV_GLB 83B00000 00001000 RESERVED
415 bin->eDrvGlb = CE_FIX_ADDRESS(header->ramEnd);
420 // Error: Did not find 'nk.exe' module
425 void setup_drv_globals(ce_driver_globals *drv_glb)
427 // Fill out driver globals
428 memset(drv_glb, 0, sizeof(ce_driver_globals));
431 drv_glb->signature = DRV_GLB_SIGNATURE;
436 #ifdef CYGPKG_REDBOOT_NETWORKING
437 // Local ethernet MAC address
438 memcpy(drv_glb->macAddr, __local_enet_addr, sizeof(__local_enet_addr));
441 memcpy(&drv_glb->ipAddr, __local_ip_addr, sizeof(__local_ip_addr));
444 memcpy(&drv_glb->ipMask, __local_ip_mask, sizeof(__local_ip_mask));
447 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
449 memcpy(&drv_glb->ipGate, __local_ip_gate, sizeof(__local_ip_gate));
454 void setup_std_drv_globals(ce_std_driver_globals *std_drv_glb)
456 // Fill out driver globals
457 memset(std_drv_glb, 0, sizeof(ce_std_driver_globals));
459 std_drv_glb->header.signature = STD_DRV_GLB_SIGNATURE;
460 std_drv_glb->header.oalVersion = 1;
461 std_drv_glb->header.bspVersion = 1;
463 std_drv_glb->kitl.flags = 0;
464 diag_sprintf(std_drv_glb->deviceId, "Triton");
466 #ifdef CYGPKG_REDBOOT_NETWORKING
467 memcpy(&std_drv_glb->kitl.mac[0], __local_enet_addr, sizeof(__local_enet_addr));
468 diag_sprintf(std_drv_glb->deviceId, "Triton%02X", __local_enet_addr[5]);
471 memcpy(&std_drv_glb->kitl.ipAddress, __local_ip_addr, sizeof(__local_ip_addr));
474 memcpy(&std_drv_glb->kitl.ipMask, __local_ip_mask, sizeof(__local_ip_mask));
477 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
479 memcpy(&std_drv_glb->kitl.ipRoute, __local_ip_gate, sizeof(__local_ip_gate));
484 void ce_prepare_run_bin(ce_bin *bin)
486 ce_driver_globals *drv_glb;
487 ce_std_driver_globals *std_drv_glb = &_KARO_CECFG_START;
488 char *karo_magic = &_KARO_MAGIC[0];
489 unsigned long *karo_structure_size = &_KARO_STRUCT_SIZE;
491 memcpy(karo_magic, "KARO_CE6", sizeof(_KARO_MAGIC));
492 *karo_structure_size = sizeof(ce_std_driver_globals);
494 // Clear os RAM area (if needed)
495 if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
496 diag_printf("Preparing clean boot ... ");
497 memset((void *)bin->eRamStart, 0, bin->eRamLen);
501 // Prepare driver globals (if needed)
503 drv_glb = (ce_driver_globals *)bin->eDrvGlb;
505 setup_drv_globals(drv_glb);
506 setup_std_drv_globals(std_drv_glb);
508 // EDBG services config
509 memcpy(&drv_glb->edbgConfig, &bin->edbgConfig, sizeof(bin->edbgConfig));
512 // Update global RedBoot entry point address
513 // to use with go/run commands
514 entry_address = bin->eEntryPoint;
517 void ce_run_bin(ce_bin *bin)
519 char *argv[] = { "go" };
521 diag_printf("Launching Windows CE ...\n");
523 // Call GO command direcly
527 // Extract version from CYGDAT_REDBOOT_CUSTOM_VERSION macro
528 // Works with versions like 'v2', 'v2.1', '2', '2.1', '2a', '2.1a'
530 void ce_redboot_version(unsigned int *vhigh, unsigned int *vlow)
532 char *pver = ""STRMAC(CYGDAT_REDBOOT_CUSTOM_VERSION);
541 p = pver + strlen(pver) - 1;
544 if (*p >= '0' && *p <= '9') {
545 *ver += ((*p - '0') * pow);
547 } else if (*p == '.') {
560 ///////////////////////////////////////////////////////////////////////////////////////////////
561 // Redboot network based routines
563 #ifdef CYGPKG_REDBOOT_NETWORKING
564 void ce_load(int argc, char *argv[])
566 struct option_info opts[3];
567 bool verbose, use_timeout;
568 int timeout, recv_timeout, ret;
571 struct sockaddr_in host_ip_addr;
573 // Prepare for command line scan
576 init_opts(&opts[0], 'v', false, OPTION_ARG_TYPE_FLG, (void *)&verbose, NULL,
577 "verbose operation");
580 init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_NUM, (void *)&timeout, &use_timeout,
581 "<timeout> - max wait time (#sec) for the connection");
584 init_opts(&opts[2], 'h', true, OPTION_ARG_TYPE_STR, (void *)&host_name, NULL,
585 "<host> - host name or IP address");
587 if (!scan_opts(argc, argv, 1, opts, 3, NULL, 0, "")) {
588 diag_printf("CELOAD - Invalid option specified\n");
592 // Check host IP address (if specified)
593 memset(&host_ip_addr, 0, sizeof(host_ip_addr));
595 if (!_gethostbyname(host_name, (in_addr_t*)&host_ip_addr)) {
596 diag_printf("CELOAD - Invalid host name: %s\n", host_name);
601 // Initialize download link
603 ce_init_download_link(&g_net, &g_bin, &host_ip_addr, verbose);
615 diag_printf("CELOAD - Canceled, timeout\n");
620 if (_rb_gets(&ctemp, 1, 1) == _GETS_CTRLC) {
621 diag_printf("CELOAD - canceled by user\n");
626 if (ce_send_bootme(&g_net)) {
627 diag_printf("CELOAD - error while sending BOOTME request\n");
633 diag_printf("Waiting for connection, timeout %d sec\n",
636 diag_printf("Waiting for connection, enter ^C to abort\n");
641 // Try to receive frame
643 if (ce_recv_frame(&g_net, recv_timeout)) {
644 // Process received data
646 ret = ce_process_download(&g_net, &g_bin);
648 if (ret != CE_PR_MORE) {
651 } else if (use_timeout) {
652 timeout -= recv_timeout;
657 // Try to receive edbg commands from host
658 ce_init_edbg_link(&g_net);
661 diag_printf("Waiting for EDBG commands ...\n");
664 while (ce_recv_frame(&g_net, 3)) {
665 ce_process_edbg(&g_net, &g_bin);
668 // Prepare WinCE image for execution
669 ce_prepare_run_bin(&g_bin);
671 // Launch WinCE, if necessary
672 if (g_net.gotJumpingRequest) {
678 void ce_init_download_link(ce_net *net, ce_bin *bin, struct sockaddr_in *host_addr, bool verbose)
680 // Initialize EDBG link for download
682 memset(net, 0, sizeof(ce_net));
684 net->locAddr.sin_family = AF_INET;
685 memcpy(&net->locAddr.sin_addr, __local_ip_addr, sizeof(__local_ip_addr));
686 net->locAddr.sin_port = htons(EDBG_DOWNLOAD_PORT);
688 net->srvAddrSend.sin_family = AF_INET;
689 net->srvAddrSend.sin_port = htons(EDBG_DOWNLOAD_PORT);
691 net->srvAddrRecv.sin_family = AF_INET;
692 net->srvAddrRecv.sin_port = 0;
694 if (host_addr->sin_addr.s_addr) {
695 // Use specified host address ...
697 net->srvAddrSend.sin_addr = host_addr->sin_addr;
698 net->srvAddrRecv.sin_addr = host_addr->sin_addr;
700 // ... or use default server address
702 net->srvAddrSend.sin_addr = my_bootp_info.bp_siaddr;
703 net->srvAddrRecv.sin_addr = my_bootp_info.bp_siaddr;
706 net->verbose = verbose;
708 // Initialize .BIN parser
710 // net->data + 0 -> Command
711 // net->data + 2 -> Block number
712 // net->data + 4 -> Block data
714 ce_init_bin(bin, net->data + 4);
717 void ce_init_edbg_link(ce_net *net)
719 // Initialize EDBG link for commands
721 net->locAddr.sin_port = htons(EDBG_DOWNLOAD_PORT);
722 net->srvAddrSend.sin_port = htons(EDBG_DOWNLOAD_PORT);
723 net->srvAddrRecv.sin_port = 0;
727 int ce_send_frame(ce_net *net)
731 return __udp_sendto(net->data, net->dataLen, &net->srvAddrSend, &net->locAddr);
734 int ce_recv_frame(ce_net *net, int timeout)
736 struct timeval timeo;
740 timeo.tv_sec = timeout;
743 // Receive UDP packet
745 net->dataLen = __udp_recvfrom(net->data, sizeof(net->data), &net->srvAddrRecv,
746 &net->locAddr, &timeo);
748 if (net->dataLen < 0) {
749 // Error! No data available
756 int ce_send_bootme(ce_net *net)
759 edbg_bootme_data *data;
760 unsigned int verHigh, verLow;
762 // Fill out BOOTME packet
763 memset(net->data, 0, BOOTME_PKT_SIZE);
765 header = (eth_dbg_hdr*)net->data;
766 data = (edbg_bootme_data*)header->data;
768 header->id = EDBG_ID;
769 header->service = EDBG_SVC_ADMIN;
770 header->flags = EDBG_FL_FROM_DEV;
771 header->seqNum = net->secNum++;
772 header->cmd = EDBG_CMD_BOOTME;
774 // Get RedBoot version
775 ce_redboot_version(&verHigh, &verLow);
777 data->versionMajor = verHigh;
778 data->versionMinor = verLow;
779 data->cpuId = EDBG_CPU_TYPE_ARM;
780 data->bootmeVer = EDBG_CURRENT_BOOTME_VERSION;
782 data->downloadPort = 0;
785 memcpy(data->macAddr, __local_enet_addr, sizeof(__local_enet_addr));
786 memcpy(&data->ipAddr, __local_ip_addr, sizeof(__local_ip_addr));
788 // Device name string (NULL terminated). Should include
789 // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc)
791 // We will use lower MAC address segment to create device name
792 // eg. MAC '00-0C-C6-69-09-05', device name 'Triton05'
794 strcpy(data->platformId, "Triton");
795 diag_sprintf(data->deviceName, "%s%02X", data->platformId, __local_enet_addr[5]);
797 diag_printf("header->id: %08X\r\n", header->id);
798 diag_printf("header->service: %08X\r\n", header->service);
799 diag_printf("header->flags: %08X\r\n", header->flags);
800 diag_printf("header->seqNum: %08X\r\n", header->seqNum);
801 diag_printf("header->cmd: %08X\r\n\r\n", header->cmd);
803 diag_printf("data->versionMajor: %08X\r\n", data->versionMajor);
804 diag_printf("data->versionMinor: %08X\r\n", data->versionMinor);
805 diag_printf("data->cpuId: %08X\r\n", data->cpuId);
806 diag_printf("data->bootmeVer: %08X\r\n", data->bootmeVer);
807 diag_printf("data->bootFlags: %08X\r\n", data->bootFlags);
808 diag_printf("data->svcPort: %08X\r\n\r\n", data->svcPort);
810 diag_printf("data->macAddr: %02X-%02X-%02X-%02X-%02X-%02X-%02X\r\n",
811 (data->macAddr[0] >> 0) & 0xFF,
812 (data->macAddr[0] >> 8) & 0xFF,
813 (data->macAddr[1] >> 0) & 0xFF,
814 (data->macAddr[1] >> 8) & 0xFF,
815 (data->macAddr[2] >> 0) & 0xFF,
816 (data->macAddr[2] >> 8) & 0xFF);
818 diag_printf("data->ipAddr: %d.%d.%d.%d\r\n",
819 (data->ipAddr >> 0) & 0xFF,
820 (data->ipAddr >> 8) & 0xFF,
821 (data->ipAddr >> 16) & 0xFF,
822 (data->ipAddr >> 24) & 0xFF);
824 diag_printf("data->platformId: %s\r\n", data->platformId);
825 diag_printf("data->deviceName: %s\r\n", data->deviceName);
827 // Some diag output ...
829 diag_printf("Sending BOOTME request [%d] to %s\n",
831 inet_ntoa((in_addr_t *)&net->srvAddrSend));
835 net->dataLen = BOOTME_PKT_SIZE;
837 return ce_send_frame(net);
840 int ce_send_write_ack(ce_net *net)
842 unsigned short *wdata = (unsigned short*)net->data;
844 wdata[ 0 ] = htons(EDBG_CMD_WRITE_ACK);
845 wdata[ 1 ] = htons(net->blockNum);
849 return ce_send_frame(net);
852 int ce_process_download(ce_net *net, ce_bin *bin)
854 int ret = CE_PR_MORE;
856 if (net->dataLen >= 2) {
857 unsigned short *wdata = (unsigned short*)net->data;
858 switch (ntohs(*wdata)) {
859 case EDBG_CMD_WRITE_REQ:
861 // Check file name for WRITE request
862 // CE EShell uses "boot.bin" file name
864 /*diag_printf(">>>>>>>> First Frame, IP: %s, port: %d\n",
865 inet_ntoa((in_addr_t *)&net->srvAddrRecv),
866 net->srvAddrRecv.sin_port);*/
867 if (strncmp((char*)(net->data + 2), "boot.bin", 8) == 0) {
870 diag_printf("Locked Down download link, IP: %s, port: %d\n",
871 inet_ntoa((in_addr_t *)&net->srvAddrRecv),
872 net->srvAddrRecv.sin_port);
875 // Lock down EShell download link
876 net->locAddr.sin_port = htons(EDBG_DOWNLOAD_PORT + 1);
877 net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
878 net->srvAddrSend.sin_addr = net->srvAddrRecv.sin_addr;
882 net->srvAddrRecv.sin_port = 0;
887 ce_send_write_ack(net);
891 // LW: is it really intended to fall thru in case of net->link != 0 ?
894 bin->dataLen = net->dataLen - 4;
896 // Parse next block of .bin file
897 ret = ce_parse_bin(bin);
899 // Request next block
900 if (ret != CE_PR_ERROR) {
903 ce_send_write_ack(net);
906 case EDBG_CMD_READ_REQ:
907 // Read requests are not supported
911 // Error condition on the host side
912 diag_printf("Error: unknown error on the host side\n");
923 void ce_process_edbg(ce_net *net, ce_bin *bin)
927 if (net->dataLen < sizeof(eth_dbg_hdr)) {
930 net->srvAddrRecv.sin_port = 0;
934 header = (eth_dbg_hdr*)net->data;
936 if (header->id != EDBG_ID) {
939 net->srvAddrRecv.sin_port = 0;
943 if (header->service != EDBG_SVC_ADMIN) {
953 diag_printf("Locked Down EDBG service link, IP: %s, port: %d\n",
954 inet_ntoa((in_addr_t *)&net->srvAddrRecv),
955 net->srvAddrRecv.sin_port);
958 // Lock down EDBG link
960 net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
964 switch (header->cmd) {
965 case EDBG_CMD_JUMPIMG:
966 net->gotJumpingRequest = true;
969 diag_printf("Received JUMPING command\n");
971 // Just pass through and copy CONFIG structure
972 case EDBG_CMD_OS_CONFIG:
973 // Copy config structure
974 memcpy(&bin->edbgConfig, header->data, sizeof(edbg_os_config_data));
976 diag_printf("Received CONFIG command\n");
977 if (bin->edbgConfig.flags & EDBG_FL_DBGMSG) {
978 diag_printf("--> Enabling DBGMSG service, IP: %d.%d.%d.%d, port: %d\n",
979 (bin->edbgConfig.dbgMsgIPAddr >> 0) & 0xFF,
980 (bin->edbgConfig.dbgMsgIPAddr >> 8) & 0xFF,
981 (bin->edbgConfig.dbgMsgIPAddr >> 16) & 0xFF,
982 (bin->edbgConfig.dbgMsgIPAddr >> 24) & 0xFF,
983 (int)bin->edbgConfig.dbgMsgPort);
985 if (bin->edbgConfig.flags & EDBG_FL_PPSH) {
986 diag_printf("--> Enabling PPSH service, IP: %d.%d.%d.%d, port: %d\n",
987 (bin->edbgConfig.ppshIPAddr >> 0) & 0xFF,
988 (bin->edbgConfig.ppshIPAddr >> 8) & 0xFF,
989 (bin->edbgConfig.ppshIPAddr >> 16) & 0xFF,
990 (bin->edbgConfig.ppshIPAddr >> 24) & 0xFF,
991 (int)bin->edbgConfig.ppshPort);
993 if (bin->edbgConfig.flags & EDBG_FL_KDBG) {
994 diag_printf("--> Enabling KDBG service, IP: %d.%d.%d.%d, port: %d\n",
995 (bin->edbgConfig.kdbgIPAddr >> 0) & 0xFF,
996 (bin->edbgConfig.kdbgIPAddr >> 8) & 0xFF,
997 (bin->edbgConfig.kdbgIPAddr >> 16) & 0xFF,
998 (bin->edbgConfig.kdbgIPAddr >> 24) & 0xFF,
999 (int)bin->edbgConfig.kdbgPort);
1001 if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
1002 diag_printf("--> Force clean boot\n");
1008 diag_printf("Received unknown command: %08X\n", header->cmd);
1014 header->flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
1015 net->dataLen = EDBG_DATA_OFFSET;