Hi Sascha, On 22-11-01, Sascha Hauer wrote: > The FCB on NAND has a special page layout and thus can't be read with > the normal MTD driver. Add a fcb command for printing information about > the installed FCB on the console. > > Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> > --- > commands/Kconfig | 9 ++ > common/imx-bbu-nand-fcb.c | 195 ++++++++++++++++++++++++++++---------- > 2 files changed, 153 insertions(+), 51 deletions(-) > > diff --git a/commands/Kconfig b/commands/Kconfig > index 9894ecb9aa..cab72b9226 100644 > --- a/commands/Kconfig > +++ b/commands/Kconfig > @@ -326,6 +326,15 @@ config CMD_SLICE > command can be used to print informations about slices and also to manipulate > them on the command line for debugging purposes. > > +config CMD_FCB > + depends on BAREBOX_UPDATE_IMX_NAND_FCB > + tristate > + prompt "fcb" > + help > + Several i.MX SoCs booting from NAND flash need a so called Flash Control Block > + at the beginning of the NAND device. The fcb command prints information about > + the FCB. > + > # end Information commands > endmenu > > diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c > index 05bee912e4..39425c7fc3 100644 > --- a/common/imx-bbu-nand-fcb.c > +++ b/common/imx-bbu-nand-fcb.c > @@ -14,6 +14,8 @@ > #include <linux/sizes.h> > #include <bbu.h> > #include <fs.h> > +#include <command.h> > +#include <complete.h> > #include <linux/mtd/mtd-abi.h> > #include <linux/mtd/nand_mxs.h> > #include <linux/mtd/mtd.h> > @@ -284,57 +286,57 @@ static __maybe_unused void dump_fcb(void *buf) > { > struct fcb_block *fcb = buf; > > - pr_debug("Checksum: 0x%08x\n", fcb->Checksum); > - pr_debug("FingerPrint: 0x%08x\n", fcb->FingerPrint); > - pr_debug("Version: 0x%08x\n", fcb->Version); > - pr_debug("DataSetup: 0x%02x\n", fcb->DataSetup); > - pr_debug("DataHold: 0x%02x\n", fcb->DataHold); > - pr_debug("AddressSetup: 0x%02x\n", fcb->AddressSetup); > - pr_debug("DSAMPLE_TIME: 0x%02x\n", fcb->DSAMPLE_TIME); > - pr_debug("NandTimingState: 0x%02x\n", fcb->NandTimingState); > - pr_debug("REA: 0x%02x\n", fcb->REA); > - pr_debug("RLOH: 0x%02x\n", fcb->RLOH); > - pr_debug("RHOH: 0x%02x\n", fcb->RHOH); > - pr_debug("PageDataSize: 0x%08x\n", fcb->PageDataSize); > - pr_debug("TotalPageSize: 0x%08x\n", fcb->TotalPageSize); > - pr_debug("SectorsPerBlock: 0x%08x\n", fcb->SectorsPerBlock); > - pr_debug("NumberOfNANDs: 0x%08x\n", fcb->NumberOfNANDs); > - pr_debug("TotalInternalDie: 0x%08x\n", fcb->TotalInternalDie); > - pr_debug("CellType: 0x%08x\n", fcb->CellType); > - pr_debug("EccBlockNEccType: 0x%08x\n", fcb->EccBlockNEccType); > - pr_debug("EccBlock0Size: 0x%08x\n", fcb->EccBlock0Size); > - pr_debug("EccBlockNSize: 0x%08x\n", fcb->EccBlockNSize); > - pr_debug("EccBlock0EccType: 0x%08x\n", fcb->EccBlock0EccType); > - pr_debug("MetadataBytes: 0x%08x\n", fcb->MetadataBytes); > - pr_debug("NumEccBlocksPerPage: 0x%08x\n", fcb->NumEccBlocksPerPage); > - pr_debug("EccBlockNEccLevelSDK: 0x%08x\n", fcb->EccBlockNEccLevelSDK); > - pr_debug("EccBlock0SizeSDK: 0x%08x\n", fcb->EccBlock0SizeSDK); > - pr_debug("EccBlockNSizeSDK: 0x%08x\n", fcb->EccBlockNSizeSDK); > - pr_debug("EccBlock0EccLevelSDK: 0x%08x\n", fcb->EccBlock0EccLevelSDK); > - pr_debug("NumEccBlocksPerPageSDK: 0x%08x\n", fcb->NumEccBlocksPerPageSDK); > - pr_debug("MetadataBytesSDK: 0x%08x\n", fcb->MetadataBytesSDK); > - pr_debug("EraseThreshold: 0x%08x\n", fcb->EraseThreshold); > - pr_debug("BootPatch: 0x%08x\n", fcb->BootPatch); > - pr_debug("PatchSectors: 0x%08x\n", fcb->PatchSectors); > - pr_debug("Firmware1_startingPage: 0x%08x\n", fcb->Firmware1_startingPage); > - pr_debug("Firmware2_startingPage: 0x%08x\n", fcb->Firmware2_startingPage); > - pr_debug("PagesInFirmware1: 0x%08x\n", fcb->PagesInFirmware1); > - pr_debug("PagesInFirmware2: 0x%08x\n", fcb->PagesInFirmware2); > - pr_debug("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress); > - pr_debug("BadBlockMarkerByte: 0x%08x\n", fcb->BadBlockMarkerByte); > - pr_debug("BadBlockMarkerStartBit: 0x%08x\n", fcb->BadBlockMarkerStartBit); > - pr_debug("BBMarkerPhysicalOffset: 0x%08x\n", fcb->BBMarkerPhysicalOffset); > - pr_debug("BCHType: 0x%08x\n", fcb->BCHType); > - pr_debug("TMTiming2_ReadLatency: 0x%08x\n", fcb->TMTiming2_ReadLatency); > - pr_debug("TMTiming2_PreambleDelay: 0x%08x\n", fcb->TMTiming2_PreambleDelay); > - pr_debug("TMTiming2_CEDelay: 0x%08x\n", fcb->TMTiming2_CEDelay); > - pr_debug("TMTiming2_PostambleDelay: 0x%08x\n", fcb->TMTiming2_PostambleDelay); > - pr_debug("TMTiming2_CmdAddPause: 0x%08x\n", fcb->TMTiming2_CmdAddPause); > - pr_debug("TMTiming2_DataPause: 0x%08x\n", fcb->TMTiming2_DataPause); > - pr_debug("TMSpeed: 0x%08x\n", fcb->TMSpeed); > - pr_debug("TMTiming1_BusyTimeout: 0x%08x\n", fcb->TMTiming1_BusyTimeout); > - pr_debug("DISBBM: 0x%08x\n", fcb->DISBBM); > - pr_debug("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData); > + printf("Checksum: 0x%08x\n", fcb->Checksum); > + printf("FingerPrint: 0x%08x\n", fcb->FingerPrint); > + printf("Version: 0x%08x\n", fcb->Version); > + printf("DataSetup: 0x%02x\n", fcb->DataSetup); > + printf("DataHold: 0x%02x\n", fcb->DataHold); > + printf("AddressSetup: 0x%02x\n", fcb->AddressSetup); > + printf("DSAMPLE_TIME: 0x%02x\n", fcb->DSAMPLE_TIME); > + printf("NandTimingState: 0x%02x\n", fcb->NandTimingState); > + printf("REA: 0x%02x\n", fcb->REA); > + printf("RLOH: 0x%02x\n", fcb->RLOH); > + printf("RHOH: 0x%02x\n", fcb->RHOH); > + printf("PageDataSize: 0x%08x\n", fcb->PageDataSize); > + printf("TotalPageSize: 0x%08x\n", fcb->TotalPageSize); > + printf("SectorsPerBlock: 0x%08x\n", fcb->SectorsPerBlock); > + printf("NumberOfNANDs: 0x%08x\n", fcb->NumberOfNANDs); > + printf("TotalInternalDie: 0x%08x\n", fcb->TotalInternalDie); > + printf("CellType: 0x%08x\n", fcb->CellType); > + printf("EccBlockNEccType: 0x%08x\n", fcb->EccBlockNEccType); > + printf("EccBlock0Size: 0x%08x\n", fcb->EccBlock0Size); > + printf("EccBlockNSize: 0x%08x\n", fcb->EccBlockNSize); > + printf("EccBlock0EccType: 0x%08x\n", fcb->EccBlock0EccType); > + printf("MetadataBytes: 0x%08x\n", fcb->MetadataBytes); > + printf("NumEccBlocksPerPage: 0x%08x\n", fcb->NumEccBlocksPerPage); > + printf("EccBlockNEccLevelSDK: 0x%08x\n", fcb->EccBlockNEccLevelSDK); > + printf("EccBlock0SizeSDK: 0x%08x\n", fcb->EccBlock0SizeSDK); > + printf("EccBlockNSizeSDK: 0x%08x\n", fcb->EccBlockNSizeSDK); > + printf("EccBlock0EccLevelSDK: 0x%08x\n", fcb->EccBlock0EccLevelSDK); > + printf("NumEccBlocksPerPageSDK: 0x%08x\n", fcb->NumEccBlocksPerPageSDK); > + printf("MetadataBytesSDK: 0x%08x\n", fcb->MetadataBytesSDK); > + printf("EraseThreshold: 0x%08x\n", fcb->EraseThreshold); > + printf("BootPatch: 0x%08x\n", fcb->BootPatch); > + printf("PatchSectors: 0x%08x\n", fcb->PatchSectors); > + printf("Firmware1_startingPage: 0x%08x\n", fcb->Firmware1_startingPage); > + printf("Firmware2_startingPage: 0x%08x\n", fcb->Firmware2_startingPage); > + printf("PagesInFirmware1: 0x%08x\n", fcb->PagesInFirmware1); > + printf("PagesInFirmware2: 0x%08x\n", fcb->PagesInFirmware2); > + printf("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress); > + printf("BadBlockMarkerByte: 0x%08x\n", fcb->BadBlockMarkerByte); > + printf("BadBlockMarkerStartBit: 0x%08x\n", fcb->BadBlockMarkerStartBit); > + printf("BBMarkerPhysicalOffset: 0x%08x\n", fcb->BBMarkerPhysicalOffset); > + printf("BCHType: 0x%08x\n", fcb->BCHType); > + printf("TMTiming2_ReadLatency: 0x%08x\n", fcb->TMTiming2_ReadLatency); > + printf("TMTiming2_PreambleDelay: 0x%08x\n", fcb->TMTiming2_PreambleDelay); > + printf("TMTiming2_CEDelay: 0x%08x\n", fcb->TMTiming2_CEDelay); > + printf("TMTiming2_PostambleDelay: 0x%08x\n", fcb->TMTiming2_PostambleDelay); > + printf("TMTiming2_CmdAddPause: 0x%08x\n", fcb->TMTiming2_CmdAddPause); > + printf("TMTiming2_DataPause: 0x%08x\n", fcb->TMTiming2_DataPause); > + printf("TMSpeed: 0x%08x\n", fcb->TMSpeed); > + printf("TMTiming1_BusyTimeout: 0x%08x\n", fcb->TMTiming1_BusyTimeout); > + printf("DISBBM: 0x%08x\n", fcb->DISBBM); > + printf("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData); > } > > static __maybe_unused ssize_t raw_read_page(struct mtd_info *mtd, void *dst, loff_t offset) > @@ -1625,3 +1627,94 @@ int imx7_bbu_nand_register_handler(const char *name, unsigned long flags) > return ret; > } > #endif > + > +static void dump_fcb_n(struct fcb_block **fcbs, int n) > +{ > + int i; > + > + if (!n || !fcbs[n]) > + goto skip_compare; > + > + for (i = 0; i < n; i++) { > + if (!fcbs[i] || !fcbs[n]) > + continue; > + > + if (!memcmp(fcbs[i], fcbs[n], sizeof(struct fcb_block))) { > + printf("FCB block#%d: same as FCB block#%d\n", n, i); > + return; > + } > + } > + > +skip_compare: > + if (fcbs[n]) { > + printf("FCB block#%d:\n", n); > + dump_fcb(fcbs[n]); > + } else { > + printf("FCB block#%d: NULL\n", n); > + } > +} > + > +#ifdef CONFIG_ARCH_IMX28 Why this #ifdef? Can't we do this by cpu_is_mx28()? Regards, Marco > +static int fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb) > +{ > + return fcb_read_hamming_13_8(mtd, block, retfcb); > +} > +#else > +static int fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb) > +{ > + if (cpu_is_mx7()) > + return imx7_fcb_read(mtd, block, retfcb); > + else if (fcb_is_bch_encoded()) > + return fcb_read_bch(mtd, block, retfcb); > + else > + return fcb_read_hamming_13_8(mtd, block, retfcb); > +} > +#endif > + > +static int cmd_fcb(int argc, char *argv[]) > +{ > + struct cdev *cdev; > + struct mtd_info *mtd; > + struct fcb_block *fcb[4] = {}; > + int i, ret; > + > + cdev = cdev_open_by_name("nand0", O_RDONLY); > + if (!cdev) { > + printf("Cannot open nand0\n"); > + return COMMAND_ERROR; > + } > + > + mtd = cdev->mtd; > + if (!mtd) { > + ret = COMMAND_ERROR; > + goto out; > + } > + > + for (i = 0; i < 4; i++) > + fcb_read(mtd, i, &fcb[i]); > + > + for (i = 0; i < 4; i++) > + dump_fcb_n(fcb, i); > + > + for (i = 0; i < 4; i++) > + free(fcb[i]); > + > + ret = 0; > + > +out: > + cdev_close(cdev); > + > + return ret; > +} > + > +BAREBOX_CMD_HELP_START(fcb) > +BAREBOX_CMD_HELP_TEXT("Dump FCB as found on /dev/nand0") > +BAREBOX_CMD_HELP_END > + > +BAREBOX_CMD_START(fcb) > + .cmd = cmd_fcb, > + BAREBOX_CMD_DESC("Dump Flash Control Block (FCB)") > + BAREBOX_CMD_GROUP(CMD_GRP_MISC) > + BAREBOX_CMD_HELP(cmd_fcb_help) > + BAREBOX_CMD_COMPLETE(empty_complete) > +BAREBOX_CMD_END > -- > 2.30.2 > > >