⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmu8xx.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                                                                     */
/***********************************************************************/
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 + -