📄 mx21_armcore.c
字号:
/**********************************************************************
*
* (C) COPYRIGHT 2004 FREESCALE, INC.
* ALL RIGHTS RESERVED
*
*
* Group/Division: WMSG/MMDO
*
* Description :
*
*
* Related Specifications:
*
* Errata:
*
* File Name: MX21_ArmCore.c
* Revision Number: 0.1
* Author(s): Sharad Kumar
* Date created: 30Apr2004
* Revision History:
* Date Rev Description
* ---- --- -----------
* 30Apr2004 0.1 First Draft
*
**********************************************************************/
#include "MX21_ArmCore.h"
//---------------------------------------------------
// Initialize the MMU. This routine uses the following
// functions to setup the MMU:
// ARM_TLBFlush(...)
// ARM_CacheFlush(...)
// ARM_SetDomainAccessControl(...)
// ARM_SetPageTableBase(...)
// The MMU table base address must be passed as an
// argument.
// The MMU table base address is a return parameter of
// the routine ARM_MMUTableSetUp()), defined in the file
// MX21_PageTable.h
//
// Typical use of this function in user programs is:
// ARM_MMU_Init((p_uint32_t) ARM_MMUTableSetUp());
//---------------------------------------------------
void ARM_MMUInit(p_uint32_t TableAddress)
{
ARM_TLBFlush();
ARM_CacheFlush();
ARM_SetDomainAccessControl(DOMAIN_ACCESS);
ARM_SetPageTableBase(TableAddress);
}
//---------------------------------------------------
// enable the MMU. Use this function to enable MMU
// once the MMU has been initialized.
//---------------------------------------------------
void ARM_MMUEnable(void)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2, #0x00000001
orr r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
//---------------------------------------------------
// disable the MMU
//---------------------------------------------------
// mov r2, #0xFFFFFFFE
void ARM_MMUDisable(void)
{
__asm {
mrc p15,0,r0,c1,c0,0
mvn r2, #~0xFFFFFFFE
and r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
//---------------------------------------------------
// Read the device ID or cache type.
// default selection is device ID.
// use ARM_IDCODES_CACHETYPE as the
// parameter if cache type is to
// be read.
//---------------------------------------------------
uint32_t
ARM_DeviceIDRead(uint32_t type)
{
uint32_t _retVal = 0;
// check if request is for cache type register
if (CPU_IDCODES_CACHETYPE == type)
{
__asm
{
mrc P15, 0, _retVal, c0, c0, 0x1
}
}
else
{
__asm
{
mrc P15, 0, _retVal, c0, c0, 0x0
}
}
return _retVal;
}
//---------------------------------------------------
// set the base address for the page tables.
// is also called by ARM_MMUInit(...) function
//---------------------------------------------------
void
ARM_SetPageTableBase(p_uint32_t TableAddress)
{
__asm
{
mcr P15, 0, TableAddress, c2, c0, 0
}
}
//---------------------------------------------------
// Set domain access control bits, CP15, register 3
// is also called by ARM_MMUInit(...) function
//---------------------------------------------------
void
ARM_SetDomainAccessControl(uint32_t flags)
{
__asm
{
mcr P15, 0, flags, c3, c0, 0
}
}
//---------------------------------------------------
// Flush the TLB, required before enabling
// the MMU
// is also called by ARM_MMUInit(...) function
//---------------------------------------------------
void
ARM_TLBFlush(void)
{
unsigned long dummy;
__asm { MCR P15, 0, dummy, c8, c7, 0; }
}
//---------------------------------------------------
// flush the instruction cache, required before
// enabling the MMU
//---------------------------------------------------
void
ARM_ICacheFlush()
{
unsigned long dummy;
__asm
{
MCR p15, 0, dummy, c7, c5, 0
}
}
//---------------------------------------------------
// flush the data cache, required before
// enabling the MMU
//---------------------------------------------------
void
ARM_DCacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c6, 0; }
}
//---------------------------------------------------
// flush the instruction and data cache, required before
// enabling the MMU
//---------------------------------------------------
void
ARM_CacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c7, 0; }
}
//---------------------------------------------------------------
// This function is used enable Instruction, and/or Data Cache
// Cache Type is:
// { CACHE_INST, CACHE_DATA, CACHE_INST_DATA, CACHE_LEVEL2 }
// Level 2 cache is not available or supported on MX21
//---------------------------------------------------------------
void
ARM_EnableCache(cache_type cachetypes)
{
switch(cachetypes)
{
case CACHE_INST:
ARM_ICacheEnable();
break;
case CACHE_DATA:
case CACHE_INST_DATA:
ARM_IDCacheEnable();
break;
// Can D Cache be enabled independent
// of I cache ?
// Level 2 cache is not supported
// on MX21.
case CACHE_LEVEL2:
default:
// How do you send an error code
break;
}
return;
}
//---------------------------------------------------------------
// This function is used disable Instruction, and/or Data Cache
// Cache Type is:
// { CACHE_INST, CACHE_DATA, CACHE_INST_DATA, CACHE_LEVEL2 }
// Level 2 cache is not available or supported on MX21
//---------------------------------------------------------------
void
ARM_DisableCache(cache_type cachetypes)
{
switch(cachetypes)
{
case CACHE_INST:
ARM_ICacheDisable();
break;
case CACHE_DATA:
ARM_DCacheDisable();
break;
case CACHE_INST_DATA:
ARM_IDCacheDisable();
break;
// Level 2 cache is not supported
// on MX21.
case CACHE_LEVEL2:
default:
// How do you send an error code
break;
}
return;
}
//---------------------------------------------------
// enable the instruction cache
//---------------------------------------------------
void
ARM_ICacheEnable(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
mov r0, #0x00001000 /* bit[12]=1 */
mcr p15,0,r0,c1,c0,0
}
}
//---------------------------------------------------
// enable the data cache
// MMU must be enabled for the
// D cache to work properly
//---------------------------------------------------
void
ARM_DCacheEnable(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
mov r2, #0x00000004
orr r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
//---------------------------------------------------
// enable the instruction & data cache's
//---------------------------------------------------
/* bit[12], bit[2], bit[3]=0b1 */
void
ARM_IDCacheEnable(void)
{
ARM_ICacheEnable();
ARM_DCacheEnable();
}
//---------------------------------------------------
// disable the instruction cache
//---------------------------------------------------
void
ARM_ICacheDisable(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
mvn r2, #~0xFFFFEFFF /* bit[12]=0b0 */
and r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
//---------------------------------------------------
// disable the data cache
//---------------------------------------------------
void
ARM_DCacheDisable(void)
{
__asm
{
// test, clean and invalidate the D Cache
_tci_loop:MRC p15,0,r15,c7,c14,3
BNE _tci_loop
// drain the write buffer
mov r0, #0
mcr p15, 0, r0, c7, c10, 4
// flush the data TLB
mcr p15, 0, r1, c8, c6, 0
// disable the D cache
mrc p15,0,r0,c1,c0,0
mvn r2, #~0xFFFFFFFB /* bit[2]=0b0 */
and r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
//---------------------------------------------------
// disable the instruction and data caches
//---------------------------------------------------
void
ARM_IDCacheDisable(void)
{
__asm
{
// just call the independent I and D cache routines
mrc p15,0,r0,c1,c0,0
mov r0, #0x00000000
mcr p15,0,r0,c1,c0,0
}
}
//---------------------------------------------------
// Set the CPU mode to USR
//---------------------------------------------------
void
ARM_SetCpuUserMode(void) {
ARM_SetCpuMode(CPU_MODE_USR);
}
//---------------------------------------------------
// Set the CPU mode to FIQ
//---------------------------------------------------
void
ARM_SetCpuFiqMode(void) {
ARM_SetCpuMode(CPU_MODE_FIQ);
}
//---------------------------------------------------
// Set the CPU mode to IRQ
//---------------------------------------------------
void
ARM_SetCpuIrqMode(void) {
ARM_SetCpuMode(CPU_MODE_IRQ);
}
//---------------------------------------------------
// Set the CPU mode to Supervisor
//---------------------------------------------------
void
ARM_SetCpuSupervisorMode() {
ARM_SetCpuMode(CPU_MODE_SUP);
}
//---------------------------------------------------
// Set the CPU mode to Abort
//---------------------------------------------------
void
ARM_SetCpuAbortMode() {
ARM_SetCpuMode(CPU_MODE_ABT);
}
//---------------------------------------------------
// Set the CPU mode to Undefined
//---------------------------------------------------
void
ARM_SetCpuUndefinedMode() {
ARM_SetCpuMode(CPU_MODE_UND);
}
//---------------------------------------------------
// Set the CPU mode to System
//---------------------------------------------------
void
ARM_SetCpuSystemMode() {
ARM_SetCpuMode(CPU_MODE_SYS);
}
//---------------------------------------------------
// establish the CPU privelege mode
//---------------------------------------------------
void
ARM_SetCpuPrivMode(uint32_t bPriveleged)
{
if(1==bPriveleged)
{
// Set PPRM to 0x40000015 (Priveleged Mode)
__asm
{
mov r0, #0x40000000
orr r0, r0, #0x15
mcr p15, 0x0, r0, c15, c2, 0x4
}
}
else
{
// Set PPRM to 0x00000000 (Non-Priveleged Mode)
__asm
{
mov r0, #0x00000000
mcr p15, 0x0, r0, c15, c2, 0x4
}
}
}
//---------------------------------------------------
// set CPU mode.
//---------------------------------------------------
void
ARM_SetCpuMode(unsigned long FullCode)
{
__asm
{
mrs r0, CPSR // Move CPSR to r0
bic r0, r0, #CPU_MODE_MASK // Clear Mode Bits
orr r0, r0, FullCode // Set Mode Bits
msr CPSR_c, r0 // Store r0 in CPSR
}
}
//---------------------------------------------------
// enable IRQ. CPSR I bit enables IRQ interrupts
// when cleared to 0
//---------------------------------------------------
void
ARM_EnableIRQ (void)
{
__asm
{
MRS r1, CPSR
BIC r1, r1, #CPU_IRQ_DIS_BIT
MSR CPSR_c, r1
}
}
//---------------------------------------------------
// disable IRQ. CPSR I bit disables IRQ interrupts
// when set to 1, enables when cleared to 0
//---------------------------------------------------
void
ARM_DisableIRQ (void)
{
__asm
{
MRS r1, CPSR
ORR r1, r1, #CPU_IRQ_DIS_BIT
MSR CPSR_c, r1
}
}
//---------------------------------------------------
// enable FIQ. CPSR F bit enables FIQ interrupts
// when cleared to 0
//---------------------------------------------------
void
ARM_EnableFIQ (void)
{
__asm
{
MRS r1, CPSR
BIC r1, r1, #CPU_FIQ_DIS_BIT
MSR CPSR_c, r1
}
}
//---------------------------------------------------
// disable FIQ. CPSR F bit disables IRQ interrupts
// when set to 1, enables when cleared to 0
//---------------------------------------------------
void
ARM_DisableFIQ (void)
{
__asm
{
MRS r1, CPSR
ORR r1, r1, #CPU_FIQ_DIS_BIT
MSR CPSR_c, r1
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -