/** * \brief Read the data and/or spare of a page of a NAND Flash chip, and verify * that the data is valid using the ECC information contained in the spare. If * one buffer pointer is 0, the corresponding area is not saved. * * \param ecc Pointer to an nand_flash_ecc instance. * \param block Number of block to read from. * \param page Number of page to read inside given block. * \param data Data area buffer. * \param spare Spare area buffer. * * \return 0 if the data has been read and is valid; otherwise returns either * NAND_COMMON_ERROR_CORRUPTEDDATA or ... */ uint32_t nand_flash_ecc_read_page(const struct nand_flash_ecc *ecc, uint16_t block, uint16_t page, uint8_t *data, uint8_t *spare) { uint32_t error; uint8_t hamming_code[NAND_COMMON_MAX_SPARE_ECC_BYTES]; uint8_t spare_buffer[NAND_COMMON_MAX_PAGE_SPARE_SIZE]; uint16_t page_data_size = nand_flash_model_get_page_data_size(MODEL(ecc)); /* if no buffer provided, use a temp one */ if (!spare) { spare = spare_buffer; } memset(spare, 0xFF, NAND_COMMON_MAX_PAGE_SPARE_SIZE); /* Start by reading the spare and the data */ nand_flash_raw_read_page(RAW(ecc), block, page, data, spare); /* Retrieve ECC information from page and verify the data */ nand_flash_spare_scheme_read_ecc(nand_flash_model_get_scheme(MODEL(ecc)), spare, hamming_code); error = hamming_verify_256x(data, page_data_size, hamming_code); if (error && (error != HAMMING_ERROR_SINGLE_BIT)) { return NAND_COMMON_ERROR_CORRUPTEDDATA; } return 0; }
//------------------------------------------------------------------------------ /// Initializes an EccNandFlash instance. /// \param ecc Pointer to an EccNandFlash instance. /// \param model Pointer to the underlying nand chip model. Can be 0. /// \param commandAddress Address at which commands are sent. /// \param addressAddress Address at which addresses are sent. /// \param dataAddress Address at which data is sent. /// \param pinChipEnable Pin controlling the CE signal of the NandFlash. /// \param pinReadyBusy Pin used to monitor the ready/busy signal of the Nand. //------------------------------------------------------------------------------ unsigned char EccNandFlash_Initialize( struct EccNandFlash *ecc, const struct NandFlashModel *model, unsigned int commandAddress, unsigned int addressAddress, unsigned int dataAddress, const Pin pinChipEnable, const Pin pinReadyBusy) { unsigned char rc; rc = RawNandFlash_Initialize(RAW(ecc), model, commandAddress, addressAddress, dataAddress, pinChipEnable, pinReadyBusy); #if defined(HARDWARE_ECC) { unsigned int ecc_page; switch(NandFlashModel_GetPageDataSize(MODEL(ecc))) { case 512: ecc_page = AT91C_HSMC4_PAGESIZE_528_Bytes; break; case 1024: ecc_page = AT91C_HSMC4_PAGESIZE_1056_Bytes; break; case 2048: ecc_page = AT91C_HSMC4_PAGESIZE_2112_Bytes; break; case 4096: ecc_page = AT91C_HSMC4_PAGESIZE_4224_Bytes; break; default: TRACE_ERROR("PageSize %d not compatible with ECC\n\r", NandFlashModel_GetPageDataSize(MODEL(ecc))); return NandCommon_ERROR_ECC_NOT_COMPATIBLE; } HSMC4_EccConfigure(AT91C_ECC_TYPCORRECT_ONE_EVERY_256_BYTES, ecc_page); } #endif return rc; }
/** * \brief Reads the data and/or the spare area of a page on a translated nandflash. * If the block is not currently mapped but could be (i.e. there are available * physical blocks), then the data/spare is filled with 0xFF. * * \param translated Pointer to a TranslatedNandFlash instance. * \param block Logical block number. * \param page Number of page to read inside logical block. * \param data Data area buffer, can be 0. * \param spare Spare area buffer, can be 0. * \return 0 if successful; otherwise returns NandCommon_ERROR_NOMOREBLOCKS */ unsigned char TranslatedNandFlash_ReadPage( const struct TranslatedNandFlash *translated, unsigned short block, unsigned short page, void *data, void *spare ) { unsigned char error ; TRACE_INFO("TranslatedNandFlash_ReadPage(B#%d:P#%d)\n\r", block, page); /* If the page to read is in the current block, there is a previous physical block and the page is clean -> read the page in the old block since the new one does not contain meaningful data*/ if ( (block == translated->currentLogicalBlock) && (translated->previousPhysicalBlock != -1) && (PageIsClean(translated, page)) ) { TRACE_DEBUG("Reading page from current block\n\r"); return ManagedNandFlash_ReadPage( MANAGED( translated ), translated->previousPhysicalBlock, page, data, spare ) ; } else { /* Try to read the page from the logical block*/ error = MappedNandFlash_ReadPage(MAPPED(translated), block, page, data, spare); /* Block was not mapped*/ if ( error == NandCommon_ERROR_BLOCKNOTMAPPED ) { assert( !spare ) ; /* "Cannot read the spare information of an unmapped block\n\r" */ /* Check if a block can be allocated*/ if ( BlockCanBeAllocated( translated ) ) { /* Return 0xFF in buffers with no error*/ TRACE_DEBUG("Block #%d is not mapped but can be allocated, filling buffer with 0xFF\n\r", block); if (data) { memset(data, 0xFF, NandFlashModel_GetPageDataSize(MODEL(translated))); } if (spare) { memset(spare, 0xFF, NandFlashModel_GetPageSpareSize(MODEL(translated))); } } else { TRACE_ERROR("Block #%d is not mapped and there are no more blocks available\n\r", block); return NandCommon_ERROR_NOMOREBLOCKS; } } /* Error*/ else { if (error) { return error; } } } return 0; }
/** * \brief Sends the column address to the NandFlash chip. * * \param raw Pointer to a RawNandFlash instance. * \param columnAddress Column address to send. */ static void WriteColumnAddress( const struct RawNandFlash *raw, unsigned short columnAddress) { unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(raw)); /* Check the data bus width of the NandFlash */ if (NandFlashModel_GetDataBusWidth(MODEL(raw)) == 16) { /* Div 2 is because we address in word and not in byte */ columnAddress >>= 1; }
int sp_loadconf_models(t_env *e) { t_model const tmp[sp_num_models] = { MODEL(sp_main_mesh, sp_porcelain_texture, &sp_unif_model_mix), MODEL(sp_plane_mesh, sp_wall_texture, &sp_unif_model), MODEL(sp_land_mesh, sp_no_texture, NULL), MODEL(sp_sun_mesh, sp_no_texture, &sp_unif_model), }; memcpy(&e->models, &tmp, sizeof(tmp)); return (0); }
/** * \brief Translate the given column and row address into first and other (1-4) * address cycles. The resulting values are stored in the provided variables * if they are not null. * * \param raw Pointer to a nand_flash_raw instance. * \param column_address Column address to translate. * \param row_address Row address to translate. * \param p_address_cycle0 First address cycle. * \param p_address_cycle1234 four address cycles. * \param five_address Flag for five address cycles. */ static void nfc_translate_address(const struct nand_flash_raw *raw, uint32_t column_address, uint32_t row_address, uint32_t *p_address_cycle0, uint32_t *p_address_cycle1234, uint32_t five_address) { uint16_t page_data_size = nand_flash_model_get_page_data_size(MODEL(raw)); uint32_t num_page = nand_flash_model_get_device_size_in_pages(MODEL(raw)); uint32_t address_cycles = 0; uint32_t address_cycle0 = 0; uint32_t address_cycle1234 = 0; /* Check the data bus width of the NAND Flash */ if (nand_flash_model_get_data_bus_width(MODEL(raw)) == 16) { /* Div 2 is because we address in word and not in byte */ column_address >>= 1; }
//------------------------------------------------------------------------------ /// Copies the data from a whole block to another block on a nandflash. Both /// blocks must be LIVE. /// Returns 0 if successful; otherwise returns NandCommon_ERROR_WRONGSTATUS if /// at least one of the blocks is not free, or a NandCommon_ERROR_xxx code. /// \param managed Pointer to a ManagedNandFlash instance. /// \param sourceBlock Source block number. /// \param destBlock Destination block number. //------------------------------------------------------------------------------ unsigned char ManagedNandFlash_CopyBlock( const struct ManagedNandFlash *managed, unsigned short sourceBlock, unsigned short destBlock) { unsigned short numPages = NandFlashModel_GetBlockSizeInPages(MODEL(managed)); unsigned char error; unsigned short page; ASSERT(sourceBlock != destBlock, "ManagedNandFlash_CopyBlock: Source block must be different from dest. block\n\r"); TRACE_INFO("ManagedNandFlash_CopyBlock(B#%d->B#%d)\n\r", sourceBlock, destBlock); // Copy all pages for (page=0; page < numPages; page++) { error = ManagedNandFlash_CopyPage(managed, sourceBlock, page, destBlock, page); if (error) { TRACE_ERROR("ManagedNandFlash_CopyPage: Failed to copy page %d\n\r", page); return error; } } return 0; }
/** * \brief This function transfers the USB MSC data to the memory * * \param addr Sector address to start write * \param nb_sector Number of sectors to transfer (sector=512 bytes) * * \return Ctrl_status */ Ctrl_status nand_flash_usb_write_10(uint32_t addr, uint16_t nb_sector) { uint8_t nb_sector_trans; uint16_t page_data_size = nand_flash_model_get_page_data_size(MODEL(&nf_translation)); if (nand_flash_status == NAND_FLASH_READY) { while (nb_sector) { nb_sector_trans = min(nb_sector, (page_data_size / SECTOR_SIZE)); udi_msc_trans_block(false, (uint8_t *)nand_flash_usb_buffer, (nb_sector_trans * SECTOR_SIZE), NULL); if (nand_flash_write((addr * SECTOR_SIZE), nand_flash_usb_buffer, (nb_sector_trans * SECTOR_SIZE))) { return CTRL_FAIL; } nb_sector -= nb_sector_trans; addr += nb_sector_trans; } return CTRL_GOOD; } return CTRL_BUSY; }
/** * \brief Read the data of a whole block on a SkipBlock nandflash. * * \param skipBlock Pointer to a SkipBlockNandFlash instance. * \param block Number of the block to read. * \param pageOffsetInBlock Number of the page to read inside the given block. * \param data Data area buffer. * \param numPages number of pages to read. * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_WritePage(). */ uint8_t SkipBlockNandFlash_ReadBlockUnaligned( const struct SkipBlockNandFlash *skipBlock, uint16_t block, uint16_t pageOffsetInBlock, uint16_t numPages, void *data ) { /* Page size*/ uint32_t pageSize; /* Page index*/ uint16_t i; /* Error returned by SkipBlockNandFlash_ReadPage*/ uint8_t error = 0; /* Retrieve model information*/ pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock)); for (i = pageOffsetInBlock; i < pageOffsetInBlock + numPages; i++) { error = SkipBlockNandFlash_ReadPage(skipBlock, block, i, data, 0); if (error == NandCommon_ERROR_BADBLOCK) { TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Block is BAD.\n\r"); return NandCommon_ERROR_BADBLOCK; } else if (error) { TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Cannot read page %d of block %d.\n\r", i, block); return NandCommon_ERROR_CANNOTREAD; } data = (void *) ((uint8_t *) data + pageSize); } return 0; }
static void icontainer_real_current( iContainer *parent, iContainer *child ) { iContainer *old_current; g_assert( IS_ICONTAINER( parent ) ); g_assert( !child || IS_ICONTAINER( child ) ); g_assert( !child || ICONTAINER_IS_CHILD( parent, child ) ); #ifdef DEBUG printf( "icontainer_real_current: parent %s \"%s\"; " "child %s \"%s\"\n", G_OBJECT_TYPE_NAME( parent ), NN( IOBJECT( parent )->name ), child ? G_OBJECT_TYPE_NAME( child ) : "NULL", child ? NN( IOBJECT( child )->name ) : "NULL" ); #endif /*DEBUG*/ old_current = parent->current; parent->current = child; if( old_current != child ) { if( old_current ) iobject_changed( IOBJECT( old_current ) ); if( child ) iobject_changed( IOBJECT( child ) ); iobject_changed( IOBJECT( parent ) ); } if( child ) model_front( MODEL( child ) ); }
/** * \brief Check the given page inside the currently written block is clean or not. * * \param translated Pointer to a TranslatedNandFlash instance. * \param page Page number. * \return 1 if the given page inside the currently written block is clean (has * not been written yet); otherwise returns 0. */ static unsigned char PageIsClean( const struct TranslatedNandFlash *translated, unsigned short page) { assert( page < NandFlashModel_GetBlockSizeInPages(MODEL(translated)) ) ; /* "PageIsClean: Page out-of-bounds\n\r" */ return ((translated->currentBlockPageStatuses[page / 8] >> (page % 8)) & 1) == 0; }
/** * \brief Marks the given page as being dirty (i.e. written). * * \param translated Pointer to a TranslatedNandFlash instance. * \param page Page number. */ static void MarkPageDirty( struct TranslatedNandFlash *translated, unsigned short page) { assert( page < NandFlashModel_GetBlockSizeInPages(MODEL(translated)) ) ; /* "PageIsClean: Page out-of-bounds\n\r" */ translated->currentBlockPageStatuses[page / 8] |= 1 << (page % 8); }
//------------------------------------------------------------------------------ /// Reads the data and/or spare of a page of a nandflash chip, and verify that /// the data is valid using the ECC information contained in the spare. If one /// buffer pointer is 0, the corresponding area is not saved. /// Returns 0 if the data has been read and is valid; otherwise returns either /// NandCommon_ERROR_CORRUPTEDDATA or ... /// \param ecc Pointer to an EccNandFlash instance. /// \param block Number of block to read from. /// \param page Number of page to read inside given block. /// \param data Data area buffer. /// \param spare Spare area buffer. //------------------------------------------------------------------------------ unsigned char EccNandFlash_ReadPage( const struct EccNandFlash *ecc, unsigned short block, unsigned short page, void *data, void *spare) { unsigned char tmpData[NandCommon_MAXPAGEDATASIZE]; unsigned char tmpSpare[NandCommon_MAXPAGESPARESIZE]; unsigned char error; unsigned char hamming[NandCommon_MAXSPAREECCBYTES]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(ecc)); unsigned char pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(ecc)); TRACE_DEBUG("EccNandFlash_ReadPage(B#%d:P#%d)\n\r", block, page); // Start by reading the spare and the data error = RawNandFlash_ReadPage(RAW(ecc), block, page, tmpData, tmpSpare); if (error) { TRACE_ERROR("EccNandFlash_ReadPage: Failed to read page\n\r"); return error; } // Retrieve ECC information from page and verify the data NandSpareScheme_ReadEcc(NandFlashModel_GetScheme(MODEL(ecc)), tmpSpare, hamming); error = Hamming_Verify256x(tmpData, pageDataSize, hamming); if (error && (error != Hamming_ERROR_SINGLEBIT)) { TRACE_ERROR("EccNandFlash_ReadPage: Unrecoverable data\n\r"); return NandCommon_ERROR_CORRUPTEDDATA; } // Copy data and/or spare into final buffers if (data) { memcpy(data, tmpData, pageDataSize); } if (spare) { memcpy(spare, tmpSpare, pageSpareSize); } return 0; }
//------------------------------------------------------------------------------ /// Writes the data and/or spare area of a nandflash page, after calculating an /// ECC for the data area and storing it in the spare. If no data buffer is /// provided, the ECC is read from the existing page spare. If no spare buffer /// is provided, the spare area is still written with the ECC information /// calculated on the data buffer. /// Returns 0 if successful; otherwise returns an error code. /// \param ecc Pointer to an EccNandFlash instance. /// \param block Number of the block to write in. /// \param page Number of the page to write inside the given block. /// \param data Data area buffer, can be 0. /// \param spare Spare area buffer, can be 0. //------------------------------------------------------------------------------ unsigned char EccNandFlash_WritePage( const struct EccNandFlash *ecc, unsigned short block, unsigned short page, void *data, void *spare) { unsigned char error; unsigned char tmpSpare[NandCommon_MAXPAGESPARESIZE]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(ecc)); unsigned short pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(ecc)); unsigned char hamming[NandCommon_MAXSPAREECCBYTES]; ASSERT(data || spare, "EccNandFlash_WritePage: At least one area must be written\n\r"); TRACE_DEBUG("EccNandFlash_WritePage(B#%d:P#%d)\n\r", block, page); // Compute ECC on the new data, if provided // If not provided, hamming code set to 0xFFFF.. to keep existing bytes memset(hamming, 0xFF, NandCommon_MAXSPAREECCBYTES); if (data) { // Compute hamming code on data Hamming_Compute256x(data, pageDataSize, hamming); } // Store code in spare buffer (if no buffer provided, use a temp. one) if (!spare) { spare = tmpSpare; memset(spare, 0xFF, pageSpareSize); } NandSpareScheme_WriteEcc(NandFlashModel_GetScheme(MODEL(ecc)), spare, hamming); // Perform write operation error = RawNandFlash_WritePage(RAW(ecc), block, page, data, spare); if (error) { TRACE_ERROR("EccNandFlash_WritePage: Failed to write page\n\r"); return error; } return 0; }
//------------------------------------------------------------------------------ /// Translates the given column and row address into first and other (1-4) address /// cycles. The resulting values are stored in the provided variables if they are not null. /// \param columnAddress Column address to translate. /// \param rowAddress Row address to translate. /// \param pAddressCycle0 First address cycle. /// \param pAddressCycle1234 four address cycles. //------------------------------------------------------------------------------ void NFC_TranslateAddress( const struct RawNandFlash *raw, unsigned short columnAddress, unsigned int rowAddress, unsigned int *pAddressCycle0, unsigned int *pAddressCycle1234, unsigned char useFiveAddress) { unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(raw)); unsigned int numPages = NandFlashModel_GetDeviceSizeInPages(MODEL(raw)); unsigned char numAddressCycles = 0; unsigned int addressCycle0 = 0; unsigned int addressCycle1234 = 0; // Check the data bus width of the NandFlash if (NandFlashModel_GetDataBusWidth(MODEL(raw)) == 16) { // Div 2 is because we address in word and not in byte columnAddress >>= 1; }
/** * \brief Write the data and/or spare area of a NAND Flash page, after * calculating an ECC for the data area and storing it in the spare. If no * data buffer is provided, the ECC is read from the existing page spare. If * no spare buffer is provided, the spare area is still written with the ECC * information calculated on the data buffer. * * \param ecc Pointer to an nand_flash_ecc instance. * \param block Number of block to read from. * \param page Number of page to read inside given block. * \param data Data area buffer. * \param spare Spare area buffer. * * \return 0 if successful; otherwise return the error code. */ uint32_t nand_flash_ecc_write_page(const struct nand_flash_ecc *ecc, uint16_t block, uint16_t page, uint8_t *data, uint8_t *spare) { uint32_t error; uint16_t page_data_size = nand_flash_model_get_page_data_size(MODEL(ecc)); uint8_t hamming_code[NAND_COMMON_MAX_SPARE_ECC_BYTES]; uint8_t spare_buffer[NAND_COMMON_MAX_PAGE_SPARE_SIZE]; /** * Compute ECC on the new data, if provided. If not provided, hamming * code set to 0xFFFF.. to keep existing bytes. */ memset(hamming_code, 0xFF, NAND_COMMON_MAX_SPARE_ECC_BYTES); if (data) { /* Compute hamming code on data */ hamming_compute_256x(data, page_data_size, hamming_code); } /* if no buffer provided, use a temp one */ if (!spare) { spare = spare_buffer; } memset(spare, 0xFF, NAND_COMMON_MAX_PAGE_SPARE_SIZE); nand_flash_spare_scheme_write_ecc(nand_flash_model_get_scheme(MODEL(ecc)), spare, hamming_code); /* Perform write operation */ error = nand_flash_raw_write_page(RAW(ecc), block, page, data, spare); if (error) { return error; } return 0; }
/** * \brief Read the data of a whole block on a SkipBlock nandflash. * * \param skipBlock Pointer to a SkipBlockNandFlash instance. * \param block Number of the block to read. * \param pageOffsetInBlock Number of the page to read inside the given block. * \param data Data area buffer. * \param numPages number of pages to read. * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_WritePage(). */ unsigned char SkipBlockNandFlash_ReadBlockUnaligned( const struct SkipBlockNandFlash *skipBlock, unsigned short block, unsigned short pageOffsetInBlock, unsigned short numPages, void *data ) { /* Number of pages per block*/ unsigned int numPagesPerBlock; /* Page size*/ unsigned int pageSize; /* Page index*/ unsigned short i; /* Error returned by SkipBlockNandFlash_ReadPage*/ unsigned char error = 0; /* Retrieve model information*/ pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock)); numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(MODEL(skipBlock)); for (i = pageOffsetInBlock; i < pageOffsetInBlock + numPages; i++) { error = SkipBlockNandFlash_ReadPage(skipBlock, block, i, data, 0); if (error == NandCommon_ERROR_BADBLOCK) { TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Block is BAD.\n\r"); return NandCommon_ERROR_BADBLOCK; } else if (error) { TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Cannot read page %d of block %d.\n\r", i, block); return NandCommon_ERROR_CANNOTREAD; } data = (void *) ((unsigned char *) data + pageSize); } return 0; }
/** * \brief Writes the data of a whole block on a SkipBlock nandflash. * * \param skipBlock Pointer to a SkipBlockNandFlash instance. * \param block Number of the block to write. * \param data Data area buffer. * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_WritePage(). */ uint8_t SkipBlockNandFlash_WriteBlock( const struct SkipBlockNandFlash *skipBlock, uint16_t block, void *data) { /* Number of pages per block */ uint32_t numPagesPerBlock; /* Page size */ uint32_t pageSize; /* Page index*/ uint16_t i; /* Error returned by SkipBlockNandFlash_WritePage*/ uint8_t error = 0; /* Retrieve model information*/ pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock)); numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(MODEL(skipBlock)); /* Check that the block is LIVE*/ if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) { TRACE_ERROR("SkipBlockNandFlash_WriteBlock: Block is BAD.\n\r"); return NandCommon_ERROR_BADBLOCK; } for (i = 0; i < numPagesPerBlock; i++) { error = EccNandFlash_WritePage(ECC(skipBlock), block, i, data, 0); if (error) { TRACE_ERROR("SkipBlockNandFlash_WriteBlock: Cannot write page %d of block %d.\n\r", i, block); return NandCommon_ERROR_CANNOTWRITE; } data = (void *) ((uint8_t *) data + pageSize); } return 0; }
static void prefs_build( GtkWidget *widget ) { Prefs *prefs = PREFS( widget ); GtkWidget *work; #ifdef DEBUG printf( "prefs_build: %p\n", prefs ); #endif /*DEBUG*/ /* Call all builds in superclasses. */ IWINDOW_CLASS( parent_class )->build( widget ); work = IDIALOG( prefs )->work; prefs->pwview = PREFWORKSPACEVIEW( prefworkspaceview_new() ); prefworkspaceview_set_caption_filter( prefs->pwview, prefs->caption_filter ); view_link( VIEW( prefs->pwview ), MODEL( prefs->ws ), NULL ); if( prefs->caption_filter ) { gtk_box_pack_start( GTK_BOX( work ), GTK_WIDGET( prefs->pwview ), TRUE, TRUE, 0 ); gtk_widget_show( GTK_WIDGET( prefs->pwview ) ); } else { /* No caption_filter set, so this is probably a big prefs * window. Build a scrolledwindow for the content. */ GtkWidget *window; window = gtk_scrolled_window_new( NULL, NULL ); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( window ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( window ), GTK_WIDGET( prefs->pwview ) ); gtk_viewport_set_shadow_type( GTK_VIEWPORT( GTK_BIN( window )->child ), GTK_SHADOW_NONE ); gtk_box_pack_start( GTK_BOX( work ), GTK_WIDGET( window ), TRUE, TRUE, 0 ); gtk_widget_show( GTK_WIDGET( prefs->pwview ) ); gtk_widget_show( window ); } }
/** * \brief Reads the data of a whole block on a SkipBlock nandflash. * * \param skipBlock Pointer to a SkipBlockNandFlash instance. * \param block Number of block to read page from. * \param page Number of page to read inside the given block. * \param data Data area buffer, can be 0. * \param spare Spare area buffer, can be 0. * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_ReadPage(). */ unsigned char SkipBlockNandFlash_ReadBlock( const struct SkipBlockNandFlash *skipBlock, unsigned short block, void *data) { /* Number of pages per block */ unsigned int numPagesPerBlock, pageSize; /* Page index */ unsigned short i; /* Error returned by SkipBlockNandFlash_WritePage */ unsigned char error = 0; /* Retrieve model information */ pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock)); numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(MODEL(skipBlock)); /* Check that the block is not BAD if data is requested */ if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) { TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Block is BAD.\n\r"); return NandCommon_ERROR_BADBLOCK; } /* Read all the pages of the block */ for (i = 0; i < numPagesPerBlock; i++) { error = EccNandFlash_ReadPage(ECC(skipBlock), block, i, data, 0); if (error) { TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Cannot read page %d of block %d.\n\r", i, block); return error; } data = (void *) ((unsigned char *) data + pageSize); } return 0; }
//------------------------------------------------------------------------------ /// Returns BADBLOCK if the given block of a nandflash device is bad; returns /// GOODBLOCK if the block is good; or returns a NandCommon_ERROR code. /// \param managed Pointer to a ManagedNandFlash instance. /// \param block Raw block to check. /// \param spare Pointer to allocated spare area (must be assigned) //------------------------------------------------------------------------------ static unsigned char CheckBlock( const struct ManagedNandFlash *managed, unsigned short block, unsigned char *spare) { unsigned char error; unsigned int i; unsigned char pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(managed)); ASSERT(spare, "ManagedNandFlash_CheckBlock: spare\n\r"); // Read spare area of first page of block error = RawNandFlash_ReadPage(RAW(managed), block, 0, 0, spare); if (error) { TRACE_ERROR("CheckBlock: Cannot read page #0 of block #%d\n\r", block); return error; } // Make sure it is all 0xFF for (i=0; i < pageSpareSize; i++) { if (spare[i] != 0xFF) { return BADBLOCK; } } // Read spare area of second page of block error = RawNandFlash_ReadPage(RAW(managed), block, 1, 0, spare); if (error) { TRACE_ERROR("CheckBlock: Cannot read page #1 of block #%d\n\r", block); return error; } // Make sure it is all 0xFF for (i=0; i < pageSpareSize; i++) { if (spare[i] != 0xFF) { return BADBLOCK; } } return GOODBLOCK; }
//------------------------------------------------------------------------------ /// Physically writes the status of a block inside its first page spare area. /// Returns 0 if successful; otherwise returns a NandCommon_ERROR_xx code. /// \param managed Pointer to a ManagedNandFlash instance. /// \param block Raw block number. /// \param pStatus Pointer to status data. /// \param spare Pointer to allocated spare area (must be assigned). //------------------------------------------------------------------------------ static unsigned char WriteBlockStatus( const struct ManagedNandFlash *managed, unsigned short block, struct NandBlockStatus *pStatus, unsigned char *spare) { ASSERT(spare, "ManagedNandFlash_WriteBlockStatus: spare\n\r"); memset(spare, 0xFF, NandCommon_MAXPAGESPARESIZE); NandSpareScheme_WriteExtra(NandFlashModel_GetScheme(MODEL(managed)), spare, pStatus, 4, 0); return RawNandFlash_WritePage(RAW(managed), block, 0, 0, spare); }
uint8_t SkipBlockNandFlash_CheckBlock( const struct SkipBlockNandFlash *skipBlock, uint16_t block) { #if !defined (OP_BOOTSTRAP_on) uint8_t spare[NandCommon_MAXPAGESPARESIZE]; uint8_t error; uint8_t badBlockMarker; const struct NandSpareScheme *scheme; /* Retrieve model scheme */ scheme = NandFlashModel_GetScheme(MODEL(skipBlock)); /* Read spare area of first page of block */ error = RawNandFlash_ReadPage(RAW(skipBlock), block, 0, 0, spare); if (error) { TRACE_ERROR("CheckBlock: Cannot read page #0 of block #%d\n\r", block); return error; } NandSpareScheme_ReadBadBlockMarker(scheme, spare, &badBlockMarker); if (badBlockMarker != 0xFF) { return BADBLOCK; } /* Read spare area of second page of block */ error = RawNandFlash_ReadPage(RAW(skipBlock), block, 1, 0, spare); if (error) { TRACE_ERROR("CheckBlock: Cannot read page #1 of block #%d\n\r", block); return error; } NandSpareScheme_ReadBadBlockMarker(scheme, spare, &badBlockMarker); if (badBlockMarker != 0xFF) { return BADBLOCK; } #endif return GOODBLOCK; }
/** * \brief Terminates the current write operation by copying all the missing pages from * the previous physical block. * * \param translated Pointer to a TranslatedNandFlash instance. * \return 0 if successful; otherwise returns error code */ unsigned char TranslatedNandFlash_Flush(struct TranslatedNandFlash *translated) { unsigned int i; unsigned char error; unsigned int currentPhysicalBlock; /* Check if there is a current block and a previous block*/ if ((translated->currentLogicalBlock == -1) || (translated->previousPhysicalBlock == -1)) { return 0; } TRACE_INFO("TranslatedNandFlash_Flush(PB#%d -> LB#%d)\n\r", translated->previousPhysicalBlock, translated->currentLogicalBlock); /* Copy missing pages in the current block*/ currentPhysicalBlock = MappedNandFlash_LogicalToPhysical( MAPPED(translated), translated->currentLogicalBlock); for (i=0; i < NandFlashModel_GetBlockSizeInPages(MODEL(translated)); i++) { if (PageIsClean(translated, i)) { TRACE_DEBUG("Copying back page #%d of block #%d\n\r", i, translated->previousPhysicalBlock); /* Copy page*/ error = ManagedNandFlash_CopyPage(MANAGED(translated), translated->previousPhysicalBlock, i, currentPhysicalBlock, i); if (error) { TRACE_ERROR("FinishCurrentWrite: copy page #%d\n\r", i); return error; } } } translated->currentLogicalBlock = -1; translated->previousPhysicalBlock = -1; return 0; }
//------------------------------------------------------------------------------ /// Returns 1 if a nandflash device is virgin (i.e. has never been used as a /// managed nandflash); otherwise return 0. /// \param managed Pointer to a ManagedNandFlash instance. /// \param spare Pointer to allocated spare area (must be assigned) //------------------------------------------------------------------------------ static unsigned char IsDeviceVirgin(const struct ManagedNandFlash *managed, unsigned char *spare) { struct NandBlockStatus blockStatus; const struct NandSpareScheme *scheme = NandFlashModel_GetScheme(MODEL(managed)); unsigned short baseBlock = managed->baseBlock; unsigned char badBlockMarker; unsigned char error; ASSERT(spare, "ManagedNandFlash_IsDeviceVirgin: spare\n\r"); // Read spare area of page #0 error = RawNandFlash_ReadPage(RAW(managed), baseBlock, 0, 0, spare); ASSERT(!error, "ManagedNandFlash_IsDeviceVirgin: Failed to read page #0\n\r"); // Retrieve bad block marker and block status from spare area NandSpareScheme_ReadBadBlockMarker(scheme, spare, &badBlockMarker); NandSpareScheme_ReadExtra(scheme, spare, &blockStatus, 4, 0); // Check if block is marked as bad if (badBlockMarker != 0xFF) { // Device is not virgin, since page #0 is guaranteed to be good return 0; } // If device is not virgin, then block status will be set to either // FREE, DIRTY or LIVE else if (blockStatus.status != NandBlockStatus_DEFAULT) { // Device is not virgin return 0; } return 1; }
/** * \brief Erases a block of a SkipBlock NandFlash. * * \param skipBlock Pointer to a SkipBlockNandFlash instance. * \param block Number of block to erase. * \return the RawNandFlash_EraseBlock code or NandCommon_ERROR_WRONGSTATUS. */ uint8_t SkipBlockNandFlash_EraseBlock( struct SkipBlockNandFlash *skipBlock, uint16_t block, uint32_t eraseType) { uint8_t error; const struct NandSpareScheme *scheme; uint8_t spare[NandCommon_MAXPAGESPARESIZE]; // TRACE_INFO("SkipBlockNandFlash_EraseBlock(%d)\n\r", block); if (eraseType != SCRUB_ERASE) { /* Check block status */ if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) { TRACE_INFO("SkipBlockNandFlash_EraseBlock: Block is BAD\n\r"); return NandCommon_ERROR_BADBLOCK; } } /* Erase block */ error = RawNandFlash_EraseBlock(RAW(skipBlock), block); if (error) { /* Try to mark the block as BAD */ TRACE_ERROR("SkipBlockNandFlash_EraseBlock: Cannot erase block, try to mark it BAD\n\r"); /* Retrieve model scheme */ scheme = NandFlashModel_GetScheme(MODEL(skipBlock)); memset(spare, 0xFF, NandCommon_MAXPAGESPARESIZE); NandSpareScheme_WriteBadBlockMarker(scheme, spare, NandBlockStatus_BAD_skip); return RawNandFlash_WritePage(RAW(skipBlock), block, 0, 0, spare); } return 0; }
/** * This function is called when the control program is loaded to zenom. * Use this function to register control parameters, to register log variables * and to initialize control parameters. * * @return Return non-zero to indicate an error. */ int ZenomMatlab::initialize() { int paramIdx, sigIdx; int nBlockParams, nSignals; const char* status; // İsmi gözükmeyen parametrelerin sayısını tutar. unknown_param_counter = 0; /* Here is where Q8 dirver is loaded to kernel space */ //system(STR(sudo insmod DQ8)); fd = rt_dev_open(DEV_NAME, O_RDWR); if(fd < 0) fprintf(stderr, "target:Q8 device open error!\n"); init_xenomai(); rtM = MODEL(); if (rtmGetErrorStatus(rtM) != NULL) { (void)fprintf(stderr,"Error during model registration: %s\n", rtmGetErrorStatus(rtM)); exit(EXIT_FAILURE); } MdlInitializeSizes(); MdlInitializeSampleTimes(); status = rt_SimInitTimingEngine(rtmGetNumSampleTimes(rtM), rtmGetStepSize(rtM), rtmGetSampleTimePtr(rtM), rtmGetOffsetTimePtr(rtM), rtmGetSampleHitPtr(rtM), rtmGetSampleTimeTaskIDPtr(rtM), rtmGetTStart(rtM), &rtmGetSimTimeStep(rtM), &rtmGetTimingData(rtM)); if (status != NULL) { (void)fprintf(stderr, "Failed to initialize sample time engine: %s\n", status); exit(EXIT_FAILURE); } rt_CreateIntegrationData(rtM); mmi = &(rtmGetDataMapInfo(rtM).mmi); if (mmi!=NULL){ //exception here } bp = rtwCAPI_GetBlockParameters(mmi); sig = rtwCAPI_GetSignals(mmi); nBlockParams = rtwCAPI_GetNumBlockParameters(mmi); nSignals = rtwCAPI_GetNumSignals(mmi); xrtpi = new XrtTargetParamInfo[nBlockParams]; xtsi = new XrtTargetSignalInfo[nSignals]; /** Get parameter and register */ Xrt_GetParameterInfo(mmi); Xrt_GetSignalInfo(mmi); /**************** ZENOM PART ***************/ for(paramIdx = 0; paramIdx < rtwCAPI_GetNumBlockParameters(mmi); paramIdx++){ std::string paramName(xrtpi[paramIdx].paramName); std::string blockName(xrtpi[paramIdx].blockName); if(paramName.empty()){ paramName = std::string("unknownBlock"); } for (std::size_t found = paramName.find_first_of(" "); found != std::string::npos ; found = paramName.find_first_of(" ")) { paramName.erase (found); } for (std::size_t found = blockName.find_first_of(" "); found != std::string::npos ; found = blockName.find_first_of(" ")) { blockName.erase (found); } paramName = blockName + "-" + paramName; registerControlVariable( xrtpi[paramIdx].dataValue, paramName, xrtpi[paramIdx].numRows, xrtpi[paramIdx].numColumns ); } for (sigIdx = 0; sigIdx < rtwCAPI_GetNumSignals(mmi); ++sigIdx){ std::string sigName(xtsi[sigIdx].signalName); if(sigName.empty()){ sigName = std::string("unknownSignal"); sigName += unknown_param_counter; } for (std::size_t found = sigName.find_first_of(" "); found != std::string::npos ; found = sigName.find_first_of(" ")) { sigName.erase (found); } registerLogVariable(xtsi[sigIdx].dataValue, sigName, xtsi[sigIdx].numRows, xtsi[sigIdx].numColumns); } setFrequency( (double)rtmGetStepSize(rtM) ); setDuration ( (double)rtmGetTFinal(rtM) ); fprintf(stderr, "init done!"); return 0; }
/** * \brief Scans a mapped nandflash to find an existing logical block mapping. If a * block contains the mapping, its index is stored in the provided variable (if * pointer is not 0). * * \param mapped Pointer to a MappedNandFlash instance. * \param logicalMappingBlock Pointer to a variable for storing the block number. * \return 0 if mapping has been found; otherwise returns * NandCommon_ERROR_NOMAPPING if no mapping exists, or another NandCommon_ERROR_xxx code. */ static unsigned char FindLogicalMappingBlock( const struct MappedNandFlash *mapped, signed short *logicalMappingBlock) { unsigned short block; unsigned char found; unsigned short numBlocks = ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)); unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped)); unsigned char error; unsigned char data[NandCommon_MAXPAGEDATASIZE]; unsigned int i; //TRACE_INFO("FindLogicalMappingBlock ~%d\n\r", numBlocks); /* Search each LIVE block */ found = 0; block = 0; while (!found && (block < numBlocks)) { /* Check that block is LIVE*/ if (MANAGED(mapped)->blockStatuses[block].status == NandBlockStatus_LIVE) { /* Read block*/ TRACE_INFO("Checking LIVE block #%d\n\r", block); error = ManagedNandFlash_ReadPage(MANAGED(mapped), block, 0, data, 0); if (!error) { /* Compare data with logical mapping pattern*/ i = 0; found = 1; while ((i < pageDataSize) && found) { if (data[i] != PATTERN(i)) { found = 0; } i++; } /* If this is the mapping, stop looking*/ if (found) { TRACE_WARNING_WP("-I- Logical mapping in block #%d\n\r", block); if (logicalMappingBlock) { *logicalMappingBlock = block; } return 0; } } else if (error != NandCommon_ERROR_WRONGSTATUS) { TRACE_ERROR( "FindLogicalMappingBlock: Failed to scan block #%d\n\r", block); return error; } } block++; } TRACE_WARNING("No logical mapping found in device\n\r"); return NandCommon_ERROR_NOMAPPING; }
/** * \brief Saves the logical mapping on a FREE, unmapped physical block. Allocates the * new block, releases the previous one (if any) and save the mapping. * * \param mapped Pointer to a MappedNandFlash instance. * \param physicalBlock Physical block number. * \return 0 if successful; otherwise, returns NandCommon_ERROR_WRONGSTATUS * if the block is not LIVE, or a NandCommon_ERROR code. */ unsigned char MappedNandFlash_SaveLogicalMapping( struct MappedNandFlash *mapped, unsigned short physicalBlock) { unsigned char error; unsigned char data[NandCommon_MAXPAGEDATASIZE]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped)); /*unsigned short numBlocks = ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped));*/ unsigned int i; unsigned int remainingSize; unsigned char *currentBuffer; unsigned short currentPage; unsigned int writeSize; signed short previousPhysicalBlock; TRACE_INFO("MappedNandFlash_SaveLogicalMapping(B#%d)\n\r", physicalBlock); /* If mapping has not been modified, do nothing*/ if (!mapped->mappingModified) { return 0; } /* Allocate new block*/ error = ManagedNandFlash_AllocateBlock(MANAGED(mapped), physicalBlock); if (error) { return error; } /* Save mapping*/ previousPhysicalBlock = mapped->logicalMappingBlock; mapped->logicalMappingBlock = physicalBlock; /* Save actual mapping in pages #1-#XXX*/ currentBuffer = (unsigned char *) mapped->logicalMapping; remainingSize = sizeof(mapped->logicalMapping); currentPage = 1; while (remainingSize > 0) { writeSize = min(remainingSize, pageDataSize); memset(data, 0xFF, pageDataSize); memcpy(data, currentBuffer, writeSize); error = ManagedNandFlash_WritePage(MANAGED(mapped), physicalBlock, currentPage, data, 0); if (error) { TRACE_ERROR( "MappedNandFlash_SaveLogicalMapping: Failed to write mapping\n\r"); return error; } currentBuffer += writeSize; remainingSize -= writeSize; currentPage++; } /* Mark page #0 of block with a distinguishible pattern, so the mapping can be retrieved at startup*/ for (i=0; i < pageDataSize; i++) { data[i] = PATTERN(i); } error = ManagedNandFlash_WritePage(MANAGED(mapped), physicalBlock, 0, data, 0); if (error) { TRACE_ERROR( "MappedNandFlash_SaveLogicalMapping: Failed to write pattern\n\r"); return error; } /* Mapping is not modified anymore*/ mapped->mappingModified = 0; /* Release previous block (if any)*/ if (previousPhysicalBlock != -1) { TRACE_DEBUG("Previous physical block was #%d\n\r", previousPhysicalBlock); error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped), previousPhysicalBlock); if (error) { return error; } } TRACE_INFO("Mapping saved on block #%d\n\r", physicalBlock); return 0; }
/** * \brief Loads the logical mapping contained in the given physical block. * block contains the mapping, its index is stored in the provided variable (if * pointer is not 0). * * \param mapped Pointer to a MappedNandFlash instance. * \param physicalBlock Physical block number. * \return 0 if successful; otherwise, returns a NandCommon_ERROR code. */ static unsigned char LoadLogicalMapping( struct MappedNandFlash *mapped, unsigned short physicalBlock) { unsigned char error; unsigned char data[NandCommon_MAXPAGEDATASIZE]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped)); unsigned short numBlocks = ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)); unsigned int remainingSize; unsigned char *currentBuffer; unsigned short currentPage; unsigned int readSize; unsigned int i; unsigned char status; signed short logicalBlock; /*signed short firstBlock, lastBlock;*/ TRACE_INFO("LoadLogicalMapping(B#%d)\n\r", physicalBlock); /* Load mapping from pages #1 - #XXX of block*/ currentBuffer = (unsigned char *) mapped->logicalMapping; remainingSize = sizeof(mapped->logicalMapping); currentPage = 1; while (remainingSize > 0) { /* Read page*/ readSize = min(remainingSize, pageDataSize); error = ManagedNandFlash_ReadPage(MANAGED(mapped), physicalBlock, currentPage, data, 0); if (error) { TRACE_ERROR( "LoadLogicalMapping: Failed to load mapping\n\r"); return error; } /* Copy page info*/ memcpy(currentBuffer, data, readSize); currentBuffer += readSize; remainingSize -= readSize; currentPage++; } /* Store mapping block index*/ mapped->logicalMappingBlock = physicalBlock; /* Power-loss recovery*/ for (i=0; i < numBlocks; i++) { /* Check that this is not the logical mapping block*/ if (i != physicalBlock) { status = mapped->managed.blockStatuses[i].status; logicalBlock = MappedNandFlash_PhysicalToLogical(mapped, i); /* Block is LIVE*/ if (status == NandBlockStatus_LIVE) { /* Block is not mapped -> release it*/ if (logicalBlock == -1) { TRACE_WARNING_WP("-I- Release unmapped LIVE #%d\n\r", i); ManagedNandFlash_ReleaseBlock(MANAGED(mapped), i); } } /* Block is DIRTY*/ else if (status == NandBlockStatus_DIRTY) { /* Block is mapped -> fake it as live*/ if (logicalBlock != -1) { TRACE_WARNING_WP("-I- Mark mapped DIRTY #%d -> LIVE\n\r", i); mapped->managed.blockStatuses[i].status = NandBlockStatus_LIVE; } } /* Block is FREE or BAD*/ else { /* Block is mapped -> remove it from mapping*/ if (logicalBlock != -1) { TRACE_WARNING_WP("-I- Unmap FREE or BAD #%d\n\r", i); mapped->logicalMapping[logicalBlock] = -1; } } } } TRACE_WARNING_WP("-I- Mapping loaded from block #%d\n\r", physicalBlock); return 0; }