Fixed cache management.
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#include "MCF5475.h"
|
#include "MCF5475.h"
|
||||||
#include "MCF5475_SLT.h"
|
#include "MCF5475_SLT.h"
|
||||||
#include "startcf.h"
|
#include "startcf.h"
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
extern uint32_t Bas_base[];
|
extern uint32_t Bas_base[];
|
||||||
extern uint8_t tos_base[];
|
extern uint8_t tos_base[];
|
||||||
@@ -77,6 +78,9 @@ void BaS(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we have copied a code area, so flush the caches */
|
||||||
|
flush_and_invalidate_caches();
|
||||||
|
|
||||||
#ifdef _NOT_USED_
|
#ifdef _NOT_USED_
|
||||||
/*
|
/*
|
||||||
* set the NVRAM checksum as invalid
|
* set the NVRAM checksum as invalid
|
||||||
|
|||||||
@@ -3,70 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
|
void flush_and_invalidate_caches(void)
|
||||||
void flushDataCacheRegion(void *adr, uint32_t length)
|
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
" move.l %0,d0 | start address\n\t"
|
|
||||||
" move.l d0,a1\n\t"
|
|
||||||
" add.l %1,a1 | add length\n\t"
|
|
||||||
" clr.l d1 | way counter\n\t"
|
|
||||||
" and.l #0xfffffff0,d0 | align start address\n\t"
|
|
||||||
".flush_dregion_way_loop:\n\t"
|
|
||||||
" move.l d0,a0 | initialize a0\n\t"
|
|
||||||
" add.l d1,a0 | set way index\n\t"
|
|
||||||
".flush_dregion_loop:\n\t"
|
|
||||||
" cpushl DC,(a0) | flush and invalidate the cache line\n\t"
|
|
||||||
" add.l #0x10,a0 | increment to next cache line\n\t"
|
|
||||||
" cmp.l a0,a1 | done with region?\n\t"
|
|
||||||
" bgt .flush_dregion_loop\n\t"
|
|
||||||
" addq.l #1,d1 | increment way counter\n\t"
|
|
||||||
" addq.l #1,a1 | update stop address to reflect new way value\n\t"
|
|
||||||
" cmp.l #4,d1 | cache way\n\t"
|
|
||||||
" bne .flush_dregion_way_loop\n\t"
|
|
||||||
/* output */ :
|
|
||||||
/* input */ : "g" (adr),
|
|
||||||
"g" (length)
|
|
||||||
/* clobber */: "d0", "d1", "a0", "a1"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flushInstructionCacheRegion(void *adr, uint32_t length)
|
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
" move.l %0,d0 | start address\n\t"
|
|
||||||
" move.l d0,a1\n\t"
|
|
||||||
" add.l %1,a1 | add length\n\t"
|
|
||||||
" clr.l d1 | way counter\n\t"
|
|
||||||
" and.l #0xfffffff0,d0 | align start address\n\t"
|
|
||||||
".flush_iregion_way_loop:\n\t"
|
|
||||||
" move.l d0,a0 | initialize a0\n\t"
|
|
||||||
" add.l d1,a0 | set way index\n\t"
|
|
||||||
".flush_iregion_loop:\n\t"
|
|
||||||
" cpushl IC,(a0) | flush and invalidate the cache line\n\t"
|
|
||||||
" add.l #0x10,a0 | increment to next cache line\n\t"
|
|
||||||
" cmp.l a0,a1 | done with region?\n\t"
|
|
||||||
" bgt .flush_iregion_loop\n\t"
|
|
||||||
" addq.l #1,d1 | increment way counter\n\t"
|
|
||||||
" addq.l #1,a1 | update stop address to reflect new way value\n\t"
|
|
||||||
" cmp.l #4,d1 | cache way\n\t"
|
|
||||||
" bne .flush_iregion_way_loop\n\t"
|
|
||||||
/* output */ :
|
|
||||||
/* input */ : "g" (adr),
|
|
||||||
"g" (length)
|
|
||||||
/* clobber */: "d0", "d1", "a0", "a1"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_caches(void)
|
|
||||||
{
|
{
|
||||||
__asm__ (
|
__asm__ (
|
||||||
"cpusha:\n\t"
|
|
||||||
" move sr,d2\n\t"
|
|
||||||
" move.l d2,-(sp)\n\t"
|
|
||||||
" move #0x2700,sr | no interrupts\n\t"
|
|
||||||
" clr.l d0\n\t"
|
" clr.l d0\n\t"
|
||||||
" clr.l d1\n\t"
|
" clr.l d1\n\t"
|
||||||
" move.l d0,a0\n\t"
|
" move.l d0,a0\n\t"
|
||||||
@@ -75,16 +14,14 @@ void clear_caches(void)
|
|||||||
" lea 0x10(a0),a0 | index+1\n\t"
|
" lea 0x10(a0),a0 | index+1\n\t"
|
||||||
" addq.l #1,d1 | index+1\n\t"
|
" addq.l #1,d1 | index+1\n\t"
|
||||||
" cmpi.w #512,d1 | all sets?\n\t"
|
" cmpi.w #512,d1 | all sets?\n\t"
|
||||||
" bne cfa_setloop | no->\n\t"
|
" bne.s cfa_setloop | no->\n\t"
|
||||||
" clr.l d1\n\t"
|
" clr.l d1\n\t"
|
||||||
" addq.l #1,d0\n\t"
|
" addq.l #1,d0\n\t"
|
||||||
" move.l d0,a0\n\t"
|
" move.l d0,a0\n\t"
|
||||||
" cmpi.w #4,d0 | all ways?\n\t"
|
" cmpi.w #4,d0 | all ways?\n\t"
|
||||||
" bne cfa_setloop | no->\n\t"
|
" bne.s cfa_setloop | no->\n\t"
|
||||||
" move.l (sp)+,d2\n\t"
|
|
||||||
" move.w d2,sr | restore previous interrupt mask\n\t"
|
|
||||||
/* input */ :
|
/* input */ :
|
||||||
/* output */ :
|
/* output */ :
|
||||||
/* clobber */ : "d0", "d1", "d2", "a0"
|
/* clobber */ : "d0", "d1", "a0"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern void flushDataCacheRegion(void *adr, uint32_t length);
|
extern void flush_and_invalidate_caches(void);
|
||||||
extern void flushInstructionCacheRegion(void *adr, uint32_t length);
|
|
||||||
|
|
||||||
#endif /* _CACHE_H_ */
|
#endif /* _CACHE_H_ */
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
.extern _rt_ssp;
|
.extern _rt_ssp;
|
||||||
.extern _rt_usp;
|
.extern _rt_usp;
|
||||||
.extern ___MMUBAR
|
.extern ___MMUBAR
|
||||||
|
.extern _flush_and_invalidate_caches
|
||||||
|
|
||||||
/* Register read/write macros */
|
/* Register read/write macros */
|
||||||
#define MCF_MMU_MMUCR __MMUBAR
|
#define MCF_MMU_MMUCR __MMUBAR
|
||||||
@@ -554,29 +555,10 @@ pv_f_d16pc:
|
|||||||
//*****************************************************
|
//*****************************************************
|
||||||
cpusha:
|
cpusha:
|
||||||
lea -16(a7),a7
|
lea -16(a7),a7
|
||||||
movem.l d0-d2/a0,(a7) // register sichern
|
movem.l d0-d1/a0-a1,(a7) // backup C trash registers
|
||||||
move sr,d2
|
jsr _flush_and_invalidate_caches
|
||||||
nop
|
movem.l (a7),d0-d1/a0-a1 // restore C trash registers
|
||||||
move #0x2700,sr // no interrupts
|
|
||||||
|
|
||||||
clr.l d0
|
|
||||||
clr.l d1
|
|
||||||
move.l d0,a0
|
|
||||||
cfa_setloop:
|
|
||||||
cpushl bc,(a0) // flush
|
|
||||||
lea 0x10(a0),a0 // index+1
|
|
||||||
addq.l #1,d1 // index+1
|
|
||||||
cmpi.w #512,d1 // alle sets?
|
|
||||||
bne cfa_setloop // nein->
|
|
||||||
clr.l d1
|
|
||||||
addq.l #1,d0
|
|
||||||
move.l d0,a0
|
|
||||||
cmpi.w #4,d0 // all ways?
|
|
||||||
bne cfa_setloop // nein->
|
|
||||||
move.w d2,sr // alte interrupt maske
|
|
||||||
movem.l (a7),d0-d2/a0 // register zur<EFBFBD>ck
|
|
||||||
lea 16(a7),a7
|
lea 16(a7),a7
|
||||||
|
|
||||||
rts
|
rts
|
||||||
//*******************************************************33
|
//*******************************************************33
|
||||||
|
|
||||||
|
|||||||
@@ -709,9 +709,8 @@ void initialize_hardware(void) {
|
|||||||
*dst++ = *src++;
|
*dst++ = *src++;
|
||||||
} while (dst < &bas_end);
|
} while (dst < &bas_end);
|
||||||
|
|
||||||
/* clear all addresses touched during copy from all cache lines */
|
/* we have copied a code area, so flush the caches */
|
||||||
flushDataCacheRegion(&BaS, (uint32_t) (&bas_end - &BaS));
|
flush_and_invalidate_caches();
|
||||||
flushInstructionCacheRegion(&BaS, (uint32_t) (&bas_end - &BaS));
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" move.l %0,a3 | calculated start address\n\t"
|
" move.l %0,a3 | calculated start address\n\t"
|
||||||
|
|||||||
Reference in New Issue
Block a user