📄 window.c
字号:
goto map_win_fail;
}
uStart = ((pWin->pPhys->uBase + uCardAddress - WinState.uOffset) / v_PageSize) * v_PageSize;
uEnd = ((uSize + (pWin->pPhys->uBase + uCardAddress - WinState.uOffset) + v_PageSize - 1) / v_PageSize) * v_PageSize;
uVirtSize = uEnd - uStart;
} else {
//
// Compute beginning and ending addresses of the mapping region (must be on page boundaries)
//
uStart = ((pWin->pPhys->uBase + uCardAddress) / v_PageSize) * v_PageSize;
uEnd = ((pWin->pPhys->uBase + uCardAddress + uSize + v_PageSize - 1) / v_PageSize) * v_PageSize;
uVirtSize = uEnd - uStart;
if (uEnd > ((pWin->pPhys->uBase + pWin->pPhys->uMaxSize + v_PageSize - 1) / v_PageSize) * v_PageSize) {
status = CERR_BAD_SIZE;
goto map_win_fail;
}
}
#ifndef SH4
//
// Change the data path width if necessary
//
if (((fAttributes & WIN_ATTR_16BIT) && (!(pWin->pPhys->fFlags & PHYS_WIN_FLAG_16BIT_MODE))) ||
((!(fAttributes & WIN_ATTR_16BIT)) && (pWin->pPhys->fFlags & PHYS_WIN_FLAG_16BIT_MODE))) {
DEBUGMSG(ZONE_MEM, (TEXT("CardMapWindow changing window %d data size.\r\n"), pWin->pPhys->uWindow));
//
// Caller must be the only one using this physical window (besides card
// services).
//
pTmp = pWin->pPhys->pLog;
while (pTmp) {
if ((pTmp->hOwner != CARDSERV_CLIENT_HANDLE) &&
(pTmp->hOwner != pWin->hOwner)) {
status = CERR_OUT_OF_RESOURCE;
goto map_win_fail;
}
pTmp = pTmp->Next;
}
status = PDCardGetWindow(pWin->pPhys->uWindow, &WinState);
if (status) {
goto map_win_fail;
}
if (pWin->fAttributes & WIN_ATTR_16BIT) {
WinState.fState |= WIN_STATE_16BIT;
pWin->pPhys->fFlags |= PHYS_WIN_FLAG_16BIT_MODE;
} else {
WinState.fState &= ~WIN_STATE_16BIT;
pWin->pPhys->fFlags &= ~PHYS_WIN_FLAG_16BIT_MODE;
}
WinState.fState |= WIN_STATE_ENABLED;
pWin->pPhys->fFlags |= PHYS_WIN_FLAG_ENABLED;
status = PDCardSetWindow(pWin->pPhys->uWindow, &WinState);
if (status) {
goto map_win_fail;
}
}
#endif // ~SH4
#ifdef x86
if (fAttributes & WIN_ATTR_IO_SPACE) {
inIoSpace = 1;
ioPhysicalBase.LowPart = pWin->pPhys->uBase+uCardAddress;
ioPhysicalBase.HighPart = 0;
if (HalTranslateBusAddress(
Isa,
0,
ioPhysicalBase,
&inIoSpace,
&ioPhysicalBase)) {
DEBUGMSG(ZONE_MEM,
(TEXT("CardMapWindow : HalTranslateBusAddress - OK\r\n")));
if (!inIoSpace) {
DEBUGMSG(ZONE_MEM, (TEXT("CardMapWindow : ! IO Space\r\n")));
if ((RetVal = (PVOID)MmMapIoSpace(
ioPhysicalBase,
uSize,
FALSE)) == NULL) {
DEBUGMSG(ZONE_MEM, (TEXT("Error mapping I/O Ports\r\n")));
status = CERR_OUT_OF_RESOURCE;
goto map_win_fail;
}
} else {
DEBUGMSG(ZONE_MEM, (TEXT("CardMapWindow : IO Space\r\n")));
RetVal = (PVOID)ioPhysicalBase.LowPart;
}
if (RetVal == NULL) {
DEBUGMSG(ZONE_MEM, (TEXT("HalTranslateBusAddress returned NULL.\r\n")));
status = CERR_BAD_BASE;
goto map_win_fail;
}
} else {
DEBUGMSG(ZONE_MEM, (TEXT("Error translating I/O Ports.\r\n")));
status = CERR_OUT_OF_RESOURCE;
goto map_win_fail;
}
pWin->pVirtMem = RetVal;
goto map_win_exit;
} else {
#endif // x86
//
// Allocate some virtual pages.
//
pWin->pVirtMem = VirtualAlloc(
0,
uVirtSize,
MEM_RESERVE,
PAGE_NOACCESS);
if (pWin->pVirtMem == NULL) {
DEBUGMSG(ZONE_WARNING,
(TEXT("CardMapWindow: VirtualAlloc failed %d\r\n"),
GetLastError()));
status = CERR_OUT_OF_RESOURCE;
goto map_win_fail;
}
//
// Map the memory.
//
#ifdef DEBUG
if (pWin->pPhys->uBase & 0xE0000000) {
DEBUGMSG(ZONE_WARNING|ZONE_ERROR|ZONE_MEM,
(TEXT("PCMCIA:CardMapWindow MAKE SURE THIS PLATFORM'S PCMCIA MEMORY AREAS ARE SPECIFIED AS ACTUAL PHYSICAL ADDRESSES\r\n")));
}
#endif
uPhysAddr = uStart;
uPhysAddr >>= 8;
if (!VirtualCopy(
pWin->pVirtMem,
(PVOID)uPhysAddr,
uVirtSize,
PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL)) {
DEBUGMSG(ZONE_WARNING,
(TEXT("CardMapWindow:VirtualCopy failed %d\r\n"), GetLastError()));
status = CERR_OUT_OF_RESOURCE;
goto map_win_fail1;
}
#ifdef SH4
{
//
// On SH4 we need to set some extra page table bits associated with PCMCIA
// (the SH4 PCMCIA controller is integrated with the CPU's paging mechanism)
//
DWORD dwPageFlags;
if (fAttributes & WIN_ATTR_IO_SPACE) {
dwPageFlags = VSPF_VARIABLE;
} else {
if (fAttributes & WIN_ATTR_ATTRIBUTE) {
dwPageFlags = VSPF_ATTRIBUTE;
} else {
dwPageFlags = VSPF_COMMON;
}
if (fAttributes & WIN_ATTR_16BIT) {
dwPageFlags |= VSPF_16BIT;
}
}
pWin->fAttributes = fAttributes;
dwPageFlags |=(isSh4Area6(pWin->pPhys->uWindow)?VSPF_TC:0);
if (!VirtualSetPageFlags(
pWin->pVirtMem,
uVirtSize,
dwPageFlags,
NULL)) {
DEBUGMSG(ZONE_WARNING,
(TEXT("I_MapWindow: VirtualSetPageFlags failed %d\r\n"),
GetLastError()));
I_DeleteLogicalWindow(pWin);
return NULL;
}
}
#endif
#ifdef x86
}
#endif // x86
#ifdef INSTRUM_DEV
ics_addCardRange(0, pWin->pVirtMem, (PVOID)(uStart), uVirtSize, 0);
#endif
//
// Return a pointer to the card offset the user specified
//
if (bSetSocket == TRUE) {
RetVal = (PVOID)((UINT)pWin->pVirtMem + ((pWin->pPhys->uBase + uCardAddress - WinState.uOffset) % v_PageSize));
} else {
RetVal = (PVOID)((UINT)pWin->pVirtMem + ((pWin->pPhys->uBase + uCardAddress) % v_PageSize));
}
#ifdef x86
map_win_exit:
#endif // x86
pWin->uReqSize = uSize;
pWin->uReqOffset = uCardAddress;
DEBUGMSG(ZONE_WARNING|ZONE_MEM,
(TEXT("CardMapWindow:Window %d @ %x (phys = %x), size = %d, returning %x\r\n"),
pWin->pPhys->uWindow,
pWin->pVirtMem,
pWin->pPhys->uBase+uStart,
uVirtSize,
(UINT)RetVal));
LeaveCriticalSection(&v_WindowCrit);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CardMapWindow succeeded\r\n")));
return RetVal;
//
// Some error occurred, set last error and return NULL.
//
map_win_fail1:
DEBUGMSG(ZONE_MEM,
(TEXT("CardMapWindow calling VirtualFree(0x%x) for failed mapping.\r\n"),
pWin->pVirtMem));
if (VirtualFree(pWin->pVirtMem, 0, MEM_RELEASE) == FALSE) {
DEBUGMSG(ZONE_MEM|ZONE_ERROR,
(TEXT("CarpMapWindow: VirtualFree(old) failed %d\r\n"),
GetLastError()));
}
pWin->pVirtMem = NULL;
map_win_fail:
if ((pWin->pPhys->fWindowCaps & WIN_CAP_IO) &&
g_IORM_ID[pWin->pPhys->uSock] != 0)
ResourceRelease(g_IORM_ID[pWin->pPhys->uSock], uCardAddress, uSize);
map_win_fail_norel:
LeaveCriticalSection(&v_WindowCrit);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CardMapWindow failed %d\r\n"), status));
SetLastError(status);
return NULL;
} // CardMapWindow
//
// @topic PCMCIA Memory access functions| Functions to read and write the different
// PC card memory spaces on platforms that do not support PCMCIA memory and I/O
// windows. System software must assert the REG line as appropriate to access the
// specified memory space. Access to the REG line must be controlled with a critical
// section in order to be thread-safe. Otherwise PC card drivers could easily end
// up unintentionally accessing the wrong memory space.
// On platforms that have separate memory regions for the three PCMCIA memory spaces
// (common, attribute and I/O) or that use memory and I/O windows on the socket controller,
// the drivers can access PC card memory directly.
//
// @xref <f CardReadAttrByte> <f CardWriteAttrByte> <f CardReadCmnByte>
//
//
// CardReadAttrByte
//
// @func STATUS | CardReadAttrByte | Read the byte at the specified offset in a PC card's
// attribute memory space.
// @rdesc Returns either CERR_SUCCESS or CERR_READ_FAILURE.
//
// @comm The uOffset for attribute space is the virtual offset into attribute
// space. uOffset of 0 represents the first byte in attribute space,
// uOffset of 1 is the next valid byte (although on the perp it is actually
// at offset 8).
// Since the parameters are not range checked and since the PC card may
// be removed at any time, this API should be called within a try/except
// construct to avoid locking up the system.
//
STATUS
CardReadAttrByte(
PVOID pAttr, // @parm Pointer to PC card memory from <f CardMapWindow>
UINT32 uOffset, // @parm Offset into PC card's attribute memory space
UINT8 * pByte // @parm Pointer to return the read byte.
)
{
STATUS ret = CERR_SUCCESS;
try {
*pByte = PDCardReadAttrByte(pAttr, uOffset);
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ZONE_ERROR|ZONE_MEM,
(TEXT("CardReadAttrByte: returning error due to exception\r\n")));
ret = CERR_READ_FAILURE;
}
return ret;
}
//
// CardReadCmnByte
//
// @func STATUS | CardReadCmnByte | Read the byte at the specified offset in a PC card's
// common memory space.
// @rdesc Returns either CERR_SUCCESS or CERR_READ_FAILURE.
//
// @comm Since the parameters are not range checked and since the PC card may
// be removed at any time, this API should be called within a try/except
// construct to avoid locking up the system.
//
STATUS
CardReadCmnByte(
PVOID pCmn, // @parm Pointer to PC card memory from <f CardMapWindow>
UINT32 uOffset, // @parm Offset into PC card's common memory space
UINT8 * pByte // @parm Pointer to return the read byte.
)
{
STATUS ret = CERR_SUCCESS;
try {
*pByte = PDCardReadCmnByte(pCmn, uOffset);
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ZONE_ERROR|ZONE_MEM,
(TEXT("CardReadCmnByte: returning error due to exception\r\n")));
ret = CERR_READ_FAILURE;
}
return ret;
}
//
// CardWriteAttrByte
//
// @func STATUS | CardWriteAttrByte | Write a byte at the specified offset in a PC card's
// attribute memory space.
// @rdesc Returns CERR_SUCCESS or CERR_WRITE_FAILURE.
//
// @comm The uOffset for attribute space is the virtual offset into attribute
// space. uOffset of 0 represents the first byte in attribute space,
// uOffset of 1 is the next valid byte (although on the perp it is actually
// at offset 8).
// Since the parameters are not range checked and since the PC card may
// be removed at any time, this API should be called within a try/except
// construct to avoid locking up the system.
//
STATUS
CardWriteAttrByte(
PVOID pAttr, // @parm Pointer to PC card memory from <f CardMapWindow>
UINT32 uOffset, // @parm Offset into PC card's attribute memory space
UINT8 uByte // @parm Byte to write
)
{
STATUS ret = CERR_SUCCESS;
try {
PDCardWriteAttrByte(pAttr, uOffset, uByte);
} except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
DEBUGMSG(ZONE_ERROR|ZONE_MEM,
(TEXT("CardWriteAttrByte: returning error due to exception\r\n")));
ret = CERR_WRITE_FAILURE;
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -