📄 window.c
字号:
}
};
//
// PDCardGetWindow
//
// @func STATUS | PDCardGetWindow | Report the current state of a memory or I/O window
// @rdesc Returns one of the CERR_* error codes in cardserv.h
//
STATUS
PDCardGetWindow(
UINT32 uWindow, // @parm Window number (the first window is 0)
PPDCARD_WINDOW_STATE pWindowState // @parm Pointer to a PDCARD_WINDOW_STATE structure.
)
{
if (uWindow >= PCMCIA_NUM_WINDOWS) {
return CERR_BAD_WINDOW;
}
memcpy(pWindowState, &(v_WinState[uWindow]), sizeof(PDCARD_WINDOW_STATE));
return CERR_SUCCESS;
}
//
// PDCardSetWindow
//
// @func STATUS | PDCardSetWindow | Change the characteristics of a memory or I/O window
// @rdesc Returns one of the CERR_* error codes in cardserv.h
//
STATUS
PDCardSetWindow(
UINT32 uWindow, // @parm Window number (the first window is 0)
PPDCARD_WINDOW_STATE pWindowState // @parm Pointer to a PDCARD_WINDOW_STATE structure.
)
{
const UINT8 *pRegisters;
DWORD RegSize;
UINT8 work;
UINT8 register_num;
UINT start;
UINT address;
UINT16 socket_num = pWindowState->uSocket;
UINT8 enabled0, enabled1;
if (uWindow >= PCMCIA_NUM_WINDOWS) {
return CERR_BAD_WINDOW;
}
pRegisters = SetWindowRegisters[uWindow].pRegisters;
RegSize = SetWindowRegisters[uWindow].RegSize;
EnterCriticalSection(&g_PCIC_Crit);
#if 0
RETAILMSG(1,(TEXT("### Socket %d ###\r\n"), socket_num));
RETAILMSG(1,(TEXT("PDCardSetWindow(%x) get started.\r\n"), uWindow));
RETAILMSG(1,(TEXT("pWindowState->uSize %x \n\r"), pWindowState->uSize));
RETAILMSG(1,(TEXT("pWindowState->uBase %x \n\r"), pWindowState->uBase));
RETAILMSG(1,(TEXT("pWindowState->uOffset %x \n\r"), pWindowState->uOffset));
#endif
// Set Memory Window Upper Address(A[31:24]) to ExCA Extended Index:0x00
PD365Write1( MEM_WIN0_SAU, 0x10 ); // PCIC #1 Window0
PD365Write1( MEM_WIN1_SAU, 0x10 ); // PCIC #1 Window1
PD365Write1( MEM_WIN2_SAU, 0x10 ); // PCIC #1 Window2
PD365Write1( MEM_WIN3_SAU, 0x10 ); // PCIC #1 Window3
PD365Write1( MEM_WIN4_SAU, 0x10 ); // PCIC #1 Window4
PD365Write2( MEM_WIN0_SAU, 0x10 ); // PCIC #2 Window0
PD365Write2( MEM_WIN1_SAU, 0x10 ); // PCIC #2 Window1
PD365Write2( MEM_WIN2_SAU, 0x10 ); // PCIC #2 Window2
PD365Write2( MEM_WIN3_SAU, 0x10 ); // PCIC #2 Window3
PD365Write2( MEM_WIN4_SAU, 0x10 ); // PCIC #2 Window4
//
// Set up the window registers for the specified window
//
if (pWindowState->fState & WIN_STATE_ENABLED){
if ((uWindow != SLOT0_WINDOW_NUM_IO0) && (uWindow != SLOT1_WINDOW_NUM_IO0)) {
if ((uWindow != SLOT0_WINDOW_NUM_IO1) && (uWindow != SLOT1_WINDOW_NUM_IO1)) {
while (RegSize) {
if ((uWindow == 0) || (uWindow == 1) || (uWindow == 4) ||
(uWindow == 5) || (uWindow == 8) ) {
PD365Write1(pRegisters[0], pRegisters[1]);
} else if ((uWindow == 2) || (uWindow == 3) || (uWindow == 6) ||
(uWindow == 7) || (uWindow == 10) ){
PD365Write2(pRegisters[0], pRegisters[1]);
}
pRegisters += 2;
RegSize -= 2;
}
}
}
//
// Set data path width
//
if (((uWindow == SLOT0_WINDOW_NUM_IO0) || (uWindow == SLOT1_WINDOW_NUM_IO0)) ||
((uWindow == SLOT0_WINDOW_NUM_IO1) || (uWindow == SLOT1_WINDOW_NUM_IO1))) {
UINT32 address;
UINT32 start;
enabled1 = PD365Read2(INDEX_MAPPING_ENABLE);
enabled0 = PD365Read1(INDEX_MAPPING_ENABLE);
//
// test for collision with other I/O windows
//
for (start = SLOT0_WINDOW_NUM_IO0; start < PCMCIA_NUM_WINDOWS; start++) {
//
// take care of a special case within SLOT0_WINDOW_NUM_IO0 to
// PCMCIA_NUM_WINDOWS range
//
if (start == SLOT1_WINDOW_NUM_COMMON3) continue;
//
// Don't worry about collisions with:
// 1. the same window
// 2. unmapped windows
// 3. disabled windows
//
if ((start == uWindow) || (v_WinState[start].uOffset == 0)) {
continue;
}
if (v_WinState[start].uSocket) {
if (!(enabled1 & SetWindowRegisters[start].EnableBits))
continue;
} else {
if (!(enabled0 & SetWindowRegisters[start].EnableBits))
continue;
}
if (pWindowState->uSocket != v_WinState[start].uSocket){
if ((pWindowState->uOffset + pWindowState->uSize) >
v_WinState[start].uOffset) {
if (pWindowState->uOffset <
(v_WinState[start].uOffset + v_WinState[start].uSize)) {
LeaveCriticalSection(&g_PCIC_Crit);
DEBUGMSG(ZONE_PDD,
(TEXT("PCMCIA:PDCardSetWindow found I/O port range collision between windows %d (0x%x 0x%x) and %d (0x%x 0x%x)\r\n"),
uWindow, pWindowState->uOffset, pWindowState->uSize,
start, v_WinState[start].uOffset, v_WinState[start].uSize));
return CERR_IN_USE;
}
}
}
}
if (socket_num) {
if (uWindow == SLOT1_WINDOW_NUM_IO0) {
PD365Write2(INDEX_IO_MAP0_START_ADDRESS_LOW,
(UINT8)pWindowState->uOffset);
PD365Write2(INDEX_IO_MAP0_START_ADDRESS_HI,
(UINT8)(pWindowState->uOffset>>8));
address = pWindowState->uOffset + pWindowState->uSize;
PD365Write2(INDEX_IO_MAP0_END_ADDRESS_LOW,
(UINT8)address);
PD365Write2(INDEX_IO_MAP0_END_ADDRESS_HI,
(UINT8)(address>>8));
} else {
PD365Write2(INDEX_IO_MAP1_START_ADDRESS_LOW,
(UINT8)pWindowState->uOffset);
PD365Write2(INDEX_IO_MAP1_START_ADDRESS_HI,
(UINT8)(pWindowState->uOffset>>8));
address = pWindowState->uOffset + pWindowState->uSize;
PD365Write2(INDEX_IO_MAP1_END_ADDRESS_LOW,
(UINT8)address);
PD365Write2(INDEX_IO_MAP1_END_ADDRESS_HI,
(UINT8)(address>>8));
}
} else {
if (uWindow == SLOT0_WINDOW_NUM_IO0) {
PD365Write1(INDEX_IO_MAP0_START_ADDRESS_LOW,
(UINT8)pWindowState->uOffset);
PD365Write1(INDEX_IO_MAP0_START_ADDRESS_HI,
(UINT8)(pWindowState->uOffset>>8));
address = pWindowState->uOffset + pWindowState->uSize;
PD365Write1(INDEX_IO_MAP0_END_ADDRESS_LOW,
(UINT8)address);
PD365Write1(INDEX_IO_MAP0_END_ADDRESS_HI,
(UINT8)(address>>8));
} else {
PD365Write1(INDEX_IO_MAP1_START_ADDRESS_LOW,
(UINT8)pWindowState->uOffset);
PD365Write1(INDEX_IO_MAP1_START_ADDRESS_HI,
(UINT8)(pWindowState->uOffset>>8));
address = pWindowState->uOffset + pWindowState->uSize;
PD365Write1(INDEX_IO_MAP1_END_ADDRESS_LOW,
(UINT8)address);
PD365Write1(INDEX_IO_MAP1_END_ADDRESS_HI,
(UINT8)(address>>8));
}
}
if (socket_num)
work = PD365Read2(INDEX_IO_WINDOW_CONTROL);
else
work = PD365Read1(INDEX_IO_WINDOW_CONTROL);
// For IO card, the data size should be determined according to the IOIS16
// signal. Otherwise network PC-card doesn't work properly.
// if (pWindowState->fState & WIN_STATE_16BIT) {
// work |= (DATA_IO_WINDOW0_SIZE|DATA_IO_WINDOW1_SIZE);
// } else {
// work &= ~(DATA_IO_WINDOW0_SIZE|DATA_IO_WINDOW1_SIZE);
// }
// Added 082200
work |= (DATA_AUTO_SIZE_IO_WINDOW1 | DATA_AUTO_SIZE_IO_WINDOW0);
//End
if (socket_num)
PD365Write2(INDEX_IO_WINDOW_CONTROL,work);
else
PD365Write1(INDEX_IO_WINDOW_CONTROL,work);
} else {
register_num = uWindow/2 + uWindow%2;
if (socket_num)
register_num--;
register_num = INDEX_MEMORY_MAP0_START_ADDRESS_HI + (register_num * 8);
if (socket_num)
work = PD365Read2(register_num);
else
work = PD365Read1(register_num);
if (pWindowState->fState & WIN_STATE_16BIT) {
work |= DATA_WINDOW_DATA_SIZE;
} else {
work &= ~DATA_WINDOW_DATA_SIZE;
}
if (socket_num)
PD365Write2(register_num,work);
else
PD365Write1(register_num,work);
}
}
//
// Enable or disable the specified window
//
if (socket_num)
work = PD365Read2(INDEX_MAPPING_ENABLE);
else
work = PD365Read1(INDEX_MAPPING_ENABLE);
if (pWindowState->fState & WIN_STATE_ENABLED){
//
// Determine the offset register values to use for the programmable
// windows
//
switch (uWindow) {
case SLOT0_WINDOW_NUM_COMMON2:
case SLOT0_WINDOW_NUM_COMMON3:
case SLOT1_WINDOW_NUM_COMMON2:
case SLOT1_WINDOW_NUM_COMMON3:
register_num = uWindow/2 + uWindow%2;
if (socket_num)
register_num--;
register_num = INDEX_MEMORY_MAP0_START_ADDRESS_LOW + (register_num * 8);
if (socket_num)
start = PD365Read2(register_num) +
(PD365Read2((UINT8)(register_num+1)) << 8);
else
start = PD365Read1(register_num) + (PD365Read1((UINT8)(register_num+1)) << 8);
start <<= 12;
DEBUGMSG(ZONE_PDD,
(TEXT("PDCardSetWindow:remapping window %d @ 0x%x to card offset 0x%x\r\n"),
uWindow, start, pWindowState->uOffset));
address = pWindowState->uOffset & 0xFFFFF000;
pWindowState->uOffset = address;
start = address - start;
start >>= 12;
DEBUGMSG(ZONE_PDD,
(TEXT("PDCardSetWindow:remapping window %d, new offset = 0x%x\r\n"),
uWindow, start & 0x3fff));
register_num = uWindow/2 + uWindow%2;
if (socket_num)
register_num--;
register_num = INDEX_MEMORY_MAP0_ADDRESS_OFFSET_LOW + (register_num * 8);
if (socket_num)
PD365Write2(register_num, (UINT8)start);
else
PD365Write1(register_num, (UINT8)start);
start >>= 8;
if (socket_num)
PD365Write2((UINT8)(register_num+1), (UINT8)(start & 0x3f));
else
PD365Write1((UINT8)(register_num+1), (UINT8)(start & 0x3f));
v_WinState[uWindow].uSize = pWindowState->uSize;
break;
}
work |= SetWindowRegisters[uWindow].EnableBits;
} else {
work &= ~SetWindowRegisters[uWindow].EnableBits;
}
if (socket_num)
PD365Write2(INDEX_MAPPING_ENABLE,work);
else
PD365Write1(INDEX_MAPPING_ENABLE,work);
LeaveCriticalSection(&g_PCIC_Crit);
v_WinState[uWindow].fState = pWindowState->fState;
v_WinState[uWindow].uSize = pWindowState->uSize;
v_WinState[uWindow].uOffset = pWindowState->uOffset;
return CERR_SUCCESS;
}
//
// PDCardInquireWindow
//
// @func STATUS | PDCardInquireWindow | Report the characteristics and capabilities
// of a memory or I/O window
// @rdesc Returns one of the CERR_* error codes in cardserv.h
//
STATUS
PDCardInquireWindow(
UINT32 uWindow, // @parm Window number (the first window is 0)
PPDCARD_WINDOW_INFO pWinInfo // @parm Pointer to a PDCARD_WINDOW_INFO structure.
)
{
if (uWindow >= PCMCIA_NUM_WINDOWS) {
return CERR_BAD_WINDOW;
}
memcpy(pWinInfo, &v_WinInfo[uWindow], sizeof(PDCARD_WINDOW_INFO));
return CERR_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -