/* ============================================================================ // fDetectHiLoTransition() // Waits for transition from SDATA = 1 to SDATA = 0. Has a 100 msec timeout. // TRANSITION_TIMEOUT is a loop counter for a 100msec timeout when waiting for // a high-to-low transition. This is used in the polling loop of // fDetectHiLoTransition(). The timing of the while(1) loops can be calculated // and the number of loops is counted, using iTimer, to determine when 100 // msec has passed. // // SCLK cannot run faster than the specified maximum frequency of 8MHz. Some // processors may need to have delays added after setting SCLK low and setting // SCLK high in order to not exceed this specification. The maximum frequency // of SCLK should be measured as part of validation of the final program // // Returns: // 0 if successful // -1 if timed out. ============================================================================*/ signed char fDetectHiLoTransition(void) { /* nTimer breaks out of the while loops if the wait in the two loops totals // more than 100 msec. Making this static makes the loop run a faster. // This is really a processor/compiler dependency and it not needed. */ static unsigned int iTimer; /* NOTE: // These loops look unconventional, but it is necessary to check SDATA_PIN // as shown because the transition can be missed otherwise, due to the // length of the SDATA Low-High-Low after certain commands. */ /* Generate clocks for the target to pull SDATA High */ iTimer = 40000; /*TRANSITION_TIMEOUT; */ while (1) { int ret; SCLKLow(); ret = fSDATACheck(); if (ret) /* exit once SDATA goes HI */ break; SCLKHigh(); /* If the wait is too long then timeout */ if (iTimer-- == 0) return ERROR; } /* Generate Clocks and wait for Target to pull SDATA Low again */ #if 0 /* wly */ iTimer = 40000;/* TRANSITION_TIMEOUT; */ while (1) { int ret; SCLKLow(); ret = fSDATACheck(); /* pr_info("wly while 2, ret=%d\n", ret); */ if (!ret) { /* exit once SDATA returns LOW */ break; } /* SCLKHigh(); // If the wait is too long then timeout */ if (iTimer-- == 0) { #ifdef USE_TP SetTPHigh(); /* Only used of Test Points are enabled */ #endif return ERROR; } } #else SCLKHigh(); SetSDATALow(); SCLKLow(); if (!fSDATACheck()) /* exit once SDATA returns LOW */ SetSDATAHiZ(); mdelay(20); #endif #ifdef USE_TP SetTPHigh(); /* Only used of Test Points are enabled */ #endif return PASS; }
/* ============================================================================ // XCH: fVerifySecurity() // This step is optional. Verifies that the security bits have been written correctly ============================================================================ */ signed char fVerifySecurity(void) { /* unsigned char bBlockNumber = 0;//wly */ bTargetAddress = 0x00; #ifdef USE_TP SetTPHigh(); /* Only used of Test Points are enabled */ #endif #ifdef USE_TP SetTPLow(); /* Only used of Test Points are enabled */ #endif SendVector(verify_security, num_bits_verify_security); fIsError = fDetectHiLoTransition(); if (fIsError) return INIT_ERROR; #ifdef USE_TP SetTPHigh(); /* Only used of Test Points are enabled */ #endif #ifdef USE_TP SetTPLow(); /* Only used of Test Points are enabled */ #endif SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); bTargetAddress = 0x00; bTargetDataPtr = 0x00; SendVector(tsync_enable, num_bits_tsync_enable); SendVector(read_write_setup, num_bits_read_write_setup); /* fReadWriteSetup(); */ /* we do SECURITY_BYTES_PER_BANK * 2 because we bTargetAddress += 2 */ while (bTargetAddress < (SECURITY_BYTES_PER_BANK * 2)) { /* Send Read Byte vector and then get a byte from Target */ SendVector(read_byte_v, 4); /* Set the drive here because SendByte() does not */ SetSDATAStrong(); SendByte(bTargetAddress, 7); SetSDATAHiZ(); /* Set to HiZ so Target can drive SDATA */ RunClock(2); /* Run two SCLK cycles between writing and reading */ bTargetDataIN = bReceiveByte(); RunClock(1); SendVector(read_byte_v + 1, 1); /* Send the ReadByte Vector End */ /* Test the Byte that was read from the Target against the original // value (already in the 128-Byte array "abTargetDataOUT[]"). If it // matches, then bump the address & pointer,loop-back and continue. // If it does NOT match abort the loop and return and error. */ if (bTargetDataIN != abTargetDataOUT[bTargetDataPtr]) return BLOCK_ERROR; /* Increment the address by two to accomodate 7-Bit addressing (puts the 7-bit address into MSBit locations for "SendByte()"). */ bTargetDataPtr++; bTargetAddress += 2; } SendVector(tsync_disable, num_bits_tsync_disable); return PASS; }
signed char download_firmware_main(char *filename) { struct file *filp; struct inode *inode = NULL; int length = 0, remaining = 0, count = 0; mm_segment_t oldfs; char *fw_buf = NULL, *buffer; oldfs = get_fs(); set_fs(KERNEL_DS); filp = filp_open(filename, O_RDONLY, S_IRUSR); if (IS_ERR(filp)) { pr_info("%s: file %s filp_open error, is_err = %x\n", __func__, filename, (int)IS_ERR(filp)); return -EIO; } if (!filp->f_op) { pr_info("%s: File Operation Method Error\n", __func__); return -EIO; } inode = filp->f_path.dentry->d_inode; if (!inode) { pr_info("%s: Get inode from filp failed\n", __func__); filp_close(filp, NULL); return -EIO; } pr_info("%s file offset opsition: %xh\n", __func__, (unsigned)filp->f_pos); length = i_size_read(inode->i_mapping->host); if (length == 0) { pr_info("%s: Try to get file size error\n", __func__); goto Transfer_DONE; } pr_info("%s: length=%d\n", __func__, length); fw_buf = (char *)kmalloc((length + 1), GFP_KERNEL); if (fw_buf == NULL) { pr_info("%s: kernel memory alloc error\n", __func__); filp_close(filp, NULL); return -EIO; } if (filp->f_op->read(filp, fw_buf, length, &filp->f_pos) != length) { pr_info("%s: file read error\n", __func__); goto Transfer_DONE; } /* >>>> ISSP Programming Starts Here <<<< */ #ifdef RESET_MODE fIsError = fXRESInitializeTargetForISSP(); if (fIsError) { pr_info("power on failed!\n"); ErrorTrap(fIsError); } pr_info("power on success!\n"); #else /* Initialize the Host & Target for ISSP operations */ fIsError = fPowerCycleInitializeTargetForISSP(); if (fIsError) { pr_info("power on failed!\n"); ErrorTrap(fIsError); } pr_info("power on success!\n"); #endif /* Run the SiliconID Verification, and proceed according to result. */ fIsError = fVerifySiliconID(); if (fIsError) { pr_info("SiliconID Verification failed!\n"); ErrorTrap(fIsError); return -EIO; } pr_info("SiliconID Verification success!\n"); /*----------------------------------------------------------------------- xch: the function call below will erase one block (128bytes) of flash in the target device. The block number to be erased is passed in as a parameter fEraseBlock(5); // arbitrarily used the 5th block for debugging purposes -------------------------------------------------------------------------- */ fIsError = fEraseTarget(); if (fIsError) ErrorTrap(fIsError); pr_info("erase one block success!\n"); /* ==============================================================// Program Flash blocks with predetermined data. In the final application this data should come from the HEX output of PSoC Designer. firmware_transfer(tgt_fw); */ remaining = length; buffer = fw_buf; iChecksumData = 0; /* Calculte the device checksum as you go */ for (bBankCounter = 0; bBankCounter < NUM_BANKS; bBankCounter++) { for (iBlockCounter = 0; iBlockCounter < BLOCKS_PER_BANK; iBlockCounter++) { /* count = (remaining > TARGET_DATABUFF_LEN)? TARGET_DATABUFF_LEN : remaining; */ LoadProgramData(bBankCounter, (unsigned char)iBlockCounter, buffer, count); /* This loads the host with test data, not the DUT if(iBlockCounter==1) return; remaining = remaining - count; buffer = &fw_buf[count * (iBlockCounter+1)]; */ iChecksumData += iLoadTarget(); /* This loads the DUT */ #ifdef USE_TP SetTPHigh(); /* Only used of Test Points are enabled */ #endif fIsError = fProgramTargetBlock(bBankCounter, (unsigned char)iBlockCounter); if (fIsError) ErrorTrap(fIsError); #ifdef USE_TP SetTPLow(); /* Only used of Test Points are enabled */ #endif fIsError = fReadStatus(); if (fIsError) /* READ-STATUS after PROGRAM-AND-VERIFY */ ErrorTrap(fIsError); } } pr_info("Program Flash blocks with predetermined data success.\n"); /*=======================================================// Doing Verify Verify included for completeness in case host desires to do a stand-alone verify at a later date. */ remaining = length; buffer = fw_buf; for (bBankCounter = 0; bBankCounter < NUM_BANKS; bBankCounter++) { for (iBlockCounter = 0; iBlockCounter < BLOCKS_PER_BANK; iBlockCounter++) { /* LoadProgramData(bBankCounter, (unsigned char) iBlockCounter,buffer,count); count = (remaining > TARGET_DATABUFF_LEN)? TARGET_DATABUFF_LEN : remaining; */ LoadProgramData(bBankCounter, (unsigned char)iBlockCounter, buffer, count); /* This loads the host with test data, not the DUT remaining = remaining - count; buffer = &fw_buf[count * (iBlockCounter+1)]; */ fIsError = fVerifySetup(bBankCounter, (unsigned char)iBlockCounter); if (fIsError) { pr_info("fVerifySetup err = %d\n", fIsError); ErrorTrap(fIsError); } fIsError = fReadStatus(); if (fIsError) { pr_info("fReadStatus err = %d\n", fIsError); ErrorTrap(fIsError); } fIsError = fReadByteLoop(); if (fIsError) { pr_info("fReadByteLoop err = %d\n", fIsError); ErrorTrap(fIsError); } } } pr_info("Doing Verify success.\n"); /*--------------------------------------------------------------------------- xch: the function call below will erase one block (128bytes) of flash in the target device. The block number to be erased is passed in as a parameter fEraseBlock(5); // arbitrarily used the 5th block for debugging purposes -----------------------------------------------------------------------------*/ /* ======================================================= Program security data into target PSoC. In the final application this data should come from the HEX output of PSoC Designer */ for (bBankCounter = 0; bBankCounter < NUM_BANKS; bBankCounter++) { /* Load one bank of security data from hex file into buffer */ fIsError = fLoadSecurityData(bBankCounter, buffer); if (fIsError) ErrorTrap(fIsError); /* Secure one bank of the target flash */ fIsError = fSecureTargetFlash(); if (fIsError) ErrorTrap(fIsError); } pr_info("set securitydata success\n"); /* ============================================================== Do VERIFY-SECURITY after SECURE Load one bank of security data from hex file into buffer loads abTargetDataOUT[] with security data that was used in secure bit stream */ fIsError = fLoadSecurityData(bBankCounter, buffer); if (fIsError) ErrorTrap(fIsError); fIsError = fVerifySecurity(); if (fIsError) ErrorTrap(fIsError); /* ======================================================= Doing Checksum after VERIFY-SECURITY */ iChecksumTarget = 0; for (bBankCounter = 0; bBankCounter < NUM_BANKS; bBankCounter++) { fIsError = fAccTargetBankChecksum(&iChecksumTarget); if (fIsError) ErrorTrap(fIsError); } pr_info("%s: checksum = %x\n", __func__, iChecksumTarget); if (iChecksumTarget != (iChecksumData & 0xFFFF)) ErrorTrap(VERIFY_ERROR); pr_info("checksum success!\n"); pr_info("download firmware success!\n"); /* *** SUCCESS *** At this point, the Target has been successfully Initialize, ID-Checked, Bulk-Erased, Block-Loaded, Block-Programmed, Block-Verified, and Device- Checksum Verified. */ return 0; Transfer_DONE: kfree(fw_buf); filp_close(filp, NULL); set_fs(oldfs); return -EIO; }