⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btflash.c

📁 strongarm的bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
  0x01e80000,   0x01ec0000,   0x01f00000,   0x01f40000,   0x01f80000,   0x01fc0000,   0x02000000 /* guard sector */};static int intelFlashReset(void);static int intelFlashProgramBlock(unsigned long flashAddress, unsigned long *values, int nbytes);static int intelFlashProgramWord(unsigned long flashAddress, unsigned long value);static int intelFlashEraseChip(void);static int intelFlashEraseSector(unsigned long sectorAddress);static int intelFlashEraseRange(unsigned long start, unsigned long len);static int intelFlashProtectRange(unsigned long start, unsigned long len, int protect);static FlashAlgorithm intelFlashAlgorithm = {   intelFlashReset,   intelFlashProgramWord,   intelFlashProgramBlock,   intelFlashEraseChip,   intelFlashEraseSector,   intelFlashEraseRange,   intelFlashProtectRange};static FlashDescriptor flashDescriptor_28F128J3A = {   "28F128J3A",    0x89, 0x18,    &intelFlashAlgorithm,   sizeof(flashSectors_28F128J3A)/sizeof(dword) - 1, flashSectors_28F128J3A,   { "bootldr",   0x00000000, 0x00040000, LFR_PATCH_BOOTLDR },   { "params",    0x000c0000, 0x00040000, 0 },   { "kernel",    0x00040000, 0x00080000, LFR_KERNEL },   { "ramdisk",   0x00100000, 0x00700000, LFR_SIZE_PREFIX },   { "usercode",  0x00100000, 0x00700000, 0 }, /* for flash cramfs */   { "altkernel", 0x00900000, 0x01100000, LFR_KERNEL },   { "debugger",  0x00900000, 0x01100000, 0 }};#endif /* CONFIG_INTEL_FLASH */static FlashDescriptor *flashDescriptors[] = {#ifdef CONFIG_AMD_FLASH   &flashDescriptor_Am29LV160BB,   &flashDescriptor_Am29DL323CT,   &flashDescriptor_Am29DL323CB,#endif /* CONFIG_AMD_FLASH */#ifdef CONFIG_BITSY   &flashDescriptor_28F128J3A,#endif /* CONFIG_BITSY */   NULL};long flash_size = 0;long flash_address_mask = -1;int nsectors = 0;unsigned long *flashSectors = NULL;FlashDescriptor *flashDescriptor = NULL;static int checkFlashDescriptor(const char *where){   if (flashDescriptor == NULL) {      putstr("No flash descriptor: "); putstr(where); putstr("\r\n");      return -1;   } else {      return 0;   }}int resetFlash (){   if (!checkFlashDescriptor("reset flash")) {      return flashDescriptor->algorithm->reset();   } else {      return 1;   }}/* * Programs value at flashAddress * Sectors must be erased before they can be programmed. */int programFlashWord(unsigned long flashAddress, unsigned long value){   if (!checkFlashDescriptor("program flash word")) {      return flashDescriptor->algorithm->programWord(flashAddress, value);   } else {      return 1;   }}/* * Programs block of values starting at flashAddress * Sectors must be erased before they can be programmed. */int programFlashBlock(unsigned long flashAddress, unsigned long *values, int nbytes){   if (!checkFlashDescriptor("program flash word")) {      return flashDescriptor->algorithm->programBlock(flashAddress, values, nbytes);   } else {      return 1;   }}int eraseFlashChip (){   if (!checkFlashDescriptor("erase flash chip")) {      return flashDescriptor->algorithm->eraseChip();   } else {      return 1;   }}/* sectorAddress must be a valid start of sector address. sectors   must be erased before they can be programmed! */int eraseFlashSector (unsigned long sectorAddress){   if (!checkFlashDescriptor("erase flash sector")) {      return flashDescriptor->algorithm->eraseSector(sectorAddress);   } else {      return 1;   }}int eraseFlashRange(unsigned long startAddress, unsigned long len){   if (!checkFlashDescriptor("erase flash range")) {      return flashDescriptor->algorithm->eraseRange(startAddress, len);   } else {      return 1;   }}int protectFlashRange(unsigned long startAddress, unsigned long len, int protect){   if (!checkFlashDescriptor("erase flash range")) {      return flashDescriptor->algorithm->protectRange(startAddress, len, protect);   } else {      return 1;   }}unsigned long queryFlash(unsigned long flashWordAddress){  /* there's a reason why we don't shift flashWordOffset by 2   * here... we want the values we pass to queryFlash match the values on pages 15-17 of the spec.   */   unsigned long result;   unsigned long flashWordOffset = flashWordAddress&flash_address_mask;   /* put flash in query mode */   flashword[0x55] = doubleword(0x98);   result = flashword[flashWordOffset];   /* reset flash */   flashword[0x55] = doubleword(0xFF);   return result;}static FlashAlgorithm *flashAlgorithm = NULL;int updateFlashAlgorithm(){  int algorithm = queryFlash(0x13) & 0xFF;  switch (algorithm) {#ifdef CONFIG_INTEL_FLASH  case 1:    flashAlgorithm = &intelFlashAlgorithm;    break;#endif#ifdef CONFIG_AMD_FLASH  case 2:    flashAlgorithm = &amdFlashAlgorithm;    break;#endif  default:    putLabeledWord("No flash algorithm known for CFI vendorID=", algorithm);  }  return algorithm;}unsigned long queryFlashID(unsigned long flashWordAddress){   unsigned long result;   unsigned long flashWordOffset = (flashWordAddress&flash_address_mask);   int algorithm = queryFlash(0x13) & 0xFF;   switch (algorithm) {   case 1:     /* reset flash -- Intel */     flashword[0x55] = doubleword(0xFF);     /* put flash in query mode */     flashword[0x555] = doubleword(0x90);     break;   case 2:     /* reset flash -- AMD */     flashword[0x55] = doubleword(0xF0);     /* put flash in query mode */     flashword[0x555] = doubleword(0xAA);     flashword[0x2AA] = doubleword(0x55);     flashword[0x555] = doubleword(0x90);     break;   }   /* read autoselect word */   result = flashword[flashWordOffset];   switch (algorithm) {   case 1:     /* reset flash -- Intel */     flashword[0x55] = doubleword(0xFF);     break;   case 2:     /* reset flash -- AMD */     flashword[0x55] = doubleword(0xF0);     break;   }   return result;}unsigned long queryFlashSecurity(unsigned long flashWordAddress){  /* there's a reason why we don't shift flashWordOffset by 2   * here... we want the values we pass to queryFlash match the values on pages 15-17 of the spec.   */   unsigned long result;   unsigned long flashWordOffset = (flashWordAddress&flash_address_mask);   /* reset flash */   flashword[0x555] = doubleword(0xF0);   flashword[0x555] = doubleword(0xF0);   /* enter SecSi Sector Region */   flashword[0x555] = doubleword(0xAA);   flashword[0x2AA] = doubleword(0x55);   flashword[0x555] = doubleword(0x88);   /* read word from SecSi region */   result = flashword[flashWordOffset];   /* exit region */   flashword[0x555] = doubleword(0xAA);   flashword[0x2AA] = doubleword(0x55);   flashword[0x555] = doubleword(0x90);   flashword[0x000] = doubleword(0x00);   return result;}#ifdef CONFIG_AMD_FLASHint amdFlashReset (){   /* send flash the reset command */   flashword[0x55] = doubleword(0xF0);   return 0;}/* * Programs value at flashAddress * Sectors must be erased before they can be programmed. */static int amdFlashProgramWord(unsigned long flashAddress, unsigned long value){   unsigned long flashWordOffset = (flashAddress&flash_address_mask) >> 2;   long timeout = FLASH_TIMEOUT;   unsigned long flashContents = flashword[flashWordOffset];   unsigned long oldFlashContents;   unsigned long hivalue = (value >> 16) & 0xFFFFl;   unsigned long lovalue = (value >> 0) & 0xFFFFl;   /* see if we can program the value without erasing */   if ((flashContents & value) != value) {      putstr("the flash sector needs to be erased first!\r\n");      putLabeledWord("  flashAddress=", flashAddress);      putLabeledWord("  flashWordOffset=", flashWordOffset);      putLabeledWord("  &flashword[flashWordOffset]=", 		     (dword)&flashword[flashWordOffset]);      putLabeledWord("  flashContents=", flashContents);      putLabeledWord("          value=", value);   }      /* send flash the program word command */   flashword[0x555] = doubleword(0xAA);   flashword[0x2AA] = doubleword(0x55);   flashword[0x555] = doubleword(0xA0);   flashword[flashWordOffset] = value;   /* now wait for it to be programmed */   while (((flashContents = flashword[flashWordOffset]) != value) &&	  (timeout > 0)) {      unsigned long hiword = (flashContents >> 16) & 0xFFFFl;      unsigned long loword = (flashContents >> 0) & 0xFFFFl;      if (0 && (hiword != hivalue) && (hiword & (1 << 5))) {         /* programming upper bank of flash timed out */         putstr("Upper bank of flash timed out!!");	 timeout = 0;         break;      }      if (0 && (loword != lovalue) && (loword & (1 << 5))) {         /* programming upper bank of flash timed out */         putstr("Lower bank of flash timed out!!");	 timeout = 0;         break;      }      oldFlashContents = flashContents;      timeout--;   }   if (timeout <= 0) {      putstr("programFlashWord timeout\r\n");      putLabeledWord("  flashAddress=", flashAddress);      putLabeledWord("  value=", value);      putLabeledWord("  flashContents=", flashContents);      putLabeledWord("  oldFlashContents=", oldFlashContents);      return(-1);   }   return 0;}static int amdFlashProgramBlock(unsigned long flashAddress, unsigned long *values, int nbytes){   int nwords = nbytes >> 2;   int result = 0;   int i;   for (i = 0; i < nwords; i++) {      result |= amdFlashProgramWord(flashAddress + (i*4), values[i]);      if (result)         break;   }   return result;}int amdFlashEraseChip (){   int i;   long timeout = FLASH_TIMEOUT;   unsigned long flashWordOffset = 0;   unsigned long flashContents;   unsigned long oldFlashContents;   const unsigned long hivalue = 0xFFFFl; /* when chip is erased, this is what we should read */   const unsigned long lovalue = 0xFFFFl; /* when chip is erased, this is what we should read */      flashword[0x555] = doubleword(0xAA);   flashword[0x2AA] = doubleword(0x55);   flashword[0x555] = doubleword(0x80);   flashword[0x555] = doubleword(0xAA);   flashword[0x2AA] = doubleword(0x55);   flashword[0x555] = doubleword(0x10);   while (((flashContents = flashword[flashWordOffset]) != 0xFFFFFFFFL) &&          (timeout > 0)) {      unsigned long hiword = (flashContents >> 16) & 0xFFFFl;      unsigned long loword = (flashContents >> 0) & 0xFFFFl;      if (0 && (hiword != hivalue) && (hiword & (1 << 5))) {         /* programming upper bank of flash timed out */         putstr("Upper bank of flash timed out!!");         break;      }      if (0 && (loword != lovalue) && (loword & (1 << 5))) {         /* programming upper bank of flash timed out */         putstr("Lower bank of flash timed out!!");         break;      }      oldFlashContents = flashContents; /* to check for toggle bits */      timeout--;   }   if (timeout <= 0) {      putstr("eraseFlashChip timeout\r\n");      putLabeledWord("  flashp=", (dword)(&flashword[flashWordOffset]));      putLabeledWord("  flashContents=", flashContents);      putLabeledWord("  oldFlashContents=", oldFlashContents);      return(-1);   }   return 0;}/* sectorAddress must be a valid start of sector address. sectors   must be erased before they can be programmed! */static int amdFlashEraseSector (unsigned long sectorAddress){   int i;   long timeout = FLASH_TIMEOUT;   unsigned long flashWordOffset = (sectorAddress&flash_address_mask) >> 2;   unsigned long flashContents;   unsigned long oldFlashContents;   const unsigned long hivalue = 0xFFFFl; /* when sector is erased, this is what we should read */   const unsigned long lovalue = 0xFFFFl; /* when sector is erased, this is what we should read */      for (i = 0; i < nsectors; i++) {      if (flashSectors[i] == sectorAddress)         break;   }   if (i >= nsectors) {      putLabeledWord("eraseFlashSector: sectorAddress must be start of a sector! address=", sectorAddress);      putLabeledWord("nsectors=", nsectors);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -