Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

441 lines
14 KiB

/******************************Module*Header**********************************\
*
* ***************
* * SAMPLE CODE *
* ***************
*
* Module Name: Permedia.h
*
* Content: various definitions for the Permedia DMA and FIFO interface
* and the Permedia class
*
* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#ifndef __permedia__
#define __permedia__
#include "mini.h"
#define FASTCALL __fastcall
#if defined(_X86_)
typedef LONG __fastcall _InterlockedExchange( IN OUT PLONG, IN LONG);
typedef _InterlockedExchange *PInterlockedExchange;
#endif
#if defined(_ALPHA_)
extern "C" VOID __MB(VOID);
#endif
//
// handy typedefs for FlushDMA and CheckForEOB function pointers
//
typedef VOID (GFNFLUSHDMA)(P2DMA*);
typedef VOID (GFNCHECKEOB)(P2DMA*, LONG);
// Some macros for DirectDraw
#define IN_VRETRACE(xppdev) bInVerticalRetrace(xppdev)
#define IN_DISPLAY(xppdev) (!IN_VRETRACE(xppdev))
#define CURRENT_VLINE(xppdev) lCurrentLine(xppdev)
#define DRAW_ENGINE_BUSY bDrawEngineBusy(pP2dma)
#define SYNC_WITH_PERMEDIA vSyncWithPermedia(pP2dma)
#define READ_CTRL_REG(uiReg)\
READ_REGISTER_ULONG(&pP2dma->pCtrlBase[uiReg/sizeof(ULONG)])
#define P2_READ_CTRL_REG(uiReg)\
READ_REGISTER_ULONG(&ppdev->pCtrlBase[uiReg/sizeof(ULONG)])
#define WRITE_CTRL_REG(uiReg, uiValue)\
{ \
WRITE_REGISTER_ULONG(&pP2dma->pCtrlBase[uiReg/sizeof(ULONG)],uiValue); \
MEMORY_BARRIER();\
}
// For sending permedia tags.
#define SEND_PERMEDIA_DATA(tag,data) \
LD_INPUT_FIFO(__Permedia2Tag##tag, data)
#define SEND_PERMEDIA_DATA_OFFSET(tag,data, i) \
LD_INPUT_FIFO(__Permedia2Tag##tag+i, data)
#define COPY_PERMEDIA_DATA(tag,data) \
LD_INPUT_FIFO( __Permedia2Tag##tag, *((unsigned long*) &(data)))
#define HOLD_CMD(tag, count) ( __Permedia2Tag##tag | ((count-1) << 16))
// use macros instead of inlines for Fifo downloads.
//@@BEGIN_DDKSPLIT
#if DBG && MULTITHREADED
#define PERMEDIA_DEFS(xppdev) \
P2DMA *pP2dma=xppdev->pP2dma; \
PULONG pTmp; \
if (pP2dma != NULL) { pP2dma->ppdev = xppdev; }
#else
//@@END_DDKSPLIT
#define PERMEDIA_DEFS(xppdev) \
P2DMA *pP2dma=xppdev->pP2dma;\
PULONG pTmp;
//@@BEGIN_DDKSPLIT
#endif
//@@END_DDKSPLIT
//----------------------------------------------------------------------------
//
// here are the API macros for DMA transport
//
//
// RESERVEDMAPTR(n) // reserve n entries for DMA
// n=GetFreeEntries() // get number of free entries to fill
// (optional)
// up to n LD_INPUT_FIFO
// COMMITDMAPTR() // adjust DMA buffer pointer
//
// FLUSHDMA();
//
//----------------------------------------------------------------------------
//@@BEGIN_DDKSPLIT
#if 1
#define RESERVEDMAWORDS(n) \
{ \
ASSERTLOCK(pP2dma->ppdev, RESERVEDMAWORDS); \
pTmp=ReserveDMAPtr(pP2dma,n); \
}
#define RESERVEDMAPTR(n) \
{ \
ASSERTLOCK(pP2dma->ppdev, RESERVEDMAPTR); \
pTmp=ReserveDMAPtr(pP2dma,2*n); \
}
#else
//@@END_DDKSPLIT
#define RESERVEDMAWORDS(n) \
{ pTmp=ReserveDMAPtr(pP2dma,n);}
#define RESERVEDMAPTR(n) \
{ pTmp=ReserveDMAPtr(pP2dma,2*n);}
//@@BEGIN_DDKSPLIT
#endif
//@@END_DDKSPLIT
#define COMMITDMAPTR() \
{ CommitDMAPtr(pP2dma,pTmp);}
#define GETFREEENTRIES() \
GetFreeEntries(pP2dma)
#define FLUSHDMA() (pP2dma->pgfnFlushDMA)(pP2dma)
// compiler does not resolve C++ inlines until use of /Ob1,
// so write inline as a real macro
#define LD_INPUT_FIFO(uiTag, uiData) \
{ *pTmp++=(uiTag);\
*pTmp++=(uiData);\
}
#define LD_INPUT_FIFO_DATA(uiData) \
*pTmp++=(uiData);
//-----------------------------------------------------------------------------
//
// define register file of Permedia 2 chip and other chip constants
//
//-----------------------------------------------------------------------------
#define PREG_RESETSTATUS 0x0
#define PREG_INTENABLE 0x8
#define PREG_INTFLAGS 0x10
#define PREG_INFIFOSPACE 0x18
#define PREG_OUTFIFOWORDS 0x20
#define PREG_INDMAADDRESS 0x28
#define PREG_INDMACOUNT 0x30
#define PREG_ERRORFLAGS 0x38
#define PREG_VCLKCTL 0x40
#define PERMEDIA_REG_TESTREGISTER 0x48
#define PREG_APERTUREONE 0x50
#define PREG_APERTURETWO 0x58
#define PREG_DMACONTROL 0x60
#define PREG_FIFODISCON 0x68
#define PREG_FIFODISCON_GPACTIVE 0x80000000L
#define PREG_CHIPCONFIG 0x70
#define PREG_OUTDMAADDRESS 0x80
#define PREG_OUTDMACOUNT 0x88
#define PREG_AGPTEXBASEADDRESS 0x90
#define PREG_BYDMAADDRESS 0xa0
#define PREG_BYDMASTRIDE 0xb8
#define PREG_BYDMAMEMADDR 0xc0
#define PREG_BYDMASIZE 0xc8
#define PREG_BYDMABYTEMASK 0xd0
#define PREG_BYDMACONTROL 0xd8
#define PREG_BYDMACOMPLETE 0xe8
#define PREG_FIFOINTERFACE 0x2000
#define PREG_LINECOUNT 0x3070
#define PREG_VBEND 0x3040
#define PREG_SCREENBASE 0x3000
#define PREG_SCREENBASERIGHT 0x3080
#define PREG_VIDEOCONTROL 0x3058
#define PREG_VC_STEREOENABLE 0x800
// use this for stereo
#define PREG_VC_SCREENBASEPENDING 0xc180
#define PREG_VC_RIGHTFRAME 0x2000
// for non stereo modes
// #define PREG_VC_SCREENBASEPENDING 0x080
// GP video enabled/disabled bit of VideoControl
#define PREG_VC_VIDEO_ENABLE 0x0001
#define P2_EXTERNALVIDEO 0x4000
#define CTRLBASE 0
#define COREBASE 0x8000
#define GPFIFO 0x2000
#define MAXINPUTFIFOLENGTH 0x100
//-----------------------------------------------------------------------------
//
// various register flags
//
//-----------------------------------------------------------------------------
#define PREG_INTFLAGS_DMA 1
#define PREG_INTFLAGS_VS 0x10
#define PREG_INTFLAGS_ERROR 0x8
#define PREG_INTFLAGS_SYNC 2
//
// DisconnectControl bits
//
#define DISCONNECT_INPUT_FIFO_ENABLE 0x1
#define DISCONNECT_OUTPUT_FIFO_ENABLE 0x2
#define DISCONNECT_INOUT_ENABLE (DISCONNECT_INPUT_FIFO_ENABLE | \
DISCONNECT_OUTPUT_FIFO_ENABLE)
#define DISCONNECT_INOUT_DISABLE 0x0
//-----------------------------------------------------------------------------
//
// Size of DMA buffer. Since we use only one wraparound DMA Buffer
// with continous physical memory, it should not be too long.
// We allocate this buffer at start of day and keep it forever, unless
// somebody forces an unload of the display driver. Selecting a larger
// size makes it more likely for the call to fail.
//
// The usage counter for the DMA memory is handled in the miniport, because
// the Permedia class gets unloaded on a mode switch.
//
//-----------------------------------------------------------------------------
// DMA command buffer stream size and minimum size
#define DMACMDSIZE DMA_BUFFERSIZE
#define DMACMDMINSIZE 0x2000L
#define MAXBLKSIZE 0x1000 // limit block transfers to 16 kb per chunk
// to have a good balance between download
// speed and latencies
#define ALIGNFACTOR 0x400 // alignment factor (4kb page)
//-----------------------------------------------------------------------------
//
// shared memory section of P2 interrupt driven DMA handler
//
//-----------------------------------------------------------------------------
struct _P2DMA {
INTERRUPT_CONTROL_BLOCK ICB;
// these are the linear Permedia base addresses of the control registers
// and the Fifo area
ULONG *pCtrlBase;
ULONG *pGPFifo;
// handle to videoport of instance
HANDLE hDriver;
LONG lDMABufferSize; // size of DMA buffer in ULONGs
ULONG uiInstances; // currently active driver instances using
// the shared memory
ULONG ulIntFlags; // cache for interrupt flag register
#if defined(_X86_)
// pointer to Interlockedexchange function in
// the kernel.
PInterlockedExchange pInterlockedExchange;
#endif
BOOL bDMAEmulation; // remember if we run in DMA emulation
GFNCHECKEOB*pgfnCheckEOB; // DMA CheckEOB buffer function pointer
GFNFLUSHDMA*pgfnFlushDMA; // DMA FlushDMA buffer function pointer
ULONG *pSharedDMABuffer; // virtual address of shared DMA buffer
LONG lSharedDMABufferSize; // size of shared DMA buffer in BYTEs
ULONG *pEmulatedDMABuffer; // address of DMA emulation buffer
LONG lEmulatedDMABufferSize;// size of DMA emulation buffer in BYTEs
BOOL bEnabled; // check if the DMA code is enabled
#if DBG
LONG lDBGState; // keep track of state in debug version
// 0: idle
// 2: ReserveDMAPtr was called
LONG bDBGIgnoreAssert;
ULONG *pDBGReservedEntries; // pointer to which we have reserved
// for debugging checks
//@@BEGIN_DDKSPLIT
#if MULTITHREADED
PPDev ppdev; // For checking multithreaded semaphore
#endif
//@@END_DDKSPLIT
#endif
} ;
//-----------------------------------------------------------------------------
//
// definitions for functions which are different in non-DMA, DMA and
// multiprocessing DMA cases. bInitializeP2DMA will decide which ones to use
// and preset the function pointers.
//
//-----------------------------------------------------------------------------
VOID vFlushDMA(P2DMA *pP2dma);
VOID vFlushDMAMP(P2DMA *pP2dma);
VOID vFlushDMAEmulation(P2DMA *pP2dma);
VOID vCheckForEOB(P2DMA *pP2dma,LONG lEntries);
VOID vCheckForEOBMP(P2DMA *pP2dma,LONG lEntries);
VOID vCheckForEOBEmulation(P2DMA *pP2dma,LONG lEntries);
//-----------------------------------------------------------------------------
//
// more helper and blockdownload functions
//
//-----------------------------------------------------------------------------
VOID vWaitDMAComplete(P2DMA *pP2dma);
LONG lWaitOutputFifoReady(P2DMA *pP2dma);
BOOL bDrawEngineBusy(P2DMA *pP2dma);
BOOL bInVerticalRetrace(PPDev ppdev);
LONG lCurrentLine(PPDev ppdev);
VOID vBlockLoadInputFifoByte (P2DMA *pP2dma,
ULONG uiTag,
BYTE *pImage,
LONG lWords);
VOID vBlockLoadInputFifo (P2DMA *pP2dma,
ULONG uiTag,
ULONG *pImage,
LONG lWords);
//-----------------------------------------------------------------------------
//
// Basic reserve/commit Api functions. They are provided as inlines for free
// builds and as functions with debug checks in checked builds.
//
//-----------------------------------------------------------------------------
ULONG *ReserveDMAPtr (P2DMA *pP2dma, const LONG nEntries);
VOID CommitDMAPtr (P2DMA *pP2dma, ULONG *pDMAPtr);
LONG GetFreeEntries(P2DMA *pP2dma);
//
// completely synchronize chip here
//
VOID vSyncWithPermedia(P2DMA *pP2dma);
//
// initialization and cleanup routines
//
BOOL bInitializeP2DMA( P2DMA *pP2dma,
HANDLE hDriver,
ULONG *pChipBase,
DWORD dwAccelerationLevel,
BOOL NewReference
);
VOID vFree(P2DMA *pP2dma);
#if !DBG
//----------------------------------------------------------------------------
//
// ReserveDMAPtr
//
// return a pointer to current position in DMA buffer. The function guarantees
// that there are at least lEntries available in the buffer.
// Otherwise the caller can ask GetFreeEntries and adjust the download to
// batch more entries. The caller MUST call CommitDMAPtr after a call to
// to ReserveDMAPtr to readjust the Index pointer.
//
//----------------------------------------------------------------------------
inline ULONG *ReserveDMAPtr(P2DMA *pP2dma,const LONG lEntries)
{
while (pP2dma->ICB.pDMAWritePos+lEntries>=
pP2dma->ICB.pDMAWriteEnd)
{
(*pP2dma->pgfnCheckEOB)(pP2dma,lEntries);
}
return (ULONG *)pP2dma->ICB.pDMAWritePos;
}
//----------------------------------------------------------------------------
//
// CommitDMAPtr
//
// pDMAPtr----DMA buffer address to which the caller has written to.
//
// Readjust write pointer after being reserved by ReserveDMAPtr.
// By committing the pointer a DMA to the committed position could already
// be started by interrupt handler!
//
//----------------------------------------------------------------------------
inline VOID CommitDMAPtr(P2DMA *pP2dma,ULONG *pDMAPtr)
{
pP2dma->ICB.pDMAWritePos=pDMAPtr;
}
//----------------------------------------------------------------------------
//
// GetFreeEntries
//
// Get free entries available for consecutive writing to the DMA buffer.
// The maximum number of returned entries is now MAXBLKSIZE.
//
// returns---number of available entries in ULONGS
//
//----------------------------------------------------------------------------
inline LONG GetFreeEntries(P2DMA *pP2dma)
{
LONG EntriesAvailable = (LONG)(pP2dma->ICB.pDMAWriteEnd - pP2dma->ICB.pDMAWritePos);
return min(MAXBLKSIZE,EntriesAvailable);
}
#endif
#endif