OEMAddressTable 内存映射表是怎么被wince使用的(作者:wogoyixikexie@gliet)
2008-12-12 17:11
477 查看
作者:wogoyixikexie@gliet
;------------------------------------------------------------------------------
;
; File: memory_cfg.inc
;
; This file is used to define g_oalAddressTable. This table is passed to
; KernelStart to estabilish physical to virtual memory mapping. This table
; is used also in IOMEM OAL module to map between physical and virtual
; memory addresses via OALPAtoVA/OALVAtoPA functions.
;
;------------------------------------------------------------------------------
; Export Definition
EXPORT g_oalAddressTable[DATA]
;------------------------------------------------------------------------------
;
; TABLE FORMAT
; cached address, physical address, size
;------------------------------------------------------------------------------
g_oalAddressTable
DCD 0x80000000, 0x30000000, 64 ; 32 MB DRAM BANK 6
DCD 0x84000000, 0x10000000, 32 ; nGCS2: PCMCIA/PCCARD
DCD 0x86000000, 0x18000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 3
DCD 0x88000000, 0x20000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 4
DCD 0x8A000000, 0x28000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 5
DCD 0x8C000000, 0x08000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 1
DCD 0x90800000, 0x48000000, 1 ; Memory control register
DCD 0x90900000, 0x49000000, 1 ; USB Host register
DCD 0x90A00000, 0x4A000000, 1 ; Interrupt Control register
DCD 0x90B00000, 0x4B000000, 1 ; DMA control register
DCD 0x90C00000, 0x4C000000, 1 ; Clock & Power register
DCD 0x90D00000, 0x4D000000, 1 ; LCD control register
DCD 0x90E00000, 0x4E000000, 1 ; NAND flash control register
DCD 0x90F00000, 0x4F000000, 1 ; Camera control register
DCD 0x91000000, 0x50000000, 1 ; UART control register
DCD 0x91100000, 0x51000000, 1 ; PWM timer register
DCD 0x91200000, 0x52000000, 1 ; USB device register
DCD 0x91300000, 0x53000000, 1 ; Watchdog Timer register
DCD 0x91400000, 0x54000000, 1 ; IIC control register
DCD 0x91500000, 0x55000000, 1 ; IIS control register
DCD 0x91600000, 0x56000000, 1 ; I/O Port register
DCD 0x91700000, 0x57000000, 1 ; RTC control register
DCD 0x91800000, 0x58000000, 1 ; A/D convert register
DCD 0x91900000, 0x59000000, 1 ; SPI register
DCD 0x91A00000, 0x5A000000, 1 ; SD Interface register
DCD 0x92000000, 0x00000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 0
DCD 0x00000000, 0x00000000, 0 ; end of table
;------------------------------------------------------------------------------
END
以前,一直不知道这个表是怎么回事,刚才偶然的机会,看见了调用他的函数
C:/WINCE500/PLATFORM/COMMON/SRC/ARM/COMMON/MEMORY/memory.c
//------------------------------------------------------------------------------
//
// File: memory.c
// 从这个代码看出ARM虚拟内存和物理内存的关系
// Memory interface routines.
//
#include <windows.h>
#include <oal_log.h>
#include <oal_memory.h>
typedef struct {
UINT32 CA; // cached virtual address
UINT32 PA; // physical address
UINT32 size; // size, in MB bytes
} OAL_ADDRESS_TABLE, *POAL_ADDRESS_TABLE;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// Function: OALPAtoVA
//
// Converts a physical address (PA) to a virtual address (VA). This routine
// uses the OEMAddressTable defined in the platform.
//
VOID* OALPAtoVA(UINT32 pa, BOOL cached)
{
OAL_ADDRESS_TABLE *pTable = g_oalAddressTable;
VOID *va = NULL;
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"+OALPAtoVA(0x%x, %d)/r/n", pa, cached));
// Search the table for address range
while (pTable->size != 0) {
if (
pa >= pTable->PA &&
pa <= (pTable->PA + (pTable->size << 20) - 1)
) break; // match found 找到表中相近的内存
pTable++;
}
// If address table entry is valid compute the VA
if (pTable->size != 0) {
va = (VOID *)(pTable->CA + (pa - pTable->PA));
// If VA is uncached, set the uncached bit
if (!cached) (UINT32)va |= OAL_MEMORY_CACHE_BIT;
}
// Indicate the virtual address
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"-OALPAtoVA(va = 0x%08x)/r/n", va));
return va;
}
//------------------------------------------------------------------------------
//
// Function: OALVAtoPA
//
// Converts a virtual address (VA) to a physical address (PA). This routine
// uses the OEMAddressTable defined in the platform.
//
UINT32 OALVAtoPA(VOID *pVA)
{
OAL_ADDRESS_TABLE *pTable = g_oalAddressTable;
UINT32 va = (UINT32)pVA;
UINT32 pa = 0;
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"+OALVAtoPA(0x%08x)/r/n", pVA));
// Virtual address must be in CACHED or UNCACHED regions.虚拟内存范围
if (va < 0x80000000 || va >= 0xC0000000) {
OALMSG(OAL_ERROR, (
L"ERROR:OALVAtoPA: invalid virtual address 0x%08x/r/n", pVA
));
goto cleanUp;
}
// Address must be cached, as entries in OEMAddressTable are cached address.
va = va&~OAL_MEMORY_CACHE_BIT;
// Search the table for address range
while (pTable->size != 0) {
if (va >= pTable->CA && va <= pTable->CA + (pTable->size << 20) - 1) {
break;
}
pTable++;
}
// If address table entry is valid compute the PA
if (pTable->size != 0) pa = pTable->PA + va - pTable->CA;
cleanUp:
// Indicate physical address
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"-OALVAtoPA(pa = 0x%x)/r/n", pa));
return pa;
}
//------------------------------------------------------------------------------
//从这两个函数可以看出,这个表只是为了容易修改而已,其实手动访问虚拟内存也是可
//的。至于访问GPIO 的那种访问留到有机会再说了。good luck 今天收获不小。
转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协。如有错误,希望能够留言指出。
;------------------------------------------------------------------------------
;
; File: memory_cfg.inc
;
; This file is used to define g_oalAddressTable. This table is passed to
; KernelStart to estabilish physical to virtual memory mapping. This table
; is used also in IOMEM OAL module to map between physical and virtual
; memory addresses via OALPAtoVA/OALVAtoPA functions.
;
;------------------------------------------------------------------------------
; Export Definition
EXPORT g_oalAddressTable[DATA]
;------------------------------------------------------------------------------
;
; TABLE FORMAT
; cached address, physical address, size
;------------------------------------------------------------------------------
g_oalAddressTable
DCD 0x80000000, 0x30000000, 64 ; 32 MB DRAM BANK 6
DCD 0x84000000, 0x10000000, 32 ; nGCS2: PCMCIA/PCCARD
DCD 0x86000000, 0x18000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 3
DCD 0x88000000, 0x20000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 4
DCD 0x8A000000, 0x28000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 5
DCD 0x8C000000, 0x08000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 1
DCD 0x90800000, 0x48000000, 1 ; Memory control register
DCD 0x90900000, 0x49000000, 1 ; USB Host register
DCD 0x90A00000, 0x4A000000, 1 ; Interrupt Control register
DCD 0x90B00000, 0x4B000000, 1 ; DMA control register
DCD 0x90C00000, 0x4C000000, 1 ; Clock & Power register
DCD 0x90D00000, 0x4D000000, 1 ; LCD control register
DCD 0x90E00000, 0x4E000000, 1 ; NAND flash control register
DCD 0x90F00000, 0x4F000000, 1 ; Camera control register
DCD 0x91000000, 0x50000000, 1 ; UART control register
DCD 0x91100000, 0x51000000, 1 ; PWM timer register
DCD 0x91200000, 0x52000000, 1 ; USB device register
DCD 0x91300000, 0x53000000, 1 ; Watchdog Timer register
DCD 0x91400000, 0x54000000, 1 ; IIC control register
DCD 0x91500000, 0x55000000, 1 ; IIS control register
DCD 0x91600000, 0x56000000, 1 ; I/O Port register
DCD 0x91700000, 0x57000000, 1 ; RTC control register
DCD 0x91800000, 0x58000000, 1 ; A/D convert register
DCD 0x91900000, 0x59000000, 1 ; SPI register
DCD 0x91A00000, 0x5A000000, 1 ; SD Interface register
DCD 0x92000000, 0x00000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 0
DCD 0x00000000, 0x00000000, 0 ; end of table
;------------------------------------------------------------------------------
END
以前,一直不知道这个表是怎么回事,刚才偶然的机会,看见了调用他的函数
C:/WINCE500/PLATFORM/COMMON/SRC/ARM/COMMON/MEMORY/memory.c
//------------------------------------------------------------------------------
//
// File: memory.c
// 从这个代码看出ARM虚拟内存和物理内存的关系
// Memory interface routines.
//
#include <windows.h>
#include <oal_log.h>
#include <oal_memory.h>
typedef struct {
UINT32 CA; // cached virtual address
UINT32 PA; // physical address
UINT32 size; // size, in MB bytes
} OAL_ADDRESS_TABLE, *POAL_ADDRESS_TABLE;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// Function: OALPAtoVA
//
// Converts a physical address (PA) to a virtual address (VA). This routine
// uses the OEMAddressTable defined in the platform.
//
VOID* OALPAtoVA(UINT32 pa, BOOL cached)
{
OAL_ADDRESS_TABLE *pTable = g_oalAddressTable;
VOID *va = NULL;
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"+OALPAtoVA(0x%x, %d)/r/n", pa, cached));
// Search the table for address range
while (pTable->size != 0) {
if (
pa >= pTable->PA &&
pa <= (pTable->PA + (pTable->size << 20) - 1)
) break; // match found 找到表中相近的内存
pTable++;
}
// If address table entry is valid compute the VA
if (pTable->size != 0) {
va = (VOID *)(pTable->CA + (pa - pTable->PA));
// If VA is uncached, set the uncached bit
if (!cached) (UINT32)va |= OAL_MEMORY_CACHE_BIT;
}
// Indicate the virtual address
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"-OALPAtoVA(va = 0x%08x)/r/n", va));
return va;
}
//------------------------------------------------------------------------------
//
// Function: OALVAtoPA
//
// Converts a virtual address (VA) to a physical address (PA). This routine
// uses the OEMAddressTable defined in the platform.
//
UINT32 OALVAtoPA(VOID *pVA)
{
OAL_ADDRESS_TABLE *pTable = g_oalAddressTable;
UINT32 va = (UINT32)pVA;
UINT32 pa = 0;
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"+OALVAtoPA(0x%08x)/r/n", pVA));
// Virtual address must be in CACHED or UNCACHED regions.虚拟内存范围
if (va < 0x80000000 || va >= 0xC0000000) {
OALMSG(OAL_ERROR, (
L"ERROR:OALVAtoPA: invalid virtual address 0x%08x/r/n", pVA
));
goto cleanUp;
}
// Address must be cached, as entries in OEMAddressTable are cached address.
va = va&~OAL_MEMORY_CACHE_BIT;
// Search the table for address range
while (pTable->size != 0) {
if (va >= pTable->CA && va <= pTable->CA + (pTable->size << 20) - 1) {
break;
}
pTable++;
}
// If address table entry is valid compute the PA
if (pTable->size != 0) pa = pTable->PA + va - pTable->CA;
cleanUp:
// Indicate physical address
OALMSG(OAL_MEMORY&&OAL_FUNC, (L"-OALVAtoPA(pa = 0x%x)/r/n", pa));
return pa;
}
//------------------------------------------------------------------------------
//从这两个函数可以看出,这个表只是为了容易修改而已,其实手动访问虚拟内存也是可
//的。至于访问GPIO 的那种访问留到有机会再说了。good luck 今天收获不小。
转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协。如有错误,希望能够留言指出。
相关文章推荐
- OEMAddressTable 内存映射表是怎么被wince使用的
- OEMAddressTable 内存映射表是怎么被wince使用的
- KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
- 如何在wince下添加和删除驱动(作者:wogoyixikexie@gliet)
- 从build.log文件了解wince编译过程(作者:wogoyixikexie@gliet)
- KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
- 浅谈wince驱动调试方法(作者:wogoyixikexie@gliet)
- wince驱动异常调试方法(作者:wogoyixikexie@gliet)
- 写给像我一样的新手——写wince单层驱动的流程(作者:wogoyixikexie@gliet)
- 反汇编stepldr.exe——第一次使用IDA反汇编(作者:wogoyixikexie@gliet)
- wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)
- 如何在wince下添加和删除驱动(作者:wogoyixikexie@gliet)
- 转---------------wince串口线程、中断等相关学习(作者:wogoyixikexie@gliet)
- wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)
- KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
- KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
- 转:wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)
- 如何使用EVC写寄存器读写软件(作者:wogoyixikexie@gliet)
- 写给像我一样的新手——写wince单层驱动的流程(作者:wogoyixikexie@gliet)
- ZLG7290(wince下)驱动之不停执行同一动作的解决办法(作者:wogoyixikexie@gliet)