window.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:16k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. /*++
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright (c) 2002. Samsung Electronics, co. ltd  All rights reserved.
  7. Module Name:  
  8. Abstract:  
  9.    Platform dependent PCMCIA memory and I/O window functions and data.
  10. Rev:
  11. 2002.4.14 : S3C2410 port (kwangyoon LEE, kwangyoon@samsung.com)
  12. 2001.12.21 : bug fixup (kwangyoon LEE, kwangyoon@samsung.com)
  13. 2001.12.12 : add S3C2400 Specific definitions (kwangyoon LEE, kwangyoon@samsung.com)
  14. Notes: 
  15. --*/
  16. #include <windows.h>
  17. #include <types.h>
  18. #include <cardserv.h>
  19. #include <sockserv.h>
  20. #include <sockpd.h>
  21. //
  22. // Memory (attribute and common) starting at 0x10000000(physical address)
  23. //
  24. #define PCMCIA_MEM_WIN_BASE0 0x10000000
  25. #define PCMCIA_MEM_WIN_BASE1 PCMCIA_MEM_WIN_BASE0+PCMCIA_MEM_WIN_SIZE
  26. #define PCMCIA_MEM_WIN_BASE2 PCMCIA_MEM_WIN_BASE1+PCMCIA_MEM_WIN_SIZE
  27. #define PCMCIA_MEM_WIN_BASE3 PCMCIA_MEM_WIN_BASE2+PCMCIA_MEM_WIN_SIZE
  28. #define PCMCIA_MEM_WIN_BASE4 PCMCIA_MEM_WIN_BASE3+PCMCIA_MEM_WIN_SIZE
  29. #define PCMCIA_MEM_WIN_SIZE 0x02000
  30. #define MEM_WIN0_START_ADDR_LO (0x00000000 >> 12)
  31. #define MEM_WIN0_END_ADDR_LO (PCMCIA_MEM_WIN_SIZE >> 12)
  32. #define PCMCIA_IO_WIN_BASE0 0x0
  33. #define PCMCIA_IO_WIN_BASE1 0x0
  34. #define PCMCIA_IO_WIN_SIZE      65536
  35. #define PCMCIA_NUM_WINDOWS 7
  36. UCHAR EnableMask[PCMCIA_NUM_WINDOWS] = {
  37.     WIN_MEM_MAP0_ENABLE,
  38.     WIN_MEM_MAP1_ENABLE,
  39.     WIN_MEM_MAP2_ENABLE,
  40.     WIN_MEM_MAP3_ENABLE,
  41.     WIN_MEM_MAP4_ENABLE,
  42.     WIN_IO_MAP0_ENABLE,
  43.     WIN_IO_MAP1_ENABLE,
  44. };
  45. // @doc DRIVERS
  46. PDCARD_WINDOW_STATE v_WinState[PCMCIA_NUM_WINDOWS] = {
  47. //
  48. // Window state for the attribute and common memory windows.
  49. //
  50.  {  // Window 0 - socket 0 attribute or common window
  51.     0,                    // socket number
  52.     WIN_STATE_ENABLED|WIN_STATE_ATTRIBUTE,    // state flags
  53.     WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_10|WIN_SPEED_USE_WAIT,
  54.     PCMCIA_MEM_WIN_SIZE,
  55.     PCMCIA_MEM_WIN_BASE0,
  56.     0
  57.  },
  58.  {  // Window 1 - socket 0 attribute or common window
  59.     0,                    // socket number
  60.     WIN_STATE_ENABLED|WIN_STATE_16BIT,    // state flags
  61.     WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_10|WIN_SPEED_USE_WAIT,
  62.     PCMCIA_MEM_WIN_SIZE,
  63.     PCMCIA_MEM_WIN_BASE1,
  64.     0
  65.  },
  66.  {  // Window 2 - socket 0 attribute or common window
  67.     0,                    // socket number
  68.     WIN_STATE_ENABLED|WIN_STATE_16BIT,    // state flags
  69.     WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_10|WIN_SPEED_USE_WAIT,
  70.     PCMCIA_MEM_WIN_SIZE,
  71.     PCMCIA_MEM_WIN_BASE2,
  72.     0
  73.  },
  74.  {  // Window 3 - socket 0 attribute or common window
  75.     0,                    // socket number
  76.     WIN_STATE_ENABLED,    // state flags
  77.     WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_10|WIN_SPEED_USE_WAIT,
  78.     PCMCIA_MEM_WIN_SIZE,
  79.     PCMCIA_MEM_WIN_BASE3,
  80.     0
  81.  },
  82.  {  // Window 4 - socket 0 attribute or common window
  83.     0,                    // socket number
  84.     WIN_STATE_ENABLED,    // state flags
  85.     WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_10|WIN_SPEED_USE_WAIT,
  86.     PCMCIA_MEM_WIN_SIZE,
  87.     PCMCIA_MEM_WIN_BASE4,
  88.     0
  89.  },
  90. //
  91. // Window state for the I/O windows.
  92. //
  93.  {  // Window 5 - socket 0 I/O window
  94.     0,                    // socket number
  95.     WIN_STATE_MAPS_IO|WIN_STATE_16BIT,
  96.     WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_10|WIN_SPEED_USE_WAIT,
  97.     PCMCIA_IO_WIN_SIZE,
  98.     0x11000000,
  99.     0
  100.  },
  101.  {  // Window 6 - socket 0 I/O window
  102.     0,                    // socket number
  103.     WIN_STATE_MAPS_IO|WIN_STATE_16BIT,
  104.     WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_10|WIN_SPEED_USE_WAIT,
  105.     PCMCIA_IO_WIN_SIZE,
  106.     0x11000000,
  107.     0
  108.  }
  109. };
  110. //
  111. // PDCardGetWindow
  112. //
  113. // @func    STATUS | PDCardGetWindow | Report the current state of a memory or I/O window
  114. // @rdesc   Returns one of the CERR_* error codes in cardserv.h
  115. //
  116. STATUS
  117. PDCardGetWindow(
  118.     UINT32 uWindow,                     // @parm Window number (the first window is 0)
  119.     PPDCARD_WINDOW_STATE pWindowState   // @parm Pointer to a PDCARD_WINDOW_STATE structure.
  120.     )
  121. {
  122.     if (uWindow >= PCMCIA_NUM_WINDOWS) {
  123.         return CERR_BAD_WINDOW;
  124.     }
  125.     memcpy(pWindowState, &(v_WinState[uWindow]), sizeof(PDCARD_WINDOW_STATE));
  126.     return CERR_SUCCESS;
  127. }
  128. //
  129. // PDCardSetWindow
  130. //
  131. // @func    STATUS | PDCardSetWindow | Change the characteristics of a memory or I/O window
  132. // @rdesc   Returns one of the CERR_* error codes in cardserv.h
  133. //
  134. STATUS
  135. PDCardSetWindow(
  136.     UINT32 uWindow,                     // @parm Window number (the first window is 0)
  137.     PPDCARD_WINDOW_STATE pWindowState   // @parm Pointer to a PDCARD_WINDOW_STATE structure.
  138.     )
  139. {
  140.     //
  141.     // base_reg will be added to a base register index to get the
  142.     // correct window register index for the specified window.
  143.     //
  144.     UINT8 base_reg;
  145.     UINT8 tmp;
  146.     UINT8 tmp_mask;
  147.     UINT32 start;
  148.     UINT32 address;
  149.     UINT  sock;
  150.     BOOL  bUserMode = TRUE;
  151.     DEBUGMSG (1,(TEXT("++PDCardSetWindow #%xnr"), uWindow));
  152.     if ( uWindow & ADP_STATE_KERNEL_MODE) { // check the kernel-mode bit
  153.         ASSERT( !(PCMCIA_NUM_WINDOWS & ADP_STATE_KERNEL_MODE) );
  154.         uWindow &= ~ADP_STATE_KERNEL_MODE;  // clear it
  155.         bUserMode = FALSE;
  156.     }
  157.     
  158. if (uWindow >= PCMCIA_NUM_WINDOWS) {
  159. return CERR_BAD_WINDOW;
  160.     }
  161.     sock = v_WinState[uWindow].uSocket;
  162.     if ( bUserMode ) {
  163.         EnterCriticalSection(&g_PCIC_Crit);
  164.     }
  165.             
  166. if (pWindowState->fState & WIN_STATE_ENABLED) {
  167.         PCICIndex(sock, REG_WINDOW_ENABLE);
  168.         tmp = PCICDataRead()|WIN_MEMCS16_DECODE;
  169.         if (uWindow >= SOCKET0_FIRST_IO_WINDOW) {
  170.             //
  171.             // We need to check here for I/O range collisions since both sockets
  172.             // are mapped onto the same system bus for I/O addresses. 
  173.             // (The memory windows won't collide because they have constant 
  174.             // address ranges in the host address space)
  175.             //
  176.             for (start = SOCKET0_FIRST_IO_WINDOW;
  177.                  start < PCMCIA_NUM_WINDOWS;
  178.                  start++) {
  179.                 //
  180.                 // Don't worry about collisions with:
  181.                 // 1. the same window
  182.                 // 2. disabled windows
  183.                 //
  184.                 if ((start == uWindow) || (!(v_WinState[start].fState & WIN_STATE_ENABLED))) {
  185.                     continue;
  186.                 }
  187.                 if ((pWindowState->uOffset + pWindowState->uSize) > 
  188.                     v_WinState[start].uOffset) {
  189.                     if (pWindowState->uOffset <
  190.                         (v_WinState[start].uOffset + v_WinState[start].uSize)) {
  191.                         LeaveCriticalSection(&g_PCIC_Crit);
  192. DEBUGMSG(1,
  193. (TEXT("PCMCIA:PDCardSetWindow I/O range collision with windows %d (0x%x 0x%x) and %d (0x%x 0x%x)rn"),
  194.           uWindow, pWindowState->uOffset, pWindowState->uSize,
  195.           start, v_WinState[start].uOffset, v_WinState[start].uSize));
  196.                         return CERR_IN_USE;
  197.                     }
  198.                 }
  199.             }
  200.         }
  201.         //
  202.         // Disable this window while we work on it.
  203.         //
  204.         tmp_mask = EnableMask[uWindow];
  205.         tmp &= ~tmp_mask;
  206.         PCICDataWrite(tmp);
  207.         if (uWindow >= SOCKET0_FIRST_IO_WINDOW) {
  208.             //
  209.             // I/O window setup
  210.             //
  211.             switch (uWindow) {
  212.             case SOCKET0_FIRST_IO_WINDOW:
  213.             case SOCKET1_FIRST_IO_WINDOW:
  214.                 base_reg = REG_IO_MAP0_START_ADDR_LO;
  215.                 break;
  216.             case SOCKET0_FIRST_IO_WINDOW+1:
  217.             case SOCKET1_FIRST_IO_WINDOW+1:
  218.                 base_reg = REG_IO_MAP1_START_ADDR_LO;
  219.                 break;
  220.             }
  221.             //
  222.             // Set the I/O window's mapping
  223.             //
  224.             PCICIndex(sock, base_reg); // REG_IO_MAPn_START_ADDR_LO
  225.             base_reg++;
  226.             PCICDataWrite((UINT8)pWindowState->uOffset);
  227.             PCICIndex(sock, base_reg); // REG_IO_MAPn_START_ADDR_HI
  228.             base_reg++;
  229.             PCICDataWrite((UINT8)(pWindowState->uOffset >> 8));
  230.             address = pWindowState->uOffset + pWindowState->uSize - 1;
  231.             PCICIndex(sock, base_reg); // REG_IO_MAPn_END_ADDR_LO
  232.             base_reg++;
  233.             PCICDataWrite((UINT8)address);
  234.             PCICIndex(sock, base_reg); // REG_IO_MAPn_END_ADDR_HI
  235.             PCICDataWrite((UINT8)(address >> 8));
  236.             //
  237.             // Set the window's data path width
  238.             //
  239.             PCICIndex(sock, REG_IO_WINDOW_CONTROL);
  240.             tmp = PCICDataRead();
  241. #if 0 // LKY 2001.12
  242.             tmp_mask = ICR_0_WAIT_STATE;
  243. #else
  244.             tmp_mask = 0;
  245. #endif
  246.             
  247.             if (pWindowState->fState & WIN_STATE_16BIT) {
  248.                 tmp_mask |= ICR_0_IOCS16|ICR_0_IO_16BIT;
  249.             }
  250.             if (!(uWindow & 1)) {
  251.                 tmp &= 0x0f;
  252.                 tmp_mask <<= 4;
  253.                 tmp |= tmp_mask;
  254.             } else {
  255.                 tmp &= 0xf0;
  256.                 tmp |= tmp_mask;
  257.             }
  258.             PCICDataWrite(tmp);
  259.             tmp_mask = PCICDataRead();
  260.             if (tmp_mask != tmp) {
  261. DEBUGMSG(1,
  262. (TEXT("PCMCIA:PDCardSetWindow window %d REG_IO_WINDOW_CONTROL = 0x%x (expected 0x%xrn"),
  263. uWindow, tmp_mask, tmp));
  264.             }
  265.             //
  266.             // Set the card type to I/O
  267.             //
  268.             PCICIndex(sock, REG_INTERRUPT_AND_GENERAL_CONTROL);
  269.             tmp = PCICDataRead();
  270.             tmp  |= INT_CARD_IS_IO;
  271.             PCICDataWrite(tmp);
  272.         } else {
  273.             //
  274.             // Memory window setup
  275.             //
  276.             if (sock) {
  277.                 base_reg = (uWindow - SOCKET1_FIRST_MEMORY_WINDOW) * 8;
  278.             } else {
  279.                 base_reg = uWindow * 8;
  280.             }
  281.             //
  282.             // Set the window to its predetermined host system address range
  283.             //
  284.             tmp = MEM_WIN0_START_ADDR_LO + (uWindow * MEM_WIN0_END_ADDR_LO);
  285.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_START_ADDR_LO));
  286.             PCICDataWrite(tmp);
  287.             tmp += MEM_WIN0_END_ADDR_LO - 1;
  288.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_END_ADDR_LO));
  289.             PCICDataWrite(tmp);
  290.             //
  291.             // Set the window's data path width
  292.             //
  293.             if (pWindowState->fState & WIN_STATE_16BIT) {
  294.                 tmp = MSH_MEM_16BIT;
  295.             } else {
  296.                 tmp = 0;
  297.             }
  298.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_START_ADDR_HI));
  299.             PCICDataWrite(tmp);
  300.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_END_ADDR_HI));
  301.             PCICDataWrite(MTH_WAIT_STATE_BIT0|MTH_WAIT_STATE_BIT1);
  302.             //
  303.             // Set the window's card offset
  304.             // (REG_MEM_MAP0_START_ADDR_HI only has 4 bits of address)
  305.             //
  306.                         
  307.             // LKY. 2001.12 add Missing code!!!
  308.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_START_ADDR_HI));
  309.             tmp = PCICDataRead();
  310.             
  311.             start = (UINT32)(tmp & 0x0f);
  312.             start <<= 8;
  313.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_START_ADDR_LO));
  314.             start |= PCICDataRead();
  315.             start <<= 12;
  316. DEBUGMSG(1,
  317. (TEXT("PCMCIA:PDCardSetWindow mapping window %d @ 0x%x to card offset 0x%xrn"),
  318.      uWindow, start, pWindowState->uOffset));
  319.             address = pWindowState->uOffset & 0xFFFFF000;
  320.             pWindowState->uOffset = address;
  321.             start = address - start;
  322.             start >>= 12;
  323.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_ADDR_OFFSET_LO));
  324.             PCICDataWrite((UINT8)start);
  325.             start >>= 8;
  326.             //
  327.             // Set the window's memory space characteristics
  328.             //
  329.             tmp = (UINT8)(start & 0x3f);
  330.             if (pWindowState->fState & WIN_STATE_ATTRIBUTE) {
  331. DEBUGMSG(1,
  332. (TEXT("PCMCIA:PDCardSetWindow mapping window %d to attribute spacern"),
  333. uWindow));
  334.                 tmp |= MOH_REG_ACTIVE;
  335.             }
  336.             PCICIndex(sock, (UINT8)(base_reg + REG_MEM_MAP0_ADDR_OFFSET_HI));
  337.             PCICDataWrite(tmp);
  338.         }   // else memory window
  339.     }
  340.     //
  341.     // Enable or disable this window as requested.
  342.     //
  343.     PCICIndex(sock, REG_WINDOW_ENABLE);
  344.     tmp = PCICDataRead()|WIN_MEMCS16_DECODE;
  345.     tmp_mask = EnableMask[uWindow];
  346.     if (pWindowState->fState & WIN_STATE_ENABLED) {
  347.         tmp |= tmp_mask;
  348.     } else {
  349.         tmp &= ~tmp_mask;
  350.     }
  351.     PCICDataWrite(tmp);
  352. #ifdef DEBUG
  353.     DeltaSocketRegisters(v_WinState[uWindow].uSocket);
  354. #endif
  355.     if (bUserMode) {
  356.         LeaveCriticalSection(&g_PCIC_Crit);
  357.     }
  358.     v_WinState[uWindow].fState = pWindowState->fState;
  359.     v_WinState[uWindow].uSize = pWindowState->uSize;
  360.     v_WinState[uWindow].uOffset = pWindowState->uOffset;
  361.     // 
  362.     if (uWindow >= SOCKET0_FIRST_IO_WINDOW) {
  363.         pWindowState->uOffset = 0;
  364.     }
  365.     DEBUGMSG (1,(TEXT("--PDCardSetWindownr")));
  366.     return CERR_SUCCESS;
  367. }   // PDCardSetWindow
  368. //
  369. // PDCardInquireWindow
  370. //
  371. // @func    STATUS | PDCardInquireWindow | Report the characteristics and capabilities
  372. //                                         of a memory or I/O window
  373. // @rdesc   Returns one of the CERR_* error codes in cardserv.h
  374. //
  375. STATUS
  376. PDCardInquireWindow(
  377.     UINT32 uWindow,                     // @parm Window number (the first window is 0)
  378.     PPDCARD_WINDOW_INFO pWinInfo        // @parm Pointer to a PDCARD_WINDOW_INFO structure.
  379.     )
  380. {
  381.     UINT uBase;
  382.     if (uWindow < SOCKET1_FIRST_MEMORY_WINDOW) {
  383.         pWinInfo->fSockets = 1;
  384.     } else if (uWindow < SOCKET0_FIRST_IO_WINDOW) {
  385.         pWinInfo->fSockets = 2;
  386.     } else if (uWindow < SOCKET1_FIRST_IO_WINDOW) {
  387.         pWinInfo->fSockets = 1;
  388.     } else if (uWindow < PCMCIA_NUM_WINDOWS) {
  389.         pWinInfo->fSockets = 2;
  390.     } else {
  391.         return CERR_BAD_WINDOW;
  392.     }
  393.     uBase = v_WinState[uWindow].uBase;
  394. // LKY 2001.12 (Window 0 -> attribute memory, others -> Common memory)
  395.     if (uWindow == 0) {
  396.         pWinInfo->fWindowCaps = WIN_CAP_ATTRIBUTE;
  397.         pWinInfo->fMemoryCaps = MEM_CAP_PRG_BASE|MEM_CAP_8BIT|MEM_CAP_16BIT;
  398.         pWinInfo->uMemFirstByte = uBase;
  399.         pWinInfo->uMemLastByte = uBase+PCMCIA_MEM_WIN_SIZE-1;
  400.         pWinInfo->uMemMinSize = 4096;
  401.         pWinInfo->uMemMaxSize = PCMCIA_MEM_WIN_SIZE;
  402.         pWinInfo->uMemGranularity = 4096;
  403.         pWinInfo->uMemBase = 0;
  404.         pWinInfo->uMemOffset = 0;
  405.         pWinInfo->fSlowest = WIN_SPEED_EXP_10MS|WIN_SPEED_MANT_12|WIN_SPEED_USE_WAIT;
  406.         pWinInfo->fFastest = WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_12|WIN_SPEED_USE_WAIT;
  407.     } 
  408.     else if (uWindow < SOCKET0_FIRST_IO_WINDOW) {
  409.         pWinInfo->fWindowCaps = WIN_CAP_COMMON;
  410.         pWinInfo->fMemoryCaps = MEM_CAP_PRG_BASE|MEM_CAP_8BIT|MEM_CAP_16BIT;
  411.         pWinInfo->uMemFirstByte = uBase;
  412.         pWinInfo->uMemLastByte = uBase+PCMCIA_MEM_WIN_SIZE-1;
  413.         pWinInfo->uMemMinSize = 4096;
  414.         pWinInfo->uMemMaxSize = PCMCIA_MEM_WIN_SIZE;
  415.         pWinInfo->uMemGranularity = 4096;
  416.         pWinInfo->uMemBase = 0;
  417.         pWinInfo->uMemOffset = 0;
  418.         pWinInfo->fSlowest = WIN_SPEED_EXP_10MS|WIN_SPEED_MANT_12|WIN_SPEED_USE_WAIT;
  419.         pWinInfo->fFastest = WIN_SPEED_EXP_1NS|WIN_SPEED_MANT_12|WIN_SPEED_USE_WAIT;
  420.     } else {
  421.         pWinInfo->fWindowCaps = WIN_CAP_IO|WIN_CAP_WAIT;
  422.         pWinInfo->fIOCaps = IO_CAP_PRG_BASE|IO_CAP_8BIT|IO_CAP_16BIT;
  423.         pWinInfo->uIOFirstByte = uBase;
  424.         pWinInfo->uIOLastByte = uBase+PCMCIA_IO_WIN_SIZE-1;
  425.         pWinInfo->uIOMinSize = 1;
  426.         pWinInfo->uIOMaxSize = PCMCIA_IO_WIN_SIZE;
  427.         pWinInfo->uIOGranularity = 1;
  428.         pWinInfo->uAddressLines = 16;
  429.     }
  430.     return CERR_SUCCESS;
  431. }