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

📄 pm.c

📁 uboot在arm处理器s3c2410的移植代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    void *mappedBIOS,    ulong BIOSLen){    /* TODO: Figure out how to do this */    return false;}void * PMAPI PM_getBIOSPointer(void){ return (void*)0x400; }void * PMAPI PM_getA0000Pointer(void){ return PM_mapPhysicalAddr(0xA0000,0xFFFF,true); }/****************************************************************************PARAMETERS:base        - Physical base address of the memory to maps inlimit       - Limit of physical memory to region to maps inRETURNS:Linear address of the newly mapped memory.REMARKS:Maps a physical memory range to a linear memory range.****************************************************************************/ulong _PM_mapPhysicalToLinear(    ulong base,    ulong limit,    int *npages){    ulong   linear,length = limit+1;    int     i,ppage,flags;    if (base < 0x100000) {	/* Windows 9x is zero based for the first meg of memory */	return base;	}    ppage = base >> 12;    *npages = (length + (base & 0xFFF) + 4095) >> 12;    flags = PR_FIXED | PR_STATIC;    if (base == 0xA0000) {	/* We require the linear address to be aligned to a 64Kb boundary	 * for mapping the banked framebuffer (so we can do efficient	 * carry checking for bank changes in the assembler code). The only	 * way to ensure this is to force the linear address to be aligned	 * to a 4Mb boundary.	 */	flags |= PR_4MEG;	}    if ((linear = (ulong)PageReserve(PR_SYSTEM,*npages,flags)) == (ulong)-1)	return 0xFFFFFFFF;    if (!PageCommitPhys(linear >> 12,*npages,ppage,PC_INCR | PC_USER | PC_WRITEABLE))	return 0xFFFFFFFF;    return linear + (base & 0xFFF);}/* Page table flags */#define PAGE_FLAGS_PRESENT			0x00000001#define PAGE_FLAGS_WRITEABLE		0x00000002#define PAGE_FLAGS_USER				0x00000004#define PAGE_FLAGS_WRITE_THROUGH	0x00000008#define PAGE_FLAGS_CACHE_DISABLE	0x00000010#define PAGE_FLAGS_ACCESSED			0x00000020#define PAGE_FLAGS_DIRTY			0x00000040#define PAGE_FLAGS_4MB	            0x00000080/****************************************************************************PARAMETERS:base        - Physical base address of the memory to maps inlimit       - Limit of physical memory to region to maps inisCached    - True if the memory should be cached, false if notRETURNS:Linear address of the newly mapped memory.REMARKS:This function maps physical memory to linear memory, which can then be usedto create a selector or used directly from 32-bit protected mode programs.This is better than DPMI 0x800, since it allows you to maps physicalmemory below 1Mb, which gets this memory out of the way of the Windows VDD'ssticky paws.NOTE:   If the memory is not expected to be cached, this function will	directly re-program the PCD (Page Cache Disable) bit in the	page tables. There does not appear to be a mechanism in the VMM	to control this bit via the regular interface.****************************************************************************/void * PMAPI PM_mapPhysicalAddr(    ulong base,    ulong limit,    ibool isCached){    ulong   linear,length = limit+1;    int     i,npages;    ulong   PDB,*pPDB;    /* Search table of existing mappings to see if we have already mapped     * a region of memory that will serve this purpose.     */    for (i = 0; i < numMappings; i++) {	if (maps[i].physical == base && maps[i].length == length && maps[i].isCached == isCached)	    return (void*)maps[i].linear;	}    if (numMappings == MAX_MEMORY_MAPPINGS)	return NULL;    /* We did not find any previously mapped memory region, so maps it in.     * Note that we do not use MapPhysToLinear, since this function appears     * to have problems mapping memory in the 1Mb physical address space.     * Hence we use PageReserve and PageCommitPhys.     */    if ((linear = _PM_mapPhysicalToLinear(base,limit,&npages)) == 0xFFFFFFFF)	return NULL;    maps[numMappings].physical = base;    maps[numMappings].length = length;    maps[numMappings].linear = linear;    maps[numMappings].npages = npages;    maps[numMappings].isCached = isCached;    numMappings++;    /* Finally disable caching where necessary */    if (!isCached && (PDB = _PM_getPDB()) != 0) {	int     startPDB,endPDB,iPDB,startPage,endPage,start,end,iPage;	ulong   pageTable,*pPageTable;	pPDB = (ulong*)_PM_mapPhysicalToLinear(PDB,0xFFF,&npages);	if (pPDB) {	    startPDB = (linear >> 22) & 0x3FF;	    startPage = (linear >> 12) & 0x3FF;	    endPDB = ((linear+limit) >> 22) & 0x3FF;	    endPage = ((linear+limit) >> 12) & 0x3FF;	    for (iPDB = startPDB; iPDB <= endPDB; iPDB++) {		/* Set the bits in the page directory entry - required as per */		/* Pentium 4 manual. This also takes care of the 4MB page entries */		pPDB[iPDB] = pPDB[iPDB] |= (PAGE_FLAGS_WRITE_THROUGH | PAGE_FLAGS_CACHE_DISABLE);		if (!(pPDB[iPDB] & PAGE_FLAGS_4MB)) {		    /* If we are dealing with 4KB pages then we need to iterate */		    /* through each of the page table entries */		    pageTable = pPDB[iPDB] & ~0xFFF;		    pPageTable = (ulong*)_PM_mapPhysicalToLinear(pageTable,0xFFF,&npages);		    start = (iPDB == startPDB) ? startPage : 0;		    end = (iPDB == endPDB) ? endPage : 0x3FF;		    for (iPage = start; iPage <= end; iPage++)			pPageTable[iPage] |= (PAGE_FLAGS_WRITE_THROUGH | PAGE_FLAGS_CACHE_DISABLE);		    PageFree((ulong)pPageTable,PR_STATIC);		    }		}	    PageFree((ulong)pPDB,PR_STATIC);	    PM_flushTLB();	    }	}    return (void*)linear;}void PMAPI PM_freePhysicalAddr(    void *ptr,    ulong limit){    /* We never free the mappings */}void PMAPI PM_sleep(ulong milliseconds){    /* We never sleep in a VxD */}int PMAPI PM_getCOMPort(int port){    /* TODO: Re-code this to determine real values using the Plug and Play */    /*       manager for the OS. */    switch (port) {	case 0: return 0x3F8;	case 1: return 0x2F8;	case 2: return 0x3E8;	case 3: return 0x2E8;	}    return 0;}int PMAPI PM_getLPTPort(int port){    /* TODO: Re-code this to determine real values using the Plug and Play */    /*       manager for the OS. */    switch (port) {	case 0: return 0x3BC;	case 1: return 0x378;	case 2: return 0x278;	}    return 0;}ulong PMAPI PM_getPhysicalAddr(    void *p){    DWORD   pte;    /* Touch the memory before calling CopyPageTable. For some reason */    /* we need to do this on Windows 9x, otherwise the memory may not */    /* be paged in correctly. Of course if the passed in pointer is */    /* invalid, this function will fault, but we shouldn't be passed bogus */    /* pointers anyway ;-) */    pte = *((ulong*)p);    /* Return assembled address value only if VMM service succeeds */    if (CopyPageTable(((DWORD)p) >> 12, 1, (PVOID*)&pte, 0))	return (pte & ~0xFFF) | (((DWORD)p) & 0xFFF);    /* Return failure to the caller! */    return 0xFFFFFFFFUL;}ibool PMAPI PM_getPhysicalAddrRange(    void *p,    ulong length,    ulong *physAddress){    int     i;    ulong   linear = (ulong)p & ~0xFFF;    for (i = (length + 0xFFF) >> 12; i > 0; i--) {	if ((*physAddress++ = PM_getPhysicalAddr((void*)linear)) == 0xFFFFFFFF)	    return false;	linear += 4096;	}    return true;}void PMAPI _PM_freeMemoryMappings(void){    int i;    for (i = 0; i < numMappings; i++)	PageFree(maps[i].linear,PR_STATIC);}void * PMAPI PM_mapRealPointer(    uint r_seg,    uint r_off){    return (void*)MK_PHYS(r_seg,r_off);}void * PMAPI PM_allocRealSeg(    uint size,    uint *r_seg,    uint *r_off){    return NULL;}void PMAPI PM_freeRealSeg(    void *mem){}void PMAPI DPMI_int86(    int intno,    DPMI_regs *regs){    /* Unsed in VxD's */}/****************************************************************************REMARKS:Load the V86 registers in the client state, and save the original statebefore loading the registers.****************************************************************************/static void LoadV86Registers(    CLIENT_STRUCT *saveRegs,    RMREGS *in,    RMSREGS *sregs){    CLIENT_STRUCT   newRegs;    Save_Client_State(saveRegs);    newRegs = *saveRegs;    newRegs.CRS.Client_EAX = in->e.eax;    newRegs.CRS.Client_EBX = in->e.ebx;    newRegs.CRS.Client_ECX = in->e.ecx;    newRegs.CRS.Client_EDX = in->e.edx;    newRegs.CRS.Client_ESI = in->e.esi;    newRegs.CRS.Client_EDI = in->e.edi;    newRegs.CRS.Client_ES = sregs->es;    newRegs.CRS.Client_DS = sregs->ds;    Restore_Client_State(&newRegs);}/****************************************************************************REMARKS:Read the V86 registers from the client state and restore the original state.****************************************************************************/static void ReadV86Registers(    CLIENT_STRUCT *saveRegs,    RMREGS *out,    RMSREGS *sregs){    CLIENT_STRUCT   newRegs;    Save_Client_State(&newRegs);    out->e.eax = newRegs.CRS.Client_EAX;    out->e.ebx = newRegs.CRS.Client_EBX;    out->e.ecx = newRegs.CRS.Client_ECX;    out->e.edx = newRegs.CRS.Client_EDX;    out->e.esi = newRegs.CRS.Client_ESI;    out->e.edi = newRegs.CRS.Client_EDI;    sregs->es = newRegs.CRS.Client_ES;    sregs->ds = newRegs.CRS.Client_DS;    Restore_Client_State(saveRegs);}/****************************************************************************REMARKS:Call a V86 real mode function with the specified register valuesloaded before the call. The call returns with a far ret.****************************************************************************/void PMAPI PM_callRealMode(    uint seg,    uint off,    RMREGS *regs,    RMSREGS *sregs){    CLIENT_STRUCT saveRegs;    /* Bail if we do not have BIOS access (ie: the VxD was dynamically     * loaded, and not statically loaded.     */    if (!_PM_haveBIOS)	return;    _TRACE("SDDHELP: Entering PM_callRealMode()\n");    Begin_Nest_V86_Exec();    LoadV86Registers(&saveRegs,regs,sregs);    Simulate_Far_Call(seg, off);    Resume_Exec();    ReadV86Registers(&saveRegs,regs,sregs);    End_Nest_Exec();    _TRACE("SDDHELP: Exiting PM_callRealMode()\n");}/****************************************************************************REMARKS:Issue a V86 real mode interrupt with the specified register valuesloaded before the interrupt.****************************************************************************/int PMAPI PM_int86(    int intno,    RMREGS *in,    RMREGS *out){    RMSREGS         sregs = {0};    CLIENT_STRUCT   saveRegs;    ushort          oldDisable;    /* Bail if we do not have BIOS access (ie: the VxD was dynamically     * loaded, and not statically loaded.     */    if (!_PM_haveBIOS) {	*out = *in;	return out->x.ax;	}    /* Disable pass-up to our VxD handler so we directly call BIOS */    _TRACE("SDDHELP: Entering PM_int86()\n");    if (disableTSRFlag) {	oldDisable = *disableTSRFlag;	*disableTSRFlag = 0;	}    Begin_Nest_V86_Exec();    LoadV86Registers(&saveRegs,in,&sregs);    Exec_Int(intno);    ReadV86Registers(&saveRegs,out,&sregs);    End_Nest_Exec();    /* Re-enable pass-up to our VxD handler if previously enabled */    if (disableTSRFlag)	*disableTSRFlag = oldDisable;    _TRACE("SDDHELP: Exiting PM_int86()\n");    return out->x.ax;}/****************************************************************************REMARKS:Issue a V86 real mode interrupt with the specified register valuesloaded before the interrupt.****************************************************************************/int PMAPI PM_int86x(    int intno,    RMREGS *in,    RMREGS *out,    RMSREGS *sregs){    CLIENT_STRUCT   saveRegs;    ushort          oldDisable;    /* Bail if we do not have BIOS access (ie: the VxD was dynamically     * loaded, and not statically loaded.     */    if (!_PM_haveBIOS) {	*out = *in;	return out->x.ax;	}    /* Disable pass-up to our VxD handler so we directly call BIOS */    _TRACE("SDDHELP: Entering PM_int86x()\n");    if (disableTSRFlag) {	oldDisable = *disableTSRFlag;	*disableTSRFlag = 0;	}    Begin_Nest_V86_Exec();    LoadV86Registers(&saveRegs,in,sregs);    Exec_Int(intno);    ReadV86Registers(&saveRegs,out,sregs);    End_Nest_Exec();    /* Re-enable pass-up to our VxD handler if previously enabled */    if (disableTSRFlag)	*disableTSRFlag = oldDisable;    _TRACE("SDDHELP: Exiting PM_int86x()\n");    return out->x.ax;}/****************************************************************************REMARKS:Returns available memory. Not possible under Windows.****************************************************************************/void PMAPI PM_availableMemory(    ulong *physical,    ulong *total){    *physical = *total = 0;}/****************************************************************************REMARKS:Allocates a block of locked physical memory.****************************************************************************/void * PMAPI PM_allocLockedMem(    uint size,    ulong *physAddr,    ibool contiguous,    ibool below16M){    MEMHANDLE   hMem;    DWORD       nPages = (size + 0xFFF) >> 12;    DWORD       flags = PAGEFIXED | PAGEUSEALIGN | (contiguous ? PAGECONTIG : 0);    DWORD       maxPhys = below16M ? 0x00FFFFFF : 0xFFFFFFFF;    void        *p;    /* TODO: This may need to be modified if the memory needs to be globally */    /*       accessible. Check how we implemented PM_mallocShared() as we */    /*       may need to do something similar in here. */    PageAllocate(nPages,PG_SYS,0,0,0,maxPhys,physAddr,flags,&hMem,&p);    /* TODO: We may need to modify the memory blocks to disable caching via */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -