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

📄 pm.c

📁 omap osk环境下的bootloader,包含完整的uboot源代码
💻 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:  32-bit OS/2** 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 "pm_help.h"#include "mtrr.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <process.h>#ifndef __EMX__#include <direct.h>#endif#define INCL_DOSERRORS#define INCL_DOS#define INCL_SUB#define INCL_VIO#define INCL_KBD#include <os2.h>/* Semaphore for communication with our background daemon */#define SHAREDSEM   ((PSZ)"\\SEM32\\SDD\\DAEMON")#define DAEMON_NAME "SDDDAEMN.EXE"/*--------------------------- Global variables ----------------------------*//* Public structures used to communicate with VIDEOPMI for implementing * the ability to call the real mode BIOS functions. */typedef struct _VIDEOMODEINFO {    ULONG   miModeId;    USHORT  usType;    USHORT  usInt10ModeSet;    USHORT  usXResolution;    USHORT  usYResolution;    ULONG   ulBufferAddress;    ULONG   ulApertureSize;    BYTE    bBitsPerPixel;    BYTE    bBitPlanes;    BYTE    bXCharSize;    BYTE    bYCharSize;    USHORT  usBytesPerScanLine;    USHORT  usTextRows;    ULONG   ulPageLength;    ULONG   ulSaveSize;    BYTE    bVrtRefresh;    BYTE    bHrtRefresh;    BYTE    bVrtPolPos;    BYTE    bHrtPolPos;    CHAR    bRedMaskSize;    CHAR    bRedFieldPosition;    CHAR    bGreenMaskSize;    CHAR    bGreenFieldPosition;    CHAR    bBlueMaskSize;    CHAR    bBlueFieldPosition;    CHAR    bRsvdMaskSize;    CHAR    bRsvdFieldPosition;    ULONG   ulColors;    ULONG   ulReserved[3];    } VIDEOMODEINFO, FAR *PVIDEOMODEINFO;typedef struct _ADAPTERINFO {    ULONG       ulAdapterID;    CHAR        szOEMString[128];    CHAR        szDACString[128];    CHAR        szRevision[128];    ULONG       ulTotalMemory;    ULONG       ulMMIOBaseAddress;    ULONG       ulPIOBaseAddress;    BYTE        bBusType;    BYTE        bEndian;    USHORT      usDeviceBusID;    USHORT      usVendorBusID;    USHORT      SlotID;    } ADAPTERINFO, FAR *PADAPTERINFO;typedef struct _VIDEO_ADAPTER {    void            *hvideo;    ADAPTERINFO     Adapter;    VIDEOMODEINFO   ModeInfo;    } VIDEO_ADAPTER, FAR *PVIDEO_ADAPTER;/* PMIREQUEST_SOFTWAREINT structures from OS/2 DDK */typedef struct {    ULONG ulFlags;                              /* VDM initialization type */#define VDM_POSTLOAD                    0x1     /* adapter just loaded, used internally for initialization */#define VDM_INITIALIZE                  0x2     /* force initialization of a permanently open VDM, even if previously initialized */#define VDM_TERMINATE_POSTINITIALIZE    0x6     /*start VDM with initialization, but close it afterwards (includes VDM_INITIALIZE) */#define VDM_QUERY_CAPABILITY            0x10    /* query the current int 10 capability */#define VDM_FULL_VDM_CREATED            0x20    /* a full VDM is created */#define VDM_MINI_VDM_CREATED            0x40    /* a mini VDM is created */#define VDM_MINI_VDM_SUPPORTED          0x80    /* mini VDM support is available */    PCHAR szName;                               /* VDM initialization program */    PCHAR szArgs;                               /* VDM initialization arguments */    }INITVDM;typedef struct {    BYTE bBufferType;#define BUFFER_NONE     0#define INPUT_BUFFER    1#define OUTPUT_BUFFER   2    BYTE bReserved;    BYTE bSelCRF;    BYTE bOffCRF;    PVOID pAddress;    ULONG ulSize;    } BUFFER, *PBUFFER;typedef struct vcrf_s {    ULONG reg_eax;    ULONG reg_ebx;    ULONG reg_ecx;    ULONG reg_edx;    ULONG reg_ebp;    ULONG reg_esi;    ULONG reg_edi;    ULONG reg_ds;    ULONG reg_es;    ULONG reg_fs;    ULONG reg_gs;    ULONG reg_cs;    ULONG reg_eip;    ULONG reg_eflag;    ULONG reg_ss;    ULONG reg_esp;    } VCRF;typedef struct {    ULONG   ulBIOSIntNo;    VCRF    aCRF;    BUFFER  pB[2];    } INTCRF;#define PMIREQUEST_LOADPMIFILE          21#define PMIREQUEST_IDENTIFYADAPTER      22#define PMIREQUEST_SOFTWAREINT          23#ifdef  PTR_DECL_IN_FRONT#define EXPENTRYP   * EXPENTRY#else#define EXPENTRYP   EXPENTRY *#endif/* Entry point to VIDEOPMI32Request. This may be overridden by external * code that has already loaded VIDEOPMI to avoid loading it twice. */APIRET (EXPENTRYP PM_VIDEOPMI32Request)(PVIDEO_ADAPTER, ULONG, PVOID, PVOID) = NULL;static ibool        haveInt10 = -1; /* True if we have Int 10 support   */static ibool        useVPMI = true; /* False if VIDEOPMI unavailable    */static VIDEO_ADAPTER Adapter;       /* Video adapter for VIDEOPMI       */static uchar        RMBuf[1024];    /* Fake real mode transfer buffer   */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 uchar *      lowMem = NULL;static ibool        isSessionSwitching = false;static ulong        parmsIn[4];     /* Must not cross 64Kb boundary!    */static ulong        parmsOut[4];    /* Must not cross 64Kb boundary!    */extern ushort       _PM_gdt;static void (PMAPIP fatalErrorCleanup)(void) = NULL;/* DosSysCtl prototype. It is not declared in the headers but it is in the * standard import libraries (DOSCALLS.876). Funny. */APIRET APIENTRY DosSysCtl(ULONG ulFunction, PVOID pvData);/* This is the stack size for the threads that track the session switch event */#define SESSION_SWITCH_STACK_SIZE   32768typedef struct {    VIOMODEINFO     vmi;    USHORT          CursorX;    USHORT          CursorY;    UCHAR           FrameBuffer[1];    } CONSOLE_SAVE;typedef struct _SESWITCHREC {    /* The following variable is volatile because of PM_SUSPEND_APP         */    volatile int    Flags;          /* -1 or PM_DEACTIVATE or PM_REACTIVATE */    PM_saveState_cb Callback;       /* Save/restore context callback        */    HMTX            Mutex;          /* Exclusive access mutex               */    HEV             Event;          /* Posted after callback is called      */    } SESWITCHREC;/* Page sized block cache */#define PAGES_PER_BLOCK     32#define PAGE_BLOCK_SIZE     (PAGES_PER_BLOCK * PM_PAGE_SIZE + (PM_PAGE_SIZE-1) + sizeof(pageblock))#define FREELIST_NEXT(p)    (*(void**)(p))typedef struct pageblock {    struct pageblock    *next;    struct pageblock    *prev;    void                *freeListStart;    void                *freeList;    void                *freeListEnd;    int                 freeCount;    PM_lockHandle       lockHandle;    } pageblock;static pageblock    *pageBlocks = NULL;/*----------------------------- Implementation ----------------------------*//****************************************************************************PARAMETERS:func        - Helper device driver function to callRETURNS:First return value from the device driver in parmsOut[0]REMARKS:Function to open our helper device driver, call it and close the filehandle. Note that we have to open the device driver for every call becauseof two problems: 1. We cannot open a single file handle in a DLL that is shared amongst    programs, since every process must have it's own open file handle. 2. For some reason there appears to be a limit of about 12 open file    handles on a device driver in the system. Hence when we open more    than about 12 file handles things start to go very strange.Hence we simply open the file handle every time that we need to call thedevice driver to work around these problems.****************************************************************************/static ulong CallSDDHelp(    int func){    static ulong    inLen;          /* Must not cross 64Kb boundary!    */    static ulong    outLen;         /* Must not cross 64Kb boundary!    */    HFILE           hSDDHelp;    ULONG           rc;    ulong           result;    if ((rc = DosOpen(PMHELP_NAME,&hSDDHelp,&result,0,0,	    FILE_OPEN, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,	    NULL)) != 0) {	if (rc == 4) {  /* Did we run out of file handles? */	    ULONG   ulNewFHs;	    LONG    lAddFHs = 5;	    if (DosSetRelMaxFH(&lAddFHs, &ulNewFHs) != 0)		PM_fatalError("Failed to raise the file handles limit!");	    else {		if ((rc = DosOpen(PMHELP_NAME,&hSDDHelp,&result,0,0,			FILE_OPEN, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,			NULL)) != 0) {		    PM_fatalError("Unable to open SDDHELP$ helper device driver! (#2)");		    }		}	    }	else	    PM_fatalError("Unable to open SDDHELP$ helper device driver!");	}    if (DosDevIOCtl(hSDDHelp,PMHELP_IOCTL,func,	    &parmsIn, inLen = sizeof(parmsIn), &inLen,	    &parmsOut, outLen = sizeof(parmsOut), &outLen) != 0)	PM_fatalError("Failure calling SDDHELP$ helper device driver!");    DosClose(hSDDHelp);    return parmsOut[0];}/****************************************************************************REMARKS:Determine if we're running on a DBCS system.****************************************************************************/ibool __IsDBCSSystem(void){    CHAR        achDBCSInfo[12];    COUNTRYCODE ccStruct = {0, 0};    memset(achDBCSInfo, 0, 12);    /* Get the DBCS vector - if it's not empty, we're on DBCS */    DosQueryDBCSEnv(sizeof(achDBCSInfo), &ccStruct, achDBCSInfo);    if (achDBCSInfo[0] != 0)	return true;    else	return false;}/****************************************************************************REMARKS:Determine if PMSHELL is running - if it isn't, we can't use certain calls****************************************************************************/ibool __isShellLoaded(void){    PVOID   ptr;    if (DosGetNamedSharedMem(&ptr, (PSZ)"\\SHAREMEM\\PMGLOBAL.MEM", PAG_READ) == NO_ERROR) {	DosFreeMem(ptr);	return true;	}    return false;}/****************************************************************************REMARKS:Initialise the PM library and connect to our helper device driver. If wecannot connect to our helper device driver, we bail out with an errormessage.****************************************************************************/void PMAPI PM_init(void){    if (!lowMem) {	/* Obtain the 32->16 callgate from the device driver to enable IOPL */	if ((_PM_gdt = CallSDDHelp(PMHELP_GETGDT32)) == 0)	    PM_fatalError("Unable to obtain call gate selector!");	PM_setIOPL(3);	/* Map the first Mb of physical memory into lowMem */	if ((lowMem = PM_mapPhysicalAddr(0,0xFFFFF,true)) == NULL)	    PM_fatalError("Unable to map first Mb physical memory!");	/* Initialise the MTRR interface functions */	MTRR_init();	}}/****************************************************************************REMARKS:Initialise the PM library for BIOS access via VIDEOPMI. This should workwith any GRADD driver, including SDD/2.****************************************************************************/static ibool InitInt10(void){    HMODULE     hModGENPMI,hModSDDPMI,hModVideoPMI;    CHAR        buf[80],path[_MAX_PATH];    HEV         hevDaemon = NULLHANDLE;    RESULTCODES resCodes;    if (haveInt10 == -1) {	/* Connect to VIDEOPMI and get entry point. Note that we only	 * do this if GENPMI or SDDPMI are already loaded, since we need	 * a GRADD based driver for this to work.	 */	PM_init();	haveInt10 = false;	if (DosQueryModuleHandle((PSZ)"GENPMI.DLL",&hModGENPMI) != 0)	    hModGENPMI = NULLHANDLE;	if (DosQueryModuleHandle((PSZ)"SDDPMI.DLL",&hModSDDPMI) != 0)	    hModSDDPMI = NULLHANDLE;	if (hModGENPMI || hModSDDPMI) {	    if (DosLoadModule((PSZ)buf,sizeof(buf),(PSZ)"VIDEOPMI.DLL",&hModVideoPMI) == 0) {		if (DosQueryProcAddr(hModVideoPMI,0,(PSZ)"VIDEOPMI32Request",(void*)&PM_VIDEOPMI32Request) != 0)		    PM_fatalError("Unable to get VIDEOPMI32Request entry point!");		strcpy(path,"X:\\OS2\\SVGADATA.PMI");		path[0] = PM_getBootDrive();		if (PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_LOADPMIFILE,path,NULL) != 0) {		    DosFreeModule(hModVideoPMI);		    PM_VIDEOPMI32Request = NULL;		    haveInt10 = false;		    }		else {		    /* Attempt to initialise the full VDM in the system. This will only		     * work if VPRPMI.SYS is loaded, but it provides support for passing		     * values in ES/DS/ESI/EDI between the BIOS which does not work with		     * kernel VDM's in fixpacks earlier than FP15. FP15 and later and		     * the new Warp 4.51 and Warp Server convenience packs should work		     * fine with the kernel mini-VDM.		     *		     * Also the full VDM is the only solution for really old kernels		     * (but GRADD won't run on them so this is superfluous ;-).		     */		    INITVDM InitVDM = {VDM_INITIALIZE,NULL,NULL};

⌨️ 快捷键说明

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