/* * $Log: V:/Flite/archives/TrueFFS5/Src/DOCSYS.C_V $ * * Rev 1.16 Apr 15 2002 08:30:30 oris * Added support for USE_TFFS_COPY compilation flag. This flag is used by bios driver a Boot SDK in order to improove performance. * * Rev 1.15 Apr 15 2002 07:35:56 oris * Reorganized for final release. * * Rev 1.14 Jan 28 2002 21:24:10 oris * Removed static prefix to all runtime configurable memory access routines. * Replaced FLFlash argument with DiskOnChip memory base pointer. * Changed interface of write and set routines (those that handle more then 8/16 bits) so that instead of FLFlash record they receive the DiskOnChip memory window base pointer and offset (2 separated arguments). The previous implementation did not support address shifting properly. * Changed tffscpy and tffsset to flcpy and flset when flUse8bit equals 0. * Changed memWinowSize to memWindowSize * * Rev 1.13 Jan 17 2002 22:59:30 oris * Completely revised, to support runtime customization and all M-Systems * DiskOnChip devices. * * Rev 1.12 Sep 25 2001 15:35:02 oris * Restored to OSAK 4.3 implementation. * */ /************************************************************************/ /* */ /* FAT-FTL Lite Software Development Kit */ /* Copyright (C) M-Systems Ltd. 1995-2001 */ /* */ /************************************************************************/ #include "docsys.h" /* * Uncomment the FL_INIT_MMU_PAGES definition for: * * 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. * */ #define FL_INIT_MMU_PAGES #ifndef FL_NO_USE_FUNC /*********************************************************/ /* Report DiskOnChip Memory size */ /*********************************************************/ /*---------------------------------------------------------------------- f l D o c M e m W i n S i z e N o S h i f t This routine is called from MTD to quary the size of the DiskOnChip memory window for none shifted DiskOnChip. ------------------------------------------------------------------------*/ dword flDocMemWinSizeNoShift(void) { return 0x2000; } /*---------------------------------------------------------------------- f l D o c M e m W i n S i z e S i n g l e S h i f t This routine is called from MTD to quary the size of the DiskOnChip memory window for DiskOnChip connected with a single addres shift. ------------------------------------------------------------------------*/ dword flDocMemWinSizeSingleShift(void) { return 0x4000; } /*---------------------------------------------------------------------- f l D o c M e m W i n S i z e D o u b l e S h i f t This routine is called from MTD to quary the size of the DiskOnChip memory window for DiskOnChip connected with a double addres shift. ------------------------------------------------------------------------*/ dword flDocMemWinSizeDoubleShift(void) { return 0x8000; } /*********************************************************/ /* Write 16 bits to DiskOnChip memory window */ /*********************************************************/ /*---------------------------------------------------------------------- f l W r i t e 1 6 b i t D u m m y Dummy routine - write 16-bits to memory (does nothing). ------------------------------------------------------------------------*/ void flWrite16bitDummy(volatile byte FAR0 * win, word offset,Reg16bitType val) { DEBUG_PRINT(("Wrong customization - 16bit write was used with no implemented.\r\n")); } /*---------------------------------------------------------------------- f l W r i t e 1 6 b i t U s i n g 1 6 b i t s N o S h i f t Note : offset must be 16-bits aligned. Write 16-bit Using 16-bits operands with no address shifted. ------------------------------------------------------------------------*/ void flWrite16bitUsing16bitsNoShift(volatile byte FAR0 * win, word offset,Reg16bitType val) { ((volatile word FAR0*)win)[offset>>1] = val; } /*---------------------------------------------------------------------- f l W r i t e 1 6 b i t U s i n g 3 2 b i t s S i n g l e S h i f t Note : offset must be 16-bits aligned. Write 16-bit Using 16-bits operands with a single address shifted. ------------------------------------------------------------------------*/ void flWrite16bitUsing32bitsSingleShift(volatile byte FAR0 * win, word offset,Reg16bitType val) { #ifdef FL_BIG_ENDIAN ((volatile dword FAR0*)win)[offset>>1] = ((dword)val)<<16; #else ((volatile dword FAR0*)win)[offset>>1] = (dword)val; #endif /* FL_BIG_ENDIAN */ } /*********************************************************/ /* Read 16 bits from DiskOnChip memory window */ /*********************************************************/ /*---------------------------------------------------------------------- f l R e a d 1 6 b i t D u m m y Dummy routine - read 16-bits from memory (does nothing). ------------------------------------------------------------------------*/ Reg16bitType flRead16bitDummy(volatile byte FAR0 * win,word offset) { DEBUG_PRINT(("Wrong customization - 16bit read was issued with no implementation.\r\n")); return 0; } /*---------------------------------------------------------------------- f l R e a d 1 6 b i t U s i n g 1 6 b i t s N o S h i f t Note : offset must be 16-bits aligned. Read 16-bit Using 16-bits operands with no address shifted. ------------------------------------------------------------------------*/ Reg16bitType flRead16bitUsing16bitsNoShift(volatile byte FAR0 * win,word offset) { return ((volatile word FAR0*)win)[offset>>1]; } /*---------------------------------------------------------------------- f l R e a d 1 6 b i t U s i n g 3 2 b i t s S i n g l e S h i f t Note : offset must be 16-bits aligned. Read 16-bit Using 16-bits operands with single address shifted. ------------------------------------------------------------------------*/ Reg16bitType flRead16bitUsing32bitsSingleShift(volatile byte FAR0 * win,word offset) { #ifdef FL_BIG_ENDIAN return (Reg16bitType)(((volatile dword FAR0*)win)[offset>>1]<<16); #else return (Reg16bitType)((volatile dword FAR0*)win)[offset>>1]; #endif /* FL_BIG_ENDIAN */ } /*********************************************************/ /* Write 8 bits to DiskOnChip memory window */ /*********************************************************/ /*---------------------------------------------------------------------- f l W r i t e 8 b i t U s i n g 8 b i t s N o S h i f t Write 8-bits Using 8-bits operands with no address shifted. ------------------------------------------------------------------------*/ void flWrite8bitUsing8bitsNoShift(volatile byte FAR0 * win, word offset,Reg8bitType val) { win[offset] = val; } /*---------------------------------------------------------------------- f l W r i t e 8 b i t U s i n g 16 b i t s N o S h i f t Note : DiskOnChip is connected with 16-bit data bus. Note : Data is written only to lower memory addresses. Write 8-bits Using 16-bits operands with no address shifted. ------------------------------------------------------------------------*/ void flWrite8bitUsing16bitsNoShift(volatile byte FAR0 * win, word offset,Reg8bitType val) { #ifdef FL_BIG_ENDIAN ((volatile word FAR0 *)win)[offset>>1] = ((word)val)<<8; #else ((volatile word FAR0 *)win)[offset>>1] = (word)val; #endif /* FL_BIG_ENDIAN */ } /*---------------------------------------------------------------------- f l W r i t e 8 b i t U s i n g 16 b i t s S i n g l e S h i f t Note : Data is written only to 8-LSB. Write 8-bits Using 16-bits operands with Single address shifted. ------------------------------------------------------------------------*/ void flWrite8bitUsing16bitsSingleShift(volatile byte FAR0 * win, word offset,Reg8bitType val) { ((volatile word FAR0 *)win)[offset] = (word)val; } /*---------------------------------------------------------------------- f l W r i t e 8 b i t U s i n g 32 b i t s S i n g l e S h i f t Note : DiskOnChip is connected with 16-bit data bus. Note : Data is written to both data bus 8-bits Write 8-bits Using 32-bits operands with single address shifted. ------------------------------------------------------------------------*/ void flWrite8bitUsing32bitsSingleShift(volatile byte FAR0 * win, word offset,Reg8bitType val) { #ifdef FL_BIG_ENDIAN ((volatile dword FAR0 *)win)[offset>>1] = (dword)val*0x01010101L; #else ((volatile dword FAR0 *)win)[offset>>1] = (dword)val; #endif /* FL_BIG_ENDIAN */ } /*---------------------------------------------------------------------- f l W r i t e 8 b i t U s i n g 32 b i t s D o u b l e S h i f t Note : Data is written only to 8-LSB. Write 8-bits Using 32-bits operands with Double address shifted. ------------------------------------------------------------------------*/ void flWrite8bitUsing32bitsDoubleShift(volatile byte FAR0 * win, word offset,Reg8bitType val) { ((volatile dword FAR0 *)win)[offset] = (dword)val; } /*********************************************************/ /* Read 8 bits to DiskOnChip memory window */ /*********************************************************/ /*---------------------------------------------------------------------- f l R e a d 8 b i t U s i n g 8 b i t s N o S h i f t Read 8-bits Using 8-bits operands with no address shifted. ------------------------------------------------------------------------*/ Reg8bitType flRead8bitUsing8bitsNoShift(volatile byte FAR0 * win,word offset) { return win[offset]; } /*---------------------------------------------------------------------- f l R e a d 8 b i t U s i n g 16 b i t s N o S h i f t Note : DiskOnChip is connected with 16-bit data bus. Read 8-bits Using 16-bits operands with no address shifted. ------------------------------------------------------------------------*/ Reg8bitType flRead8bitUsing16bitsNoShift(volatile byte FAR0 * win,word offset) { #ifdef FL_BIG_ENDIAN return (((offset & 0x1) == 0) ? #else return (( offset & 0x1 ) ? #endif /* FL_BIG_ENDIAN */ (Reg8bitType)(((volatile word FAR0 *)win)[offset>>1]>>8) : (Reg8bitType) ((volatile word FAR0 *)win)[offset>>1] ); } /*---------------------------------------------------------------------- f l R e a d 8 b i t U s i n g 16 b i t s S i n g l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Read 8-bits Using 16-bits operands with Single address shifted. ------------------------------------------------------------------------*/ Reg8bitType flRead8bitUsing16bitsSingleShift(volatile byte FAR0 * win,word offset) { return (Reg8bitType)((volatile word FAR0 *)win)[offset]; } /*---------------------------------------------------------------------- f l R e a d 8 b i t U s i n g 32 b i t s S i n g l e S h i f t Note : DiskOnChip is connected with 16-bit data bus. Read 8-bits Using 16-bits operands with Single address shifted. ------------------------------------------------------------------------*/ Reg8bitType flRead8bitUsing32bitsSingleShift(volatile byte FAR0 * win,word offset) { #ifdef FL_BIG_ENDIAN return (((offset & 0x1) == 0) ? #else return (( offset & 0x1 ) ? #endif /* FL_BIG_ENDIAN */ (Reg8bitType)(((volatile dword FAR0 *)win)[offset>>1]>>24) : (Reg8bitType) ((volatile dword FAR0 *)win)[offset>>1] ); } /*---------------------------------------------------------------------- f l R e a d 8 b i t U s i n g 32 b i t s D o u b l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Read 8-bits Using 16-bits operands with Single address shifted. ------------------------------------------------------------------------*/ Reg8bitType flRead8bitUsing32bitsDoubleShift(volatile byte FAR0 * win,word offset) { return (Reg8bitType)((volatile dword FAR0 *)win)[offset]; } /*********************************************************/ /*********************************************************/ /*** Operation on several bytes (read/write/set) ***/ /*********************************************************/ /*********************************************************/ /*************************************************/ /* 8-Bit DiskOnChip - No Shift */ /*************************************************/ /*---------------------------------------------------------------------- f l 8 b i t D o c R e a d N o S h i f t Read 'count' bytes, from a none shifted address bus using tffscpy. ------------------------------------------------------------------------*/ void fl8bitDocReadNoShift(volatile byte FAR0 * win,word offset,byte FAR1* dest,word count) { #ifdef FL_INIT_MMU_PAGES if (count == 0) return; *dest = (byte)0; *((byte FAR1*)addToFarPointer(dest, (count - 1)) ) = (byte)0; #endif /* FL_INIT_MMU_PAGES */ tffscpy(dest,(void FAR0*)(win+offset),count); } /*---------------------------------------------------------------------- f l 8 b i t D o c W r i t e N o S h i f t Write 'count' bytes, from a none shifted address bus using tffscpy. ------------------------------------------------------------------------*/ void fl8bitDocWriteNoShift(volatile byte FAR0 * win,word offset,byte FAR1* src,word count) { tffscpy((void FAR0*)( win+offset),src,count); } /*---------------------------------------------------------------------- f l 8 b i t D o c S e t N o S h i f t Set 'count' bytes, from a none shifted address bus using tffsset. ------------------------------------------------------------------------*/ void fl8bitDocSetNoShift(volatile byte FAR0 * win,word offset,word count, byte val) { tffsset((void FAR0*)( win+offset),val,count); } /*************************************************/ /* 8-Bit DiskOnChip - Single Shift */ /*************************************************/ /*---------------------------------------------------------------------- f l 8 b i t D o c R e a d S i n g l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Read 'count' bytes, from data bus's LSB lane with 1 address shifted ------------------------------------------------------------------------*/ void fl8bitDocReadSingleShift(volatile byte FAR0 * win,word offset,byte FAR1* dest,word count) { volatile word FAR0 * doc = (volatile word FAR0 *) win + offset; register int i; #ifdef FL_INIT_MMU_PAGES if (count == 0) return; *dest = (byte)0; *((byte FAR1*)addToFarPointer(dest, (count - 1)) ) = (byte)0; #endif /* FL_INIT_MMU_PAGES */ for(i=0;( i < count );i++) dest[i] = (Reg8bitType)doc[i]; } /*---------------------------------------------------------------------- f l 8 b i t D o c W r i t e S i n g l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Write 'count' bytes, to data bus's LSB lane with 1 address shifted. ------------------------------------------------------------------------*/ void fl8bitDocWriteSingleShift(volatile byte FAR0 * win,word offset,byte FAR1* src,word count) { volatile word FAR0 * doc = (volatile word FAR0 *) win + offset; register int i; for(i=0;( i < count );i++) doc[i] = (word)src[i]; } /*---------------------------------------------------------------------- f l 8 b i t D o c S e t S i n g l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Set 'count' bytes, of data bus's LSB lane with 1 address shifted. ------------------------------------------------------------------------*/ void fl8bitDocSetSingleShift(volatile byte FAR0 * win,word offset,word count, byte val) { volatile word FAR0 * doc = (volatile word FAR0 *) win + offset; register int i; for(i=0;( i < count );i++) doc[i] = (word)val; } /*************************************************/ /* 8-Bit DiskOnChip - Double Shift */ /*************************************************/ /*---------------------------------------------------------------------- f l 8 b i t D o c R e a d D o u b l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Read 'count' bytes, from data bus's LSB lane with 2 address shifted. ------------------------------------------------------------------------*/ void fl8bitDocReadDoubleShift(volatile byte FAR0 * win,word offset,byte FAR1* dest,word count) { volatile dword FAR0 * doc = (volatile dword FAR0 *) win + offset; register int i; #ifdef FL_INIT_MMU_PAGES if (count == 0) return; *dest = (byte)0; *((byte FAR1*)addToFarPointer(dest, (count - 1)) ) = (byte)0; #endif /* FL_INIT_MMU_PAGES */ for(i=0;( i < count );i++) dest[i] = (Reg8bitType)doc[i]; } /*---------------------------------------------------------------------- f l 8 b i t D o c W r i t e D o u b l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Write 'count' bytes, to data bus's LSB lane with 2 address shifted. ------------------------------------------------------------------------*/ void fl8bitDocWriteDoubleShift(volatile byte FAR0 * win,word offset,byte FAR1* src,word count) { volatile dword FAR0 * doc = (volatile dword FAR0 *) win + offset; register int i; for(i=0;( i < count );i++) doc[i] = (dword)src[i]; } /*---------------------------------------------------------------------- f l 8 b i t D o c S e t D o u b l e S h i f t Note : Assume data is found in 8-LSB of DiskOnChip Set 'count' bytes, of data bus's LSB lane with 2 address shifted. ------------------------------------------------------------------------*/ void fl8bitDocSetDoubleShift(volatile byte FAR0 * win,word offset,word count, byte val) { volatile dword FAR0 * doc = (volatile dword FAR0 *) win+offset; register int i; for(i=0;( i < count );i++) doc[i] = (dword)val; } /*************************************************/ /* 16-Bit DiskOnChip - No Shift */ /*************************************************/ /*---------------------------------------------------------------------- f l 1 6 b i t D o c R e a d N o S h i f t Read 'count' bytes from M+ DiskOnChip with none shifted address bus. ------------------------------------------------------------------------*/ void fl16bitDocReadNoShift (volatile byte FAR0 * win, word offset, byte FAR1 * dest, word count ) { volatile word FAR0 * swin = (volatile word FAR0 *)( win + offset); register int i; register word tmp; #ifdef FL_INIT_MMU_PAGES if (count == 0) return; *dest = (byte)0; *((byte FAR1*)addToFarPointer(dest, (count - 1)) ) = (byte)0; #endif /* FL_INIT_MMU_PAGES */ if( pointerToPhysical(dest) & 0x1 ) { /* rare case: unaligned target buffer */ for (i = 0; i < (int)count; ) { tmp = *swin; #ifdef FL_BIG_ENDIAN dest[i++] = (byte)(tmp>>8); dest[i++] = (byte)tmp; #else dest[i++] = (byte)tmp; dest[i++] = (byte)(tmp>>8); #endif /* FL_BIG_ENDIAN */ } } else { /* mainstream case */ #ifdef USE_TFFS_COPY tffscpy( dest, (void FAR0 *)( win + offset), count ); #else #ifdef ENVIRONMENT_VARS if (flUse8Bit == 0) { flcpy( dest, (void FAR0 *)( win + offset), count ); } else #endif /* ENVIRONMENT_VARS */ { /* read in short words */ for (i = 0, count = count >> 1; i < (int)count; i++) ((word FAR1 *)dest)[i] = swin[i]; } #endif /* USE_TFFS_COPY */ } } /*---------------------------------------------------------------------- f l 1 6 b i t D o c W r i t e N o S h i f t Write 'count' bytes to M+ DiskOnChip with none shifted address bus. ------------------------------------------------------------------------*/ void fl16bitDocWriteNoShift ( volatile byte FAR0 * win , word offset , byte FAR1 * src, word count ) { volatile word FAR0 * swin = (volatile word FAR0 *)( win + offset); register int i; register word tmp; if( pointerToPhysical(src) & 0x1 ) /* rare case: unaligned source buffer */ { for (i = 0; i < (int)count; i+=2) { /* tmp variable is just a precation from compiler optimizations */ #ifdef FL_BIG_ENDAIN tmp = ((word)src[i]<<8) + (word)src[i+1]; #else tmp = (word)src[i] + ((word)src[i+1]<<8); #endif /* FL_BIG_ENDAIN */ *swin = tmp; } } else /* mainstream case */ { #ifdef USE_TFFS_COPY tffscpy( (void FAR0 *)(win + offset), src, count ); #else #ifdef ENVIRONMENT_VARS if (flUse8Bit == 0) { flcpy( (void FAR0 *)(win + offset), src, count ); } else #endif /* ENVIRONMENT_VARS */ { /* write in short words */ for (i = 0, count = count >> 1; i < (int)count; i++) *swin = ((word FAR1 *)src)[i]; } #endif /* USE_TFFS_COPY */ } } /*---------------------------------------------------------------------- f l 1 6 b i t D o c S e t N o S h i f t Set 'count' bytes of M+ DiskOnChip with none shifted address bus ------------------------------------------------------------------------*/ void fl16bitDocSetNoShift ( volatile byte FAR0 * win , word offset , word count , byte val) { volatile word FAR0 * swin = (volatile word FAR0 *)( win + offset); register int i; word tmpVal = (word)val * 0x0101; #ifdef USE_TFFS_COPY tffsset( (void FAR0 *)(win + offset), val, count ); #else #ifdef ENVIRONMENT_VARS if (flUse8Bit == 0) { flset( (void FAR0 *)(win + offset), val, count ); } else #endif /* ENVIRONMENT_VARS */ { /* write in short words */ for (i = 0; i < (int)count; i+=2) *swin = tmpVal; } #endif /* USE_TFFS_COPY */ } /*************************************************************/ /* 16-Bit DiskOnChip - No Shift - Only 8 bits are valid */ /*************************************************************/ /*---------------------------------------------------------------------- f l 1 6 b i t D o c R e a d N o S h i f t I g n o r e H i g h e r 8 B i t s Note : offset must be 16-bits aligned. Read 'count' bytes from M+ DiskOnChip connected with all 16 data bits, but in interleave-1 mode , therefore only one of the 8 bits contains actual data. The DiskOnChip is connected without an address shift. ------------------------------------------------------------------------*/ void fl16bitDocReadNoShiftIgnoreHigher8bits(volatile byte FAR0 * win, word offset, byte FAR1 * dest, word count ) { volatile word FAR0 * swin = (volatile word FAR0 *)( win + offset); register int i; #ifdef FL_INIT_MMU_PAGES if (count == 0) return; *dest = (byte)0; *((byte FAR1*)addToFarPointer(dest, (count - 1)) ) = (byte)0; #endif /* FL_INIT_MMU_PAGES */ for (i = 0; i < (int)count; i++) { #ifdef FL_BIG_ENDIAN dest[i] = (byte)(swin[i]>>8); #else dest[i] = (byte)swin[i]; #endif /* FL_BIG_ENDIAN */ } } /*---------------------------------------------------------------------- f l 1 6 D o c W r i t e N o S h i f t I g n o r e H i g h e r 8 b i t s Note : offset must be 16-bits aligned. Write 'count' bytes to M+ DiskOnChip connected with all 16 data bits, but in interleave-1 mode , therefore only one of the 8bits contains actual data. The DiskOnChip is connected without an address shift. ------------------------------------------------------------------------*/ void fl16bitDocWriteNoShiftIgnoreHigher8bits ( volatile byte FAR0 * win , word offset , byte FAR1 * src, word count ) { volatile word FAR0 * swin = (volatile word FAR0 *)( win + offset); register int i; for (i = 0; i < (int)count; i++) { #ifdef FL_BIG_ENDIAN *swin = ((word)src[i])<<8; #else *swin = (word)src[i]; #endif /* FL_BIG_ENDIAN */ } } /*---------------------------------------------------------------------- f l 1 6 D o c S e t N o S h i f t I g n o r e H i g h e r 8 b i t s Note : offset must be 16-bits aligned. Set 'count' bytes to M+ DiskOnChip connected with all 16 data bits, but in interleave-1 mode , therefore only one of the 8bits contains actual data. The DiskOnChip is connected without an address shift. ------------------------------------------------------------------------*/ void fl16bitDocSetNoShiftIgnoreHigher8bits ( volatile byte FAR0 * win , word offset , word count , byte val) { volatile word FAR0 * swin = (volatile word FAR0 *)( win + offset); register int i; word tmpVal = val * 0x0101; for (i = 0; i < (int)count; i++) *swin = tmpVal; } /****************************************/ /* 16-Bit DiskOnChip - Single Shift */ /****************************************/ /*---------------------------------------------------------------------- f l 1 6 b i t D o c R e a d S i n g l e S h i f t Read 'count' bytes from M+ DiskOnChip with none shifted address bus. ------------------------------------------------------------------------*/ void fl16bitDocReadSingleShift (volatile byte FAR0 * win, word offset, byte FAR1 * dest, word count ) { volatile dword FAR0 * swin = (volatile dword FAR0 *)win + (offset>>1); register int i; register dword tmp; #ifdef FL_INIT_MMU_PAGES if (count == 0) return; *dest = (byte)0; *((byte FAR1*)addToFarPointer(dest, (count - 1)) ) = (byte)0; #endif /* FL_INIT_MMU_PAGES */ if( pointerToPhysical(dest) & 0x1 ) { /* rare case: unaligned target buffer */ for (i = 0; i < (int)count; ) { tmp = *swin; #ifdef FL_BIG_ENDAIN dest[i++] = (byte)(tmp>>24); dest[i++] = (byte)(tmp>>16); #else dest[i++] = (byte)tmp; dest[i++] = (byte)(tmp>>8); #endif /* FL_BIG_ENDAIN */ } } else { /* mainstream case */ for (i = 0, count = count >> 1; i < (int)count; i++) { #ifdef FL_BIG_ENDAIN ((word FAR1 *)dest)[i] = (word)(swin[i]>>16); #else ((word FAR1 *)dest)[i] = (word)swin[i]; #endif /* FL_BIG_ENDAIN */ } } } /*---------------------------------------------------------------------- f l 1 6 b i t D o c W r i t e S i n g l e S h i f t Write 'count' bytes to M+ DiskOnChip with none shifted address bus. ------------------------------------------------------------------------*/ void fl16bitDocWriteSingleShift ( volatile byte FAR0 * win , word offset , byte FAR1 * src, word count ) { volatile dword FAR0 * swin = (volatile dword FAR0 *)win + (offset>>1); register int i; register dword tmp; if( pointerToPhysical(src) & 0x1 ) /* rare case: unaligned source buffer */ { for (i = 0; i < (int)count; i+=2) { #ifdef FL_BIG_ENDAIN tmp = (((dword)src[i])<<24) + (((dword)src[i+1])<<16); #else tmp = (dword)src[i] + (((dword)src[i+1])<<8); #endif /* FL_BIG_ENDAIN */ *swin = tmp; } } else /* mainstream case */ { for (i = 0, count = count >> 1; i < (int)count; i++) #ifdef FL_BIG_ENDIAN *swin = ((dword)((word FAR1 *)src)[i])<<16; #else *swin = (dword)((word FAR1 *)src)[i]; #endif /* FL_BIG_ENDIAN */ } } /*---------------------------------------------------------------------- f l 1 6 b i t D o c S e t S i n g l e S h i f t Set 'count' bytes of M+ DiskOnChip with none shifted address bus ------------------------------------------------------------------------*/ void fl16bitDocSetSingleShift ( volatile byte FAR0 * win , word offset , word count , byte val) { volatile dword FAR0 * swin = (volatile dword FAR0 *)win + (offset>>1); register int i; register dword tmpVal = (dword)val * 0x01010101L; for (i = 0; i < (int)count; i+=2) *swin = tmpVal; } /**************************************************************/ /* 16-Bit DiskOnChip - Single Shift - Only 8 bits are valid */ /**************************************************************/ /*---------------------------------------------------------------------- f l 1 6 b i t D o c R e a d S i n g l e S h i f t I g n o r e H i g h e r 8 B i t s Note : offset must be 16-bits aligned. Read 'count' bytes from M+ DiskOnChip connected with all 16 data bits, but in interleave-1 mode , therefore only one of the 8 bits contains actual data. The DiskOnChip is connected without an address shift. ------------------------------------------------------------------------*/ void fl16bitDocReadSingleShiftIgnoreHigher8bits(volatile byte FAR0 * win, word offset, byte FAR1 * dest, word count ) { volatile dword FAR0 * swin = (volatile dword FAR0 *)win + (offset>>1); register int i; #ifdef FL_INIT_MMU_PAGES if (count == 0) return; *dest = (byte)0; *((byte FAR1*)addToFarPointer(dest, (count - 1)) ) = (byte)0; #endif /* FL_INIT_MMU_PAGES */ for (i = 0; i < (int)count; i++) { #ifdef FL_BIG_ENDAIN dest[i] = (byte)(swin[i]>>24); #else dest[i] = (byte)swin[i]; #endif /* FL_BIG_ENDAIN */ } } /*---------------------------------------------------------------------- f l 1 6 D o c W r i t e S i n g l e S h i f t I g n o r e H i g h e r 8 b i t s Note : offset must be 16-bits aligned. Write 'count' bytes to M+ DiskOnChip connected with all 16 data bits, but in interleave-1 mode , therefore only one of the 8bits contains actual data. The DiskOnChip is connected without an address shift. ------------------------------------------------------------------------*/ void fl16bitDocWriteSingleShiftIgnoreHigher8bits ( volatile byte FAR0 * win , word offset , byte FAR1 * src, word count ) { volatile dword FAR0 * swin = (volatile dword FAR0 *)win + (offset>>1); register int i; for (i = 0; i < (int)count; i++) { #ifdef FL_BIG_ENDAIN *swin = ((dword)src[i]<<24); #else *swin = (dword)src[i]; #endif /* FL_BIG_ENDAIN */ } } /*---------------------------------------------------------------------- f l 1 6 D o c S e t S i n g l e S h i f t I g n o r e H i g h e r 8 b i t s Note : offset must be 16-bits aligned. Set 'count' bytes to M+ DiskOnChip connected with all 16 data bits, but in interleave-1 mode , therefore only one of the 8bits contains actual data. The DiskOnChip is connected without an address shift. ------------------------------------------------------------------------*/ void fl16bitDocSetSingleShiftIgnoreHigher8bits ( volatile byte FAR0 * win , word offset , word count , byte val) { volatile dword FAR0 * swin = (volatile dword FAR0 *)win + (offset>>1); register int i; dword tmpVal = (dword)val * 0x01010101L; for (i = 0; i < (int)count; i++) *swin = tmpVal; } /**********************************************************/ /* Set proper access type routines into the proper record */ /**********************************************************/ /*----------------------------------------------------------------------*/ /* s e t B u s T y p e O f F l a s h */ /* */ /* Set DiskOnChip socket / flash memory access routine. */ /* This routine must be called by the MTD prior to any access to the */ /* DiskOnChip */ /* */ /* Parameters: */ /* flflash : Pointer to sockets flash record. */ /* access : Type of memory access routines to install */ /* */ /* Note: The possible type of memory access routine are comprised of: */ /* */ /* Address shift: */ /* FL_NO_ADDR_SHIFT - No address shift */ /* FL_SINGLE_ADDR_SHIFT - Single address shift */ /* FL_DOUBLE_ADDR_SHIFT - Double address shift */ /* */ /* Platform bus capabilities (access width): */ /* FL_BUS_HAS_8BIT_ACCESS - Bus can access 8-bit */ /* FL_BUS_HAS_16BIT_ACCESS - Bus can access 16-bit */ /* FL_BUS_HAS_32BIT_ACCESS - Bus can access 32-bit */ /* */ /* Number of data bits connected to the DiskOnChip (if_cfg): */ /* FL_8BIT_DOC_ACCESS - DiskOnChip has 8 data bits */ /* FL_16BIT_DOC_ACCESS - DiskOnChip has 16 data bits */ /* */ /* Flash data bits that can be accessed in a bus cycle (interleave): */ /* FL_8BIT_FLASH_ACCESS - 8 bits of flash per cycle */ /* FL_16BIT_FLASH_ACCESS - 16 bits of flash per cycle */ /* */ /* Ignore all of the above and use user defined access routines: */ /* FL_ACCESS_USER_DEFINED - Do not install any routine since */ /* user already installed custome made */ /* routines */ /* */ /* Returns: */ /* FLStatus : 0 on success, otherwise failed */ /*----------------------------------------------------------------------*/ FLStatus setBusTypeOfFlash(FLFlash * flash,dword access) { /* sanity checks here if needed */ if(flash==NULL) { DEBUG_PRINT(("Flash record passed to setBusTypeOfFlash is NULL.\r\n")); return flBadParameter; } /* check if user already defined the memory access routines */ if ((access & FL_ACCESS_USER_DEFINED) != 0) return flOK; /************************************/ /* install requested access methods */ /************************************/ switch(access & FL_XX_ADDR_SHIFT_MASK) { case FL_NO_ADDR_SHIFT: flash->memWindowSize = &flDocMemWinSizeNoShift; switch(access & FL_XX_DATA_BITS_MASK) { case FL_8BIT_DOC_ACCESS: /* if_cfg set to 8-bits */ /* Make sure bus supports 8 bit access */ if((access & FL_BUS_HAS_8BIT_ACCESS) == 0) { DEBUG_PRINT(("ERROR: TrueFFS requires 8-bit access to DiskOnChip memory window\r\n")); DEBUG_PRINT((" for 8-bit DiskOnChip connected with no address shift.\r\n")); return flBadParameter; } flash->memWrite8bit = &flWrite8bitUsing8bitsNoShift; flash->memRead8bit = &flRead8bitUsing8bitsNoShift; flash->memRead16bit = &flRead16bitDummy; flash->memWrite16bit = &flWrite16bitDummy; flash->memRead = &fl8bitDocReadNoShift; flash->memWrite = &fl8bitDocWriteNoShift; flash->memSet = &fl8bitDocSetNoShift; break; case FL_16BIT_DOC_ACCESS: /* if_cfg set to 16-bits (Plus family) */ /* Make sure bus supports 16 bit access */ if((access & FL_BUS_HAS_16BIT_ACCESS) == 0) { DEBUG_PRINT(("ERROR: TrueFFS requires 16-bit access to DiskOnChip memory window\r\n")); DEBUG_PRINT((" for 16-bit DiskOnChip connected with no address shift.\r\n")); return flBadParameter; } flash->memWrite8bit = &flWrite8bitUsing16bitsNoShift; flash->memRead8bit = &flRead8bitUsing16bitsNoShift; flash->memRead16bit = &flRead16bitUsing16bitsNoShift; flash->memWrite16bit = &flWrite16bitUsing16bitsNoShift; switch(access & FL_XX_FLASH_ACCESS_MASK) /* Interleave */ { case FL_8BIT_FLASH_ACCESS: /* Interleave - 1 */ flash->memRead = &fl16bitDocReadNoShiftIgnoreHigher8bits; flash->memWrite = &fl16bitDocWriteNoShiftIgnoreHigher8bits; flash->memSet = &fl16bitDocSetNoShiftIgnoreHigher8bits; break; case FL_16BIT_FLASH_ACCESS: /* Interleave - 2 */ flash->memRead = &fl16bitDocReadNoShift; flash->memWrite = &fl16bitDocWriteNoShift; flash->memSet = &fl16bitDocSetNoShift; break; default: DEBUG_PRINT(("TrueFFS does not support this flash access type (setBusTypeOfFlash).\r\n")); return flBadParameter; } break; default: DEBUG_PRINT(("TrueFFS does not support this number of DiskOnChip data bits (setBusTypeOfFlash).\r\n")); return flBadParameter; } break; case FL_SINGLE_ADDR_SHIFT: /* Install memory window size routine */ flash->memWindowSize = &flDocMemWinSizeSingleShift; switch(access & FL_XX_DATA_BITS_MASK) { case FL_8BIT_DOC_ACCESS: /* if_cfg set to 8bits (None plus family)*/ /* Make sure bus supports 16 bit access */ if((access & FL_BUS_HAS_16BIT_ACCESS) == 0) { DEBUG_PRINT(("ERROR: TrueFFS requires 16-bit access to DiskOnChip memory window\r\n")); DEBUG_PRINT((" for 8-bit DiskOnChip connected with a single address shift.\r\n")); return flBadParameter; } flash->memWrite8bit = &flWrite8bitUsing16bitsSingleShift; flash->memRead8bit = &flRead8bitUsing16bitsSingleShift; flash->memRead16bit = &flRead16bitDummy; flash->memWrite16bit = &flWrite16bitDummy; flash->memRead = &fl8bitDocReadSingleShift; flash->memWrite = &fl8bitDocWriteSingleShift; flash->memSet = &fl8bitDocSetSingleShift; break; case FL_16BIT_DOC_ACCESS: /* if_cfg set to 8bits (Plus family) */ /* Make sure bus supports 32 bit access */ if((access & FL_BUS_HAS_32BIT_ACCESS) == 0) { DEBUG_PRINT(("ERROR: TrueFFS requires 32-bit access to DiskOnChip memory window\r\n")); DEBUG_PRINT((" for 16-bit DiskOnChip connected with a single address shift.\r\n")); return flBadParameter; } flash->memWrite8bit = &flWrite8bitUsing32bitsSingleShift; flash->memRead8bit = &flRead8bitUsing32bitsSingleShift; flash->memRead16bit = &flRead16bitUsing32bitsSingleShift; flash->memWrite16bit = &flWrite16bitUsing32bitsSingleShift; switch(access & FL_XX_FLASH_ACCESS_MASK) /* Interleave */ { case FL_8BIT_FLASH_ACCESS: /* Interleave - 1 */ flash->memRead = &fl16bitDocReadSingleShiftIgnoreHigher8bits; flash->memWrite = &fl16bitDocWriteSingleShiftIgnoreHigher8bits; flash->memSet = &fl16bitDocSetSingleShiftIgnoreHigher8bits; break; case FL_16BIT_FLASH_ACCESS: /* Interleave - 2 */ flash->memRead = &fl16bitDocReadSingleShift; flash->memWrite = &fl16bitDocWriteSingleShift; flash->memSet = &fl16bitDocSetSingleShift; break; default: DEBUG_PRINT(("TrueFFS does not support this flash access type (setBusTypeOfFlash).\r\n")); return flBadParameter; } break; default: DEBUG_PRINT(("TrueFFS does not support this number of DiskOnChip data bits (setBusTypeOfFlash).\r\n")); return flBadParameter; } break; case FL_DOUBLE_ADDR_SHIFT: /* Install memory window size routine */ flash->memWindowSize = &flDocMemWinSizeDoubleShift; switch(access & FL_XX_DATA_BITS_MASK) { case FL_8BIT_DOC_ACCESS: /* if_cfg set to 8bits or none plus family */ /* Make sure bus supports 32 bit access */ if((access & FL_BUS_HAS_32BIT_ACCESS) == 0) { DEBUG_PRINT(("ERROR: TrueFFS requires 32-bit access to DiskOnChip memory window\r\n")); DEBUG_PRINT((" for 8-bit DiskOnChip connected with a double address shift.\r\n")); return flBadParameter; } flash->memWrite8bit = &flWrite8bitUsing32bitsDoubleShift; flash->memRead8bit = &flRead8bitUsing32bitsDoubleShift; flash->memRead16bit = &flRead16bitDummy; flash->memWrite16bit = &flWrite16bitDummy; flash->memRead = &fl8bitDocReadDoubleShift; flash->memWrite = &fl8bitDocWriteDoubleShift; flash->memSet = &fl8bitDocSetDoubleShift; break; default: DEBUG_PRINT(("TrueFFS does not support this number of DiskOnChip data bits\r\n")); DEBUG_PRINT(("when connected with a double address shift (setBusTypeOfFlash).\r\n")); return flBadParameter; } break; default: DEBUG_PRINT(("TrueFFS does not support this kind of address shifting (setBusTypeOfFlash).\r\n")); return flBadParameter; } /* Store access type in flash record */ flash->busAccessType = access; return flOK; } #endif /* FL_NO_USE_FUNC */