📄 dev_flash_intel.c
字号:
/* dev_lcd_pxa.c - skyeye PXA25x serial lcd controllor simulation Copyright (C) 2003 - 2005 Skyeye Develop Group for help please send mail to <skyeye-developer@lists.gro.clinux.org> 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 *//* * 09/22/2005 rewrite for new framework * walimis * * ywc 2005-01-21 add for flash simulation * core flash simulation source code from ipaqsim * Thanks to ipaqsim's AUTHOR(s): Ye Wen (wenye@cs.ucsb.edu) */#include <stdio.h>//koodailar add for mingw 2005.12.18 ----------------------------------------#ifdef __MINGW32__#include "arch/arm/common/armdefs.h"#include "arch/arm/common/armmem.h"#else#include "armdefs.h"#include "armmem.h"#endif// end ----------------------------------------------------------------------#include "dev_flash_intel.h"/*ywc 2005-04-01*/void init_querytable ();static u32 query[INTEL_QUERYTABLE_SIZE]; /* query table *//* return the lock bit */#define ISLOCKED(x) (io->lock[(x)>>FLASH_SECTOR_SHIFT])#define ADDR_SUSPENDED(x) \((io->program_suspended && ((x) == io->program_latch_addr)) || \ (io->progbuf_suspended && (((x) >= io->pb_start) && ((x) < (io->pb_start+io->pb_count)))) || \ (io->erase_suspended && (((x) & FLASH_SECTOR_MASK) == (io->erase_latch_addr & FLASH_SECTOR_MASK))) )#define DEVICE_SUSPENDED (io->program_suspended || io->progbuf_suspended || io->erase_suspended)voidflash_intel_reset (struct device_desc *dev){ struct flash_device *flash_dev = (struct flash_device *) dev->dev; struct flash_intel_io *io = (struct flash_intel_io *) dev->data; unsigned int i; io->size = INTEL28F128J3A_SIZE; io->lock = malloc (io->size / FLASH_SECTOR_SIZE); if (io->lock == NULL) { printf ("\nflash memory lock allocation failed"); /* exit */ } for (i = 0; i < io->size / FLASH_SECTOR_SIZE; i++) { io->lock[i] = 0; } io->read_mode = WSM_READ_ARRAY; io->wsm_mode = WSM_READY; io->program_busy = io->progbuf_busy = io->erase_busy = io->lock_busy = 0; io->program_suspended = io->progbuf_suspended = io->erase_suspended = 0; io->protection_error = io->program_setlb_error = io->erase_clearlb_error = io->program_volt_error = 0; //io->vpen = 0; /* disable program/erase */ io->vpen = 1; /* enable program/erase */ io->pb_count = io->pb_loaded = 0; init_querytable ();}static voidflash_intel_fini (struct device_desc *dev){ struct flash_intel_io *io = (struct flash_intel_io *) dev->data; if (!dev->dev) free (dev->dev); if (!io) free (io);}intflash_intel_read_byte (struct device_desc *dev, u32 addr, u8 * data){ struct machine_config *mc = (struct machine_config *) dev->mach; ARMul_State *state = (ARMul_State *) mc->state; u32 temp, offset; int ret = ADDR_HIT; flash_intel_read_word (dev, addr, &temp); offset = (((u32) state->bigendSig * 3) ^ (addr & 3)) << 3; *data = (temp >> offset & 0xffL); return ret;}intflash_intel_read_halfword (struct device_desc *dev, u32 addr, u16 * data){ struct machine_config *mc = (struct machine_config *) dev->mach; ARMul_State *state = (ARMul_State *) mc->state; u32 temp, offset; int ret = ADDR_HIT; flash_intel_read_word (dev, addr, &temp); offset = (((u32) state->bigendSig * 2) ^ (addr & 2)) << 3; *data = (temp >> offset & 0xffffL); return ret;}intflash_intel_read_word (struct device_desc *dev, u32 addr, u32 * data){ struct flash_device *flash_dev = (struct flash_device *) dev->dev; struct flash_intel_io *io = (struct flash_intel_io *) dev->data; struct machine_config *mc = (struct machine_config *) dev->mach; ARMul_State *state = (ARMul_State *) mc->state; int ret = ADDR_HIT; u32 temp; switch (io->read_mode) { case WSM_READ_ARRAY: /* read flash */ //data = mem[WORD_ADDR(addr)]; *data = real_read_word (state, addr); //data = state->mem.rom[mbp - skyeye_config.mem.mem_banks][(addr- mbp->addr)>>2]; break; case WSM_READ_ID: //read IDs temp = WORD_ADDR (addr) & 0x00000001; if (temp == 0) { *data = BOTHCHIP (INTEL_MANUFACTURER_CODE); } //manu. ID else if (temp == 1) { *data = BOTHCHIP (INTEL_28F128J3A_DEVICE_CODE); } // device ID else if (((addr & FLASH_SECTOR_OFF) >> WORD_SHIFT) == 2) //read lock state *data = BOTHCHIP (ISLOCKED (addr) & 0x1); else { *data = 0; printf ("\nFlash: read ID error: unknown address 0x%x\n", addr); } break; case WSM_READ_STATUS: /* read status register */ /* first get the WSM busy/ready state */ temp = !io->program_busy && !io->progbuf_busy && !io->lock_busy && !io->erase_busy; /* suppose no voltage error */ *data = BOTHCHIP ((temp << 7) | (io->erase_suspended << 6) | (io->erase_clearlb_error << 5) | (io->program_setlb_error << 4) | (io->program_volt_error << 3) | (io->program_suspended << 2) | (io-> protection_error) << 1); break; case WSM_READ_QUERY: // read query table //temp = WORD_ADDR(addr); temp = WORD_ADDR (addr & 0x0000ffff); *data = (temp < INTEL_QUERYTABLE_SIZE) ? query[temp] : 0; break; default: printf ("\nFlash: invalid read mode: %d", io->read_mode); *data = 0; break; } return ret;}intflash_intel_write_byte (struct device_desc *dev, u32 addr, u8 data){ int ret = ADDR_HIT; printf ("\nFlash in current config does not support halfword write at 0x%x", addr); return ret;}intflash_intel_write_halfword (struct device_desc *dev, u32 addr, u16 data){ int ret = ADDR_HIT; printf ("\nFlash in current config does not support byte write at 0x%x", addr); return ret;}/* initialize a new WSM command sequence */voidinit_wsm (struct device_desc *dev, u32 addr, u32 data){ struct flash_intel_io *io = (struct flash_intel_io *) dev->data; /* maybe we don't need to care the data symmetry */ //CHECK_DATA_VALID(data); /* * No timing support now, so Suspend/Resume has no effect * July 1st, 2004 Ye Wen */ int i; u32 cmd = data & 0xff; switch (cmd) { case WSM_READ_ARRAY: io->read_mode = WSM_READ_ARRAY; break; case WSM_READ_ID: io->read_mode = WSM_READ_ID; break; case WSM_READ_STATUS: io->read_mode = WSM_READ_STATUS; break; case WSM_READ_QUERY: io->read_mode = WSM_READ_QUERY; break; case WSM_CLEAR_STATUS: io->protection_error = io->program_setlb_error = io->erase_clearlb_error = io->program_volt_error = 0; // is this right? I can't see it from spec. // but the bootldr code implies this. Check // program_flash_region in bootldr.c // -July 28, 2004 Ye Wen io->read_mode = WSM_READ_ARRAY; break; case WSM_PROGRAM: case WSM_PROGRAM2: io->wsm_mode = WSM_PROGRAM; break; case WSM_WRITE_BUFFER: io->wsm_mode = WSM_WRITE_BUFFER; io->read_mode = WSM_READ_STATUS; io->pb_count = io->pb_loaded = 0; for (i = 0; i < INTEL_WRITEBUFFER_SIZE; i++) io->pb_buf[i] = 0xffffffff; break; case WSM_BLOCK_ERASE: io->wsm_mode = WSM_BLOCK_ERASE; break; case WSM_SUSPEND: if (io->program_busy) io->program_suspended = 1; else if (io->progbuf_busy) io->progbuf_suspended = 1; else if (io->erase_busy) io->erase_suspended = 1; else { //ywc //printf("\nFlash: nothing busy for suspending"); } break; case WSM_RESUME: if (io->program_suspended) io->program_suspended = 0; else if (io->progbuf_suspended) io->progbuf_suspended = 0; else if (io->erase_suspended) io->erase_suspended = 0; else { //ywc //printf("\nFlash: nothing to resume"); } break; case WSM_LOCK_ACCESS: io->wsm_mode = WSM_LOCK_ACCESS; break; case WSM_CONFIG: case WSM_PROTECT: printf ("\nFlash: command 0x%x not supported yet", cmd); break; default: //ywc //printf("\nFlash: command 0x%x unrecognized", cmd); break; }}intflash_intel_write_word (struct device_desc *dev, u32 addr, u32 data){ struct machine_config *mc = (struct machine_config *) dev->mach; struct flash_intel_io *io = (struct flash_intel_io *) dev->data; ARMul_State *state = (ARMul_State *) mc->state; unsigned int i; int ret = ADDR_HIT; u32 j; //CHECK_ADDR_RANGE(addr); switch (io->wsm_mode) { case WSM_READY: init_wsm (dev, addr, data); break; case WSM_WRITE_BUFFER: if (io->pb_count == 0) { /* step 1: get count */ io->pb_count = (data & 0xff) + 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -