📄 mx29lv320.c
字号:
* * INPUT: * flash -- Address of the block to wirte. * src -- Source address of this image. * size -- image size to write to the flash. *----------------------------------------------------------------------*/static int mx29lv320_write(struct FLASH_DESC_S *cp, char *flash, char *src, int size){ register int i, j; register int rc = FLASH_OK; volatile short val; volatile short *block = (volatile short *) flash; volatile short *data = (volatile short *) src; volatile short *p555 = (short *)((unsigned long)cp->start + 0x0aaa); volatile short *p2aa = (short *)((unsigned long)cp->start + 0x0554); /* Convert size in bytes into size in word. */ size=(size + 1) / 2; /***********************/ /* Write data */ /***********************/ enable_write(); // unprotect flash *block = 0xf0; // Set to reset state for (i = 0; i<size; i++) { /* Write data */ *p555 = 0xaa; *p2aa = 0x55; *p555 = 0xa0; *block = *data; j = 0; while (1) { val = *block; // Wait complement completed if ((val & 0x80) == (*data & 0x80)) { /* write successful */ break; /* Do next byte */ } else { if (j++ > 1024) { if ((*block & 0x80) != (*data & 0x80)) { rc = FLASH_ERROR; goto exit_write; /* UGH */ } } } } // while(1) block++; data++; } /* Update the flash and source pointers */ block--; /* back to the previous chip */exit_write: /* UGH */ *block = 0xf0; /* Reset to read array */ disable_write(); return rc;}/*---------------------------------------------------------------------- * mx29lv320_init * Disable writing to the flash main blocks *----------------------------------------------------------------------*/int mx29lv320_init(){ flash_add(&mx29lv320_dev); return 0;}/*---------------------------------------------------------------------- * mx29lv320_protectinfo * Examine flash locking and protection *----------------------------------------------------------------------*/int mx29lv320_protectinfo(struct FLASH_DESC_S *cp){ register int i, j; register int rc = FLASH_OK; unsigned int ssv_lo, ssv_med, ssv_hi, mx_blk; volatile short *saaddr; short protectval; /* This operates completely in "byte mode". Remember this when referring to the datasheet. In particular, page 16 of the MX29LV320AT/B REV 0.2 datasheet is informative. */ /* The datasheet says use 0x0555 in word-mode and 0x0AAA in byte mode */ volatile short *p555 = (short *)((unsigned long)cp->start + 0x0AAA); /* The datasheet says use 0x02AA in word-mode and 0x555 in byte mode but that is WRONG. It actually should be 0x02AA << 1, or 0x0554 */ volatile short *p2aa = (short *)((unsigned long)cp->start + 0x0554); volatile short *preset = (short *)((unsigned long)cp->start + 0x0013C000); // Corresp to "empty" flash if (cp == 0 || cp->start == 0) return 0; mx_ssv_lo = mx_ssv_med = mx_ssv_hi = 0; // Initialize all security descriptor bits to 0 for all 71 sectors *preset = 0xf0; // Set to reset state /* Get manufacturer ID */ *p555 = 0xAA; *p2aa = 0x55; *p555 = 0x90; mx_mfg_id = *preset; /* Get device ID */ *p555 = 0xAA; *p2aa = 0x55; *p555 = 0x90; mx_dev_id = *(preset + 1); // address is actually 2 bytes away /* Get Security Sector Factory Protect Verify */ *p555 = 0xAA; *p2aa = 0x55; *p555 = 0x90; mx_factory_protect = *(preset + 3); // address is actually 6 bytes away /* VERY HAPPY to see that on the H2WR54G the security code is 0x19 which means the device's Security Sector is NOT locked at the factory */ /* Get Security Sector Protect Verify bits */ for (i = 0; i < cp->num; i++) { /* This works. Once. Then everything shows up 0 after that. */// mx_blk = mx29lv320_blocks[i] >> 4; // to match SA /* These don't work */// mx_blk = mx29lv320_sas[i] << 12; // to match SA mx_blk = mx29lv320_blocks[i]; // test since it stopped working// saaddr = (short *)((unsigned long) cp->start + mx_blk + 4); saaddr = (short *)((unsigned long) cp->start + mx_blk + 2); // What a pain in the ass if (i >= 32) { unsigned int itemp = ((unsigned int) saaddr) | 0x00100000; // A20 on for SA 32 or greater saaddr = (unsigned short *) itemp; } *p555 = 0xAA; *p2aa = 0x55; *p555 = 0x90; protectval = *saaddr; if (i < 32) { j = i; mx_blk = 1 << j; // just re-using the variable if (protectval != 0) mx_ssv_lo |= mx_blk; // turn bit on } else if (i < 64) { j = i - 32; mx_blk = 1 << j; // just re-using the variable if (protectval != 0) mx_ssv_med |= mx_blk; // turn bit on } else { j = i - 64; mx_blk = 1 << j; // just re-using the variable if (protectval != 0) mx_ssv_hi |= mx_blk; // turn bit on } } /* RESULTS from this test indicate that SA 0 is the ONLY sector that is protected. */ /* Sectors 0, 1, 2 and 3 cover the first 32K on the chip, from addresses 0 - 0x7FFF */ *preset = 0xf0; // Set to reset state return rc;}/*---------------------------------------------------------------------- * mx29lv320_enter_ss * Enter the security sector *----------------------------------------------------------------------*/void mx29lv320_enter_ss(){ volatile short *p555 = (short *)(0xbfc00000 + 0x0aaa); volatile short *p2aa = (short *)(0xbfc00000 + 0x0554); volatile short *block = (short *)(0xbfc00000 + 0x00013C00); *block = 0xF0; *p555 = 0xAA; *p2aa = 0x55; *p555 = 0x88; *block = 0xF0; ssopen = 1;}/*---------------------------------------------------------------------- * mx29lv320_exit_ss * Exit the security sector *----------------------------------------------------------------------*/void mx29lv320_exit_ss(){ volatile short *p555 = (short *)(0xbfc00000 + 0x0aaa); volatile short *p2aa = (short *)(0xbfc00000 + 0x0554); volatile short *block = (short *)(0xbfc00000 + 0x00013C00); /* The datasheet is not clear whether to read or write at address XXX for the last bus cycle on an "Exit Security Sector" command sequence. Note, however, that a read will perform an Automatic Select of the Manufacturer ID word, not what we want. So we'll write to it. */ *block = 0xF0; *p555 = 0xAA; *p2aa = 0x55; *p555 = 0x90; *block = 0x00; *block = 0xF0; ssopen = 0;}/*---------------------------------------------------------------------- * mx29lv320_whack_ss * Whack the security sector *----------------------------------------------------------------------*/void mx29lv320_whack_ss(struct FLASH_DESC_S *cp, char *dest, char *src, int size){ mx29lv320_enter_ss(); mx29lv320_write(cp, dest, src, size); mx29lv320_exit_ss();}/*---------------------------------------------------------------------- * mx29lv320_erase_ss * Erase the 64K security sector *----------------------------------------------------------------------*/void mx29lv320_erase_ss(struct FLASH_DESC_S *cp){ char *flash = (char *) 0xbfc00000; int size = 65536; mx29lv320_enter_ss(); mx29lv320_erase(cp, flash, size); mx29lv320_exit_ss();}/*---------------------------------------------------------------------- * mx29lv320_update_ss * Re-program the 64K security sector *----------------------------------------------------------------------*/int mx29lv320_update_ss(char *image, int size){ FLASH_DESC *cp = flash_get_head_chip(); char *flash = (char *) PA2VA(MX29LV_SECSEC_BASE); int rc = 0; if (cp != 0) { if (size > MX29LV_SECSEC_SIZE) size = MX29LV_SECSEC_SIZE; mx29lv320_enter_ss(); mx29lv320_erase(cp, flash, size); mx29lv320_write(cp, flash, image, size); mx29lv320_exit_ss(); rc = 1; } return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -