#include <redboot.h>
+#include <cyg/io/flash.h>
#include <net/net.h>
#include CYGHWR_MEMORY_LAYOUT_H
#include <wince.h>
#define CE_WINCE_VRAM_BASE 0x80000000
#define CE_FIX_ADDRESS(a) (((a) - CE_WINCE_VRAM_BASE) + CE_RAM_BASE)
+#ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
+extern void *flash_start, *flash_end;
+
+static inline int is_rom_addr(void *addr)
+{
+ return addr >= flash_start && addr <= flash_end;
+}
+#else
+#define is_rom_addr(p) 0
+#endif
+
+static inline int is_ram_addr(unsigned long addr)
+{
+ return addr >= CE_RAM_BASE && addr < CE_RAM_END;
+}
+
// Bin image parse states
#define CE_PS_RTI_ADDR 0
#define CE_PS_RTI_LEN 1
///////////////////////////////////////////////////////////////////////////////////////////////
// Local types
typedef struct {
- unsigned int rtiPhysAddr;
- unsigned int rtiPhysLen;
- unsigned int ePhysAddr;
- unsigned int ePhysLen;
- unsigned int eChkSum;
+ unsigned long rtiPhysAddr;
+ unsigned long rtiPhysLen;
+ unsigned long ePhysAddr;
+ unsigned long ePhysLen;
+ unsigned long eChkSum;
- unsigned int eEntryPoint;
- unsigned int eRamStart;
- unsigned int eRamLen;
- unsigned int eDrvGlb;
+ unsigned long eEntryPoint;
+ unsigned long eRamStart;
+ unsigned long eRamLen;
+ unsigned long eDrvGlb;
unsigned char parseState;
- unsigned int parseChkSum;
+ unsigned long parseChkSum;
int parseLen;
unsigned char *parsePtr;
- int secion;
+ int section;
int dataLen;
unsigned char *data;
bool ce_lookup_ep_bin(ce_bin *bin);
void ce_prepare_run_bin(ce_bin *bin);
void ce_run_bin(ce_bin *bin);
-void ce_redboot_version(unsigned int *vhigh, unsigned int *vlow);
#ifdef CYGPKG_REDBOOT_NETWORKING
// Redboot network based routines
bool ce_is_bin_image(void *image, int imglen)
{
if (imglen < CE_BIN_SIGN_LEN) {
+ diag_printf("Not a valid CE image: image size %u shorter than minimum %u\n",
+ imglen, CE_BIN_SIGN_LEN);
return 0;
}
+ if (is_rom_addr(image)) {
+ unsigned char sign_buf[CE_BIN_SIGN_LEN];
+ void *err_addr;
- return (memcmp(image, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0);
+ if (flash_read(image, sign_buf,
+ CE_BIN_SIGN_LEN, &err_addr) != FLASH_ERR_OK) {
+ return 0;
+ }
+ return memcmp(sign_buf, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0;
+ }
+ return memcmp(image, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0;
}
void ce_bin_init_parser()
{
// No buffer address by now, will be specified
- // latter by the ce_bin_parse_next routine
-
+ // later by the ce_bin_parse_next routine
ce_init_bin(&g_bin, NULL);
}
if (pbLen) {
if (bin->binLen == 0) {
// Check for the .BIN signature first
-
if (!ce_is_bin_image(pbData, pbLen)) {
- diag_printf("Error: Invalid or corrupted .BIN image!\n");
+ diag_printf("** Error: Invalid or corrupted .BIN image!\n");
return CE_PR_ERROR;
}
diag_printf("Loading Windows CE .BIN image ...\n");
// Skip signature
-
pbLen -= CE_BIN_SIGN_LEN;
pbData += CE_BIN_SIGN_LEN;
}
copyLen = CE_MIN(sizeof(unsigned int) - bin->parseLen, pbLen);
- memcpy(&bin->parsePtr[ bin->parseLen ], pbData, copyLen);
+ if (is_rom_addr(pbData)) {
+ void *err_addr;
+ if (flash_read(pbData, &bin->parsePtr[bin->parseLen],
+ copyLen, &err_addr) != FLASH_ERR_OK) {
+ return CE_PR_ERROR;
+ }
+ } else {
+ memcpy(&bin->parsePtr[bin->parseLen], pbData, copyLen);
+ }
bin->parseLen += copyLen;
pbLen -= copyLen;
pbData += copyLen;
if (bin->parseLen == sizeof(unsigned int)) {
if (bin->parseState == CE_PS_RTI_ADDR) {
bin->rtiPhysAddr = CE_FIX_ADDRESS(bin->rtiPhysAddr);
+ if (!is_ram_addr(bin->rtiPhysAddr)) {
+ diag_printf("Invalid address %08lx in CE_PS_RTI_ADDR section\n",
+ bin->rtiPhysAddr);
+ return CE_PR_ERROR;
+ }
} else if (bin->parseState == CE_PS_E_ADDR) {
if (bin->ePhysAddr) {
bin->ePhysAddr = CE_FIX_ADDRESS(bin->ePhysAddr);
+ if (!is_ram_addr(bin->ePhysAddr)) {
+ diag_printf("Invalid address %08lx in CE_PS_E_ADDR section\n",
+ bin->ePhysAddr);
+ return CE_PR_ERROR;
+ }
}
}
bin->parseState ++;
bin->parseLen = 0;
bin->parsePtr += sizeof(unsigned int);
-
if (bin->parseState == CE_PS_E_DATA) {
if (bin->ePhysAddr) {
bin->parsePtr = (unsigned char*)(bin->ePhysAddr);
bin->parseChkSum = 0;
} else {
// EOF
-
pbLen = 0;
bin->endOfBin = 1;
}
break;
case CE_PS_E_DATA:
-
if (bin->ePhysAddr) {
copyLen = CE_MIN(bin->ePhysLen - bin->parseLen, pbLen);
bin->parseLen += copyLen;
pbLen -= copyLen;
+ if (is_rom_addr(pbData)) {
+ void *err_addr;
- while (copyLen --) {
- bin->parseChkSum += *pbData;
- *bin->parsePtr ++ = *pbData ++;
+ if (flash_read(pbData, bin->parsePtr,
+ copyLen, &err_addr) != FLASH_ERR_OK) {
+ return CE_PR_ERROR;
+ }
+ pbData += copyLen;
+ while (copyLen--) {
+ bin->parseChkSum += *bin->parsePtr++;
+ }
+ } else {
+ while (copyLen--) {
+ bin->parseChkSum += *pbData;
+ *bin->parsePtr ++ = *pbData ++;
+ }
}
-
if (bin->parseLen == bin->ePhysLen) {
- diag_printf("Section [%02d]: address 0x%08X, size 0x%08X, checksum %s\n",
- bin->secion,
+ diag_printf("Section [%02d]: address 0x%08lX, size 0x%08lX, checksum %s\n",
+ bin->section,
bin->ePhysAddr,
bin->ePhysLen,
(bin->eChkSum == bin->parseChkSum) ? "ok" : "fail");
return CE_PR_ERROR;
}
- bin->secion ++;
+ bin->section ++;
bin->parseState = CE_PS_E_ADDR;
bin->parseLen = 0;
bin->parsePtr = (unsigned char*)(&bin->ePhysAddr);
// Find entry point
if (!ce_lookup_ep_bin(bin)) {
- diag_printf("Error: entry point not found!\n");
+ diag_printf("** Error: entry point not found!\n");
bin->binLen = 0;
return CE_PR_ERROR;
}
- diag_printf("Entry point: 0x%08X, address range: 0x%08X-0x%08X\n",
+ diag_printf("Entry point: 0x%08lX, address range: 0x%08lX-0x%08lX\n",
bin->eEntryPoint,
bin->rtiPhysAddr,
bin->rtiPhysAddr + bin->rtiPhysLen);
unsigned int i;
// Check image Table Of Contents (TOC) signature
-
if (*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE) {
// Error: Did not find image TOC signature!
// Lookup entry point
-
header = (ce_rom_hdr*)CE_FIX_ADDRESS(*(unsigned int*)(bin->rtiPhysAddr +
ROM_SIGNATURE_OFFSET +
sizeof(unsigned int)));
for (i = 0; i < header->nummods; i ++) {
// Look for 'nk.exe' module
-
if (strcmp((char*)CE_FIX_ADDRESS(tentry[ i ].fileName), "nk.exe") == 0) {
// Save entry point and RAM addresses
e32 = (e32_rom*)CE_FIX_ADDRESS(tentry[ i ].e32Offset);
- bin->eEntryPoint = CE_FIX_ADDRESS(tentry[ i ].loadOffset) + e32->e32_entryrva;
+ bin->eEntryPoint = CE_FIX_ADDRESS(tentry[ i ].loadOffset) +
+ e32->e32_entryrva;
bin->eRamStart = CE_FIX_ADDRESS(header->ramStart);
bin->eRamLen = header->ramEnd - header->ramStart;
// DRV_GLB 83B00000 00001000 RESERVED
//
- bin->eDrvGlb = CE_FIX_ADDRESS(header->ramEnd);
-
+ bin->eDrvGlb = CE_FIX_ADDRESS(header->ramEnd) -
+ sizeof(ce_driver_globals);
return 1;
}
}
return 0;
}
-void ce_prepare_run_bin(ce_bin *bin)
+void setup_drv_globals(ce_driver_globals *drv_glb)
{
- ce_driver_globals *drv_glb;
+ diag_printf("%s %p\n", __FUNCTION__, drv_glb);
- // Clear os RAM area (if needed)
+ // Fill out driver globals
+ memset(drv_glb, 0, sizeof(ce_driver_globals));
- if (1 || bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
- diag_printf("Preparing clean boot ... ");
- memset((void*)bin->eRamStart, 0, bin->eRamLen);
- diag_printf("ok\n");
- }
+ // Signature
+ drv_glb->signature = DRV_GLB_SIGNATURE;
- // Prepare driver globals (if needed)
+ // No flags by now
+ drv_glb->flags = 0;
- if (bin->eDrvGlb) {
- drv_glb = (ce_driver_globals*)bin->eDrvGlb;
+#ifdef CYGPKG_REDBOOT_NETWORKING
+ // Local ethernet MAC address
+ memcpy(drv_glb->macAddr, __local_enet_addr, sizeof(__local_enet_addr));
+
+ // Local IP address
+ memcpy(&drv_glb->ipAddr, __local_ip_addr, sizeof(__local_ip_addr));
+
+ // Subnet mask
+ memcpy(&drv_glb->ipMask, __local_ip_mask, sizeof(__local_ip_mask));
+
+ // Gateway config
+#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
+ // Getway IP address
+ memcpy(&drv_glb->ipGate, __local_ip_gate, sizeof(__local_ip_gate));
+#endif
+#endif
+}
- // Fill out driver globals
- memset(drv_glb, 0, sizeof(ce_driver_globals));
+#if WINCE_ALTERNATE_ARG_BASE
+void setup_alt_drv_globals(ce_alt_driver_globals *alt_drv_glb)
+{
+ diag_printf("%s %p\n", __FUNCTION__, alt_drv_glb);
+ // Fill out driver globals
+ memset(alt_drv_glb, 0, sizeof(ce_alt_driver_globals));
- // Signature
- drv_glb->signature = DRV_GLB_SIGNATURE;
+ alt_drv_glb->header.signature = ALT_DRV_GLB_SIGNATURE;
+ alt_drv_glb->header.oalVersion = 1;
+ alt_drv_glb->header.bspVersion = 1;
- // No flags by now
- drv_glb->flags = 0;
+ alt_drv_glb->kitl.flags = 0;
+ diag_sprintf(alt_drv_glb->deviceId, "Triton");
#ifdef CYGPKG_REDBOOT_NETWORKING
- // Local ethernet MAC address
- memcpy(drv_glb->macAddr, __local_enet_addr, sizeof(__local_enet_addr));
+ memcpy(&alt_drv_glb->kitl.mac[0], __local_enet_addr, sizeof(__local_enet_addr));
+ diag_sprintf(alt_drv_glb->deviceId, "Triton%02X", __local_enet_addr[5]);
- // Local IP address
- memcpy(&drv_glb->ipAddr, __local_ip_addr, sizeof(__local_ip_addr));
+ // Local IP address
+ memcpy(&alt_drv_glb->kitl.ipAddress, __local_ip_addr, sizeof(__local_ip_addr));
- // Subnet mask
- memcpy(&drv_glb->ipMask, __local_ip_mask, sizeof(__local_ip_mask));
+ // Subnet mask
+ memcpy(&alt_drv_glb->kitl.ipMask, __local_ip_mask, sizeof(__local_ip_mask));
- // Gateway config
+ // Gateway config
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
- // Getway IP address
- memcpy(&drv_glb->ipGate, __local_ip_gate, sizeof(__local_ip_gate));
+ // Getway IP address
+ memcpy(&alt_drv_glb->kitl.ipRoute, __local_ip_gate, sizeof(__local_ip_gate));
#endif
+#endif
+}
#else
- // Local ethernet MAC address
- memset(drv_glb->macAddr, 0, sizeof(drv_glb->macAddr));
+#define setup_alt_drv_globals(x) CYG_EMPTY_STATEMENT
+#endif
- // Local IP address
- memset(&drv_glb->ipAddr, 0, sizeof(drv_glb->ipAddr));
+void ce_prepare_run_bin(ce_bin *bin)
+{
+ ce_driver_globals *drv_glb;
- // Subnet mask
- memset(&drv_glb->ipMask, 0, sizeof(drv_glb->ipMask));
+ diag_printf("%s\n", __FUNCTION__);
- // Getway IP address
- memset(&drv_glb->ipGate, 0, sizeof(drv_glb->ipGate));
-#endif // CYGPKG_REDBOOT_NETWORKING
- // EDBG services config
- memcpy(&drv_glb->edbgConfig, &bin->edbgConfig, sizeof(bin->edbgConfig));
+#if WINCE_ALTERNATE_ARG_BASE
+ ce_alt_driver_globals *alt_drv_glb = &_KARO_CECFG_START;
+ char *karo_magic = &_KARO_MAGIC[0];
+ unsigned long *karo_structure_size = &_KARO_STRUCT_SIZE;
- // Equotip specific
-#ifdef CYGPKG_HAL_ARM_XSCALE_TRITON270_EQT32
- // Copy configuration
+ memcpy(karo_magic, "KARO_CE6", sizeof(_KARO_MAGIC));
+ *karo_structure_size = sizeof(ce_alt_driver_globals);
+#endif
+ // Clear os RAM area (if needed)
+ if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
+ diag_printf("Preparing clean boot ... ");
+ memset((void *)bin->eRamStart, 0, bin->eRamLen);
+ diag_printf("ok\n");
+ }
- drv_glb->contrastDefault = eedat.lcd_contrast;
- drv_glb->contrastBand = eedat.lcd_contrast_band;
- drv_glb->backlight = eedat.lcd_backlight;
- drv_glb->backlightOffset = eedat.lcd_backlight_offset;
+ // Prepare driver globals (if needed)
+ if (bin->eDrvGlb) {
+ drv_glb = (ce_driver_globals *)bin->eDrvGlb;
- memcpy(drv_glb->macAddr, eedat.mac_address, sizeof(drv_glb->macAddr));
-#endif
+ setup_drv_globals(drv_glb);
+ setup_alt_drv_globals(alt_drv_glb);
+
+ // EDBG services config
+ memcpy(&drv_glb->edbgConfig, &bin->edbgConfig, sizeof(bin->edbgConfig));
}
// Update global RedBoot entry point address
pow = 1;
p = pver + strlen(pver) - 1;
- while (len --) {
+ while (len--) {
if (*p >= '0' && *p <= '9') {
*ver += ((*p - '0') * pow);
pow *= 10;
break;
}
}
- p --;
+ p--;
}
}
if (g_bin.binLen) {
// Try to receive edbg commands from host
-
ce_init_edbg_link(&g_net);
if (verbose) {
}
// Prepare WinCE image for execution
-
ce_prepare_run_bin(&g_bin);
// Launch WinCE, if necessary
-
if (g_net.gotJumpingRequest) {
ce_run_bin(&g_bin);
}
{
eth_dbg_hdr *header;
edbg_bootme_data *data;
- int verHigh, verLow;
+ unsigned int verHigh, verLow;
// Fill out BOOTME packet
memset(net->data, 0, BOOTME_PKT_SIZE);
// Some diag output ...
if (net->verbose) {
diag_printf("Sending BOOTME request [%d] to %s\n",
- (int)net->secNum,
- inet_ntoa((in_addr_t *)&net->srvAddrSend));
+ net->secNum,
+ inet_ntoa((in_addr_t *)&net->srvAddrSend));
}
// Send packet