OEMAddressTable (Windows Embedded CE 6.0)
OEMAddressTable defines a table that maps a 4 GB physical address space to the kernel's 512-MB unmapped space for a device. Each entry in the table consists of the virtual base address to map to, the physical base address to map from, and the number of MB to map.
The data must be declared in a READONLY section and there must be at least one non-zero entry for the structure to be valid. For x86-based hardware platforms, the first entry must identify RAM, and it must start at 0x80000000. For ARM-based hardware platforms, 0x80000000 can be mapped to anything.
Each entry is of the following format.
Virtual Address, Physical Address, Size.
The Size must be a multiple of 4MB for x86-based hardware platforms and a multiple of 1MB for ARM. The last entry of the table must be zeroed. You can leave holes between ranges but you cannot have overlapping ranges.
The only valid virtual memory mapping range is from 0x80000000 to 0x9FFFFFFF.
For every entry created in the table, the kernel creates two virtual address ranges:
One exists in the virtual address range from 0x80000000 to 0x9FFFFFFF and is memory that has caching enabled.
The second exists in the virtual address range from 0xA0000000 to 0xBFFFFFFF and has caching disabled.
If you modify the RAM entry in OEMAddressTable, you must update Config.bib to use the new memory mapping.
Any memory that is not mapped at boot time cannot be directly accessed by an interrupt service routine (ISR) without first calling CreateStaticMapping to map the address.
The following code example shows an implementation of OEMAddressTable for x86-based hardware platforms, which has the restriction of VA 0x80000000 = PA 0x00000000. ARM-based hardware platforms do not have this restriction.
public _OEMAddressTable _OEMAddressTable: ; ; OEMAddressTable defines the mapping between Physical and Virtual Address ; o MUST be in a READONLY Section ; o First Entry MUST be RAM, mapping from 0x80000000 -> 0x00000000 ; o each entry is of the format ( VA, PA, cbSize ) ; o cbSize must be multiple of 4M ; o last entry must be (0, 0, 0) ; o must have at least one non-zero entry ; RAM 0x80000000 -> 0x00000000, size 64M dd 80000000h, 0, 04000000h ; FLASH and other memory, if any ; dd FlashVA, FlashPA, FlashSize ; Last entry, all zeros dd 0 0 0
If a device with an XScale CPU hangs when executing the instruction that enables MMU, you can attempt to isolate the problem by including an identity mapping for FLASH memory in OEMAddressTable. If the identity mapping allows execution to continue past the failed MMU instruction, then this indicates that the problem is specific to the XScale CPU. Although the identity mapping can get you past the MMU enable instruction, it is likely to cause the system to crash later in the boot process when virtual memory is accessed.
Once you identify that this is the XScale specific issue, you can workaround this problem by performing the following steps:
- Create the identity mapping in the first call to OEMARMCacheMode. You can determine if it is the first call by testing whether the instruction counter is a physical address, in which case MMU is not enabled yet.
- In OEMInitDebugSerial, remove the identity mapping.