📄 mmu8xx.c
字号:
/* */
/***********************************************************************/
void
MapVir2RealAddr(UCHAR *VirAddr, UCHAR *RealAddr,
ULONG Size, PAGE_T Attributes, ULONG cachePolicy)
{
ULONG msize;
ULONG adjust;
adjust = (ULONG)VirAddr & ~(LVL1_PAGE_SIZE - 1);
while(Size) {
if(Size > (LVL1_PAGE_SIZE - adjust) )
msize = LVL1_PAGE_SIZE - adjust;
else
msize = Size;
MapVir2RealArea(VirAddr, RealAddr, msize, Attributes, cachePolicy);
VirAddr += msize;
RealAddr += msize;
Size -= msize;
adjust = 0;
}
}
/***********************************************************************/
/* MapVir2RealArea(): Setup table for virtual to real mapping. */
/* */
/* This routine maps in a block of memory (no more than 4M ) at a */
/* given virtual address to a real address, with the specified */
/* attributes for the block. Also, a level two page table entry is */
/* created if one does not exist. */
/***********************************************************************/
void
MapVir2RealArea(UCHAR *VirAddr, UCHAR *RealAddr,
ULONG Size, PAGE_T Attributes, ULONG cachePolicy)
{
SEG_T Seg; /* segment prototype */
PAGE_T *Page, *PTEntry; /* page and page table entry pointers */
while(Size) {
/*
* Get segment entry to translate an address to
* Segment Descriptor Index
*/
Seg = gSegAddr[ADR2SDI(VirAddr)];
/*
* Check if this segment is valid, if not allocate
* a page for level-2 descriptor.
*/
if (!Seg.Bit.SegValid){
/*
* Note: Atleast 12 bits are zero since
* AllocBlankPage() routine always returns page
* alignment.
*/
Seg.Word = (ULONG)AllocBlankPage();
Seg.Bit.SegValid++; /* mark segment valid */
/* 1: Write-thru mode; 0: Write-back mode */
Seg.Bit.SegCachePolicy = cachePolicy;
gSegAddr[ADR2SDI(VirAddr)] = Seg;
}
/* Convert segment to page table pointer */
Page = SEG2PAGE(Seg);
/* Point to page table entry for 'virtual' address */
PTEntry = &Page[ADR2PDI(VirAddr)];
PTEntry->Word = Attributes.Word; /* set up page attribute */
/* Setup the Real Page Number (RPN) for real address */
PTEntry->Bit.PageRPN = ADR2RPN(RealAddr);
VirAddr += PAGE_SIZE; /* next virtual page */
RealAddr += PAGE_SIZE; /* next real page */
/* Go to next page if any */
if (Size && (Size < PAGE_SIZE))
Size = PAGE_SIZE;
Size -= PAGE_SIZE;
}
}
/***********************************************************************/
/* DisCacheing(): Disable cacheing for this buffer */
/***********************************************************************/
void
DisCacheing(UCHAR *Addr, ULONG Len, UCHAR Cache)
{
PAGE_T *Page, *PTEntry; /* page and page table entry pointers */
SEG_T Seg; /* segment prototype */
ULONG old_ipl;
ULONG VirAddr = (ULONG)((ULONG)Addr & ~(PAGE_SIZE - 1));
ULONG Size = (ULONG)(Addr - VirAddr + Len);
#if (BSP_MMU == YES)
#ifdef DEBUG
LogPrint("MMU8XX.C: Disable cacheing for address 0x%x, of size 0x%x",
Addr, Len);
#endif
old_ipl = splx(MAX_ILEV);
while(Size) {
/* get segment entry */
Seg = gSegAddr[ADR2SDI(VirAddr)];
if (!Seg.Bit.SegValid){ /* not yet allocated */
/*
* We should PANIC here, trying to change
* non-existing map
*/
Print("\n MMU8XX:Changing attributes of Invalid Segment");
k_fatal(0,0);
return;
}
/* convert segment to page table pointer */
Page = SEG2PAGE(Seg);
/* point to page table entry for 'start' address */
PTEntry = (PAGE_T *)&Page[ADR2PDI(VirAddr)];
/* Not yet mapped in */
if (!PTEntry->Bit.PageValid) {
/*
* We should PANIC here, trying to change
* non-existing page.
*/
Print("\n MMU8XX:Changing attributes of Invalid page");
k_fatal(0,0);
return;
}
/* Disable/Enable Caching depending on the attributes */
PTEntry->Bit.PageCacheDis = (Cache & 0x00000001);
VirAddr += PAGE_SIZE;
/* Go to next page if any */
if (Size && (Size < PAGE_SIZE))
Size = PAGE_SIZE;
Size -= PAGE_SIZE;
}
splx(old_ipl);
#endif
}
/***********************************************************************/
/* */
/* void EnableCache(void) */
/* */
/* This routine initializes both Instruction Cache and Data Cache */
/* registers. At first, the cache is unlocked just in case */
/* portions of the cache was locked. Next, the cache contents are */
/* invalidated, and Enables it. */
/* Note:This function must be called after MMU is enabled. Otherwise, */
/* certain I/O regions may be cachable as supposed to be cache- */
/* -inhibited. */
/* */
/***********************************************************************/
void
EnableCache(void)
{
/*
* Unlock all I-Cache & D-cache entries just in case it
* was locked after reset.
*/
#if (BRD_ICACHE == YES)
SysIcacheInit();
#endif
#if (BRD_DCACHE == YES)
#if (BRD_DCACHE_WRITE_THRU == YES)
SysDcacheInit(1);
#else
SysDcacheInit(0);
#endif
#endif
}
/***********************************************************************/
/* */
/* void DisableCache(void) */
/* */
/* This routine disables both Instruction Cache and Data Caches. */
/* */
/***********************************************************************/
void
DisableCache(void)
{
/*
* Unlock all I-Cache & D-cache entries just in case it
* was locked after reset.
*/
#if (BRD_ICACHE == YES)
SysIcacheInhibit();
#endif
#if (BRD_DCACHE == YES)
SysDcacheInhibit();
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -