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

📄 pm.c

📁 该源码是AT91rm9200的U-boot原代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************                   SciTech OS Portability Manager Library**  ========================================================================**    The contents of this file are subject to the SciTech MGL Public*    License Version 1.0 (the "License"); you may not use this file*    except in compliance with the License. You may obtain a copy of*    the License at http://www.scitechsoft.com/mgl-license.txt**    Software distributed under the License is distributed on an*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or*    implied. See the License for the specific language governing*    rights and limitations under the License.**    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.**    The Initial Developer of the Original Code is SciTech Software, Inc.*    All Rights Reserved.**  ========================================================================** Language:     ANSI C* Environment:  16/32 bit DOS** Description:  Implementation for the OS Portability Manager Library, which*               contains functions to implement OS specific services in a*               generic, cross platform API. Porting the OS Portability*               Manager library is the first step to porting any SciTech*               products to a new platform.*****************************************************************************/#include "pmapi.h"#include "drvlib/os/os.h"#include "ztimerc.h"#include "mtrr.h"#include "pm_help.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dos.h>#include <conio.h>#ifdef  __GNUC__#include <unistd.h>#include <sys/nearptr.h>#include <sys/stat.h>#else#include <direct.h>#endif#ifdef  __BORLANDC__#pragma warn -par#endif/*--------------------------- Global variables ----------------------------*/typedef struct {    int     oldMode;    int     old50Lines;    } DOS_stateBuf;#define MAX_RM_BLOCKS   10static struct {    void    *p;    uint    tag;    } rmBlocks[MAX_RM_BLOCKS];static uint     VESABuf_len = 1024;     /* Length of the VESABuf buffer     */static void     *VESABuf_ptr = NULL;    /* Near pointer to VESABuf          */static uint     VESABuf_rseg;           /* Real mode segment of VESABuf     */static uint     VESABuf_roff;           /* Real mode offset of VESABuf      */static void     (PMAPIP fatalErrorCleanup)(void) = NULL;ushort _VARAPI  _PM_savedDS = 0;#ifdef  DOS4GWstatic ulong    PDB = 0,*pPDB = NULL;#endif#ifndef REALMODEstatic char     VXD_name[] = PMHELP_NAME;static char     VXD_module[] = PMHELP_MODULE;static char     VXD_DDBName[] = PMHELP_DDBNAME;static uint     VXD_version = -1;static uint     VXD_loadOff = 0;static uint     VXD_loadSel = 0;uint _VARAPI    _PM_VXD_off = 0;uint _VARAPI    _PM_VXD_sel = 0;int _VARAPI     _PM_haveCauseWay = -1;/* Memory mapping cache */#define MAX_MEMORY_MAPPINGS 100typedef struct {    ulong   physical;    ulong   linear;    ulong   limit;    } mmapping;static mmapping     maps[MAX_MEMORY_MAPPINGS] = {0};static int          numMaps = 0;/* Page sized block cache */#define PAGES_PER_BLOCK     100#define FREELIST_NEXT(p)    (*(void**)(p))typedef struct pageblock {    struct pageblock    *next;    struct pageblock    *prev;    void                *freeListStart;    void                *freeList;    void                *freeListEnd;    int                 freeCount;    } pageblock;static pageblock    *pageBlocks = NULL;#endif/* Start of all page tables in CauseWay */#define CW_PAGE_TABLE_START (1024UL*4096UL*1023UL)/*----------------------------- Implementation ----------------------------*//* External assembler functions */ulong   _ASMAPI _PM_getPDB(void);int     _ASMAPI _PM_pagingEnabled(void);void    _ASMAPI _PM_VxDCall(VXD_regs *regs,uint off,uint sel);#ifndef REALMODE/****************************************************************************REMARKS:Exit function to unload the dynamically loaded VxD****************************************************************************/static void UnloadVxD(void){    PMSREGS     sregs;    VXD_regs    r;    r.eax = 2;    r.ebx = 0;    r.edx = (uint)VXD_module;    PM_segread(&sregs);#ifdef  __16BIT__    r.ds = ((ulong)VXD_module) >> 16;#else    r.ds = sregs.ds;#endif    r.es = sregs.es;    _PM_VxDCall(&r,VXD_loadOff,VXD_loadSel);}/****************************************************************************REMARKS:External function to call the PMHELP helper VxD.****************************************************************************/void PMAPI PM_VxDCall(    VXD_regs *regs){    if (_PM_VXD_sel != 0 || _PM_VXD_off != 0)        _PM_VxDCall(regs,_PM_VXD_off,_PM_VXD_sel);}/****************************************************************************RETURNS:BCD coded version number of the VxD, or 0 if not loaded (ie: 0x202 - 2.2)REMARKS:This function gets the version number for the VxD that we have connected to.****************************************************************************/uint PMAPI PMHELP_getVersion(void){    VXD_regs    r;    /* Call the helper VxD to determine the version number */    if (_PM_VXD_sel != 0 || _PM_VXD_off != 0) {        memset(&r,0,sizeof(r));        r.eax = API_NUM(PMHELP_GETVER);        _PM_VxDCall(&r,_PM_VXD_off,_PM_VXD_sel);        return VXD_version = (uint)r.eax;        }    return VXD_version = 0;}/****************************************************************************DESCRIPTION:Connects to the helper VxD and returns the version numberRETURNS:True if the VxD was found and loaded, false otherwise.REMARKS:This function connects to the VxD (loading it if it is dynamically loadable)and returns the version number of the VxD.****************************************************************************/static ibool PMHELP_connect(void){    PMREGS      regs;    PMSREGS     sregs;    VXD_regs    r;    /* Bail early if we have alread connected */    if (VXD_version != -1)        return VXD_version != 0;    /* Get the static SDDHELP.VXD entry point if available */    PM_segread(&sregs);    regs.x.ax = 0x1684;    regs.x.bx = SDDHELP_DeviceID;    regs.x.di = 0;    sregs.es = 0;    PM_int386x(0x2F,&regs,&regs,&sregs);    _PM_VXD_sel = sregs.es;    _PM_VXD_off = regs.x.di;    if (_PM_VXD_sel != 0 || _PM_VXD_off != 0) {        if (PMHELP_getVersion() >= PMHELP_VERSION)            return true;        }    /* If we get here, then either SDDHELP.VXD is not loaded, or it is an     * earlier version. In this case try to dynamically load the PMHELP.VXD     * helper VxD instead.     */    PM_segread(&sregs);    regs.x.ax = 0x1684;    regs.x.bx = VXDLDR_DeviceID;    regs.x.di = 0;    sregs.es = 0;    PM_int386x(0x2F,&regs,&regs,&sregs);    VXD_loadSel = sregs.es;    VXD_loadOff = regs.x.di;    if (VXD_loadSel == 0 && VXD_loadOff == 0)        return VXD_version = 0;    r.eax = 1;    r.ebx = 0;    r.edx = (uint)VXD_name;    PM_segread(&sregs);    r.ds = sregs.ds;    r.es = sregs.es;    _PM_VxDCall(&r,VXD_loadOff,VXD_loadSel);    if (r.eax != 0)        return VXD_version = 0;    /* Get the dynamic VxD entry point so we can call it */    atexit(UnloadVxD);    PM_segread(&sregs);    regs.x.ax = 0x1684;    regs.x.bx = 0;    regs.e.edi = (uint)VXD_DDBName;    PM_int386x(0x2F,&regs,&regs,&sregs);    _PM_VXD_sel = sregs.es;    _PM_VXD_off = regs.x.di;    if (_PM_VXD_sel == 0 && _PM_VXD_off == 0)        return VXD_version = 0;    if (PMHELP_getVersion() >= PMHELP_VERSION)        return true;    return VXD_version = 0;}#endif/****************************************************************************REMARKS:Initialise the PM library. First we try to connect to a static SDDHELP.VXDhelper VxD, and check that it is a version we can use. If not we try todynamically load the PMHELP.VXD helper VxD****************************************************************************/void PMAPI PM_init(void){#ifndef REALMODE    PMREGS  regs;    /* Check if we are running under CauseWay under real DOS */    if (_PM_haveCauseWay == -1) {        /* Check if we are running under DPMI in which case we will not be         * able to use our special ring 0 CauseWay functions.         */        _PM_haveCauseWay = false;        regs.x.ax = 0xFF00;        PM_int386(0x31,&regs,&regs);        if (regs.x.cflag || !(regs.e.edi & 8)) {            /* We are not under DPMI, so now check if CauseWay is active */            regs.x.ax = 0xFFF9;            PM_int386(0x31,&regs,&regs);            if (!regs.x.cflag && regs.e.ecx == 0x43415553 && regs.e.edx == 0x45574159)                _PM_haveCauseWay = true;            }        /* Now connect to PMHELP.VXD and initialise MTRR module */        if (!PMHELP_connect())            MTRR_init();        }#endif}/****************************************************************************PARAMETERS:base    - The starting physical base address of the regionsize    - The size in bytes of the regiontype    - Type to place into the MTRR registerRETURNS:Error code describing the result.REMARKS:Function to enable write combining for the specified region of memory.****************************************************************************/int PMAPI PM_enableWriteCombine(    ulong base,    ulong size,    uint type){#ifndef REALMODE    VXD_regs    regs;    if (PMHELP_connect()) {        memset(&regs,0,sizeof(regs));        regs.eax = API_NUM(PMHELP_ENABLELFBCOMB);        regs.ebx = base;        regs.ecx = size;        regs.edx = type;        _PM_VxDCall(&regs,_PM_VXD_off,_PM_VXD_sel);        return regs.eax;        }    return MTRR_enableWriteCombine(base,size,type);#else    return PM_MTRR_NOT_SUPPORTED;#endif}ibool PMAPI PM_haveBIOSAccess(void){ return true; }long PMAPI PM_getOSType(void){ return _OS_DOS; }int PMAPI PM_getModeType(void){#if defined(REALMODE)    return PM_realMode;#elif defined(PM286)    return PM_286;#elif defined(PM386)    return PM_386;#endif}void PMAPI PM_backslash(char *s){    uint pos = strlen(s);    if (s[pos-1] != '\\') {        s[pos] = '\\';        s[pos+1] = '\0';        }}void PMAPI PM_setFatalErrorCleanup(    void (PMAPIP cleanup)(void)){    fatalErrorCleanup = cleanup;}void PMAPI PM_fatalError(const char *msg){    if (fatalErrorCleanup)        fatalErrorCleanup();    fprintf(stderr,"%s\n", msg);    exit(1);}static void ExitVBEBuf(void){    if (VESABuf_ptr)        PM_freeRealSeg(VESABuf_ptr);    VESABuf_ptr = 0;}void * PMAPI PM_getVESABuf(uint *len,uint *rseg,uint *roff){    if (!VESABuf_ptr) {        /* Allocate a global buffer for communicating with the VESA VBE */        if ((VESABuf_ptr = PM_allocRealSeg(VESABuf_len, &VESABuf_rseg, &VESABuf_roff)) == NULL)            return NULL;        atexit(ExitVBEBuf);        }    *len = VESABuf_len;    *rseg = VESABuf_rseg;    *roff = VESABuf_roff;    return VESABuf_ptr;}int PMAPI PM_int386(int intno, PMREGS *in, PMREGS *out){    PMSREGS sregs;    PM_segread(&sregs);    return PM_int386x(intno,in,out,&sregs);}/* Routines to set and get the real mode interrupt vectors, by making * direct real mode calls to DOS and bypassing the DOS extenders API. * This is the safest way to handle this, as some servers try to be * smart about changing real mode vectors. */void PMAPI _PM_getRMvect(int intno, long *realisr){    RMREGS  regs;    RMSREGS sregs;    PM_saveDS();    regs.h.ah = 0x35;    regs.h.al = intno;    PM_int86x(0x21, &regs, &regs, &sregs);    *realisr = ((long)sregs.es << 16) | regs.x.bx;}void PMAPI _PM_setRMvect(int intno, long realisr){    RMREGS  regs;    RMSREGS sregs;    PM_saveDS();    regs.h.ah = 0x25;    regs.h.al = intno;    sregs.ds = (int)(realisr >> 16);    regs.x.dx = (int)(realisr & 0xFFFF);    PM_int86x(0x21, &regs, &regs, &sregs);}void PMAPI _PM_addRealModeBlock(void *mem,uint tag){    int i;    for (i = 0; i < MAX_RM_BLOCKS; i++) {        if (rmBlocks[i].p == NULL) {            rmBlocks[i].p = mem;            rmBlocks[i].tag = tag;            return;            }        }    PM_fatalError("To many real mode memory block allocations!");}uint PMAPI _PM_findRealModeBlock(void *mem){    int i;    for (i = 0; i < MAX_RM_BLOCKS; i++) {        if (rmBlocks[i].p == mem)            return rmBlocks[i].tag;        }    PM_fatalError("Could not find prior real mode memory block allocation!");

⌨️ 快捷键说明

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