aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/Source/c_loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'AT91SAM7S256/Source/c_loader.c')
-rw-r--r--AT91SAM7S256/Source/c_loader.c577
1 files changed, 577 insertions, 0 deletions
diff --git a/AT91SAM7S256/Source/c_loader.c b/AT91SAM7S256/Source/c_loader.c
new file mode 100644
index 0000000..b6e6436
--- /dev/null
+++ b/AT91SAM7S256/Source/c_loader.c
@@ -0,0 +1,577 @@
+//
+// Date init 14.12.2004
+//
+// Revision date $Date:: 12-03-08 15:28 $
+//
+// Filename $Workfile:: c_loader.c $
+//
+// Version $Revision:: 5 $
+//
+// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $
+//
+// Platform C
+//
+
+#include "stdconst.h"
+#include "modules.h"
+#include "c_loader.iom"
+#include "c_ioctrl.iom"
+#include "d_loader.h"
+#include "c_loader.h"
+#include <string.h>
+
+static IOMAPLOADER IOMapLoader;
+static VARSLOADER VarsLoader;
+static HEADER **pHeaders;
+
+const HEADER cLoader =
+{
+ 0x00090001L,
+ "Loader",
+ cLoaderInit,
+ cLoaderCtrl,
+ cLoaderExit,
+ (void *)&IOMapLoader,
+ (void *)&VarsLoader,
+ (UWORD)sizeof(IOMapLoader),
+ (UWORD)sizeof(VarsLoader),
+ 0x0000 //Code size - not used so far
+};
+
+UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength);
+UWORD cLoaderGetIoMapInfo(ULONG ModuleId, UBYTE *pIoMap, UWORD *pIoMapSize);
+UWORD cLoaderFindModule(UBYTE *pBuffer);
+void cLoaderGetModuleName(UBYTE *pDst, UBYTE *pModule);
+UWORD cLoaderCreateFile(UBYTE *pFileName, ULONG *pLength, UBYTE bLinear, UBYTE fType);
+UWORD cLoaderRenameFile(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength);
+UWORD cLoaderOpenRead(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength, UBYTE bLinear);
+UWORD cLoaderDeleteFile(UBYTE *pFileName);
+UWORD cLoaderResizeFile(UBYTE *pFileName, ULONG pLength);
+
+void cLoaderInit(void* pHeader)
+{
+
+ IOMapLoader.pFunc = &cLoaderFileRq;
+ VarsLoader.IoMapHandle = FALSE;
+ VarsLoader.Resizing = FALSE;
+ pHeaders = pHeader;
+ dLoaderInit();
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+}
+
+void cLoaderCtrl(void)
+{
+ if (VarsLoader.Resizing)
+ {
+ // keep resizing the file currently in the file resize operation
+ // copy 1024 bytes from old file handle to new file handle
+ // if no more bytes to copy then set Resizing to FALSE,
+ // close both files, and delete the old file.
+ }
+}
+
+UWORD cLoaderCreateFile(UBYTE *pFileName, ULONG *pLength, UBYTE bLinear, UBYTE fType)
+{
+ UWORD ReturnState;
+ /* This is to create a new file */
+ ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, bLinear, fType);
+ if (0x8000 <= ReturnState)
+ {
+ dLoaderCloseHandle(ReturnState);
+ }
+ else
+ {
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ }
+ return ReturnState;
+}
+
+UWORD cLoaderRenameFile(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength)
+{
+ UWORD ReturnState;
+ UBYTE FoundName[FILENAME_LENGTH + 1];
+
+ /* Check for file exists*/
+ ReturnState = dLoaderFind(pBuffer, FoundName, pLength, pLength, (UBYTE) SEARCHING);
+ dLoaderCloseHandle(LOADER_HANDLE(ReturnState));
+ if (FILENOTFOUND == LOADER_ERR(ReturnState))
+ {
+ ReturnState = dLoaderFind(pFileName, FoundName, pLength, pLength, (UBYTE) SEARCHING);
+ if (ReturnState < 0x8000)
+ {
+ ReturnState = dLoaderCheckFiles((UBYTE) ReturnState);
+ if (ReturnState < 0x8000)
+ {
+ dLoaderRenameFile((UBYTE) ReturnState, pBuffer);
+ }
+ }
+ dLoaderCloseHandle(LOADER_HANDLE(ReturnState));
+ }
+ else
+ {
+ if (SUCCESS == LOADER_ERR(ReturnState))
+ {
+ ReturnState |= FILEEXISTS;
+ }
+ }
+ return ReturnState;
+}
+
+UWORD cLoaderOpenRead(UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength, UBYTE bLinear)
+{
+ UWORD ReturnState;
+ if (bLinear)
+ ReturnState = dLoaderGetFilePtr(pFileName, pBuffer, pLength);
+ else
+ ReturnState = dLoaderOpenRead(pFileName, pLength);
+ if (0x8000 <= ReturnState)
+ {
+ dLoaderCloseHandle(ReturnState);
+ }
+ return ReturnState;
+}
+
+UWORD cLoaderDeleteFile(UBYTE *pFileName)
+{
+ UWORD ReturnState;
+ ReturnState = dLoaderDelete(pFileName);
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ return ReturnState;
+}
+
+UWORD cLoaderResizeFile(UBYTE *pFileName, ULONG pLength)
+{
+ UWORD ReturnState = SUCCESS;
+ /*
+ All that this method can do is start the process of
+ resizing a file. To do that we will
+ a) rename the file
+ b) open old file for reading
+ c) create new file for writing
+ d) store both handles in VarsLoader & set resizing flag
+ e) if any errors occur in a, b, or c then restore original file
+ f) return LOADER_BUSY (maybe?)
+ */
+/*
+ // rename file to _tmpoldname
+ strcat __frsFRArgs.NewFilename, '_tmp', __frsOldName
+ mov __frsFRArgs.OldFilename, __frsOldName
+ syscall FileRename, __frsFRArgs
+ mov __frsResult, __frsFRArgs.Result
+ brtst NEQ, __frsEnd, __frsResult
+ // old file has been renamed successfully
+ mov __frsFOReadArgs.Filename, __frsFRArgs.NewFilename
+ syscall FileOpenRead, __frsFOReadArgs
+ mov __frsResult, __frsFOReadArgs.Result
+ brtst NEQ, __frsOpenReadFailed, __frsResult
+ // renamed file is open for reading
+ mov __frsFOWriteArgs.Filename, __frsOldName
+ mov __frsFOWriteArgs.Length, __frsNewSize
+ syscall FileOpenWrite, __frsFOWriteArgs
+ mov __frsResult, __frsFOWriteArgs.Result
+ brtst NEQ, __frsOpenWriteFailed, __frsResult
+ // both files are open
+ mov __frsFReadArgs.FileHandle, __frsFOReadArgs.FileHandle
+ mov __frsFWriteArgs.FileHandle, __frsFOWriteArgs.FileHandle
+__frsCopyLoop:
+ set __frsFReadArgs.Length, 1024
+ syscall FileRead, __frsFReadArgs
+ brtst NEQ, __frsEndLoop, __frsFReadArgs.Result
+ brtst LTEQ, __frsEndLoop, __frsFReadArgs.Length
+ mov __frsFWriteArgs.Buffer, __frsFReadArgs.Buffer
+ mov __frsFWriteArgs.Length, __frsFReadArgs.Length
+ syscall FileWrite, __frsFWriteArgs
+ brtst NEQ, __frsEndLoop, __frsFWriteArgs.Result
+ jmp __frsCopyLoop
+__frsEndLoop:
+ // close read file
+ mov __frsFCArgs.FileHandle, __frsFOReadArgs.FileHandle
+ syscall FileClose, __frsFCArgs
+ // close write file
+ mov __frsFCArgs.FileHandle, __frsFOWriteArgs.FileHandle
+ syscall FileClose, __frsFCArgs
+ // delete read file
+ mov __frsFDArgs.Filename, __frsFOReadArgs.Filename
+ syscall FileDelete, __frsFDArgs
+ jmp __frsEnd
+__frsOpenWriteFailed:
+ // close read file
+ mov __frsFCArgs.FileHandle, __frsFOReadArgs.FileHandle
+ syscall FileClose, __frsFCArgs
+// jmp __frsEnd
+__frsOpenReadFailed:
+ // if the open read failed rename tmp back to original and exit
+ mov __frsFRArgs.OldFilename, __frsFRArgs.NewFilename
+ mov __frsFRArgs.NewFilename, __frsOldName
+ syscall FileRename, __frsFRArgs
+__frsEnd:
+ return
+*/
+ return ReturnState;
+}
+
+UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLength)
+{
+ UWORD ReturnState;
+
+ ReturnState = SUCCESS;
+
+ switch(Cmd)
+ {
+ case OPENREAD:
+ {
+ ReturnState = cLoaderOpenRead(pFileName, pBuffer, pLength, FALSE);
+ }
+ break;
+ case OPENREADLINEAR:
+ {
+ ReturnState = cLoaderOpenRead(pFileName, pBuffer, pLength, TRUE);
+ }
+ break;
+ case OPENWRITE:
+ {
+
+ /* This is to create a new file */
+ ReturnState = cLoaderCreateFile(pFileName, pLength, (UBYTE) NONLINEAR, SYSTEMFILE);
+ }
+ break;
+ case OPENWRITELINEAR:
+ {
+ ReturnState = cLoaderCreateFile(pFileName, pLength, (UBYTE) LINEAR, SYSTEMFILE);
+ }
+ break;
+ case OPENWRITEDATA:
+ {
+ ReturnState = cLoaderCreateFile(pFileName, pLength, (UBYTE) NONLINEAR, DATAFILE);
+ }
+ break;
+ case OPENAPPENDDATA:
+ {
+ ReturnState = dLoaderOpenAppend(pFileName, pLength);
+ if (LOADER_ERR(ReturnState) != SUCCESS)
+ {
+ dLoaderCloseHandle(ReturnState);
+ }
+ }
+ break;
+ case CLOSE:
+ {
+ ReturnState = dLoaderCloseHandle(*pFileName);
+ }
+ break;
+ case CROPDATAFILE:
+ {
+ ReturnState = dLoaderCropDatafile(*pFileName);
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ }
+ break;
+ case RESIZEDATAFILE:
+ {
+ ReturnState = cLoaderResizeFile(pFileName, *pLength);
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+ }
+ break;
+ case SEEKFROMSTART:
+ case SEEKFROMCURRENT:
+ case SEEKFROMEND:
+ {
+ // *pFileName is the handle, *pLength is the offset, Cmd-SEEKFROMSTART is the origin
+ ReturnState = dLoaderSeek(*pFileName, *(SLONG*)pLength, Cmd-SEEKFROMSTART);
+ }
+ break;
+ case FILEPOSITION:
+ {
+ // *pFileName is the handle, pLength is the returned file position
+ ReturnState = dLoaderTell(*pFileName, pLength);
+ }
+ break;
+ case READ:
+ {
+ ReturnState = dLoaderRead(*pFileName, pBuffer, pLength);
+ }
+ break;
+ case WRITE:
+ {
+ ReturnState = dLoaderWriteData(*pFileName, pBuffer, (UWORD*)pLength);
+ }
+ break;
+ case FINDFIRST:
+ {
+ ULONG DataLength;
+
+ ReturnState = dLoaderFind(pFileName, pBuffer, pLength, &DataLength, (UBYTE) SEARCHING);
+ if (0x8000 <= ReturnState)
+ {
+ dLoaderCloseHandle(ReturnState);
+ }
+ }
+ break;
+ case FINDNEXT:
+ {
+ UWORD Handle;
+ ULONG DataLength;
+
+ Handle = *pFileName;
+ ReturnState = dLoaderFindNext(Handle, pBuffer, pLength, &DataLength);
+ }
+ break;
+ case DELETE:
+ {
+ ReturnState = cLoaderDeleteFile(pFileName);
+
+ }
+ break;
+ case DELETEUSERFLASH:
+ {
+ dLoaderDeleteAllFiles();
+ IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash();
+
+ }
+ break;
+
+ case FINDFIRSTMODULE:
+ {
+ if (FALSE == VarsLoader.IoMapHandle)
+ {
+ VarsLoader.IoMapHandle = TRUE;
+ VarsLoader.ModSearchIndex = 0;
+ dLoaderInsertSearchStr(VarsLoader.ModSearchStr, pFileName, &(VarsLoader.ModSearchType));
+ ReturnState = cLoaderFindModule(pBuffer);
+ }
+ else
+ {
+ ReturnState = NOMOREHANDLES;
+ }
+ }
+ break;
+
+ case FINDNEXTMODULE:
+ {
+ ReturnState = cLoaderFindModule(pBuffer);
+ }
+ break;
+
+ case CLOSEMODHANDLE:
+ {
+ VarsLoader.IoMapHandle = FALSE;
+ ReturnState = SUCCESS;
+ }
+ break;
+
+ case IOMAPREAD:
+ {
+
+ UBYTE *pIoMap;
+ ULONG Ptr;
+ UWORD IoMapSize;
+ UBYTE Tmp;
+
+ pIoMap = NULL;
+ ReturnState = cLoaderGetIoMapInfo((*(ULONG*)(pFileName)),(UBYTE*)(&pIoMap), &IoMapSize);
+
+ /* Did we have a valid module ID ?*/
+ if (SUCCESS == LOADER_ERR(ReturnState))
+ {
+
+ /* This is the offset */
+ Ptr = pBuffer[0];
+ Ptr |= (UWORD)pBuffer[1] << 8;
+
+ /* is the offset within the limits of the iomap size? */
+ if ((Ptr + *pLength) <= IoMapSize)
+ {
+
+ /* Add the offset to the pointer */
+ pIoMap += Ptr;
+
+ for (Tmp = 0; Tmp < *pLength; Tmp++)
+ {
+ pBuffer[Tmp + 2] = *pIoMap;
+ pIoMap++;
+ }
+ }
+ else
+ {
+
+ /* Error - not within the bounderies */
+ ReturnState = OUTOFBOUNDERY;
+ *pLength = 0;
+ }
+ }
+ else
+ {
+
+ /* Error - not a valid module id */
+ *pLength = 0;
+ }
+ }
+ break;
+
+ case IOMAPWRITE:
+ {
+ UBYTE *pIoMap;
+ ULONG Ptr;
+ UWORD IoMapSize;
+ UWORD Tmp;
+
+
+ pIoMap = NULL;
+ ReturnState = cLoaderGetIoMapInfo(*((ULONG*)pFileName), (UBYTE*)&pIoMap, &IoMapSize);
+
+ if (LOADER_ERR(ReturnState) == SUCCESS)
+ {
+
+ /* This is the offset */
+ Ptr = *pBuffer;
+ pBuffer++;
+ Tmp = *pBuffer;
+ Ptr |= Tmp << 8;
+ pBuffer++;
+
+ if ((Ptr + *pLength) <= IoMapSize)
+ {
+
+ pIoMap += Ptr;
+ for (Tmp = 0; Tmp < *pLength; Tmp++)
+ {
+ *pIoMap = pBuffer[Tmp];
+ pIoMap++;
+ }
+ }
+ else
+ {
+
+ /* Error - not within the bounderies */
+ ReturnState = OUTOFBOUNDERY;
+ *pLength = 0;
+ }
+ }
+ else
+ {
+
+ /* Error - not a valid module id */
+ *pLength = 0;
+ }
+ }
+ break;
+
+ case RENAMEFILE:
+ {
+ ReturnState = cLoaderRenameFile(pFileName, pBuffer, pLength);
+ }
+ break;
+
+ default:
+ {
+ }
+ break;
+ }
+ return (ReturnState);
+}
+
+UWORD cLoaderGetIoMapInfo(ULONG ModuleId, UBYTE *pIoMap, UWORD *pIoMapSize)
+{
+ UBYTE Tmp;
+ UBYTE Exit;
+ UWORD RtnVal;
+
+ RtnVal = SUCCESS;
+ Tmp = 0;
+ Exit = FALSE;
+ while((Tmp < 32) && (Exit == FALSE))
+ {
+ if ((*(pHeaders[Tmp])).ModuleID == ModuleId)
+ {
+ Exit = TRUE;
+ }
+ else
+ {
+ Tmp++;
+ }
+ }
+
+ /* Did we have a valid module ID ?*/
+ if (TRUE == Exit)
+ {
+ /* Get the pointer of the module io map */
+ *((ULONG *)pIoMap) = (ULONG)((*(pHeaders[Tmp])).pIOMap);
+ *pIoMapSize = (*(pHeaders[Tmp])).IOMapSize;
+ }
+ else
+ {
+ RtnVal = MODULENOTFOUND;
+ }
+
+ /* To avoid a warning - this is optimized away */
+ *pIoMap = *pIoMap;
+ return(RtnVal);
+}
+
+UWORD cLoaderFindModule(UBYTE *pBuffer)
+{
+ UBYTE Tmp;
+ UWORD RtnVal;
+ UBYTE ModuleName[FILENAME_SIZE];
+
+ RtnVal = MODULENOTFOUND;
+
+ for (Tmp = VarsLoader.ModSearchIndex; Tmp < 32; Tmp++)
+ {
+ if (pHeaders[Tmp] != 0)
+ {
+
+ cLoaderGetModuleName(ModuleName, ((*(pHeaders[Tmp])).ModuleName));
+ if (SUCCESS == dLoaderCheckName(ModuleName, VarsLoader.ModSearchStr, VarsLoader.ModSearchType))
+ {
+
+ dLoaderCopyFileName(pBuffer, ModuleName);
+
+ pBuffer[FILENAME_SIZE] = (UBYTE) ((*(pHeaders[Tmp])).ModuleID);
+ pBuffer[FILENAME_SIZE + 1] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 8);
+ pBuffer[FILENAME_SIZE + 2] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 16);
+ pBuffer[FILENAME_SIZE + 3] = (UBYTE)(((*(pHeaders[Tmp])).ModuleID) >> 24);
+
+ pBuffer[FILENAME_SIZE + 4] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize));
+ pBuffer[FILENAME_SIZE + 5] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 8);
+ pBuffer[FILENAME_SIZE + 6] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 16);
+ pBuffer[FILENAME_SIZE + 7] = (UBYTE)(((*(pHeaders[Tmp])).ModuleSize) >> 24);
+
+ pBuffer[FILENAME_SIZE + 8] = (UBYTE) ((*(pHeaders[Tmp])).IOMapSize);
+ pBuffer[FILENAME_SIZE + 9] = (UBYTE)(((*(pHeaders[Tmp])).IOMapSize) >> 8);
+
+ RtnVal = SUCCESS;
+ (VarsLoader.ModSearchIndex) = Tmp + 1;
+ Tmp = 32;
+ }
+ }
+ }
+ return(RtnVal);
+}
+
+void cLoaderGetModuleName(UBYTE *pDst, UBYTE *pModule)
+{
+ UBYTE Tmp;
+
+ for(Tmp = 0; Tmp < FILENAME_SIZE; Tmp++)
+ {
+ if (0 != pModule[Tmp])
+ {
+ pDst[Tmp] = pModule[Tmp];
+ }
+ else
+ {
+ pDst[Tmp++] = '.';
+ pDst[Tmp++] = 'm';
+ pDst[Tmp++] = 'o';
+ pDst[Tmp++] = 'd';
+ pDst[Tmp] = '\0';
+ Tmp = FILENAME_SIZE;
+ }
+ }
+}
+
+void cLoaderExit(void)
+{
+}
+
+