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

📄 pm.c

📁 uboot在arm处理器s3c2410的移植代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************                   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!");    return 0;}char * PMAPI PM_getCurrentPath(    char *path,    int maxLen){    return getcwd(path,maxLen);}char PMAPI PM_getBootDrive(void){ return 'C'; }const char * PMAPI PM_getVBEAFPath(void){ return "c:\\"; }const char * PMAPI PM_getNucleusPath(void){    static char path[256];    char        *env;    if ((env = getenv("NUCLEUS_PATH")) != NULL)	return env;    if ((env = getenv("WINBOOTDIR")) != NULL) {	/* Running in a Windows 9x DOS box or DOS mode */	strcpy(path,env);	strcat(path,"\\system\\nucleus");	return path;	}    if ((env = getenv("SystemRoot")) != NULL) {	/* Running in an NT/2K DOS box */	strcpy(path,env);	strcat(path,"\\system32\\nucleus");	return path;	}    return "c:\\nucleus";}const char * PMAPI PM_getNucleusConfigPath(void){    static char path[256];    strcpy(path,PM_getNucleusPath());    PM_backslash(path);    strcat(path,"config");    return path;}const char * PMAPI PM_getUniqueID(void){ return "DOS"; }const char * PMAPI PM_getMachineName(void){ return "DOS"; }int PMAPI PM_kbhit(void){    return kbhit();}int PMAPI PM_getch(void){    return getch();}PM_HWND PMAPI PM_openConsole(PM_HWND hwndUser,int device,int xRes,int yRes,int bpp,ibool fullScreen){    /* Not used for DOS */    (void)hwndUser;    (void)device;    (void)xRes;    (void)yRes;    (void)bpp;    (void)fullScreen;    return 0;}int PMAPI PM_getConsoleStateSize(void){    return sizeof(DOS_stateBuf);}void PMAPI PM_saveConsoleState(void *stateBuf,PM_HWND hwndConsole){    RMREGS          regs;    DOS_stateBuf    *sb = stateBuf;    /* Save the old video mode state */    regs.h.ah = 0x0F;    PM_int86(0x10,&regs,&regs);    sb->oldMode = regs.h.al & 0x7F;    sb->old50Lines = false;    if (sb->oldMode == 0x3) {	regs.x.ax = 0x1130;	regs.x.bx = 0;	regs.x.dx = 0;	PM_int86(0x10,&regs,&regs);	sb->old50Lines = (regs.h.dl == 42 || regs.h.dl == 49);	}    (void)hwndConsole;}void PMAPI PM_setSuspendAppCallback(int (_ASMAPIP saveState)(int flags)){    /* Not used for DOS */    (void)saveState;}void PMAPI PM_restoreConsoleState(const void *stateBuf,PM_HWND hwndConsole){    RMREGS              regs;    const DOS_stateBuf  *sb = stateBuf;    /* Retore 50 line mode if set */

⌨️ 快捷键说明

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