/******************************************************************************
* *
* \brief Function to setup MMU. This function Maps three regions (1. DDR *
* 2. OCMC and 3. Device memory) and enables MMU. *
* *
* - 使能MMU,使能非对齐访问,解决数据异常问题 *
* 1、ARMv7默认支持非对齐地址访问,但有些条件: *
* (1)CP15系统控制寄存器(SCTLR), bit.A = 0, (bit.U = 1, ARMv7已默认置1) *
* (2)访问地址必须为Normal memory, 访问Device memory或Strongly memory *
* 会引发alignment fault的Data Abort。而如果MMU disable的话,所有的memory *
* 都被当作Strongly memory处理。所以MMU必须enable, *
* 2、如果目标处理器选择了ARMv6、ARMv7-A、ARMv7-R,编译器的缺省选项是 *
* --unaligned_access *
* 3、如果目标平台是ARMv6或ARMv7-AR,但代码中MMU disable,那应该手动添加编译 *
* 选项--no_unaligned_access,让编译器来生成非对齐访问。 *
******************************************************************************/
//SECTION大小为1M,DDR3存储器为512M字节
#define START_ADDR_DDR (0x80000000)
#define START_ADDR_DEV (0x44000000)
#define START_ADDR_OCMC (0x40300000)
#define NUM_SECTIONS_DDR (512)
#define NUM_SECTIONS_DEV (960)
#define NUM_SECTIONS_OCMC (1)
//MMU页表
#pragma data_alignment=16384
static volatile unsigned int pageTable[4*1024];
//MMU配置
void MMUConfigAndEnable(void)
{
/*
** Define DDR memory region of AM335x. DDR can be configured as Normal
** memory with R/W access in user/privileged modes. The cache attributes
** specified here are,
** Inner - Write through, No Write Allocate
** Outer - Write Back, Write Allocate
*/
REGION regionDdr = {
MMU_PGTYPE_SECTION, START_ADDR_DDR, NUM_SECTIONS_DDR,
MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
MMU_CACHE_WT_NOWA),
MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
(unsigned int*)pageTable
};
/*
** Define OCMC RAM region of AM335x. Same Attributes of DDR region given.
*/
REGION regionOcmc = {
MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,
MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
MMU_CACHE_WT_NOWA),
MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
(unsigned int*)pageTable
};
/*
** Define Device Memory Region. The region between OCMC and DDR is
** configured as device memory, with R/W access in user/privileged modes.
** Also, the region is marked 'Execute Never'.
*/
REGION regionDev = {
MMU_PGTYPE_SECTION, START_ADDR_DEV, NUM_SECTIONS_DEV,
MMU_MEMTYPE_STRONG_ORD_SHAREABLE,
MMU_REGION_NON_SECURE,
MMU_AP_PRV_RW_USR_RW | MMU_SECTION_EXEC_NEVER,
(unsigned int*)pageTable
};
/* Initialize the page table and MMU */
MMUInit((unsigned int*)pageTable);
/* Map the defined regions */
MMUMemRegionMap(®ionDdr);
MMUMemRegionMap(®ionOcmc);
MMUMemRegionMap(®ionDev);
/* Now Safe to enable MMU */
MMUEnable((unsigned int*)pageTable);
}
|