|Why I'm reading wrong data from my card?|
|Reason:||There is a bug in memory window mapping algorithm of several versions of PCMCIA.SYS. Practically this bug results in window mapping to wrong offset of the PC Card if memory allocated for PC Card is not aligned to 64MB boundary. Please see Details section for bug description.|
|Solution:||CardWare Memory Card Support for Windows 2000 / XP implements a special work-around and should be immune for this bug. However we strongly recommend update your system to latest Service Pack of the OS. Windows 2000 SP3, retail version of Windows XP and Windows XP SP1 are free from this bug. The Windows 2000 SP3 is available for free download on Microsoft WEB site (http://www.microsoft.com/windows2000/downloads/servicepacks/sp3/default.asp)|
|Details:||The PCIC compatible 16-bit PCMCIA controller implements 24 address lines
for host memory and 26 address line for card memory. Therefore the maximal
size of the host memory window could be 2^24 = 16MB and maximal size of the
card memory could be 2^26 = 64MB. For both attribute and common memory lower
address bits A0 ... A11 cannot be set by the user and considered be wired to
0 for memory window starting address and to 1 for memory window ending address.
Therefore memory window can be allocated in host memory and/or re-mapped in
card memory with granularity of 2 ^ 12 = 4KB.
Important to understand that card offset is programmed not with the card offset itself, but with the difference between card offset address and host address.
For example, if memory window is located at host address 0x00DF000 and you want map it to the card offset 0, the value to write into Card Offset registers is calculated as:
(Card Offset (0x0000000) - Host Offset (0x00DF000)) AND (Mask 0x03FFF000) = FF21000 & 0x03FFF000 = 0x3F21000
Since lower 12 bits are not considered and only 14 bits are significant, the resulting value will be 0x3F21
The above formula is implemented by Microsoft and works well for truly 16-bit adapters, where host address is always in range 0 ... 16 MB (0x000000 ... 0xFFFFFF).
In case of CardBus adapter, however, the host address can be anywhere in 4GB address space. The remaining address bits A25 ... A31 are typically programmed via ExCA registers 0x40 (for Memory Window 0) trough 0x44 (for Memory Window 4). This additional address byte is common for host starting and host ending address and therefore the window itself remains maximum 16 MB in size. Important to understand that despite 32-bit addressing the window remains essentially 16-bit compatible.
In that case the above formula causes the wrong result, if host address is aligned to 16MB boundary and card offset is equal or bigger as 16MB.
For example, if host address is 0xEE000000 and Card address is 0, 0x1000000 (16MB), 0x2000000 (32 MB) or 0x3000000 (48 MB) the formula will give:
(0x0000000 - 0xEF000000) & 0x3FFF000 = 0x11000000 & 0x3FFF000 = 0x02000000 => 10 00 (0x1000000 - 0xEF000000) & 0x3FFF000 = 0x12000000 & 0x3FFF000 = 0x03000000 => 20 00 (0x2000000 - 0xEF000000) & 0x3FFF000 = 0x13000000 & 0x3FFF000 = 0x00000000 => 30 00 (0x3000000 - 0xEF000000) & 0x3FFF000 = 0x14000000 & 0x3FFF000 = 0x01000000 => 00 00
This result is incorrect, because in fact window still have 24 bit address lines
The proper formula should be as follow:
(Card Offset - (Host Offset & 0xFFFFFF)) AND (Mask 0x03FF000)
Applying the new formula to above sample we will receive:
(0x0000000 - (0xEF000000 & 0xFFFFFF)) & 0x3FFF000 = 0x00000000 & 0x3FFF000 = 0x0000000 => 00 00 (0x1000000 - (0xEF000000 & 0xFFFFFF)) & 0x3FFF000 = 0x01000000 & 0x3FFF000 = 0x1000000 => 10 00 (0x2000000 - (0xEF000000 & 0xFFFFFF)) & 0x3FFF000 = 0x02000000 & 0x3FFF000 = 0x2000000 => 20 00 (0x3000000 - (0xEF000000 & 0xFFFFFF)) & 0x3FFF000 = 0x03000000 & 0x3FFF000 = 0x3000000 => 30 00
Simple analyze of above data shows that error occurs if host window address has bits 24 and/or 25 set, i.e. memory resource is not 64MB aligned.