📄 pm.c
字号:
// NOTE: This function *must* be able to handle any phsyical base // address, and hence you will have to handle rounding of // the physical base address to a page boundary (ie: 4Kb on // x86 CPU's) to be able to properly map in the memory // region. // NOTE: If possible the isCached bit should be used to ensure that // the PCD (Page Cache Disable) and PWT (Page Write Through) // bits are set to disable caching for a memory mapping used // for MMIO register access. We also disable caching using // the MTRR registers for Pentium Pro and later chipsets so if // MTRR support is enabled for your OS then you can safely ignore // the isCached flag and always enable caching in the page // tables. return NULL;}/****************************************************************************REMARKS:Free a physical address mapping allocated by PM_mapPhysicalAddr.****************************************************************************/void PMAPI PM_freePhysicalAddr( void *ptr, ulong limit){ // TODO: This function will free a physical memory mapping previously // allocated with PM_mapPhysicalAddr() if at all possible. If // you can't free physical memory mappings, simply do nothing.}/****************************************************************************REMARKS:Find the physical address of a linear memory address in current process.****************************************************************************/ulong PMAPI PM_getPhysicalAddr(void *p){ // TODO: This function should find the physical address of a linear // address. return 0xFFFFFFFFUL;}void PMAPI PM_sleep(ulong milliseconds){ // TODO: Put the process to sleep for milliseconds}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; } 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;}/****************************************************************************REMARKS:Allocate a block of (unnamed) shared memory.****************************************************************************/void * PMAPI PM_mallocShared( long size){ // TODO: This is used to allocate memory that is shared between process // that all access the common Nucleus drivers via a common display // driver DLL. If your OS does not support shared memory (or if // the display driver does not need to allocate shared memory // for each process address space), this should just call malloc. return malloc(size);}/****************************************************************************REMARKS:Map the (unnamed) shared memory block into the process address space.****************************************************************************/int PMAPI PM_mapShared( void *ptr){ // TODO: Map the pointer to previously allocated shared memory into the // address space of the calling process. The memory would have // been previously allocated with PM_mallocShared in another // process (as unnamed shared memory). If you don't need shared // memory, return 0. return 0;}/****************************************************************************REMARKS:Free a block of shared memory.****************************************************************************/void PMAPI PM_freeShared( void *ptr){ // TODO: Free the shared memory block. This will be called in the context // of the original calling process that allocated the shared // memory with PM_mallocShared. Simply call free if you do not // need this. free(ptr);}/****************************************************************************REMARKS:Map a linear memory address to the calling process address space. Theaddress will have been allocated in another process using thePM_mapPhysicalAddr function.****************************************************************************/void * PMAPI PM_mapToProcess( void *base, ulong limit){ // TODO: This function is used to map a physical memory mapping // previously allocated with PM_mapPhysicalAddr into the // address space of the calling process. If the memory mapping // allocated by PM_mapPhysicalAddr is global to all processes, // simply return the pointer. // NOTE: This function must also handle rounding to page boundaries, // since this function is used to map in shared memory buffers // allocated with PM_mapPhysicalAddr(). Hence if you aligned // the physical address above, then you also need to do it here. return base;}/****************************************************************************REMARKS:Map a real mode pointer to a protected mode pointer.****************************************************************************/void * PMAPI PM_mapRealPointer( uint r_seg, uint r_off){ // TODO: This function maps a real mode memory pointer into the // calling processes address space as a 32-bit near pointer. If // you do not support BIOS access, simply return NULL here. if (!zeroPtr) zeroPtr = PM_mapPhysicalAddr(0,0xFFFFF); return (void*)(zeroPtr + MK_PHYS(r_seg,r_off));}/****************************************************************************REMARKS:Allocate a block of real mode memory****************************************************************************/void * PMAPI PM_allocRealSeg( uint size, uint *r_seg, uint *r_off){ // TODO: This function allocates a block of real mode memory for the // calling process used to communicate with real mode BIOS // functions. If you do not support BIOS access, simply return // NULL here. return NULL;}/****************************************************************************REMARKS:Free a block of real mode memory.****************************************************************************/void PMAPI PM_freeRealSeg( void *mem){ // TODO: Frees a previously allocated real mode memory block. If you // do not support BIOS access, this function should be empty.}/****************************************************************************REMARKS:Issue a real mode interrupt (parameters in DPMI compatible structure)****************************************************************************/void PMAPI DPMI_int86( int intno, DPMI_regs *regs){ // TODO: This function calls the real mode BIOS using the passed in // register structure. If you do not support real mode BIOS // access, this function should be empty.}/****************************************************************************REMARKS:Issue a real mode interrupt.****************************************************************************/int PMAPI PM_int86( int intno, RMREGS *in, RMREGS *out){ // TODO: This function calls the real mode BIOS using the passed in // register structure. If you do not support real mode BIOS // access, this function should return 0. return 0;}/****************************************************************************REMARKS:Issue a real mode interrupt.****************************************************************************/int PMAPI PM_int86x( int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs){ // TODO: This function calls the real mode BIOS using the passed in // register structure. If you do not support real mode BIOS // access, this function should return 0. return 0;}/****************************************************************************REMARKS:Call a real mode far function.****************************************************************************/void PMAPI PM_callRealMode( uint seg, uint off, RMREGS *in, RMSREGS *sregs){ // TODO: This function calls a real mode far function with a far call. // If you do not support BIOS access, this function should be // empty.}/****************************************************************************REMARKS:Return the amount of available memory.****************************************************************************/void PMAPI PM_availableMemory( ulong *physical, ulong *total){ // TODO: Report the amount of available memory, both the amount of // physical memory left and the amount of virtual memory left. // If the OS does not provide these services, report 0's. *physical = *total = 0;}/****************************************************************************REMARKS:Allocate a block of locked, physical memory for DMA operations.****************************************************************************/void * PMAPI PM_allocLockedMem( uint size, ulong *physAddr){ // TODO: Allocate a block of locked, physical memory of the specified // size. This is used for bus master operations. If this is not // supported by the OS, return NULL and bus mastering will not // be used. return NULL;}/****************************************************************************REMARKS:Free a block of locked physical memory.****************************************************************************/void PMAPI PM_freeLockedMem( void *p, uint size){ // TODO: Free a memory block allocated with PM_allocLockedMem.}/****************************************************************************REMARKS:Call the VBE/Core software interrupt to change display banks.****************************************************************************/void PMAPI PM_setBankA( int bank){ RMREGS regs; // TODO: This does a bank switch function by calling the real mode // VESA BIOS. If you do not support BIOS access, this function should // be empty. regs.x.ax = 0x4F05; regs.x.bx = 0x0000; regs.x.dx = bank; PM_int86(0x10,®s,®s);}/****************************************************************************REMARKS:Call the VBE/Core software interrupt to change display banks.****************************************************************************/void PMAPI PM_setBankAB( int bank){ RMREGS regs; // TODO: This does a bank switch function by calling the real mode // VESA BIOS. If you do not support BIOS access, this function should // be empty. regs.x.ax = 0x4F05; regs.x.bx = 0x0000; regs.x.dx = bank; PM_int86(0x10,®s,®s); regs.x.ax = 0x4F05; regs.x.bx = 0x0001; regs.x.dx = bank; PM_int86(0x10,®s,®s);}/****************************************************************************REMARKS:Call the VBE/Core software interrupt to change display start address.****************************************************************************/void PMAPI PM_setCRTStart( int x, int y, int waitVRT){ RMREGS regs; // TODO: This changes the display start address by calling the real mode // VESA BIOS. If you do not support BIOS access, this function // should be empty. regs.x.ax = 0x4F07; regs.x.bx = waitVRT; regs.x.cx = x; regs.x.dx = y; PM_int86(0x10,®s,®s);}/****************************************************************************REMARKS:Enable write combining for the memory region.****************************************************************************/ibool PMAPI PM_enableWriteCombine( ulong base, ulong length, uint type){ // TODO: This function should enable Pentium Pro and Pentium II MTRR // write combining for the passed in physical memory base address // and length. Normally this is done via calls to an OS specific // device driver as this can only be done at ring 0. // // NOTE: This is a *very* important function to implement! If you do // not implement, graphics performance on the latest Intel chips // will be severly impaired. For sample code that can be used // directly in a ring 0 device driver, see the MSDOS implementation // which includes assembler code to do this directly (if the // program is running at ring 0). return false;}/****************************************************************************REMARKS:Execute the POST on the secondary BIOS for a controller.****************************************************************************/ibool PMAPI PM_doBIOSPOST( ushort axVal, ulong BIOSPhysAddr, void *mappedBIOS){ // TODO: This function is used to run the BIOS POST code on a secondary // controller to initialise it for use. This is not necessary // for multi-controller operation, but it will make it a lot // more convenicent for end users (otherwise they have to boot // the system once with the secondary controller as primary, and // then boot with both controllers installed). // // Even if you don't support full BIOS access, it would be // adviseable to be able to POST the secondary controllers in the // system using this function as a minimum requirement. Some // graphics hardware has registers that contain values that only // the BIOS knows about, which makes bring up a card from cold // reset difficult if the BIOS has not POST'ed it. return false;}/****************************************************************************REMARKS:Load an OS specific shared library or DLL. If the OS does not supportshared libraries, simply return NULL.****************************************************************************/PM_MODULE PMAPI PM_loadLibrary( const char *szDLLName){ (void)szDLLName; return NULL;}/****************************************************************************REMARKS:Get the address of a named procedure from a shared library.****************************************************************************/void * PMAPI PM_getProcAddress( PM_MODULE hModule, const char *szProcName){ (void)hModule; (void)szProcName; return NULL;}/****************************************************************************REMARKS:Unload a shared library.****************************************************************************/void PMAPI PM_freeLibrary( PM_MODULE hModule){ (void)hModule;}/****************************************************************************REMARKS:Enable requested I/O privledge level (usually only to set to a value of3, and then restore it back again). If the OS is protected this functionmust be implemented in order to enable I/O port access for ring 3applications. The function should return the IOPL level active beforethe switch occurred so it can be properly restored.****************************************************************************/int PMAPI PM_setIOPL( int level){ return level;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -