491 lines
16 KiB
C
491 lines
16 KiB
C
/*****************************************************************************
|
|
* *
|
|
* FAT-FTL Lite Software Development Kit *
|
|
* Copyright (C) M-Systems Ltd. 1995-2001 *
|
|
* *
|
|
*****************************************************************************
|
|
* *
|
|
* In order to make your code faster: *
|
|
* *
|
|
* 1. Get rid of routines flRead8bitRegPlus()/flPreInitRead8bitReg()Plus, *
|
|
* and make M+ MTD calling routine mplusReadReg8() directly. *
|
|
* *
|
|
* 2. Get rid of routines flWrite8bitRegPlus()/flPreInitWrite8bitReg()Plus, *
|
|
* and make M+ MTD calling routine mplusWriteReg8() directly. *
|
|
* *
|
|
* 3. Eliminate overhead of calling routines tffscpy/tffsset() by *
|
|
* adding these routines' code into docPlusRead/docPlusWrite/docPlusSet *
|
|
* routines. *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*
|
|
* $Log: V:/Flite/archives/TrueFFS5/Src/docsysp.c_V $
|
|
*
|
|
* Rev 1.4 Nov 18 2001 20:26:50 oris
|
|
* Bug fix- Bad implementation of 8-bit access when ENVIRNOMENT_VARS is not defined.
|
|
*
|
|
* Rev 1.3 Nov 16 2001 00:26:54 oris
|
|
* When ENVIRONMENT_VARS is not defined use for loop of bytes instead of tffscpy.
|
|
*
|
|
* Rev 1.2 Sep 25 2001 15:39:38 oris
|
|
* Bug fix - Add special support for flUse8Bit environement variable.
|
|
*
|
|
* Rev 1.1 Sep 24 2001 18:23:32 oris
|
|
* Completely revised to support runtime true 16-bit access.
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
* configuration
|
|
*/
|
|
|
|
/* #define FL_INIT_MMU_PAGES */
|
|
|
|
|
|
|
|
|
|
/*
|
|
* includes
|
|
*/
|
|
|
|
#include "docsysp.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
* macros
|
|
*/
|
|
|
|
/* types of access to M+: 8 or 16-bit */
|
|
|
|
#define FL_MPLUS_ACCESS_8BIT 0x10
|
|
#define FL_MPLUS_ACCESS_16BIT 0x20
|
|
#define FL_MPLUS_ACCESS_MASK 0xf0 /* mask for the above */
|
|
|
|
/* in case of 16-bit access to M+ */
|
|
|
|
#define FL_MPLUS_ACCESS_BE 0x100
|
|
|
|
|
|
|
|
|
|
/*
|
|
* routines
|
|
*/
|
|
|
|
#ifdef FL_INIT_MMU_PAGES
|
|
|
|
static void flInitMMUpages (byte FAR1 *buf, int bufsize);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
* vars
|
|
*/
|
|
|
|
/* run-time configuration of DiskOnChip access */
|
|
|
|
int flMplusAccessType = FL_MPLUS_ACCESS_8BIT;
|
|
/* FL_MPLUS_ACCESS_8BIT
|
|
FL_MPLUS_ACCESS_16BIT
|
|
FL_MPLUS_ACCESS_BE */
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* m p l u s R e a d R e g 8 *
|
|
* *
|
|
* Read single byte from memory mapped 8-bit M+ register. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
unsigned char mplusReadReg8 ( void FAR0 * win, int offset )
|
|
{
|
|
if( flMplusAccessType & FL_MPLUS_ACCESS_16BIT ) {
|
|
|
|
/* can't read byte, only short word */
|
|
|
|
unsigned short sval;
|
|
|
|
sval = *((volatile unsigned short FAR0 *)win + (offset >> 1));
|
|
|
|
return *(((unsigned char *) &sval) + (offset & 0x1));
|
|
}
|
|
|
|
/* FL_MPLUS_ACCESS_8BIT case */
|
|
|
|
return *((volatile unsigned char FAR0 *)win + offset);
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* m p l u s W r i t e R e g 8 *
|
|
* *
|
|
* Write single byte to memory mapped 8-bit M+ register. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
void mplusWriteReg8 ( void FAR0 * win, int offset, unsigned char val )
|
|
{
|
|
switch( flMplusAccessType & FL_MPLUS_ACCESS_MASK ) {
|
|
|
|
case FL_MPLUS_ACCESS_16BIT:
|
|
|
|
*((volatile unsigned short FAR0 *)win + (offset >> 1)) =
|
|
(unsigned short)(val * 0x0101);
|
|
break;
|
|
|
|
default: /* FL_MPLUS_ACCESS_8BIT */
|
|
|
|
*((volatile unsigned char FAR0 *)win + offset) = val;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* f l R e a d 1 6 b i t R e g P l u s *
|
|
* *
|
|
* Read single word from memory mapped 16-bit M+ register. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
Reg16bitType flRead16bitRegPlus ( FLFlash vol, unsigned offset )
|
|
{
|
|
return (Reg16bitType)
|
|
(*((volatile unsigned short FAR0 *)((char FAR0 *)NFDC21thisVars->win + (int)offset)));
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* f l W r i t e 1 6 b i t R e g P l u s *
|
|
* *
|
|
* Write single word to memory mapped 16-bit M+ register. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
void flWrite16bitRegPlus ( FLFlash vol, unsigned offset, Reg16bitType val )
|
|
{
|
|
*((volatile unsigned short FAR0 *)((char FAR0 *)NFDC21thisVars->win + (int)offset)) =
|
|
(unsigned short) val;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* d o c P l u s R e a d *
|
|
* *
|
|
* This routine is called from M+ MTD to read data block from M+. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
void docPlusRead ( FLFlash vol, unsigned offset, void FAR1 * dest, unsigned int count )
|
|
{
|
|
volatile unsigned short FAR0 * swin;
|
|
register int i;
|
|
register unsigned short tmp;
|
|
|
|
if (count == 0)
|
|
return;
|
|
|
|
#ifdef FL_INIT_MMU_PAGES
|
|
|
|
flInitMMUpages( (byte FAR1 *)dest, (int)count );
|
|
|
|
#endif
|
|
|
|
if ((vol.interleaving == 1) && (NFDC21thisVars->if_cfg == 16)) {
|
|
|
|
/* rare case: 16-bit hardware interface AND interleave == 1 */
|
|
|
|
for (i = 0; i < (int)count; i++) {
|
|
|
|
*((unsigned char FAR1 *)dest + i) =
|
|
mplusReadReg8 ((void FAR0 *)NFDC21thisVars->win, ((int)offset));
|
|
}
|
|
}
|
|
else {
|
|
|
|
switch( flMplusAccessType & FL_MPLUS_ACCESS_MASK ) {
|
|
|
|
case FL_MPLUS_ACCESS_16BIT:
|
|
|
|
swin = (volatile unsigned short FAR0 *)NFDC21thisVars->win + ((int)offset >> 1);
|
|
|
|
if( pointerToPhysical(dest) & 0x1 ) {
|
|
|
|
/* rare case: unaligned target buffer */
|
|
|
|
if( flMplusAccessType & FL_MPLUS_ACCESS_BE ) { /* big endian */
|
|
|
|
for (i = 0; i < (int)count; ) {
|
|
|
|
tmp = *(swin + (i >> 1));
|
|
|
|
*((unsigned char FAR1 *)dest + (i++)) = (unsigned char) (tmp >> 8);
|
|
*((unsigned char FAR1 *)dest + (i++)) = (unsigned char) tmp;
|
|
}
|
|
}
|
|
else { /* little endian */
|
|
|
|
for (i = 0; i < (int)count; ) {
|
|
|
|
tmp = *(swin + (i >> 1));
|
|
|
|
*((unsigned char FAR1 *)dest + (i++)) = (unsigned char) tmp;
|
|
*((unsigned char FAR1 *)dest + (i++)) = (unsigned char) (tmp >> 8);
|
|
}
|
|
}
|
|
}
|
|
else { /* mainstream case */
|
|
#ifdef ENVIRONMENT_VARS
|
|
if (flUse8Bit == 0) {
|
|
|
|
tffscpy( dest, (void FAR0 *)((NDOC2window)NFDC21thisWin + offset), count );
|
|
}
|
|
else
|
|
#endif /* ENVIRONMENT_VARS */
|
|
{ /* read in short words */ /* andrayk: do we need this ? */
|
|
|
|
for (i = 0; i < ((int)count >> 1); i++)
|
|
*((unsigned short FAR1 *)dest + i) = *(swin + i);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default: /* FL_MPLUS_ACCESS_8BIT */
|
|
#ifdef ENVIRONMENT_VARS
|
|
tffscpy( dest, (void FAR0 *)((NDOC2window)NFDC21thisWin + offset), count );
|
|
#else
|
|
for (i = 0; i < (int)count; i++)
|
|
((byte FAR1 *)dest)[i] = *((NDOC2window)NFDC21thisWin + offset);
|
|
#endif /* ENVIRONMENT_VARS */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* d o c P l u s W r i t e *
|
|
* *
|
|
* This routine is called from M+ MTD to write data block to M+. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
void docPlusWrite ( FLFlash vol, void FAR1 * src, unsigned int count )
|
|
{
|
|
volatile unsigned short FAR0 * swin;
|
|
register int i;
|
|
register unsigned short tmp;
|
|
|
|
if (count == 0)
|
|
return;
|
|
|
|
if ((vol.interleaving == 1) && (NFDC21thisVars->if_cfg == 16)) {
|
|
|
|
/* rare case: 16-bit hardware interface AND interleave == 1 */
|
|
|
|
for (i = 0; i < (int)count; i++) {
|
|
|
|
mplusWriteReg8( (void FAR0 *)NFDC21thisVars->win, ((int)NFDC21thisIO),
|
|
*((unsigned char FAR1 *)src + i) );
|
|
}
|
|
}
|
|
else {
|
|
|
|
switch( flMplusAccessType & FL_MPLUS_ACCESS_MASK ) {
|
|
|
|
case FL_MPLUS_ACCESS_16BIT:
|
|
|
|
swin = (volatile unsigned short FAR0 *)NFDC21thisVars->win + ((int)NFDC21thisIO >> 1);
|
|
|
|
if( pointerToPhysical(src) & 0x1 ) {
|
|
|
|
/* rare case: unaligned source buffer */
|
|
|
|
if( flMplusAccessType & FL_MPLUS_ACCESS_BE ) { /* big endian */
|
|
|
|
for (i = 0; i < (int)count; ) {
|
|
|
|
tmp = ((unsigned short) (*((unsigned char FAR1 *)src + (i++)))) << 8;
|
|
tmp |= (*((unsigned char FAR1 *)src + (i++)));
|
|
|
|
*(swin + (i >> 1)) = tmp;
|
|
}
|
|
}
|
|
else {
|
|
|
|
for (i = 0; i < (int)count; ) { /* little endian */
|
|
|
|
tmp = (*((unsigned char FAR1 *)src + (i++)));
|
|
tmp |= ((unsigned short) (*((unsigned char FAR1 *)src + (i++)))) << 8;
|
|
|
|
*(swin + (i >> 1)) = tmp;
|
|
}
|
|
}
|
|
}
|
|
else { /* mainstream case */
|
|
#ifdef ENVIRONMENT_VARS
|
|
if (flUse8Bit == 0) {
|
|
|
|
tffscpy( (void FAR0 *)((NDOC2window)NFDC21thisWin + NFDC21thisIO), src, count );
|
|
}
|
|
else
|
|
#endif /* ENVIRONMENT_VARS */
|
|
{ /* write in short words */ /* andrayk: do we need this ? */
|
|
|
|
for (i = 0; i < ((int)count >> 1); i++)
|
|
*(swin + i) = *((unsigned short FAR1 *)src + i);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default: /* FL_MPLUS_ACCESS_8BIT */
|
|
#ifdef ENVIRONMENT_VARS
|
|
tffscpy( (void FAR0 *)((NDOC2window)NFDC21thisWin + NFDC21thisIO), src, count );
|
|
#else
|
|
for (i = 0; i < (int)count; i++)
|
|
*((NDOC2window)NFDC21thisWin + NFDC21thisIO) =
|
|
((byte FAR1 *)src)[i];
|
|
#endif /* ENVIRONMENT_VARS */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* d o c P l u s S e t *
|
|
* *
|
|
* This routine is called from M+ MTD to set data block on M+ to 'val'. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
void docPlusSet ( FLFlash vol, unsigned int count, unsigned char val )
|
|
{
|
|
volatile unsigned short FAR0 * swin;
|
|
register int i;
|
|
register unsigned short sval;
|
|
|
|
if (count == 0)
|
|
return;
|
|
|
|
if ((vol.interleaving == 1) && (NFDC21thisVars->if_cfg == 16)) {
|
|
|
|
/* rare case: 16-bit hardware interface AND interleave == 1 */
|
|
|
|
for (i = 0; i < (int)count; i++)
|
|
mplusWriteReg8( (void FAR0 *)NFDC21thisVars->win, (int)NFDC21thisIO, val );
|
|
}
|
|
else { /* mainstream case */
|
|
|
|
switch( flMplusAccessType & FL_MPLUS_ACCESS_MASK ) {
|
|
|
|
case FL_MPLUS_ACCESS_16BIT:
|
|
#ifdef ENVIRONMENT_VARS
|
|
if (flUse8Bit == 0) {
|
|
|
|
tffsset( (void FAR0 *)((NDOC2window)NFDC21thisWin + NFDC21thisIO), val, count );
|
|
}
|
|
else
|
|
#endif /* ENVIRONMENT_VARS */
|
|
{ /* do short word access */ /* andrayk: do we need this ? */
|
|
|
|
swin = (volatile unsigned short FAR0 *)NFDC21thisVars->win +
|
|
((int)NFDC21thisIO >> 1);
|
|
|
|
sval = ((unsigned short)val << 8) | val;
|
|
|
|
for (i = 0; i < ((int)count >> 1); i++)
|
|
*(swin + i) = sval;
|
|
}
|
|
break;
|
|
|
|
default: /* FL_MPLUS_ACCESS_8BIT */
|
|
#ifdef ENVIRONMENT_VARS
|
|
tffsset( (void FAR0 *)((NDOC2window)NFDC21thisWin + NFDC21thisIO), val, count );
|
|
#else
|
|
for (i = 0; i < (int)count; i++)
|
|
*((NDOC2window)NFDC21thisWin + NFDC21thisIO) = val;
|
|
#endif /* ENVIRONMENT_VARS */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* m p l u s W i n S i z e *
|
|
* *
|
|
* This routine is called from M+ MTD to find out size of M+ window in *
|
|
* bytes. *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
unsigned long mplusWinSize ( void )
|
|
{
|
|
return 0x2000L;
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef FL_INIT_MMU_PAGES
|
|
|
|
/* ---------------------------------------------------------------------- *
|
|
* *
|
|
* f l I n i t M M U p a g e s *
|
|
* *
|
|
* Initializes the first and last byte of the given buffer. *
|
|
* When the user buffer resides on separated memory pages the read *
|
|
* operation may cause a page fault. Some CPU's return from a page *
|
|
* fault (after loading the new page) and reread the bytes that caused *
|
|
* the page fault from the new loaded page. In order to prevent such a *
|
|
* case the first and last bytes of the buffer are written *
|
|
* *
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
static void flInitMMUpages ( byte FAR1 *buf, int bufsize )
|
|
{
|
|
*buf = (byte)0;
|
|
|
|
*( addToFarPointer(buf, (bufsize - 1)) ) = (byte)0;
|
|
}
|
|
|
|
#endif /* FL_INIT_MMU_PAGES */
|
|
|
|
|
|
|