📄 skyeye_flash.c
字号:
/*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>
#include "armdefs.h"
#include "skyeye_flash.h"
#include "armmem.h"
/*ywc 2005-04-01*/
void init_querytable ();
ARMword *mem; /* data */
ARMWord *mem; /* data */
char *lock; /* sector lock */
unsigned long size; /* byte size */
//ARMAddr base; /* start of flash bank */
ARMWord read_mode; /* mode for read operation */
ARMWord wsm_mode; /* write state machine */
static ARMWord query[INTEL_QUERYTABLE_SIZE]; /* query table */
/*
* state bits for handlers: program, buffer program, erase, lock
* xxxx_busy: whether WSM is busy on the handler
* xxxx_suspended: whether the handler is suspended
* xxxx_error: operation errors
*/
ARMByte program_busy, progbuf_busy, erase_busy, lock_busy;
ARMByte program_suspended, progbuf_suspended, erase_suspended;
ARMByte protection_error, program_setlb_error, erase_clearlb_error,
program_volt_error;
/* latch address&data for each handlers */
ARMAddr program_latch_addr, program_latch_data;
ARMAddr progbuf_latch_addr, progbuf_latch_data;
ARMAddr erase_latch_addr, erase_latch_data;
/*
* stateful information for buffer program handler
*/
/* total count and number to be loaded/programmed */
ARMWord pb_count, pb_loaded;
ARMAddr pb_start; /* start address */
ARMWord pb_buf[INTEL_WRITEBUFFER_SIZE]; /* write buffer */
/* VPEN pin: should controlled by EGPIO ??? */
ARMByte vpen;
/* return the lock bit */
#define ISLOCKED(x) (lock[(x)>>FLASH_SECTOR_SHIFT])
#define ADDR_SUSPENDED(x) \
((program_suspended && ((x) == program_latch_addr)) || \
(progbuf_suspended && (((x) >= pb_start) && ((x) < (pb_start+pb_count)))) || \
(erase_suspended && (((x) & FLASH_SECTOR_MASK) == (erase_latch_addr & FLASH_SECTOR_MASK))) )
#define DEVICE_SUSPENDED (program_suspended || progbuf_suspended || erase_suspended)
void
Intel28F128J3A_flash_init (ARMul_State * state)
{
unsigned int i;
size = INTEL28F128J3A_SIZE;
//base = 0x00000000;
/*
if (this->mem == NULL){
printf("\nFlash memory allocation failed"); // exit
}
*/
/*
for (unsigned int i = 0; i < size >> WORD_SHIFT; i ++){
//this->mem[i] = 0xffffffff; // initial state of flash
}
*/
lock = malloc (size / FLASH_SECTOR_SIZE);
if (lock == NULL)
{
printf ("\nflash memory lock allocation failed"); /* exit */
}
for (i = 0; i < size / FLASH_SECTOR_SIZE; i++)
{
lock[i] = 0;
}
read_mode = WSM_READ_ARRAY;
wsm_mode = WSM_READY;
program_busy = progbuf_busy = erase_busy = lock_busy = 0;
program_suspended = progbuf_suspended = erase_suspended = 0;
protection_error = program_setlb_error = erase_clearlb_error =
program_volt_error = 0;
//vpen = 0; /* disable program/erase */
vpen = 1; /* enable program/erase */
pb_count = pb_loaded = 0;
init_querytable ();
}
ARMword
Intel28F128J3A_flash_read_byte (ARMul_State * state, ARMword addr)
{
ARMword data, offset;
data = Intel28F128J3A_flash_read_word (state, addr);
offset = (((ARMword) state->bigendSig * 3) ^ (addr & 3)) << 3;
return (data >> offset & 0xffL);
}
ARMword
Intel28F128J3A_flash_read_halfword (ARMul_State * state, ARMword addr)
{
ARMword data, offset;
data = Intel28F128J3A_flash_read_word (state, addr);
offset = (((ARMword) state->bigendSig * 2) ^ (addr & 2)) << 3;
return (data >> offset & 0xffffL);
}
ARMword
Intel28F128J3A_flash_read_word (ARMul_State * state, ARMword addr)
{
ARMword temp;
ARMword data;
switch (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 = !program_busy && !progbuf_busy && !lock_busy && !erase_busy;
/* suppose no voltage error */
data = BOTHCHIP ((temp << 7) |
(erase_suspended << 6) |
(erase_clearlb_error << 5) |
(program_setlb_error << 4) |
(program_volt_error << 3) |
(program_suspended << 2) | (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", read_mode);
data = 0;
break;
}
return data;
}
void
Intel28F128J3A_flash_write_byte (ARMul_State * state, ARMword addr,
ARMword data)
{
printf ("\nFlash in current config does not support halfword write at 0x%x",
addr);
//Intel28F128J3A_flash_write_word(state,addr,data);
}
void
Intel28F128J3A_flash_write_halfword (ARMul_State * state, ARMword addr,
ARMword data)
{
printf ("\nFlash in current config does not support byte write at 0x%x",
addr);
//Intel28F128J3A_flash_write_word(state,addr,data);
}
/* initialize a new WSM command sequence */
void
init_wsm (ARMAddr addr, ARMWord 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;
ARMWord cmd = data & 0xff;
switch (cmd)
{
case WSM_READ_ARRAY:
read_mode = WSM_READ_ARRAY;
break;
case WSM_READ_ID:
read_mode = WSM_READ_ID;
break;
case WSM_READ_STATUS:
read_mode = WSM_READ_STATUS;
break;
case WSM_READ_QUERY:
read_mode = WSM_READ_QUERY;
break;
case WSM_CLEAR_STATUS:
protection_error = program_setlb_error =
erase_clearlb_error = 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
read_mode = WSM_READ_ARRAY;
break;
case WSM_PROGRAM:
case WSM_PROGRAM2:
wsm_mode = WSM_PROGRAM;
break;
case WSM_WRITE_BUFFER:
wsm_mode = WSM_WRITE_BUFFER;
read_mode = WSM_READ_STATUS;
pb_count = pb_loaded = 0;
for (i = 0; i < INTEL_WRITEBUFFER_SIZE; i++)
pb_buf[i] = 0xffffffff;
break;
case WSM_BLOCK_ERASE:
wsm_mode = WSM_BLOCK_ERASE;
break;
case WSM_SUSPEND:
if (program_busy)
program_suspended = 1;
else if (progbuf_busy)
progbuf_suspended = 1;
else if (erase_busy)
erase_suspended = 1;
else
{
//ywc
//printf("\nFlash: nothing busy for suspending");
}
break;
case WSM_RESUME:
if (program_suspended)
program_suspended = 0;
else if (progbuf_suspended)
progbuf_suspended = 0;
else if (erase_suspended)
erase_suspended = 0;
else
{
//ywc
//printf("\nFlash: nothing to resume");
}
break;
case WSM_LOCK_ACCESS:
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;
}
}
void
Intel28F128J3A_flash_write_word (ARMul_State * state, ARMword addr,
ARMword data)
{
unsigned int i;
ARMAddr j;
//CHECK_ADDR_RANGE(addr);
switch (wsm_mode)
{
case WSM_READY:
init_wsm (addr, data);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -