📄 amd32.c
字号:
/* * amd32.c: AMD 32 bit (2x 16 bit) flash driver * * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) * Copyright (C) 2001 Russ Dill (Russ.Dill@asu.edu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#ident "$Id: amd32.c,v 1.4 2002/01/02 01:23:18 erikm Exp $"#ifdef HAVE_CONFIG_H# include <blob/config.h>#endif#include <blob/errno.h>#include <blob/flash.h>#include <blob/util.h>#include <blob/serial.h>/* flash commands for two 16 bit AMD flash chips */#define READ_ARRAY 0x00F000F0#define UNLOCK1 0x00AA00AA#define UNLOCK2 0x00550055#define ERASE_SETUP 0x00800080#define ERASE_CONFIRM 0x00300030#define PGM_SETUP 0x00A000A0#define UNLOCK_BYPASS 0x00200020#define FLASH_ADDR1 (0x00000555 << 2)#define FLASH_ADDR2 (0x000002AA << 2)#define ERASE_DONE 0x00800080#define RDY_MASK 0x00800080#define STATUS_PGM_ERR 0x00200020#define STATUS_ERASE_ERR 0x00000001#define READY 1#define ERR 2static int flash_erase_amd32(u32 *addr){ u32 result; int chip1, chip2; /* prepare for erase */ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); barrier(); *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); barrier(); *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); barrier(); /* erase command */ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); barrier(); *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); barrier(); *addr = data_to_flash(ERASE_CONFIRM); /* I just can't find clean ways of dealing with this flash... * The error bit is a *set* bit, so if its read, and bit 7 is 0, * but bit 5 is 1, its an error, however, after these status reads * are done, erased flash goes to 0xff...sooo...each chip has to * be caught where the bits are the status bits -- Russ */ /* Russ, why don't you do this like the LART does? Just check * the status of chips with a single compare. -- Erik */ chip1 = chip2 = 0; do { result = data_from_flash(*addr); barrier(); if (!chip1 && (result & 0xFFFF) & ERASE_DONE) chip1 = READY; if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) chip1 = ERR; if (!chip2 && (result >> 16) & ERASE_DONE) chip2 = READY; if (!chip2 && (result >> 16) & STATUS_PGM_ERR) chip2 = ERR; } while(!chip1 || !chip2); /* put flash back into Read Array mode */ *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); barrier(); if (chip1 == ERR || chip2 == ERR) return -EFLASHERASE; return 0;}static int flash_write_amd32(u32 *dst, const u32* src){ u32 result; int chip1, chip2; *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); barrier(); *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); barrier(); *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); barrier(); *dst = data_to_flash(PGM_SETUP); barrier(); *dst = *src; barrier(); /* This is a pretty similar situation to the erasing status below * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 * gets set before this happens, there is an error, but this could * happen near the clock edge, and bit 5 could be the actual data * before bit 7 changes, so we have to read again. -- Russ */ chip1 = chip2 = 0; do { result = data_from_flash(*dst); barrier(); if (!chip1 && ((result & 0x80) == (*src & 0x80))) chip1 = READY; if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { result = data_from_flash(*dst); barrier(); if ((result & 0x80) == (*src & 0x80)) chip1 = READY; else chip1 = ERR; } if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) chip2 = READY; if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { result = data_from_flash(*dst); barrier(); if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) chip2 = READY; else chip2 = ERR; } } while (!chip1 || !chip2); *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); barrier(); if (chip1 == ERR || chip2 == ERR || *dst != *src) return -EFLASHPGM; return 0;}static int flash_lock_block_amd32(u32 *blockStart){ /* FIXME: if AMD flash can be locked, this function should be * fleshed out -- Erik */ return 0;}static int flash_unlock_block_amd32(u32 *blockStart){ /* FIXME: if AMD flash can be unlocked, this function should * be fleshed out -- Erik */ return 0;}static int flash_query_block_lock_amd32(u32 *blockStart){ /* FIXME: if AMD flash can be queried, this function should be * fleshed out -- Erik */ return 0;}/* flash driver structure */flash_driver_t amd32_flash_driver = { erase: flash_erase_amd32, write: flash_write_amd32, lock_block: flash_lock_block_amd32, unlock_block: flash_unlock_block_amd32, query_block_lock: flash_query_block_lock_amd32};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -