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

📄 pm.c

📁 AT91RM9200-U-Boot at91rm9200u-boot移植源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    ibool locked){#ifndef REALMODE    VXD_regs        regs;    pageblock       *block;    void            *p;    PM_lockHandle   lh; /* Unused in DOS */    /* Call the helper VxD for this service if we are running in a DOS box */    if (VXD_version) {        memset(&regs,0,sizeof(regs));        regs.eax = API_NUM(PMHELP_ALLOCPAGE);        regs.ebx = locked;        _PM_VxDCall(&regs,_PM_VXD_off,_PM_VXD_sel);        return (void*)regs.eax;        }    /* Scan the block list looking for any free blocks. Allocate a new     * page block if no free blocks are found.     */    for (block = pageBlocks; block != NULL; block = block->next) {        if (block->freeCount)            break;        }    if (block == NULL && (block = PM_addNewPageBlock()) == NULL)        return NULL;    block->freeCount--;    p = block->freeList;    block->freeList = FREELIST_NEXT(p);    if (locked)        PM_lockDataPages(p,PM_PAGE_SIZE,&lh);    return p;#else    return NULL;#endif}/****************************************************************************REMARKS:Free a page aligned and page sized block of memory****************************************************************************/void PMAPI PM_freePage(    void *p){#ifndef REALMODE    VXD_regs    regs;    pageblock   *block;    /* Call the helper VxD for this service if we are running in a DOS box */    if (VXD_version) {        memset(&regs,0,sizeof(regs));        regs.eax = API_NUM(PMHELP_FREEPAGE);        regs.ebx = (ulong)p;        _PM_VxDCall(&regs,_PM_VXD_off,_PM_VXD_sel);        return;        }    /* First find the page block that this page belongs to */    for (block = pageBlocks; block != NULL; block = block->next) {        if (p >= block->freeListStart && p <= block->freeListEnd)            break;        }    CHECK(block != NULL);    /* Now free the block by adding it to the free list */    FREELIST_NEXT(p) = block->freeList;    block->freeList = p;    if (++block->freeCount == PAGES_PER_BLOCK) {        /* If all pages in the page block are now free, free the entire         * page block itself.         */        if (block == pageBlocks) {            /* Delete from head */            pageBlocks = block->next;            if (block->next)                block->next->prev = NULL;            }        else {            /* Delete from middle of list */            CHECK(block->prev != NULL);            block->prev->next = block->next;            if (block->next)                block->next->prev = block->prev;            }        PM_free(block);        }#else    (void)p;#endif}/*-------------------------------------------------------------------------*//* DOS Real Mode support.                                                  *//*-------------------------------------------------------------------------*/#ifdef REALMODE#ifndef MK_FP#define MK_FP(s,o)  ( (void far *)( ((ulong)(s) << 16) + \                    (ulong)(o) ))#endifvoid * PMAPI PM_mapRealPointer(uint r_seg,uint r_off){ return MK_FP(r_seg,r_off); }void * PMAPI PM_getBIOSPointer(void){    return MK_FP(0x40,0);}void * PMAPI PM_getA0000Pointer(void){    return MK_FP(0xA000,0);}void * PMAPI PM_mapPhysicalAddr(ulong base,ulong limit,ibool isCached){    uint sel = base >> 4;    uint off = base & 0xF;    limit = limit;    return MK_FP(sel,off);}void PMAPI PM_freePhysicalAddr(void *ptr,ulong limit){ ptr = ptr; }ulong PMAPI PM_getPhysicalAddr(void *p){    return ((((ulong)p >> 16) << 4) + (ushort)p);}ibool PMAPI PM_getPhysicalAddrRange(void *p,ulong length,ulong *physAddress){ return false; }void * PMAPI PM_mapToProcess(void *base,ulong limit){ return (void*)base; }void * PMAPI PM_allocRealSeg(uint size,uint *r_seg,uint *r_off){    /* Call malloc() to allocate the memory for us */    void *p = PM_malloc(size);    *r_seg = FP_SEG(p);    *r_off = FP_OFF(p);    return p;}void PMAPI PM_freeRealSeg(void *mem){    if (mem) PM_free(mem);}int PMAPI PM_int86(int intno, RMREGS *in, RMREGS *out){    return PM_int386(intno,in,out);}int PMAPI PM_int86x(int intno, RMREGS *in, RMREGS *out,    RMSREGS *sregs){    return PM_int386x(intno,in,out,sregs);}void PMAPI PM_availableMemory(ulong *physical,ulong *total){    PMREGS regs;    regs.h.ah = 0x48;    regs.x.bx = 0xFFFF;    PM_int86(0x21,&regs,&regs);    *physical = *total = regs.x.bx * 16UL;}#endif/*-------------------------------------------------------------------------*//* Phar Lap TNT DOS Extender support.                                      *//*-------------------------------------------------------------------------*/#ifdef TNT#include <pldos32.h>#include <pharlap.h>#include <hw386.h>static uchar *zeroPtr = NULL;void * PMAPI PM_getBIOSPointer(void){    if (!zeroPtr)        zeroPtr = PM_mapPhysicalAddr(0,0xFFFFF,true);    return (void*)(zeroPtr + 0x400);}void * PMAPI PM_getA0000Pointer(void){    static void *bankPtr;    if (!bankPtr)        bankPtr = PM_mapPhysicalAddr(0xA0000,0xFFFF,true);    return bankPtr;}void * PMAPI PM_mapPhysicalAddr(ulong base,ulong limit,ibool isCached){    CONFIG_INF  config;    ULONG       offset;    int         err;    ulong       baseAddr,baseOfs,newLimit;    VXD_regs    regs;    /* If we have connected to our helper VxD in a Windows DOS box, use     * the helper VxD services to map memory instead of the DPMI services.     * We do this because the helper VxD can properly disable caching     * where necessary, which we can only do directly here if we are     * running at ring 0 (ie: under real DOS).     */    if (VXD_version == -1)        PM_init();    if (VXD_version) {        memset(&regs,0,sizeof(regs));        regs.eax = API_NUM(PMHELP_MAPPHYS);        regs.ebx = base;        regs.ecx = limit;        regs.edx = isCached;        _PM_VxDCall(&regs,_PM_VXD_off,_PM_VXD_sel);        return (void*)regs.eax;        }    /* Round the physical address to a 4Kb boundary and the limit to a     * 4Kb-1 boundary before passing the values to TNT. If we round the     * physical address, then we also add an extra offset into the address     * that we return.     */    baseOfs = base & 4095;    baseAddr = base & ~4095;    newLimit = ((limit+baseOfs+1+4095) & ~4095)-1;    _dx_config_inf(&config, (UCHAR*)&config);    err = _dx_map_phys(config.c_ds_sel,baseAddr,(newLimit + 4095) / 4096,&offset);    if (err == 130) {        /* If the TNT function failed, we are running in a DPMI environment         * and this function does not work. However we know how to handle         * DPMI properly, so we use our generic DPMI functions to do         * what the TNT runtime libraries can't.         */        return DPMI_mapPhysicalAddr(base,limit,isCached);        }    if (err == 0)        return (void*)(offset + baseOfs);    return NULL;}void PMAPI PM_freePhysicalAddr(void *ptr,ulong limit){}ulong PMAPI PM_getPhysicalAddr(void *p){ return 0xFFFFFFFFUL; }ibool PMAPI PM_getPhysicalAddrRange(void *p,ulong length,ulong *physAddress){ return false; }void * PMAPI PM_mapToProcess(void *base,ulong limit){ return (void*)base; }void * PMAPI PM_mapRealPointer(uint r_seg,uint r_off){    if (!zeroPtr)        zeroPtr = PM_mapPhysicalAddr(0,0xFFFFF);    return (void*)(zeroPtr + MK_PHYS(r_seg,r_off));}void * PMAPI PM_allocRealSeg(uint size,uint *r_seg,uint *r_off){    USHORT  addr,t;    void    *p;    if (_dx_real_alloc((size + 0xF) >> 4,&addr,&t) != 0)        return 0;    *r_seg = addr;                  /* Real mode segment address    */    *r_off = 0;                     /* Real mode segment offset     */    p = PM_mapRealPointer(*r_seg,*r_off);    _PM_addRealModeBlock(p,addr);    return p;}void PMAPI PM_freeRealSeg(void *mem){    if (mem) _dx_real_free(_PM_findRealModeBlock(mem));}#define INDPMI(reg)     rmregs.reg = regs->reg#define OUTDPMI(reg)    regs->reg = rmregs.regvoid PMAPI DPMI_int86(int intno, DPMI_regs *regs){    SWI_REGS    rmregs;    memset(&rmregs, 0, sizeof(rmregs));    INDPMI(eax); INDPMI(ebx); INDPMI(ecx); INDPMI(edx); INDPMI(esi); INDPMI(edi);    _dx_real_int(intno,&rmregs);    OUTDPMI(eax); OUTDPMI(ebx); OUTDPMI(ecx); OUTDPMI(edx); OUTDPMI(esi); OUTDPMI(edi);    regs->flags = rmregs.flags;}#define IN(reg)     rmregs.reg = in->e.reg#define OUT(reg)    out->e.reg = rmregs.regint PMAPI PM_int86(int intno, RMREGS *in, RMREGS *out){    SWI_REGS    rmregs;    memset(&rmregs, 0, sizeof(rmregs));    IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);    _dx_real_int(intno,&rmregs);    OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);    out->x.cflag = rmregs.flags & 0x1;    return out->x.ax;}int PMAPI PM_int86x(int intno, RMREGS *in, RMREGS *out,    RMSREGS *sregs){    SWI_REGS    rmregs;    memset(&rmregs, 0, sizeof(rmregs));    IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);    rmregs.es = sregs->es;    rmregs.ds = sregs->ds;    _dx_real_int(intno,&rmregs);    OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);    sregs->es = rmregs.es;    sregs->cs = rmregs.cs;    sregs->ss = rmregs.ss;    sregs->ds = rmregs.ds;    out->x.cflag = rmregs.flags & 0x1;    return out->x.ax;}void PMAPI PM_availableMemory(ulong *physical,ulong *total){    PMREGS  r;    uint    data[25];    r.x.ax = 0x2520;                /* Get free memory info */    r.x.bx = 0;    r.e.edx = (uint)data;    PM_int386(0x21, &r, &r);    *physical = data[21] * 4096;    *total = data[23] * 4096;}#endif/*-------------------------------------------------------------------------*//* Symantec C++ DOSX and FlashTek X-32/X-32VM support                      *//*-------------------------------------------------------------------------*/#if defined(DOSX) || defined(X32VM)#ifdef  X32VM#include <x32.h>#define _x386_mk_protected_ptr(p)   _x32_mk_protected_ptr((void*)p)#define _x386_free_protected_ptr(p) _x32_free_protected_ptr(p)#define _x386_zero_base_ptr         _x32_zero_base_ptr#elseextern void *_x386_zero_base_ptr;#endifvoid * PMAPI PM_mapRealPointer(uint r_seg,uint r_off){    return (void*)((ulong)_x386_zero_base_ptr + MK_PHYS(r_seg,r_off));}void * PMAPI PM_allocRealSeg(uint size,uint *r_seg,uint *r_off){    PMREGS  r;    r.h.ah = 0x48;                  /* DOS function 48h - allocate mem  */    r.x.bx = (size + 0xF) >> 4;     /* Number of paragraphs to allocate */    PM_int386(0x21, &r, &r);        /* Call DOS extender                */    if (r.x.cflag)        return 0;                   /* Could not allocate the memory    */    *r_seg = r.e.eax;    *r_off = 0;    return PM_mapRealPointer(*r_seg,*r_off);}void PMAPI PM_freeRealSeg(void *mem){    /* Cannot de-allocate this memory */    mem = mem;}#pragma pack(1)typedef struct {    ushort  intno;    ushort  ds;    ushort  es;    ushort  fs;    ushort  gs;    ulong   eax;    ulong   edx;    } _RMREGS;#pragma pack()#define IN(reg)     regs.e.reg = in->e.reg#define OUT(reg)    out->e.reg = regs.e.regint PMAPI PM_int86(int intno, RMREGS *in, RMREGS *out){    _RMREGS rmregs;    PMREGS  regs;    PMSREGS pmsregs;    rmregs.intno = intno;    rmregs.eax = in->e.eax;    rmregs.edx = in->e.edx;    IN(ebx); IN(ecx); IN(esi); IN(edi);    regs.x.ax = 0x2511;    regs.e.edx = (uint)(&rmregs);    PM_segread(&pmsregs);    PM_int386x(0x21,&regs,&regs,&pmsregs);    OUT(eax); OUT(ebx); OUT(ecx); OUT(esi); OUT(edi);    out->x.dx = rmregs.edx;    out->x.cflag = regs.x.cflag;    return out->x.ax;}int PMAPI PM_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs){    _RMREGS rmregs;    PMREGS  regs;    PMSREGS pmsregs;    rmregs.intno = intno;    rmregs.eax = in->e.eax;    rmregs.edx = in->e.edx;    rmregs.es = sregs->es;    rmregs.ds = sregs->ds;    IN(ebx); IN(ecx); IN(esi); IN(edi);

⌨️ 快捷键说明

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