simplified MMU initialization
removed (apparently unneeded) MMU TLBs added source file templates for SPI dma routines
This commit is contained in:
@@ -7,4 +7,6 @@ define tbtr
|
|||||||
target remote | m68k-bdm-gdbserver pipe /dev/tblcf3
|
target remote | m68k-bdm-gdbserver pipe /dev/tblcf3
|
||||||
end
|
end
|
||||||
source mcf5474.gdb
|
source mcf5474.gdb
|
||||||
|
set breakpoint auto-hw
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ OBJCOPY=$(TCPREFIX)objcopy
|
|||||||
AR=$(TCPREFIX)ar
|
AR=$(TCPREFIX)ar
|
||||||
RANLIB=$(TCPREFIX)ranlib
|
RANLIB=$(TCPREFIX)ranlib
|
||||||
|
|
||||||
INCLUDE=-Iinclude
|
INCLUDE=-Iinclude -Imcdapi
|
||||||
CFLAGS=-mcpu=5474\
|
CFLAGS=-mcpu=5474\
|
||||||
-Wall\
|
-Wall\
|
||||||
-g\
|
-g\
|
||||||
@@ -72,6 +72,7 @@ CSRCS= \
|
|||||||
$(SRCDIR)/wait.c \
|
$(SRCDIR)/wait.c \
|
||||||
$(SRCDIR)/s19reader.c \
|
$(SRCDIR)/s19reader.c \
|
||||||
$(SRCDIR)/flash.c \
|
$(SRCDIR)/flash.c \
|
||||||
|
$(SRCDIR)/spidma.c \
|
||||||
$(SRCDIR)/xhdi_sd.c \
|
$(SRCDIR)/xhdi_sd.c \
|
||||||
$(SRCDIR)/xhdi_interface.c
|
$(SRCDIR)/xhdi_interface.c
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ $(FLASH_EXEC): TARGET_ADDRESS=0xe0000000
|
|||||||
$(FLASH_EXEC): LDCFILE=bas.lk
|
$(FLASH_EXEC): LDCFILE=bas.lk
|
||||||
$(FLASH_EXEC): MAPFILE=bas.map
|
$(FLASH_EXEC): MAPFILE=bas.map
|
||||||
|
|
||||||
$(RAM_EXEC): TARGET_ADDRESS=0x00008000
|
$(RAM_EXEC): TARGET_ADDRESS=0x1d000000
|
||||||
$(RAM_EXEC): LDCFILE=ram.lk
|
$(RAM_EXEC): LDCFILE=ram.lk
|
||||||
$(RAM_EXEC): MAPFILE=ram.map
|
$(RAM_EXEC): MAPFILE=ram.map
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ SECTIONS
|
|||||||
objs/supervisor.o(.text)
|
objs/supervisor.o(.text)
|
||||||
objs/illegal_instruction.o(.text)
|
objs/illegal_instruction.o(.text)
|
||||||
objs/exceptions.o(.text)
|
objs/exceptions.o(.text)
|
||||||
|
objs/spidma.o(.text)
|
||||||
|
mcdapi/MCD_dmaApi.o(.text)
|
||||||
|
mcdapi/MCD_tasks.o(.text)
|
||||||
|
mcdapi/MCD_tasksInit.o(.text)
|
||||||
objs/xhdi_sd.o(.text)
|
objs/xhdi_sd.o(.text)
|
||||||
objs/xhdi_interface.o(text)
|
objs/xhdi_interface.o(text)
|
||||||
objs/xhdi_vec.o(text)
|
objs/xhdi_vec.o(text)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ extern size_t strlen(const char *str);
|
|||||||
extern char *strcat(char *dst, const char *src);
|
extern char *strcat(char *dst, const char *src);
|
||||||
extern char *strncat(char *dst, const char *src, int max);
|
extern char *strncat(char *dst, const char *src, int max);
|
||||||
extern int atoi(const char *c);
|
extern int atoi(const char *c);
|
||||||
|
extern void *memcpy(void *dst, const void *src, size_t n);
|
||||||
|
|
||||||
#define isdigit(c) (((c) >= '0') && ((c) <= '9'))
|
#define isdigit(c) (((c) >= '0') && ((c) <= '9'))
|
||||||
#define isupper(c) ((c) >= 'A' && ((c) <= 'Z'))
|
#define isupper(c) ((c) >= 'A' && ((c) <= 'Z'))
|
||||||
|
|||||||
16
BaS_gcc/include/spidma.h
Normal file
16
BaS_gcc/include/spidma.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* spidma.h
|
||||||
|
*
|
||||||
|
* Created on: 27.07.2013
|
||||||
|
* Author: mfro
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SPIDMA_H_
|
||||||
|
#define _SPIDMA_H_
|
||||||
|
|
||||||
|
#include <MCF5475.h>
|
||||||
|
|
||||||
|
extern int spidma_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _SPIDMA_H_ */
|
||||||
@@ -29,25 +29,21 @@ extern TaskTableEntry MCD_modelTaskTableSrc[NUMOFVARIANTS];
|
|||||||
volatile TaskTableEntry *MCD_taskTable;
|
volatile TaskTableEntry *MCD_taskTable;
|
||||||
TaskTableEntry *MCD_modelTaskTable;
|
TaskTableEntry *MCD_modelTaskTable;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MCD_chStatus[] is an array of status indicators for remembering
|
* MCD_chStatus[] is an array of status indicators for remembering
|
||||||
* whether a DMA has ever been attempted on each channel, pausing
|
* whether a DMA has ever been attempted on each channel, pausing
|
||||||
* status, etc.
|
* status, etc.
|
||||||
*/
|
*/
|
||||||
static int MCD_chStatus[NCHANNELS] =
|
static int MCD_chStatus[NCHANNELS] =
|
||||||
{
|
{ MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
|
||||||
MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
|
MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
|
||||||
MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
|
MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA };
|
||||||
MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
|
|
||||||
MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes for local functions
|
* Prototypes for local functions
|
||||||
*/
|
*/
|
||||||
static void MCD_memcpy (int *dest, int *src, u32 size);
|
static void MCD_memcpy(int *dest, int *src, u32 size);
|
||||||
static void MCD_resmActions (int channel);
|
static void MCD_resmActions(int channel);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Buffer descriptors used for storage of progress info for single Dmas
|
* Buffer descriptors used for storage of progress info for single Dmas
|
||||||
@@ -61,7 +57,6 @@ MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
|
|||||||
#endif
|
#endif
|
||||||
MCD_bufDesc *MCD_relocBuffDesc;
|
MCD_bufDesc *MCD_relocBuffDesc;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines for the debug control register's functions
|
* Defines for the debug control register's functions
|
||||||
*/
|
*/
|
||||||
@@ -145,7 +140,7 @@ MCD_remVariant MCD_remVariants;
|
|||||||
*/
|
*/
|
||||||
extern u32 MCD_funcDescTab0[];
|
extern u32 MCD_funcDescTab0[];
|
||||||
|
|
||||||
int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
int MCD_initDma(dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
TaskTableEntry *entryPtr;
|
TaskTableEntry *entryPtr;
|
||||||
@@ -167,8 +162,8 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check if physical address is aligned on 512 byte boundary */
|
/* check if physical address is aligned on 512 byte boundary */
|
||||||
if (((u32)taskTableDest & 0x000001ff) != 0)
|
if (((u32) taskTableDest & 0x000001ff) != 0)
|
||||||
return(MCD_TABLE_UNALIGNED);
|
return (MCD_TABLE_UNALIGNED);
|
||||||
|
|
||||||
MCD_taskTable = taskTableDest; /* set up local pointer to task Table */
|
MCD_taskTable = taskTableDest; /* set up local pointer to task Table */
|
||||||
|
|
||||||
@@ -183,7 +178,7 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
|
|
||||||
taskTableSize = NCHANNELS * sizeof(TaskTableEntry);
|
taskTableSize = NCHANNELS * sizeof(TaskTableEntry);
|
||||||
/* align variable tables to size */
|
/* align variable tables to size */
|
||||||
varTabsOffset = taskTableSize + (u32)taskTableDest;
|
varTabsOffset = taskTableSize + (u32) taskTableDest;
|
||||||
if ((varTabsOffset & (VAR_TAB_SIZE - 1)) != 0)
|
if ((varTabsOffset & (VAR_TAB_SIZE - 1)) != 0)
|
||||||
varTabsOffset = (varTabsOffset + VAR_TAB_SIZE) & (~VAR_TAB_SIZE);
|
varTabsOffset = (varTabsOffset + VAR_TAB_SIZE) & (~VAR_TAB_SIZE);
|
||||||
/* align function descriptor tables */
|
/* align function descriptor tables */
|
||||||
@@ -191,27 +186,28 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
funcDescTabsOffset = varTabsOffset + varTabsSize;
|
funcDescTabsOffset = varTabsOffset + varTabsSize;
|
||||||
|
|
||||||
if ((funcDescTabsOffset & (FUNCDESC_TAB_SIZE - 1)) != 0)
|
if ((funcDescTabsOffset & (FUNCDESC_TAB_SIZE - 1)) != 0)
|
||||||
funcDescTabsOffset = (funcDescTabsOffset + FUNCDESC_TAB_SIZE) &
|
funcDescTabsOffset = (funcDescTabsOffset + FUNCDESC_TAB_SIZE)
|
||||||
(~FUNCDESC_TAB_SIZE);
|
& (~FUNCDESC_TAB_SIZE);
|
||||||
|
|
||||||
funcDescTabsSize = FUNCDESC_TAB_NUM * FUNCDESC_TAB_SIZE;
|
funcDescTabsSize = FUNCDESC_TAB_NUM * FUNCDESC_TAB_SIZE;
|
||||||
contextSavesOffset = funcDescTabsOffset + funcDescTabsSize;
|
contextSavesOffset = funcDescTabsOffset + funcDescTabsSize;
|
||||||
contextSavesSize = (NCHANNELS * CONTEXT_SAVE_SIZE);
|
contextSavesSize = (NCHANNELS * CONTEXT_SAVE_SIZE);
|
||||||
fixedSize = taskTableSize + varTabsSize + funcDescTabsSize +
|
fixedSize = taskTableSize + varTabsSize + funcDescTabsSize
|
||||||
contextSavesSize;
|
+ contextSavesSize;
|
||||||
|
|
||||||
/* zero the thing out */
|
/* zero the thing out */
|
||||||
fixedPtr = (u32 *)taskTableDest;
|
fixedPtr = (u32 *) taskTableDest;
|
||||||
for (i = 0;i<(fixedSize/4);i++)
|
for (i = 0; i < (fixedSize / 4); i++)
|
||||||
fixedPtr[i] = 0;
|
fixedPtr[i] = 0;
|
||||||
|
|
||||||
entryPtr = (TaskTableEntry*)MCD_taskTable;
|
entryPtr = (TaskTableEntry*) MCD_taskTable;
|
||||||
/* set up fixed pointers */
|
/* set up fixed pointers */
|
||||||
for (i = 0; i < NCHANNELS; i++)
|
for (i = 0; i < NCHANNELS; i++)
|
||||||
{
|
{
|
||||||
entryPtr[i].varTab = (u32)varTabsOffset; /* update ptr to local value */
|
entryPtr[i].varTab = (u32) varTabsOffset; /* update ptr to local value */
|
||||||
entryPtr[i].FDTandFlags = (u32)funcDescTabsOffset | MCD_TT_FLAGS_DEF;
|
entryPtr[i].FDTandFlags = (u32) funcDescTabsOffset
|
||||||
entryPtr[i].contextSaveSpace = (u32)contextSavesOffset;
|
| MCD_TT_FLAGS_DEF;
|
||||||
|
entryPtr[i].contextSaveSpace = (u32) contextSavesOffset;
|
||||||
varTabsOffset += VAR_TAB_SIZE;
|
varTabsOffset += VAR_TAB_SIZE;
|
||||||
#ifdef MCD_INCLUDE_EU /* if not there is only one, just point to the same one */
|
#ifdef MCD_INCLUDE_EU /* if not there is only one, just point to the same one */
|
||||||
funcDescTabsOffset += FUNCDESC_TAB_SIZE;
|
funcDescTabsOffset += FUNCDESC_TAB_SIZE;
|
||||||
@@ -219,31 +215,32 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
contextSavesOffset += CONTEXT_SAVE_SIZE;
|
contextSavesOffset += CONTEXT_SAVE_SIZE;
|
||||||
}
|
}
|
||||||
/* copy over the function descriptor table */
|
/* copy over the function descriptor table */
|
||||||
for ( i = 0; i < FUNCDESC_TAB_NUM; i++)
|
for (i = 0; i < FUNCDESC_TAB_NUM; i++)
|
||||||
{
|
{
|
||||||
MCD_memcpy((void*)(entryPtr[i].FDTandFlags & ~MCD_TT_FLAGS_MASK),
|
MCD_memcpy((void*) (entryPtr[i].FDTandFlags & ~MCD_TT_FLAGS_MASK),
|
||||||
(void*)MCD_funcDescTab0, FUNCDESC_TAB_SIZE);
|
(void*) MCD_funcDescTab0, FUNCDESC_TAB_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy model task table to where the context saves stuff leaves off*/
|
/* copy model task table to where the context saves stuff leaves off*/
|
||||||
MCD_modelTaskTable = (TaskTableEntry*)contextSavesOffset;
|
MCD_modelTaskTable = (TaskTableEntry*) contextSavesOffset;
|
||||||
|
|
||||||
MCD_memcpy ((void*)MCD_modelTaskTable, (void*)MCD_modelTaskTableSrc,
|
MCD_memcpy((void*) MCD_modelTaskTable, (void*) MCD_modelTaskTableSrc,
|
||||||
NUMOFVARIANTS * sizeof(TaskTableEntry));
|
NUMOFVARIANTS * sizeof(TaskTableEntry));
|
||||||
|
|
||||||
entryPtr = MCD_modelTaskTable; /* point to local version of
|
entryPtr = MCD_modelTaskTable; /* point to local version of
|
||||||
model task table */
|
model task table */
|
||||||
taskDescTabsOffset = (u32)MCD_modelTaskTable +
|
taskDescTabsOffset = (u32) MCD_modelTaskTable
|
||||||
(NUMOFVARIANTS * sizeof(TaskTableEntry));
|
+ (NUMOFVARIANTS * sizeof(TaskTableEntry));
|
||||||
|
|
||||||
/* copy actual task code and update TDT ptrs in local model task table */
|
/* copy actual task code and update TDT ptrs in local model task table */
|
||||||
for (i = 0; i < NUMOFVARIANTS; i++)
|
for (i = 0; i < NUMOFVARIANTS; i++)
|
||||||
{
|
{
|
||||||
taskDescTabSize = entryPtr[i].TDTend - entryPtr[i].TDTstart + 4;
|
taskDescTabSize = entryPtr[i].TDTend - entryPtr[i].TDTstart + 4;
|
||||||
MCD_memcpy ((void*)taskDescTabsOffset, (void*)entryPtr[i].TDTstart, taskDescTabSize);
|
MCD_memcpy((void*) taskDescTabsOffset, (void*) entryPtr[i].TDTstart,
|
||||||
entryPtr[i].TDTstart = (u32)taskDescTabsOffset;
|
taskDescTabSize);
|
||||||
|
entryPtr[i].TDTstart = (u32) taskDescTabsOffset;
|
||||||
taskDescTabsOffset += taskDescTabSize;
|
taskDescTabsOffset += taskDescTabSize;
|
||||||
entryPtr[i].TDTend = (u32)taskDescTabsOffset - 4;
|
entryPtr[i].TDTend = (u32) taskDescTabsOffset - 4;
|
||||||
}
|
}
|
||||||
#ifdef MCD_INCLUDE_EU /* Tack single DMA BDs onto end of code so API controls
|
#ifdef MCD_INCLUDE_EU /* Tack single DMA BDs onto end of code so API controls
|
||||||
where they are since DMA might write to them */
|
where they are since DMA might write to them */
|
||||||
@@ -258,8 +255,8 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
/* point the would-be relocated task tables and the
|
/* point the would-be relocated task tables and the
|
||||||
buffer descriptors to the ones the linker generated */
|
buffer descriptors to the ones the linker generated */
|
||||||
|
|
||||||
if (((u32)MCD_realTaskTableSrc & 0x000001ff) != 0)
|
if (((u32) MCD_realTaskTableSrc & 0x000001ff) != 0)
|
||||||
return(MCD_TABLE_UNALIGNED);
|
return (MCD_TABLE_UNALIGNED);
|
||||||
|
|
||||||
/* need to add code to make sure that every thing else is aligned properly TBD*/
|
/* need to add code to make sure that every thing else is aligned properly TBD*/
|
||||||
/* this is problematic if we init more than once or after running tasks,
|
/* this is problematic if we init more than once or after running tasks,
|
||||||
@@ -267,9 +264,9 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
entryPtr = MCD_realTaskTableSrc;
|
entryPtr = MCD_realTaskTableSrc;
|
||||||
for (i = 0; i < NCHANNELS; i++)
|
for (i = 0; i < NCHANNELS; i++)
|
||||||
{
|
{
|
||||||
if (((entryPtr[i].varTab & (VAR_TAB_SIZE - 1)) != 0) ||
|
if (((entryPtr[i].varTab & (VAR_TAB_SIZE - 1)) != 0)
|
||||||
((entryPtr[i].FDTandFlags & (FUNCDESC_TAB_SIZE - 1)) != 0))
|
|| ((entryPtr[i].FDTandFlags & (FUNCDESC_TAB_SIZE - 1)) != 0))
|
||||||
return(MCD_TABLE_UNALIGNED);
|
return (MCD_TABLE_UNALIGNED);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCD_taskTable = MCD_realTaskTableSrc;
|
MCD_taskTable = MCD_realTaskTableSrc;
|
||||||
@@ -277,7 +274,6 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
MCD_relocBuffDesc = MCD_singleBufDescs;
|
MCD_relocBuffDesc = MCD_singleBufDescs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Make all channels as totally inactive, and remember them as such: */
|
/* Make all channels as totally inactive, and remember them as such: */
|
||||||
|
|
||||||
MCD_dmaBar->taskbar = (u32) MCD_taskTable;
|
MCD_dmaBar->taskbar = (u32) MCD_taskTable;
|
||||||
@@ -300,7 +296,7 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
else
|
else
|
||||||
MCD_dmaBar->ptdControl |= PTD_CTL_COMM_PREFETCH;
|
MCD_dmaBar->ptdControl |= PTD_CTL_COMM_PREFETCH;
|
||||||
|
|
||||||
return(MCD_OK);
|
return (MCD_OK);
|
||||||
}
|
}
|
||||||
/*********************** End of MCD_initDma() ***********************/
|
/*********************** End of MCD_initDma() ***********************/
|
||||||
|
|
||||||
@@ -310,31 +306,31 @@ int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
|
|||||||
* Arguments: channel - channel number
|
* Arguments: channel - channel number
|
||||||
* Returns: Predefined status indicators
|
* Returns: Predefined status indicators
|
||||||
*/
|
*/
|
||||||
int MCD_dmaStatus (int channel)
|
int MCD_dmaStatus(int channel)
|
||||||
{
|
{
|
||||||
u16 tcrValue;
|
u16 tcrValue;
|
||||||
|
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if ((channel < 0) || (channel >= NCHANNELS))
|
||||||
return(MCD_CHANNEL_INVALID);
|
return (MCD_CHANNEL_INVALID);
|
||||||
|
|
||||||
tcrValue = MCD_dmaBar->taskControl[channel];
|
tcrValue = MCD_dmaBar->taskControl[channel];
|
||||||
if ((tcrValue & TASK_CTL_EN) == 0)
|
if ((tcrValue & TASK_CTL_EN) == 0)
|
||||||
{ /* nothing running */
|
{ /* nothing running */
|
||||||
/* if last reported with task enabled */
|
/* if last reported with task enabled */
|
||||||
if ( MCD_chStatus[channel] == MCD_RUNNING
|
if (MCD_chStatus[channel] == MCD_RUNNING
|
||||||
|| MCD_chStatus[channel] == MCD_IDLE)
|
|| MCD_chStatus[channel] == MCD_IDLE)
|
||||||
MCD_chStatus[channel] = MCD_DONE;
|
MCD_chStatus[channel] = MCD_DONE;
|
||||||
}
|
}
|
||||||
else /* something is running */
|
else /* something is running */
|
||||||
{
|
{
|
||||||
/* There are three possibilities: paused, running or idle. */
|
/* There are three possibilities: paused, running or idle. */
|
||||||
if ( MCD_chStatus[channel] == MCD_RUNNING
|
if (MCD_chStatus[channel] == MCD_RUNNING
|
||||||
|| MCD_chStatus[channel] == MCD_IDLE)
|
|| MCD_chStatus[channel] == MCD_IDLE)
|
||||||
{
|
{
|
||||||
MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;
|
MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;
|
||||||
/* This register is selected to know which initiator is
|
/* This register is selected to know which initiator is
|
||||||
actually asserted. */
|
actually asserted. */
|
||||||
if ((MCD_dmaBar->ptdDebug >> channel ) & 0x1 )
|
if ((MCD_dmaBar->ptdDebug >> channel) & 0x1)
|
||||||
MCD_chStatus[channel] = MCD_RUNNING;
|
MCD_chStatus[channel] = MCD_RUNNING;
|
||||||
else
|
else
|
||||||
MCD_chStatus[channel] = MCD_IDLE;
|
MCD_chStatus[channel] = MCD_IDLE;
|
||||||
@@ -352,22 +348,21 @@ int MCD_dmaStatus (int channel)
|
|||||||
* Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
|
* Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int MCD_startDma (
|
int MCD_startDma(int channel, /* the channel on which to run the DMA */
|
||||||
int channel, /* the channel on which to run the DMA */
|
s8 *srcAddr, /* the address to move data from, or physical buffer-descriptor address */
|
||||||
s8 *srcAddr, /* the address to move data from, or physical buffer-descriptor address */
|
s16 srcIncr, /* the amount to increment the source address per transfer */
|
||||||
s16 srcIncr, /* the amount to increment the source address per transfer */
|
s8 *destAddr, /* the address to move data to */
|
||||||
s8 *destAddr, /* the address to move data to */
|
s16 destIncr, /* the amount to increment the destination address per transfer */
|
||||||
s16 destIncr, /* the amount to increment the destination address per transfer */
|
u32 dmaSize, /* the number of bytes to transfer independent of the transfer size */
|
||||||
u32 dmaSize, /* the number of bytes to transfer independent of the transfer size */
|
u32 xferSize, /* the number bytes in of each data movement (1, 2, or 4) */
|
||||||
u32 xferSize, /* the number bytes in of each data movement (1, 2, or 4) */
|
u32 initiator, /* what device initiates the DMA */
|
||||||
u32 initiator, /* what device initiates the DMA */
|
int priority, /* priority of the DMA */
|
||||||
int priority, /* priority of the DMA */
|
u32 flags, /* flags describing the DMA */
|
||||||
u32 flags, /* flags describing the DMA */
|
u32 funcDesc /* a description of byte swapping, bit swapping, and CRC actions */
|
||||||
u32 funcDesc /* a description of byte swapping, bit swapping, and CRC actions */
|
|
||||||
#ifdef MCD_NEED_ADDR_TRANS
|
#ifdef MCD_NEED_ADDR_TRANS
|
||||||
s8 *srcAddrVirt /* virtual buffer descriptor address TBD*/
|
s8 *srcAddrVirt /* virtual buffer descriptor address TBD*/
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int srcRsdIncr, destRsdIncr;
|
int srcRsdIncr, destRsdIncr;
|
||||||
int *cSave;
|
int *cSave;
|
||||||
@@ -377,8 +372,8 @@ int MCD_startDma (
|
|||||||
u32 *realFuncArray;
|
u32 *realFuncArray;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if ((channel < 0) || (channel >= NCHANNELS))
|
||||||
return(MCD_CHANNEL_INVALID);
|
return (MCD_CHANNEL_INVALID);
|
||||||
|
|
||||||
/* tbd - need to determine the proper response to a bad funcDesc when not
|
/* tbd - need to determine the proper response to a bad funcDesc when not
|
||||||
including EU functions, for now, assign a benign funcDesc, but maybe
|
including EU functions, for now, assign a benign funcDesc, but maybe
|
||||||
@@ -388,7 +383,7 @@ int MCD_startDma (
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MCD_DEBUG
|
#ifdef MCD_DEBUG
|
||||||
printf("startDma:Setting up params\n");
|
printf("startDma:Setting up params\n");
|
||||||
#endif
|
#endif
|
||||||
/* Set us up for task-wise priority. We don't technically need to do this on every start, but
|
/* Set us up for task-wise priority. We don't technically need to do this on every start, but
|
||||||
since the register involved is in the same longword as other registers that users are in control
|
since the register involved is in the same longword as other registers that users are in control
|
||||||
@@ -410,7 +405,8 @@ printf("startDma:Setting up params\n");
|
|||||||
MCD_remVariants.remXferSize[channel] = xferSize;
|
MCD_remVariants.remXferSize[channel] = xferSize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cSave = (int*)(MCD_taskTable[channel].contextSaveSpace) + CSAVE_OFFSET + CURRBD;
|
cSave = (int*) (MCD_taskTable[channel].contextSaveSpace) + CSAVE_OFFSET
|
||||||
|
+ CURRBD;
|
||||||
|
|
||||||
#ifdef MCD_INCLUDE_EU /* may move this to EU specific calls */
|
#ifdef MCD_INCLUDE_EU /* may move this to EU specific calls */
|
||||||
realFuncArray = (u32 *) (MCD_taskTable[channel].FDTandFlags & 0xffffff00);
|
realFuncArray = (u32 *) (MCD_taskTable[channel].FDTandFlags & 0xffffff00);
|
||||||
@@ -425,32 +421,32 @@ printf("startDma:Setting up params\n");
|
|||||||
MDE access to the initiator-register file, so we have to verify that the write
|
MDE access to the initiator-register file, so we have to verify that the write
|
||||||
reads back correctly. */
|
reads back correctly. */
|
||||||
|
|
||||||
MCD_dmaBar->taskControl[channel] =
|
MCD_dmaBar->taskControl[channel] = (initiator << 8) | TASK_CTL_HIPRITSKEN
|
||||||
(initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM;
|
| TASK_CTL_HLDINITNUM;
|
||||||
|
|
||||||
while(((MCD_dmaBar->taskControl[channel] & 0x1fff) !=
|
while (((MCD_dmaBar->taskControl[channel] & 0x1fff)
|
||||||
((initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM)) &&
|
!= ((initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM))
|
||||||
(tcrCount < 1000))
|
&& (tcrCount < 1000))
|
||||||
{
|
{
|
||||||
tcrCount++;
|
tcrCount++;
|
||||||
/*MCD_dmaBar->ptd_tcr[channel] = (initiator << 8) | 0x0020;*/
|
/*MCD_dmaBar->ptd_tcr[channel] = (initiator << 8) | 0x0020;*/
|
||||||
MCD_dmaBar->taskControl[channel] =
|
MCD_dmaBar->taskControl[channel] = (initiator << 8)
|
||||||
(initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM;
|
| TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCD_dmaBar->priority[channel] = (u8)priority & PRIORITY_PRI_MASK;
|
MCD_dmaBar->priority[channel] = (u8) priority & PRIORITY_PRI_MASK;
|
||||||
/* should be albe to handle this stuff with only one write to ts reg - tbd */
|
/* should be albe to handle this stuff with only one write to ts reg - tbd */
|
||||||
if (channel < 8 && channel >= 0)
|
if (channel < 8 && channel >= 0)
|
||||||
{
|
{
|
||||||
MCD_dmaBar->taskSize0 &= ~(0xf << (7-channel)*4);
|
MCD_dmaBar->taskSize0 &= ~(0xf << (7 - channel) * 4);
|
||||||
MCD_dmaBar->taskSize0 |= (xferSize & 3) << (((7 - channel)*4) + 2);
|
MCD_dmaBar->taskSize0 |= (xferSize & 3) << (((7 - channel) * 4) + 2);
|
||||||
MCD_dmaBar->taskSize0 |= (xferSize & 3) << ((7 - channel)*4);
|
MCD_dmaBar->taskSize0 |= (xferSize & 3) << ((7 - channel) * 4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MCD_dmaBar->taskSize1 &= ~(0xf << (15-channel)*4);
|
MCD_dmaBar->taskSize1 &= ~(0xf << (15 - channel) * 4);
|
||||||
MCD_dmaBar->taskSize1 |= (xferSize & 3) << (((15 - channel)*4) + 2);
|
MCD_dmaBar->taskSize1 |= (xferSize & 3) << (((15 - channel) * 4) + 2);
|
||||||
MCD_dmaBar->taskSize1 |= (xferSize & 3) << ((15 - channel)*4);
|
MCD_dmaBar->taskSize1 |= (xferSize & 3) << ((15 - channel) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup task table flags/options which mostly control the line buffers */
|
/* setup task table flags/options which mostly control the line buffers */
|
||||||
@@ -460,18 +456,21 @@ printf("startDma:Setting up params\n");
|
|||||||
if (flags & MCD_FECTX_DMA)
|
if (flags & MCD_FECTX_DMA)
|
||||||
{
|
{
|
||||||
/* TDTStart and TDTEnd */
|
/* TDTStart and TDTEnd */
|
||||||
MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_FECTX].TDTstart;
|
MCD_taskTable[channel].TDTstart =
|
||||||
|
MCD_modelTaskTable[TASK_FECTX].TDTstart;
|
||||||
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECTX].TDTend;
|
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECTX].TDTend;
|
||||||
MCD_startDmaENetXmit(srcAddr, srcAddr, destAddr, MCD_taskTable, channel);
|
MCD_startDmaENetXmit(srcAddr, srcAddr, destAddr, MCD_taskTable,
|
||||||
|
channel);
|
||||||
}
|
}
|
||||||
else if (flags & MCD_FECRX_DMA)
|
else if (flags & MCD_FECRX_DMA)
|
||||||
{
|
{
|
||||||
/* TDTStart and TDTEnd */
|
/* TDTStart and TDTEnd */
|
||||||
MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_FECRX].TDTstart;
|
MCD_taskTable[channel].TDTstart =
|
||||||
|
MCD_modelTaskTable[TASK_FECRX].TDTstart;
|
||||||
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECRX].TDTend;
|
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECRX].TDTend;
|
||||||
MCD_startDmaENetRcv(srcAddr, srcAddr, destAddr, MCD_taskTable, channel);
|
MCD_startDmaENetRcv(srcAddr, srcAddr, destAddr, MCD_taskTable, channel);
|
||||||
}
|
}
|
||||||
else if(flags & MCD_SINGLE_DMA)
|
else if (flags & MCD_SINGLE_DMA)
|
||||||
{
|
{
|
||||||
/* this buffer descriptor is used for storing off initial parameters for later
|
/* this buffer descriptor is used for storing off initial parameters for later
|
||||||
progress query calculation and for the DMA to write the resulting checksum
|
progress query calculation and for the DMA to write the resulting checksum
|
||||||
@@ -486,68 +485,82 @@ printf("startDma:Setting up params\n");
|
|||||||
MCD_relocBuffDesc[channel].next = 0; /* not used */
|
MCD_relocBuffDesc[channel].next = 0; /* not used */
|
||||||
|
|
||||||
/* Initialize the progress-querying stuff to show no progress:*/
|
/* Initialize the progress-querying stuff to show no progress:*/
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET] = (int)srcAddr;
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[SRCPTR
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET] = (int)destAddr;
|
+ CSAVE_OFFSET] = (int) srcAddr;
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0;
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[DESTPTR
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET] =
|
+ CSAVE_OFFSET] = (int) destAddr;
|
||||||
(u32) &(MCD_relocBuffDesc[channel]);
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[DCOUNT
|
||||||
|
+ CSAVE_OFFSET] = 0;
|
||||||
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[CURRBD
|
||||||
|
+ CSAVE_OFFSET] = (u32) &(MCD_relocBuffDesc[channel]);
|
||||||
/* tbd - need to keep the user from trying to call the EU routine
|
/* tbd - need to keep the user from trying to call the EU routine
|
||||||
when MCD_INCLUDE_EU is not defined */
|
when MCD_INCLUDE_EU is not defined */
|
||||||
if( funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2)
|
if (funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2)
|
||||||
{
|
{
|
||||||
/* TDTStart and TDTEnd */
|
/* TDTStart and TDTEnd */
|
||||||
MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_SINGLENOEU].TDTstart;
|
MCD_taskTable[channel].TDTstart =
|
||||||
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_SINGLENOEU].TDTend;
|
MCD_modelTaskTable[TASK_SINGLENOEU].TDTstart;
|
||||||
MCD_startDmaSingleNoEu(srcAddr, srcIncr, destAddr, destIncr, dmaSize,
|
MCD_taskTable[channel].TDTend =
|
||||||
xferSizeIncr, flags, (int *)&(MCD_relocBuffDesc[channel]), cSave,
|
MCD_modelTaskTable[TASK_SINGLENOEU].TDTend;
|
||||||
MCD_taskTable, channel);
|
MCD_startDmaSingleNoEu(srcAddr, srcIncr, destAddr, destIncr,
|
||||||
|
dmaSize, xferSizeIncr, flags,
|
||||||
|
(int *) &(MCD_relocBuffDesc[channel]), cSave, MCD_taskTable,
|
||||||
|
channel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TDTStart and TDTEnd */
|
/* TDTStart and TDTEnd */
|
||||||
MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_SINGLEEU].TDTstart;
|
MCD_taskTable[channel].TDTstart =
|
||||||
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_SINGLEEU].TDTend;
|
MCD_modelTaskTable[TASK_SINGLEEU].TDTstart;
|
||||||
|
MCD_taskTable[channel].TDTend =
|
||||||
|
MCD_modelTaskTable[TASK_SINGLEEU].TDTend;
|
||||||
MCD_startDmaSingleEu(srcAddr, srcIncr, destAddr, destIncr, dmaSize,
|
MCD_startDmaSingleEu(srcAddr, srcIncr, destAddr, destIncr, dmaSize,
|
||||||
xferSizeIncr, flags, (int *)&(MCD_relocBuffDesc[channel]), cSave,
|
xferSizeIncr, flags, (int *) &(MCD_relocBuffDesc[channel]),
|
||||||
MCD_taskTable, channel);
|
cSave, MCD_taskTable, channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* chained DMAS */
|
{ /* chained DMAS */
|
||||||
/* Initialize the progress-querying stuff to show no progress:*/
|
/* Initialize the progress-querying stuff to show no progress:*/
|
||||||
#if 1 /* (!defined(MCD_NEED_ADDR_TRANS)) */
|
#if 1 /* (!defined(MCD_NEED_ADDR_TRANS)) */
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET]
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[SRCPTR
|
||||||
= (int)((MCD_bufDesc*) srcAddr)->srcAddr;
|
+ CSAVE_OFFSET] = (int) ((MCD_bufDesc*) srcAddr)->srcAddr;
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET]
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[DESTPTR
|
||||||
= (int)((MCD_bufDesc*) srcAddr)->destAddr;
|
+ CSAVE_OFFSET] = (int) ((MCD_bufDesc*) srcAddr)->destAddr;
|
||||||
#else /* if using address translation, need the virtual addr of the first buffdesc */
|
#else /* if using address translation, need the virtual addr of the first buffdesc */
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET]
|
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET]
|
||||||
= (int)((MCD_bufDesc*) srcAddrVirt)->srcAddr;
|
= (int)((MCD_bufDesc*) srcAddrVirt)->srcAddr;
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET]
|
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET]
|
||||||
= (int)((MCD_bufDesc*) srcAddrVirt)->destAddr;
|
= (int)((MCD_bufDesc*) srcAddrVirt)->destAddr;
|
||||||
#endif
|
#endif
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0;
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[DCOUNT
|
||||||
((volatile int *)MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET] = (u32) srcAddr;
|
+ CSAVE_OFFSET] = 0;
|
||||||
|
((volatile int *) MCD_taskTable[channel].contextSaveSpace)[CURRBD
|
||||||
|
+ CSAVE_OFFSET] = (u32) srcAddr;
|
||||||
|
|
||||||
if( funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2)
|
if (funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2)
|
||||||
{
|
{
|
||||||
/*TDTStart and TDTEnd*/
|
/*TDTStart and TDTEnd*/
|
||||||
MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_CHAINNOEU].TDTstart;
|
MCD_taskTable[channel].TDTstart =
|
||||||
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_CHAINNOEU].TDTend;
|
MCD_modelTaskTable[TASK_CHAINNOEU].TDTstart;
|
||||||
MCD_startDmaChainNoEu((int *)srcAddr, srcIncr, destIncr, xferSize,
|
MCD_taskTable[channel].TDTend =
|
||||||
|
MCD_modelTaskTable[TASK_CHAINNOEU].TDTend;
|
||||||
|
MCD_startDmaChainNoEu((int *) srcAddr, srcIncr, destIncr, xferSize,
|
||||||
xferSizeIncr, cSave, MCD_taskTable, channel);
|
xferSizeIncr, cSave, MCD_taskTable, channel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*TDTStart and TDTEnd*/
|
/*TDTStart and TDTEnd*/
|
||||||
MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_CHAINEU].TDTstart;
|
MCD_taskTable[channel].TDTstart =
|
||||||
MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_CHAINEU].TDTend;
|
MCD_modelTaskTable[TASK_CHAINEU].TDTstart;
|
||||||
MCD_startDmaChainEu((int *)srcAddr, srcIncr, destIncr, xferSize,
|
MCD_taskTable[channel].TDTend =
|
||||||
|
MCD_modelTaskTable[TASK_CHAINEU].TDTend;
|
||||||
|
MCD_startDmaChainEu((int *) srcAddr, srcIncr, destIncr, xferSize,
|
||||||
xferSizeIncr, cSave, MCD_taskTable, channel);
|
xferSizeIncr, cSave, MCD_taskTable, channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MCD_chStatus[channel] = MCD_IDLE;
|
MCD_chStatus[channel] = MCD_IDLE;
|
||||||
return(MCD_OK);
|
return (MCD_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************ End of MCD_startDma() *********************/
|
/************************ End of MCD_startDma() *********************/
|
||||||
@@ -584,7 +597,7 @@ printf("startDma:Setting up params\n");
|
|||||||
*/
|
*/
|
||||||
#define STABTIME 0
|
#define STABTIME 0
|
||||||
|
|
||||||
int MCD_XferProgrQuery (int channel, MCD_XferProg *progRep)
|
int MCD_XferProgrQuery(int channel, MCD_XferProg *progRep)
|
||||||
{
|
{
|
||||||
MCD_XferProg prevRep;
|
MCD_XferProg prevRep;
|
||||||
int again; /* true if we are to try again to get consistent results */
|
int again; /* true if we are to try again to get consistent results */
|
||||||
@@ -596,32 +609,43 @@ int MCD_XferProgrQuery (int channel, MCD_XferProg *progRep)
|
|||||||
int subModVal, addModVal; /* Mode values to added and subtracted from the
|
int subModVal, addModVal; /* Mode values to added and subtracted from the
|
||||||
final destAddr */
|
final destAddr */
|
||||||
|
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if ((channel < 0) || (channel >= NCHANNELS))
|
||||||
return(MCD_CHANNEL_INVALID);
|
return (MCD_CHANNEL_INVALID);
|
||||||
|
|
||||||
/* Read a trial value for the progress-reporting values*/
|
/* Read a trial value for the progress-reporting values*/
|
||||||
prevRep.lastSrcAddr =
|
prevRep.lastSrcAddr =
|
||||||
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET];
|
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR
|
||||||
|
+ CSAVE_OFFSET];
|
||||||
prevRep.lastDestAddr =
|
prevRep.lastDestAddr =
|
||||||
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET];
|
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR
|
||||||
prevRep.dmaSize = ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET];
|
+ CSAVE_OFFSET];
|
||||||
|
prevRep.dmaSize =
|
||||||
|
((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT
|
||||||
|
+ CSAVE_OFFSET];
|
||||||
prevRep.currBufDesc =
|
prevRep.currBufDesc =
|
||||||
(MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET];
|
(MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD
|
||||||
|
+ CSAVE_OFFSET];
|
||||||
/* Repeatedly reread those values until they match previous values: */
|
/* Repeatedly reread those values until they match previous values: */
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
/* Waste a little bit of time to ensure stability: */
|
/* Waste a little bit of time to ensure stability: */
|
||||||
for (i = 0; i < STABTIME; i++)
|
for (i = 0; i < STABTIME; i++)
|
||||||
i += i >> 2; /* make sure this loop does something so that it doesn't get optimized out */
|
i += i >> 2; /* make sure this loop does something so that it doesn't get optimized out */
|
||||||
/* Check them again: */
|
/* Check them again: */
|
||||||
progRep->lastSrcAddr =
|
progRep->lastSrcAddr =
|
||||||
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET];
|
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR
|
||||||
|
+ CSAVE_OFFSET];
|
||||||
progRep->lastDestAddr =
|
progRep->lastDestAddr =
|
||||||
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET];
|
(s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR
|
||||||
progRep->dmaSize = ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET];
|
+ CSAVE_OFFSET];
|
||||||
|
progRep->dmaSize =
|
||||||
|
((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT
|
||||||
|
+ CSAVE_OFFSET];
|
||||||
progRep->currBufDesc =
|
progRep->currBufDesc =
|
||||||
(MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET];
|
(MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD
|
||||||
|
+ CSAVE_OFFSET];
|
||||||
/* See if they match: */
|
/* See if they match: */
|
||||||
if ( prevRep.lastSrcAddr != progRep->lastSrcAddr
|
if (prevRep.lastSrcAddr != progRep->lastSrcAddr
|
||||||
|| prevRep.lastDestAddr != progRep->lastDestAddr
|
|| prevRep.lastDestAddr != progRep->lastDestAddr
|
||||||
|| prevRep.dmaSize != progRep->dmaSize
|
|| prevRep.dmaSize != progRep->dmaSize
|
||||||
|| prevRep.currBufDesc != progRep->currBufDesc)
|
|| prevRep.currBufDesc != progRep->currBufDesc)
|
||||||
@@ -637,36 +661,42 @@ int MCD_XferProgrQuery (int channel, MCD_XferProg *progRep)
|
|||||||
again = MCD_FALSE;
|
again = MCD_FALSE;
|
||||||
} while (again == MCD_TRUE);
|
} while (again == MCD_TRUE);
|
||||||
|
|
||||||
|
|
||||||
/* Update the dCount, srcAddr and destAddr */
|
/* Update the dCount, srcAddr and destAddr */
|
||||||
/* To calculate dmaCount, we consider destination address. C
|
/* To calculate dmaCount, we consider destination address. C
|
||||||
overs M1,P1,Z for destination */
|
overs M1,P1,Z for destination */
|
||||||
switch(MCD_remVariants.remDestRsdIncr[channel]) {
|
switch (MCD_remVariants.remDestRsdIncr[channel])
|
||||||
|
{
|
||||||
case MINUS1:
|
case MINUS1:
|
||||||
subModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
|
subModVal = ((int) progRep->lastDestAddr)
|
||||||
addModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
|
& ((MCD_remVariants.remXferSize[channel]) - 1);
|
||||||
|
addModVal = ((int) progRep->currBufDesc->destAddr)
|
||||||
|
& ((MCD_remVariants.remXferSize[channel]) - 1);
|
||||||
LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - addModVal;
|
LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - addModVal;
|
||||||
LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal;
|
LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal;
|
||||||
destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr;
|
destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr;
|
||||||
bytesNotXfered = (destDiffBytes/MCD_remVariants.remDestIncr[channel]) *
|
bytesNotXfered = (destDiffBytes / MCD_remVariants.remDestIncr[channel])
|
||||||
( MCD_remVariants.remDestIncr[channel]
|
* (MCD_remVariants.remDestIncr[channel]
|
||||||
+ MCD_remVariants.remXferSize[channel]);
|
+ MCD_remVariants.remXferSize[channel]);
|
||||||
progRep->dmaSize = destDiffBytes - bytesNotXfered + addModVal - subModVal;
|
progRep->dmaSize = destDiffBytes - bytesNotXfered + addModVal
|
||||||
|
- subModVal;
|
||||||
break;
|
break;
|
||||||
case ZERO:
|
case ZERO:
|
||||||
progRep->lastDestAddr = progRep->currBufDesc->destAddr;
|
progRep->lastDestAddr = progRep->currBufDesc->destAddr;
|
||||||
break;
|
break;
|
||||||
case PLUS1:
|
case PLUS1:
|
||||||
/* This value has to be subtracted from the final calculated dCount. */
|
/* This value has to be subtracted from the final calculated dCount. */
|
||||||
subModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
|
subModVal = ((int) progRep->currBufDesc->destAddr)
|
||||||
|
& ((MCD_remVariants.remXferSize[channel]) - 1);
|
||||||
/* These bytes are already in lastDestAddr. */
|
/* These bytes are already in lastDestAddr. */
|
||||||
addModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
|
addModVal = ((int) progRep->lastDestAddr)
|
||||||
|
& ((MCD_remVariants.remXferSize[channel]) - 1);
|
||||||
LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - subModVal;
|
LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - subModVal;
|
||||||
LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal;
|
LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal;
|
||||||
destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr);
|
destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr);
|
||||||
numIterations = ( LWAlignedCurrDestAddr - LWAlignedInitDestAddr)/MCD_remVariants.remDestIncr[channel];
|
numIterations = (LWAlignedCurrDestAddr - LWAlignedInitDestAddr)
|
||||||
bytesNotXfered = numIterations *
|
/ MCD_remVariants.remDestIncr[channel];
|
||||||
( MCD_remVariants.remDestIncr[channel]
|
bytesNotXfered = numIterations
|
||||||
|
* (MCD_remVariants.remDestIncr[channel]
|
||||||
- MCD_remVariants.remXferSize[channel]);
|
- MCD_remVariants.remXferSize[channel]);
|
||||||
progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal;
|
progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal;
|
||||||
break;
|
break;
|
||||||
@@ -675,26 +705,28 @@ int MCD_XferProgrQuery (int channel, MCD_XferProg *progRep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This covers M1,P1,Z for source */
|
/* This covers M1,P1,Z for source */
|
||||||
switch(MCD_remVariants.remSrcRsdIncr[channel]) {
|
switch (MCD_remVariants.remSrcRsdIncr[channel])
|
||||||
|
{
|
||||||
case MINUS1:
|
case MINUS1:
|
||||||
progRep->lastSrcAddr =
|
progRep->lastSrcAddr = progRep->currBufDesc->srcAddr
|
||||||
progRep->currBufDesc->srcAddr +
|
+ (MCD_remVariants.remSrcIncr[channel]
|
||||||
( MCD_remVariants.remSrcIncr[channel] *
|
* (progRep->dmaSize
|
||||||
(progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
|
/ MCD_remVariants.remXferSize[channel]));
|
||||||
break;
|
break;
|
||||||
case ZERO:
|
case ZERO:
|
||||||
progRep->lastSrcAddr = progRep->currBufDesc->srcAddr;
|
progRep->lastSrcAddr = progRep->currBufDesc->srcAddr;
|
||||||
break;
|
break;
|
||||||
case PLUS1:
|
case PLUS1:
|
||||||
progRep->lastSrcAddr =
|
progRep->lastSrcAddr = progRep->currBufDesc->srcAddr
|
||||||
progRep->currBufDesc->srcAddr +
|
+ (MCD_remVariants.remSrcIncr[channel]
|
||||||
( MCD_remVariants.remSrcIncr[channel] *
|
* (progRep->dmaSize
|
||||||
(progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
|
/ MCD_remVariants.remXferSize[channel]));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(MCD_OK);
|
return (MCD_OK);
|
||||||
}
|
}
|
||||||
/******************* End of MCD_XferProgrQuery() ********************/
|
/******************* End of MCD_XferProgrQuery() ********************/
|
||||||
|
|
||||||
@@ -705,13 +737,16 @@ int MCD_XferProgrQuery (int channel, MCD_XferProg *progRep)
|
|||||||
* enable before resuming it, but the resume function has to do nothing
|
* enable before resuming it, but the resume function has to do nothing
|
||||||
* if there is no DMA on that channel (i.e., if the enable bit is 0).
|
* if there is no DMA on that channel (i.e., if the enable bit is 0).
|
||||||
*/
|
*/
|
||||||
static void MCD_resmActions (int channel)
|
static void MCD_resmActions(int channel)
|
||||||
{
|
{
|
||||||
|
u32 debugStatus;
|
||||||
|
|
||||||
MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
|
MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
|
||||||
MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus;
|
debugStatus = MCD_dmaBar->debugStatus;
|
||||||
|
MCD_dmaBar->debugStatus = debugStatus;
|
||||||
MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; /* This register is selected to know
|
MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; /* This register is selected to know
|
||||||
which initiator is actually asserted. */
|
which initiator is actually asserted. */
|
||||||
if((MCD_dmaBar->ptdDebug >> channel ) & 0x1)
|
if ((MCD_dmaBar->ptdDebug >> channel) & 0x1)
|
||||||
MCD_chStatus[channel] = MCD_RUNNING;
|
MCD_chStatus[channel] = MCD_RUNNING;
|
||||||
else
|
else
|
||||||
MCD_chStatus[channel] = MCD_IDLE;
|
MCD_chStatus[channel] = MCD_IDLE;
|
||||||
@@ -730,15 +765,15 @@ static void MCD_resmActions (int channel)
|
|||||||
* always goes to the MCD_HALTED state even if it is killed while in
|
* always goes to the MCD_HALTED state even if it is killed while in
|
||||||
* the MCD_NO_DMA or MCD_IDLE states.
|
* the MCD_NO_DMA or MCD_IDLE states.
|
||||||
*/
|
*/
|
||||||
int MCD_killDma (int channel)
|
int MCD_killDma(int channel)
|
||||||
{
|
{
|
||||||
/* MCD_XferProg progRep; */
|
/* MCD_XferProg progRep; */
|
||||||
|
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if ((channel < 0) || (channel >= NCHANNELS))
|
||||||
return(MCD_CHANNEL_INVALID);
|
return (MCD_CHANNEL_INVALID);
|
||||||
|
|
||||||
MCD_dmaBar->taskControl[channel] = 0x0;
|
MCD_dmaBar->taskControl[channel] = 0x0;
|
||||||
MCD_resumeDma (channel);
|
MCD_resumeDma(channel);
|
||||||
/*
|
/*
|
||||||
* This must be after the write to the TCR so that the task doesn't
|
* This must be after the write to the TCR so that the task doesn't
|
||||||
* start up again momentarily, and before the status assignment so
|
* start up again momentarily, and before the status assignment so
|
||||||
@@ -753,7 +788,7 @@ int MCD_killDma (int channel)
|
|||||||
* MCD_XferProgrQuery (channel, &progRep);
|
* MCD_XferProgrQuery (channel, &progRep);
|
||||||
* progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
|
* progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
|
||||||
*/
|
*/
|
||||||
return(MCD_OK);
|
return (MCD_OK);
|
||||||
}
|
}
|
||||||
/************************ End of MCD_killDma() **********************/
|
/************************ End of MCD_killDma() **********************/
|
||||||
|
|
||||||
@@ -768,15 +803,15 @@ int MCD_killDma (int channel)
|
|||||||
* This routine does not check to see if there is a task which can
|
* This routine does not check to see if there is a task which can
|
||||||
* be continued. Also this routine should not be used with single DMAs.
|
* be continued. Also this routine should not be used with single DMAs.
|
||||||
*/
|
*/
|
||||||
int MCD_continDma (int channel)
|
int MCD_continDma(int channel)
|
||||||
{
|
{
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if ((channel < 0) || (channel >= NCHANNELS))
|
||||||
return(MCD_CHANNEL_INVALID);
|
return (MCD_CHANNEL_INVALID);
|
||||||
|
|
||||||
MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN;
|
MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN;
|
||||||
MCD_chStatus[channel] = MCD_RUNNING;
|
MCD_chStatus[channel] = MCD_RUNNING;
|
||||||
|
|
||||||
return(MCD_OK);
|
return (MCD_OK);
|
||||||
}
|
}
|
||||||
/********************** End of MCD_continDma() **********************/
|
/********************** End of MCD_continDma() **********************/
|
||||||
|
|
||||||
@@ -819,12 +854,12 @@ int MCD_continDma (int channel)
|
|||||||
* Arguments: channel
|
* Arguments: channel
|
||||||
* Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
|
* Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
|
||||||
*/
|
*/
|
||||||
int MCD_pauseDma (int channel)
|
int MCD_pauseDma(int channel)
|
||||||
{
|
{
|
||||||
/* MCD_XferProg progRep; */
|
/* MCD_XferProg progRep; */
|
||||||
|
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if ((channel < 0) || (channel >= NCHANNELS))
|
||||||
return(MCD_CHANNEL_INVALID);
|
return (MCD_CHANNEL_INVALID);
|
||||||
|
|
||||||
if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
|
if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
|
||||||
{
|
{
|
||||||
@@ -839,7 +874,7 @@ int MCD_pauseDma (int channel)
|
|||||||
* progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
|
* progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
return(MCD_OK);
|
return (MCD_OK);
|
||||||
}
|
}
|
||||||
/************************* End of MCD_pauseDma() ********************/
|
/************************* End of MCD_pauseDma() ********************/
|
||||||
|
|
||||||
@@ -850,15 +885,15 @@ int MCD_pauseDma (int channel)
|
|||||||
* Arguments: channel - channel on which to resume DMA
|
* Arguments: channel - channel on which to resume DMA
|
||||||
* Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
|
* Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
|
||||||
*/
|
*/
|
||||||
int MCD_resumeDma (int channel)
|
int MCD_resumeDma(int channel)
|
||||||
{
|
{
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if ((channel < 0) || (channel >= NCHANNELS))
|
||||||
return(MCD_CHANNEL_INVALID);
|
return (MCD_CHANNEL_INVALID);
|
||||||
|
|
||||||
if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
|
if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
|
||||||
MCD_resmActions (channel);
|
MCD_resmActions(channel);
|
||||||
|
|
||||||
return(MCD_OK);
|
return (MCD_OK);
|
||||||
}
|
}
|
||||||
/************************ End of MCD_resumeDma() ********************/
|
/************************ End of MCD_resumeDma() ********************/
|
||||||
|
|
||||||
@@ -872,7 +907,7 @@ int MCD_resumeDma (int channel)
|
|||||||
* Notes:
|
* Notes:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int MCD_csumQuery (int channel, u32 *csum)
|
int MCD_csumQuery(int channel, u32 *csum)
|
||||||
{
|
{
|
||||||
#ifdef MCD_INCLUDE_EU
|
#ifdef MCD_INCLUDE_EU
|
||||||
if((channel < 0) || (channel >= NCHANNELS))
|
if((channel < 0) || (channel >= NCHANNELS))
|
||||||
@@ -881,7 +916,7 @@ int MCD_csumQuery (int channel, u32 *csum)
|
|||||||
*csum = MCD_relocBuffDesc[channel].csumResult;
|
*csum = MCD_relocBuffDesc[channel].csumResult;
|
||||||
return(MCD_OK);
|
return(MCD_OK);
|
||||||
#else
|
#else
|
||||||
return(MCD_ERROR);
|
return (MCD_ERROR);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*********************** End of MCD_resumeDma() *********************/
|
/*********************** End of MCD_resumeDma() *********************/
|
||||||
@@ -896,7 +931,7 @@ int MCD_getCodeSize(void)
|
|||||||
#ifdef MCD_INCLUDE_EU
|
#ifdef MCD_INCLUDE_EU
|
||||||
return(0x2b5c);
|
return(0x2b5c);
|
||||||
#else
|
#else
|
||||||
return(0x173c);
|
return (0x173c);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/********************** End of MCD_getCodeSize() ********************/
|
/********************** End of MCD_getCodeSize() ********************/
|
||||||
@@ -915,7 +950,7 @@ char MCD_versionString[] = "Multi-channel DMA API Alpha v0.3 (2004-04-26)";
|
|||||||
int MCD_getVersion(char **longVersion)
|
int MCD_getVersion(char **longVersion)
|
||||||
{
|
{
|
||||||
*longVersion = MCD_versionString;
|
*longVersion = MCD_versionString;
|
||||||
return((MCD_REV_MAJOR << 8) | MCD_REV_MINOR);
|
return ((MCD_REV_MAJOR << 8) | MCD_REV_MINOR);
|
||||||
}
|
}
|
||||||
/********************** End of MCD_getVersion() *********************/
|
/********************** End of MCD_getVersion() *********************/
|
||||||
|
|
||||||
@@ -923,7 +958,7 @@ int MCD_getVersion(char **longVersion)
|
|||||||
/* Private version of memcpy()
|
/* Private version of memcpy()
|
||||||
* Note that everything this is used for is longword-aligned.
|
* Note that everything this is used for is longword-aligned.
|
||||||
*/
|
*/
|
||||||
static void MCD_memcpy (int *dest, int *src, u32 size)
|
static void MCD_memcpy(int *dest, int *src, u32 size)
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "startcf.h"
|
#include "startcf.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "bas_printf.h"
|
#include "bas_printf.h"
|
||||||
|
#include "bas_string.h"
|
||||||
#include "bas_types.h"
|
#include "bas_types.h"
|
||||||
#include "sd_card.h"
|
#include "sd_card.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
#include "s19reader.h"
|
#include "s19reader.h"
|
||||||
|
#include "spidma.h"
|
||||||
|
|
||||||
/* imported routines */
|
/* imported routines */
|
||||||
extern int mmu_init();
|
extern int mmu_init();
|
||||||
@@ -151,10 +153,15 @@ void nvram_init(void)
|
|||||||
xprintf("finished\r\n");
|
xprintf("finished\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ACP interrupt controller */
|
||||||
|
#define FPGA_INTR_CONTRL 0xf0010000
|
||||||
|
#define FPGA_INTR_ENABLE 0xf0010004
|
||||||
|
#define FPGA_INTR_PENDIN 0xf0010008
|
||||||
|
|
||||||
void enable_coldfire_interrupts()
|
void enable_coldfire_interrupts()
|
||||||
{
|
{
|
||||||
xprintf("enable interrupts: ");
|
xprintf("enable interrupts: ");
|
||||||
* (volatile uint32_t *) 0xf0010004 = 0L; /* disable all interrupts */
|
* (volatile uint32_t *) FPGA_INTR_CONTRL = 0L; /* disable all interrupts */
|
||||||
MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */
|
MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */
|
||||||
|
|
||||||
MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */
|
MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */
|
||||||
@@ -189,11 +196,7 @@ void BaS(void)
|
|||||||
|
|
||||||
/* copy EMUTOS */
|
/* copy EMUTOS */
|
||||||
src = (uint8_t *) EMUTOS;
|
src = (uint8_t *) EMUTOS;
|
||||||
while (src < (uint8_t *)(EMUTOS + EMUTOS_SIZE))
|
memcpy(dst, src, EMUTOS_SIZE);
|
||||||
{
|
|
||||||
*dst++ = *src++;
|
|
||||||
}
|
|
||||||
|
|
||||||
xprintf("finished\r\n");
|
xprintf("finished\r\n");
|
||||||
|
|
||||||
/* we have copied a code area, so flush the caches */
|
/* we have copied a code area, so flush the caches */
|
||||||
@@ -308,6 +311,8 @@ void BaS(void)
|
|||||||
xprintf("Call OS. BaS initialization finished...\r\n");
|
xprintf("Call OS. BaS initialization finished...\r\n");
|
||||||
enable_coldfire_interrupts();
|
enable_coldfire_interrupts();
|
||||||
|
|
||||||
|
spidma_init();
|
||||||
|
|
||||||
ROM_HEADER* os_header = (ROM_HEADER*)TOS;
|
ROM_HEADER* os_header = (ROM_HEADER*)TOS;
|
||||||
os_header->initial_pc();
|
os_header->initial_pc();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,16 @@
|
|||||||
|
|
||||||
#include "bas_string.h"
|
#include "bas_string.h"
|
||||||
|
|
||||||
|
void *memcpy(void *dst, const void *src, size_t n)
|
||||||
|
{
|
||||||
|
char *to = dst;
|
||||||
|
|
||||||
|
while (to < (char *) dst + n)
|
||||||
|
*to++ = * (char *) src++;
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, int max)
|
int strncmp(const char *s1, const char *s2, int max)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|||||||
@@ -100,9 +100,9 @@
|
|||||||
#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V)
|
#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V)
|
||||||
#define mmuord_d ( MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
#define mmuord_d ( MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||||
#define mmuord_i (MCF_MMU_MMUOR_ITLB|MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
#define mmuord_i (MCF_MMU_MMUOR_ITLB|MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||||
#define wt_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
#define writethrough_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||||
#define cb_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
#define copyback_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||||
#define nc_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(10)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
#define nocache_precise_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(10)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
@@ -519,10 +519,10 @@ irq6: // mfp
|
|||||||
add.l #std_mmutr,d0
|
add.l #std_mmutr,d0
|
||||||
move.l d3,d1 // page 0?
|
move.l d3,d1 // page 0?
|
||||||
beq irq6_sca_pn0 // ja ->
|
beq irq6_sca_pn0 // ja ->
|
||||||
add.l #cb_mmudr,d1 // sonst page cb
|
add.l #copyback_mmudr,d1 // sonst page cb
|
||||||
bra irq6_sca_pn1c
|
bra irq6_sca_pn1c
|
||||||
irq6_sca_pn0:
|
irq6_sca_pn0:
|
||||||
add.l #wt_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked
|
add.l #writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked
|
||||||
irq6_sca_pn1c:
|
irq6_sca_pn1c:
|
||||||
mvz.w #0x10b,d2 // MMU update
|
mvz.w #0x10b,d2 // MMU update
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
@@ -824,7 +824,7 @@ video_copy_data_loop:
|
|||||||
move.l d4,MCF_MMU_MMUAR
|
move.l d4,MCF_MMU_MMUAR
|
||||||
move.l d0,d1
|
move.l d0,d1
|
||||||
add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
|
add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
|
||||||
add.l #0x60000000|wt_mmudr|MCF_MMU_MMUDR_LK,d1
|
add.l #0x60000000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||||
mvz.w #0x10b,d2 // MMU update
|
mvz.w #0x10b,d2 // MMU update
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ static volatile DSTATUS Stat = 0 /* STA_NOINIT */; /* Physical drive status */
|
|||||||
static uint8_t CardType; /* Card type flags */
|
static uint8_t CardType; /* Card type flags */
|
||||||
|
|
||||||
|
|
||||||
static uint32_t dspi_fifo_val = // MCF_DSPI_DTFR_CONT | /* enable continous chip select */
|
static uint32_t dspi_fifo_val = MCF_DSPI_DTFR_CONT | /* enable continous chip select */
|
||||||
/* CTAS use DCTAR0 for clock and attributes */
|
/* CTAS use DCTAR0 for clock and attributes */
|
||||||
MCF_DSPI_DTFR_CTCNT;
|
MCF_DSPI_DTFR_CTCNT;
|
||||||
|
|
||||||
|
|||||||
@@ -71,9 +71,9 @@
|
|||||||
#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V)
|
#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V)
|
||||||
#define mmuord_d ( MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
#define mmuord_d ( MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||||
#define mmuord_i (MCF_MMU_MMUOR_ITLB|MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
#define mmuord_i (MCF_MMU_MMUOR_ITLB|MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||||
#define wt_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
#define writethrough_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||||
#define cb_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
#define copyback_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||||
#define nc_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(10)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
#define nocache_precise_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(10)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||||
|
|
||||||
.global _mmu_init
|
.global _mmu_init
|
||||||
.global _mmutr_miss
|
.global _mmutr_miss
|
||||||
@@ -112,66 +112,75 @@ _mmu_init:
|
|||||||
move.l #MCF_MMU_MMUOR_CA,d0 // clear all entries,
|
move.l #MCF_MMU_MMUOR_CA,d0 // clear all entries,
|
||||||
move.l d0,MCF_MMU_MMUOR
|
move.l d0,MCF_MMU_MMUOR
|
||||||
nop
|
nop
|
||||||
|
|
||||||
// 0000'0000 locked
|
// 0000'0000 locked
|
||||||
moveq.l #0x00000000|std_mmutr,d0
|
moveq.l #0x00000000|std_mmutr,d0
|
||||||
moveq.l #0x00000000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
moveq.l #0x00000000|copyback_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||||
moveq.l #mmuord_d,d2 // MMU update date
|
moveq.l #mmuord_d,d2 // MMU update data
|
||||||
moveq.l #mmuord_i,d3 // MMU update instruction
|
moveq.l #mmuord_i,d3 // MMU update instruction
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
move.l d2,MCF_MMU_MMUOR // MMU update date
|
move.l d2,MCF_MMU_MMUOR // MMU update data
|
||||||
move.l d3,MCF_MMU_MMUOR // MMU update instruction
|
move.l d3,MCF_MMU_MMUOR // MMU update instruction
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
// 00d0'0000 locked ID=6
|
// 00d0'0000 locked ID=6
|
||||||
// video ram: read write execute normal write true
|
// video ram: read write execute normal write true
|
||||||
move.l #0x00d00000|MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
|
move.l #0x00d00000|MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
|
||||||
move.l #0x60d00000|wt_mmudr|MCF_MMU_MMUDR_LK,d1
|
move.l #0x60d00000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
move.l d2,MCF_MMU_MMUOR // MMU update date
|
move.l d2,MCF_MMU_MMUOR // MMU update data
|
||||||
move.l #0x00d00000|std_mmutr,d0
|
move.l #0x00d00000|std_mmutr,d0
|
||||||
move.l d3,MCF_MMU_MMUOR // MMU update instruction
|
move.l d3,MCF_MMU_MMUOR // MMU update instruction
|
||||||
|
|
||||||
move.l #0x2000,d0
|
move.l #0x2000,d0
|
||||||
move.l d0,_video_tlb // set page as video page
|
move.l d0,_video_tlb // set page as video page
|
||||||
clr.l _video_sbt // clear time
|
clr.l _video_sbt // clear time
|
||||||
|
|
||||||
|
#ifdef _NOT_USED_
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// Make the TOS (in SDRAM) read-only
|
// Make the TOS (in SDRAM) read-only
|
||||||
move.l #__TOS+std_mmutr,d0
|
move.l #__TOS+std_mmutr,d0
|
||||||
move.l #__TOS+cb_mmudr+MCF_MMU_MMUDR_LK,d1
|
move.l #__TOS+copyback_mmudr+MCF_MMU_MMUDR_LK,d1
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
move.l d2,MCF_MMU_MMUOR // setzen read only ?????? noch nicht
|
move.l d2,MCF_MMU_MMUOR // setzen read only ?????? noch nicht
|
||||||
move.l d3,MCF_MMU_MMUOR // setzen
|
move.l d3,MCF_MMU_MMUOR // setzen
|
||||||
|
#endif /* _NOT_USED_ */
|
||||||
|
|
||||||
// 00f0'0000 locked
|
// 00f0'0000 locked
|
||||||
move.l #0x00f00000|std_mmutr,d0
|
move.l #0x00f00000|std_mmutr,d0
|
||||||
move.l #0xfff00000|nc_mmudr|MCF_MMU_MMUDR_LK,d1
|
move.l #0xfff00000|nocache_precise_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
move.l d2,MCF_MMU_MMUOR // maped to ffffxxx, precise,
|
move.l d2,MCF_MMU_MMUOR // mapped to ffffxxx, precise,
|
||||||
move.l d3,MCF_MMU_MMUOR // maped to ffffxxx, precise,
|
move.l d3,MCF_MMU_MMUOR // mapped to ffffxxx, precise,
|
||||||
|
|
||||||
// 1fe0'0000 locked
|
// 1fe0'0000 locked
|
||||||
move.l #0x1FE00000|std_mmutr,d0
|
move.l #0x1FE00000|std_mmutr,d0
|
||||||
move.l #0x1FE00000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
move.l #0x1FE00000|copyback_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
move.l d2,MCF_MMU_MMUOR // setzen data
|
move.l d2,MCF_MMU_MMUOR // setzen data
|
||||||
move.l d3,MCF_MMU_MMUOR // setzen instr
|
move.l d3,MCF_MMU_MMUOR // setzen instr
|
||||||
// 1ff0'0000 locked
|
|
||||||
|
#ifdef _NOT_USED_
|
||||||
|
// 1ff0'0000 locked (FIXME: why is this?)
|
||||||
move.l #0x1FF00000|std_mmutr,d0
|
move.l #0x1FF00000|std_mmutr,d0
|
||||||
move.l #0x1FF00000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
move.l #0x1FF00000|copyback_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
move.l d2,MCF_MMU_MMUOR // setzen data
|
move.l d2,MCF_MMU_MMUOR // setzen data
|
||||||
move.l d3,MCF_MMU_MMUOR // setzen instr
|
move.l d3,MCF_MMU_MMUOR // setzen instr
|
||||||
// instr 0xFFF0'0000 nach 0x1FF0'0000 umleiten -->> short sprung
|
// instr 0xFFF0'0000 nach 0x1FF0'0000 umleiten -->> short sprung
|
||||||
/* move.l #0xFFF00000|std_mmutr,d0
|
/* move.l #0xFFF00000|std_mmutr,d0
|
||||||
move.l #0x1FF00000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
move.l #0x1FF00000|copyback_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
move.l d1,MCF_MMU_MMUDR
|
move.l d1,MCF_MMU_MMUDR
|
||||||
move.l d3,MCF_MMU_MMUOR // setzen instr
|
move.l d3,MCF_MMU_MMUOR // setzen instr
|
||||||
*/
|
*/
|
||||||
|
#endif /* _NOT_USED_ */
|
||||||
move.l (sp)+,d2 // Restore registers
|
move.l (sp)+,d2 // Restore registers
|
||||||
move.l (sp)+,d3
|
move.l (sp)+,d3
|
||||||
rts
|
rts
|
||||||
@@ -185,7 +194,7 @@ _mmutr_miss:
|
|||||||
or.l #std_mmutr,d0
|
or.l #std_mmutr,d0
|
||||||
move.l d0,MCF_MMU_MMUTR
|
move.l d0,MCF_MMU_MMUTR
|
||||||
and.l #0xFFF00000,d0
|
and.l #0xFFF00000,d0
|
||||||
or.l #cb_mmudr,d0
|
or.l #copyback_mmudr,d0
|
||||||
move.l d0,MCF_MMU_MMUDR
|
move.l d0,MCF_MMU_MMUDR
|
||||||
moveq.l #mmuord_d,d0 // MMU update data
|
moveq.l #mmuord_d,d0 // MMU update data
|
||||||
move.l d0,MCF_MMU_MMUOR // set
|
move.l d0,MCF_MMU_MMUOR // set
|
||||||
|
|||||||
26
BaS_gcc/sources/spidma.c
Normal file
26
BaS_gcc/sources/spidma.c
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* spidma.c
|
||||||
|
*
|
||||||
|
* Created on: 27.07.2013
|
||||||
|
* Author: mfro
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "spidma.h"
|
||||||
|
#include <MCD_dma.h>
|
||||||
|
#include "bas_printf.h"
|
||||||
|
|
||||||
|
extern char *_SYS_SRAM;
|
||||||
|
|
||||||
|
int spidma_init(void)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = MCD_initDma((dmaRegs *) &MCF_DMA_TASKBAR, &_SYS_SRAM, MCD_RELOC_TASKS | MCD_COMM_PREFETCH_EN);
|
||||||
|
if (res != MCD_OK)
|
||||||
|
{
|
||||||
|
xprintf("DMA API initialization failed (0x%x)\r\n", res);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
xprintf("DMA API initialized. Tasks are at %p\r\n", &_SYS_SRAM);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "sysinit.h"
|
#include "sysinit.h"
|
||||||
#include "bas_printf.h"
|
#include "bas_printf.h"
|
||||||
|
#include "bas_string.h"
|
||||||
#include "bas_types.h"
|
#include "bas_types.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
|
|
||||||
@@ -796,10 +797,10 @@ extern uint8_t _FIRETOS[];
|
|||||||
#define FIRETOS ((uint32_t)_FIRETOS) /* where FireTOS is stored in flash */
|
#define FIRETOS ((uint32_t)_FIRETOS) /* where FireTOS is stored in flash */
|
||||||
|
|
||||||
extern uint8_t _BAS_LMA[];
|
extern uint8_t _BAS_LMA[];
|
||||||
#define BAS_LMA ((uint32_t)_BAS_LMA) /* where the BaS is stored in flash */
|
#define BAS_LMA (&_BAS_LMA[0]) /* where the BaS is stored in flash */
|
||||||
|
|
||||||
extern uint8_t _BAS_IN_RAM[];
|
extern uint8_t _BAS_IN_RAM[];
|
||||||
#define BAS_IN_RAM ((uint32_t)_BAS_IN_RAM) /* where the BaS is run in RAM */
|
#define BAS_IN_RAM (&_BAS_IN_RAM[0]) /* where the BaS is run in RAM */
|
||||||
|
|
||||||
extern uint8_t _BAS_SIZE[];
|
extern uint8_t _BAS_SIZE[];
|
||||||
#define BAS_SIZE ((uint32_t)_BAS_SIZE) /* size of the BaS, in bytes */
|
#define BAS_SIZE ((uint32_t)_BAS_SIZE) /* size of the BaS, in bytes */
|
||||||
@@ -808,11 +809,6 @@ extern uint8_t _FASTRAM_END[];
|
|||||||
#define FASTRAM_END ((uint32_t)_FASTRAM_END)
|
#define FASTRAM_END ((uint32_t)_FASTRAM_END)
|
||||||
|
|
||||||
void initialize_hardware(void) {
|
void initialize_hardware(void) {
|
||||||
/* used in copy loop */
|
|
||||||
uint32_t *src; /* src address to read from flash */
|
|
||||||
uint32_t *end; /* end address to read from flash */
|
|
||||||
uint32_t *dst; /* destination address to copy to */
|
|
||||||
|
|
||||||
/* Test for FireTOS switch: DIP switch #5 up */
|
/* Test for FireTOS switch: DIP switch #5 up */
|
||||||
if (!(DIP_SWITCH & (1 << 6))) {
|
if (!(DIP_SWITCH & (1 << 6))) {
|
||||||
/* Minimal hardware initialization */
|
/* Minimal hardware initialization */
|
||||||
@@ -923,22 +919,11 @@ void initialize_hardware(void) {
|
|||||||
//video_1280_1024();
|
//video_1280_1024();
|
||||||
init_ac97();
|
init_ac97();
|
||||||
|
|
||||||
/* copy the BaS .data and .bss contained in flash to its final location */
|
xprintf("copying BaS data (%p - %p) to RAM (%p)\r\n", BAS_LMA, BAS_LMA + BAS_SIZE, BAS_IN_RAM);
|
||||||
src = (uint32_t *) BAS_LMA;
|
|
||||||
end = (uint32_t *) (BAS_LMA + BAS_SIZE);
|
|
||||||
dst = (uint32_t *) BAS_IN_RAM;
|
|
||||||
|
|
||||||
xprintf("copying BaS data (%p - %p) to RAM (%p)\r\n", src, end, dst);
|
|
||||||
/* The linker script will ensure that the Bas size
|
/* The linker script will ensure that the Bas size
|
||||||
* is a multiple of the following.
|
* is a multiple of the following.
|
||||||
*/
|
*/
|
||||||
while (src < end)
|
memcpy((void *) BAS_IN_RAM, BAS_LMA, BAS_SIZE);
|
||||||
{
|
|
||||||
*dst++ = *src++;
|
|
||||||
*dst++ = *src++;
|
|
||||||
*dst++ = *src++;
|
|
||||||
*dst++ = *src++;
|
|
||||||
}
|
|
||||||
xprintf("finished.\r\n");
|
xprintf("finished.\r\n");
|
||||||
|
|
||||||
/* we have copied a code area, so flush the caches */
|
/* we have copied a code area, so flush the caches */
|
||||||
|
|||||||
Reference in New Issue
Block a user