📄 mmu.s
字号:
;/***************************************************************************; Copyright ARM Limited 1998 - 2000. All rights reserved.;****************************************************************************;; Memory Management and Cache Initialisation Routines for the ARM. All ; access to the Co-processor must be in supervisor mode and these routines ; handle all these issues internally.;; $Id: mmu.s,v 1.1.1.1 2002/12/06 05:23:02 bruce Exp $;;****************************************************************************/ ;INCLUDE bits.s INCLUDE sizes.s ;INCLUDE platform.s INCLUDE mmumacro.s GET retmacro.s ; Thumb/ARM interworking INCLUDE t_mmu.s IMPORT Level1tab IMPORT Level2tab_ROM IMPORT MPUMaptab EXPORT uHALr_InitMMU ; Setup page tables, MMU etc. EXPORT uHALr_ResetMMU ; Reset Memory to initial state, no MMU EXPORT uHALir_MMUSupported EXPORT uHALir_MPUSupported EXPORT uHALir_CacheSupported EXPORT uHALir_CheckUnifiedCache EXPORT uHALir_BranchPredSupported EXPORT uHALir_WriteBranchPredictionMode EXPORT uHALir_WriteCacheMode EXPORT uHALir_ReadCacheMode EXPORT uHALir_DisableICache EXPORT uHALir_DisableDCache EXPORT uHALir_DisableWriteBuffer EXPORT uHALir_CleanCache EXPORT uHALir_CleanDCache EXPORT uHALir_CleanDCacheEntry ; Enter Supervisor mode & disable IRQ. ;IMPORT uHALir_EnterLockedSvcMode ;IMPORT uHALir_ExitSvcMode ; Exit Supervisor mode. IMPORT uHAL_AddressTable IMPORT uHAL_MappingTable KEEP AREA uHAL_MMU, CODE, READONLY;-------------------------------------------------------------------; Routine to initialise the page tables & MMU to memmap layout.;; See SETUPMMU macro for description; WARNING: The MMU must be disabled when this routine is called,; but routine checks MMU, will do nothing if enabled.;; void uHALir_InitMMU(void) - Init MMU to flat-memory mapuHALr_InitMMU STMFD sp!,{r0-r2, r4-r9, lr} ; Save registers MOV r9, r0 ; Save the mode ; Switch into SVC returns CPSR in r0 ;BL uHALir_EnterLockedSvcMode ; If the MMU is already on, do nothing.. TEST_MMU r1 BEQ %F27 MOV r5, #0 SETUPMMU r4, r5, r6, r7, r8, r1, r2 ; Enable MMU, and any caching required. ; ; This code must maintain the state of all other bits in the ; control register that apart from cache, write buffer & MMU ; enable bits MOV r1, #(EnableMMU :OR: EnableDcache :OR: EnableWB) ORR r1, r1, #EnableIcache ; Create mask of the bits we can touch AND r9, r9, r1 ; Clear all other bits from the mask supplied RDMMU_STATE r2 ; Read current state of control register BIC r2, r2, r1 ; Clear the bits that we may change ORR r9, r9, r2 ; Merge in the supplied mask WRMMU_STATE r9 ; Write this to the control register ; Make sure the pipeline is clear of any cached entries NOP NOP NOP27 ; Switch back to the mode we started in (restores interrupts, if any) ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> cpsr POP_RETURN_EXTEND r0-r2, r4-r9;-------------------------------------------------------------------; void uHALr_ResetMMU(void) - Function to reset the MMU.;; Flushes the Icache, cleans & flushes the Dcache, disables IC, DC, WB and; MMU returning the memory system to its powerup state (flat map allows this);; Never call ResetMMU without having called InitMMU first.;; When running semihosted, care should be exercised to leave the debugger; in a state similar to that when starting our application.uHALr_ResetMMU STMFD sp!, {r0, r4-r6, lr} ; Save registers IF :DEF: DUMMY ; Has this CPU an MPU? CHECK_FOR_MPU r0 BNE %F40 ; Make sure this CPU has an MMU CHECK_FOR_MMU r0 BEQ %F41 ; If the current memory map is not 1-1 at 0, do NOT reset MMU MOV r0, #0 TEST_121MAP r0, r4, r5 BNE %F41 ENDIF40 ; Switch into SVC returns SPSR in r0 ;BL uHALir_EnterLockedSvcMode ; Do we need to clean the Dcache? ;TEST_MMU r4 ;BLEQ uHALir_CleanDCache WRMMU_FlushTB r4 ; Flush ITB's and DTB's WRCACHE_FlushIDC r4 ; Flush the ICache and DCache ; Reset MMU control register RDMMU_STATE r4 CLEAR_IDC r4 CLEAR_MMU r4 WRMMU_STATE r4 ; Make sure the pipeline is clear of any cached entries NOP NOP NOP ; Switch back to the mode we started in (restores interrupts, if any) ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr41 POP_RETURN_EXTEND r0, r4-r6;-------------------------------------------------------------------; Shell routines around MMU/cache query macrosuHALir_MMUSupported CHECK_FOR_MMU r0 RETURN lruHALir_MPUSupported CHECK_FOR_MPU r0 RETURN lruHALir_CacheSupported CHECK_CACHE r0 RETURN lruHALir_CheckUnifiedCache CHECK_UNIFIED r0 RETURN lruHALir_BranchPredSupported CHECK_FOR_BRANCH_PRED r0 RETURN lr;-------------------------------------------------------------------; unsigned int uHALir_ReadCacheMode(void);; Routine to read the mmu state from the Co-processoruHALir_ReadCacheMode STMFD sp!, {r1, lr} ;BL uHALir_EnterLockedSvcMode RDMMU_STATE r1 ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr ; ; We need to clear all bits apart from cache, write buffer & MMU ; enable bits ; MOV r0, #(EnableMMU :OR: EnableDcache :OR: EnableWB) ORR r0, r0, #EnableIcache AND r0, r0, r1 POP_RETURN r1;-------------------------------------------------------------------; void uHALir_WriteBranchPredictionMode(unsigned int);; Sets the branch prediction mode to the value passed in r0uHALir_WriteBranchPredictionMode STMFD sp!, {r0, r4-r6, lr} ; Save registers MOV r5, r0 ; save the new mode CHECK_FOR_BRANCH_PRED r0 BEQ %F42 ; Switch into SVC returns SPSR in r0 ;BL uHALir_EnterLockedSvcMode AND r5, r5, #BranchPrediction ; Clear all other bits from mask RDMMU_STATE r4 ; Read current state of control register BIC r4, r4, #BranchPrediction ; Clear bits that we may change ORR r5, r5, r4 ; Merge in the supplied mask WRMMU_STATE r5 ; Write this to the control register ; Switch back to the mode we started in (restores interrupts, if any) ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr42 POP_RETURN_EXTEND r0, r4-r6;-------------------------------------------------------------------; void uHALir_WriteCacheMode(unsigned int);; Routine to write the mmu state to the Co-processoruHALir_WriteCacheMode STMFD sp!, {r0, r4-r6, lr} ; Save registers MOV r6, r0 ; save the new mode CHECK_CACHE r0 BEQ %F43 ; Switch into SVC returns SPSR in r0 ;BL uHALir_EnterLockedSvcMode ; This code must maintain the state of all other bits in the ; control register that apart from cache, write buffer & MMU ; enable bits MOV r5, #(EnableMMU :OR: EnableDcache :OR: EnableWB) ORR r5, r5, #EnableIcache ; Create mask of the bits we can touch AND r6, r6, r5 ; Clear all other bits from the mask RDMMU_STATE r4 ; Read current state of control register BIC r4, r4, r5 ; Clear the bits that we may change ORR r6, r6, r4 ; Merge in the supplied mask ORR r6, r6, #0xC0000000 ; Async mode issue WRMMU_STATE r6 ; Write this to the control register ; Make sure the pipeline is clear of any cached entries NOP NOP NOP ; Switch back to the mode we started in (restores interrupts, if any) ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr43 POP_RETURN_EXTEND r0, r4-r6;-------------------------------------------------------------------; void uHALir_DisableICache(void);; Routine to flush and disable the I CacheuHALir_DisableICache STMFD sp!,{r0, r4-r5, lr} ; Save registers CHECK_CACHE r0 BEQ %F44 ; Switch into SVC returns SPSR in r0 ;BL uHALir_EnterLockedSvcMode MOV r4, #0 WRCACHE_FlushIC r4 ; Flush ICache RDMMU_STATE r4 CLEAR_ICACHE r4 WRMMU_STATE r4 ; Update current state ; Make sure the pipeline is clear of any cached entries NOP NOP NOP ; Switch back to the mode we started in (restores interrupts, if any) ; uHALir_ExitSvcMode(spsr); ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr44 POP_RETURN_EXTEND r0, r4-r5;-------------------------------------------------------------------; void uHALir_DisableDCache(void);; Routine to flush and disable the D CacheuHALir_DisableDCache STMFD sp!,{r0, r4-r5, lr} ; Save registers CHECK_CACHE r0 BEQ %F45 ; Switch into SVC returns SPSR in r0 ;BL uHALir_EnterLockedSvcMode ; Clean the Dcache before flush BL uHALir_CleanDCache MOV r4, #0 WRCACHE_FlushDC r4 ; Flush DCache RDMMU_STATE r4 CLEAR_DCACHE r4 WRMMU_STATE r4 ; Update current state ; Make sure the pipeline is clear of any cached entries NOP NOP NOP ; Switch back to the mode we started in (restores interrupts, if any) ; uHALir_ExitSvcMode(spsr); ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr45 POP_RETURN_EXTEND r0, r4-r5;-------------------------------------------------------------------; void uHALir_DisableWriteBuffer(void);; Routine to disable the Write BufferuHALir_DisableWriteBuffer STMFD sp!,{r0, r4-r5, lr} ; Save registers CHECK_CACHE r0 BEQ %F46 ; Switch into SVC returns SPSR in r0 ;BL uHALir_EnterLockedSvcMode ; Clean the Dcache before flush BL uHALir_CleanDCache MOV r4, #0 WRCACHE_FlushDC r4 ; Flush DCache RDMMU_STATE r4 CLEAR_DCACHE r4 CLEAR_WBUFFER r4 WRMMU_STATE r4 ; Update current state ; Make sure the pipeline is clear of any cached entries NOP NOP NOP ; Switch back to the mode we started in (restores interrupts, if any) ; uHALir_ExitSvcMode(spsr); ;BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr46 POP_RETURN_EXTEND r0, r4-r5;-------------------------------------------------------------------;void uHALir_CleanDCacheEntry (void *);; Routine to clean (at least) one Data Cache entryuHALir_CleanDCacheEntry STMFD sp!,{r0-r1, lr} ; Save registers WRCACHE_CleanDCentry r0 POP_RETURN r0-r1;-------------------------------------------------------------------; void uHALir_CleanDCache(void) ;; Routine to clean D cacheuHALir_CleanDCache STMFD sp!,{r0-r5, lr} ; Save registers WRCACHE_CleanDCache r0, r1, r2, r3, r4, r5 POP_RETURN r0-r5;-------------------------------------------------------------------; void uHALir_CleanCache(void) ;; Routine to clean Instruction and Data cachesuHALir_CleanCache STMFD sp!,{r0-r5, lr} ; Save registers WRCACHE_CleanDCache r0, r1, r2, r3, r4, r5 MOV r4, #0 WRCACHE_FlushDC r4 ; Flush DCache WRCACHE_FlushIC r4 ; Flush ICache POP_RETURN r0-r5 END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -