📄 mmu.s.svn-base
字号:
;/***************************************************************************; Copyright ARM Limited 1998 - 2002. 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 2005/05/26 15:51:47 sp_head Exp $; ; $Log: mmu.s,v $; Revision 1.1 2005/05/26 15:51:47 sp_head; user NI;; Revision 1.1.1.2 2004/12/03 15:34:24 spear; First import from CRD;; Revision 1.1.1.1 2004/12/02 11:07:22 spear; First import from CRD;; ; Revision: 1.1 Mon Sep 13 21:32:55 2004 gazzina; freeze pre-AFE; ; Revision: 1.4 Tue Nov 11 11:53:56 2003 gazzina; lettura della dtcm size (per il debug) itcm support added; ; Revision: 1.3 Thu Jul 3 12:38:53 2003 lert; Modify MPU settings Modified 'uHALMPU_SETUP' to program 8 Regions; ; Revision: 1.2 Tue Feb 4 10:10:13 2003 lert; Lert....try to add support for ARM946 MPU ! Add some controls for TCM Handlers; ;****************************************************************************/ GET retmacro.s ; Thumb/ARM interworking INCLUDE mmu946T.s INCLUDE arm.equ INCLUDE MPU_TABLE.equ 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 ; EXPORT uHALMPU_SETUP ; EXPORT uHALDTCM_SETUP ; EXPORT uHALITCM_PHY_SZ ; EXPORT uHALITCM_SET_SIZE ; EXPORT uHALITCM_INIT ; EXPORT uHALITCM_ENABLE ; EXPORT uHALITCM_DISABLE ; ; Enter Supervisor mode & disable IRQ. IMPORT uHALir_EnterLockedSvcMode IMPORT uHALir_ExitSvcMode ; Exit Supervisor mode. KEEP AREA uHAL_MMU, CODE, READONLY;-------------------------------------------------------------------; Shell routines around MMU/cache query macrosuHALir_MMUSupported CHECK_FOR_MMU_946T r0 RETURN lruHALir_MPUSupported CHECK_FOR_MPU_946T r0 RETURN lruHALir_CacheSupported CHECK_CACHE_946T r0 RETURN lruHALir_CheckUnifiedCache CHECK_UNIFIED_946T r0 RETURN lruHALir_BranchPredSupported NO_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_946T r1 BL uHALir_ExitSvcMode ; Switch out of SVC mode, r0 -> spsr LDMFD sp!,{r0,r1} ; ; 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 NO_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_946T 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_946T 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 -> spsr LDMFD sp!,{r0,r1}42 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_946T 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_946T 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 WRMMU_STATE_946T 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 -> spsr LDMFD sp!,{r0,r1}43 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_946T r0 BEQ %F44 ; Switch into SVC returns SPSR in r0 BL uHALir_EnterLockedSvcMode MOV r4, #0 WRCACHE_FlushIC_946T r4 ; Flush ICache RDMMU_STATE_946T r4 CLEAR_ICACHE_946T r4 WRMMU_STATE_946T 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 -> spsr LDMFD sp!,{r0,r1}44 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_946T 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_946T r4 ; Flush DCache RDMMU_STATE_946T r4 CLEAR_DCACHE_946T r4 WRMMU_STATE_946T 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 -> spsr LDMFD sp!,{r0,r1}45 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_946T 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_946T r4 ; Flush DCache RDMMU_STATE_946T r4 CLEAR_DCACHE_946T r4 NO_CLEAR_WBUFFER r4 WRMMU_STATE_946T 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 -> spsr LDMFD sp!,{r0,r1}46 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_946T r0 POP_RETURN r0-r1;-------------------------------------------------------------------; void uHALir_CleanDCache(void) ;; Routine to clean D cacheuHALir_CleanDCache STMFD sp!,{r0-r5, lr} ; Save registers WRCACHE_CleanDCache_946T 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_946T r0, r1, r2, r3, r4, r5 MOV r4, #0 WRCACHE_FlushDC_946T r4 ; Flush DCache WRCACHE_FlushIC_946T r4 ; Flush ICache POP_RETURN r0-r5;-------------------------------------------------------------------; void uHALMPU_SETUP(void); ; Enable MPU UnituHALMPU_SETUP STMFD sp!,{r0, r4-r5, lr} ; Save registers ; Switch into SVC returns SPSR in r0 BL uHALir_EnterLockedSvcMode ; Set-Up Regionn ; Warning: DONT USE R0 AS WORKING REGISTER !!! LDR r4, =CP15_c6_REGION0 WRMPU_Region_946T 0, r4 LDR r4, =CP15_c6_REGION1 WRMPU_Region_946T 1, r4 LDR r4, =CP15_c6_REGION2 WRMPU_Region_946T 2, r4 LDR r4, =CP15_c6_REGION3 WRMPU_Region_946T 3, r4 LDR r4, =CP15_c6_REGION4 WRMPU_Region_946T 4, r4 LDR r4, =CP15_c6_REGION5 WRMPU_Region_946T 5, r4 LDR r4, =CP15_c6_REGION6 WRMPU_Region_946T 6, r4 LDR r4, =CP15_c6_REGION7 WRMPU_Region_946T 7, r4 ; Access Permission for Micro Accesses LDR r4, =CP15_c5_ACCESS_PERMISSION WRMPU_AccessBits_946T r4 ;Now Cachable Regions... LDR r4, =CP15_c2_CACHE_CONFIGURATION_REGISTER WRMPU_CacheBits_946T r4 ; Switch back to the mode we started BL uHALir_ExitSvcMode LDMFD sp!,{r0,r1} POP_RETURN_EXTEND r0, r4-r5;-------------------------------------------------------------------; void uHALDTCM_SETUP(void)uHALDTCM_SETUP STMFD sp!,{r0, r4-r5, lr} ; Save registers ; Switch into SVC returns SPSR in r0 BL uHALir_EnterLockedSvcMode ; Set-Up Region Register ; Preserve Misterius SBZ Bit... RD_DTCM_REGION_REGISTER r4 AND r4,r4,#0x00000001 LDR r5, =CP9_DTCM_MAPPING ORR r4,r4,r5 WR_DTCM_REGION_REGISTER r4 ; Turn-On DTCM Load Mode SET_DTCM_LOAD_MODE r4 ; Turn-Off DTCM Load Mode RESET_DTCM_LOAD_MODE r4 ; Enable DTCM ! ENABLE_DTCM r4 ; Read the DTCM size (debug!!!) MRC p15, 0, r4, c0, c0, 2 ; Switch back to the mode we started BL uHALir_ExitSvcMode LDMFD sp!,{r0,r1} POP_RETURN_EXTEND r0, r4-r5;-------------------------------------------------------------------; void uHALITCM_PHY_SZ(unsigned int *) : restituisce il valore della; dimensione fisica delle ITCMuHALITCM_PHY_SZ STMFD sp!, {r5, r6, lr} ; Save registers MOV r6, r0 ; save the new mode ; Switch into SVC returns SPSR in r0 BL uHALir_EnterLockedSvcMode GET_ITCM_PHY_SZ r5 ; Switch back to the mode we started BL uHALir_ExitSvcMode LDMFD sp!,{r0,r1} STR r5, [r6] POP_RETURN_EXTEND r5, r6 ;-------------------------------------------------------------------; void uHALITCM_SET_SIZE(unsigned int); Funzione che determina la dimensione dell'area di memoria; coperta dalle itcm. NB: l'indirizzo di partenza e' sempre 0x00000000uHALITCM_SET_SIZE STMFD sp!, {r4-r5, lr} ; Save registers MOV r5, r0, LSL #1 ; save the new mode : R0 left shifted by 1 ; Switch into SVC returns SPSR in r0 BL uHALir_EnterLockedSvcMode ; Set-Up Region Register ; Preserve Misterius SBZ Bit... RD_ITCM_REGION_REGISTER r4 AND r4,r4,#0x00000001 ;; devo shiftare a sinistra di 1 bit R5 ORR r4,r4,r5 WR_ITCM_REGION_REGISTER r4 ; Switch back to the mode we started BL uHALir_ExitSvcMode LDMFD sp!,{r0,r1} POP_RETURN r4-r5 ;---------------------------------------------------------------------; uHALITCM_INIT(unsigned int) : abilitazione del load mode e inizializzazione; della itcm. NB: esco con le ITCM disabilitate; La funzione riceve in ingresso un parametro che si trova in r0:; questo parametro e' la dimensione della ITCM e viene copiato in R5; e poi in R1 (R1 potrebbe sporcarsi nel passaggio a SVmode) uHALITCM_INIT STMFD sp!,{r1-r10, lr} ; Save registers MOV r5, r0 ; save the new mode ;; non metto subito r0 in r1 perche' poi r1 si sporca entrando in SVmode BL uHALir_EnterLockedSvcMode MOV R1, R5 MOV R10, #0 ; sporco R0 ma tanto il suo contenuto non mi serve piu'! SET_ITCM_LOAD_MODE R2 ENABLE_ITCM R2CopyLoop LDMIA R10, {R2 - R9} ; Load 8 registers from main memory STMIA R10!, {R2 - R9} ; Store 8 regs into ITCM (NB:load mode is enable!) CMP R1, R10 BGT CopyLoop DISABLE_ITCM R2 RESET_ITCM_LOAD_MODE R2 ; Switch back to the mode we started BL uHALir_ExitSvcMode LDMFD sp!,{r0,r1} POP_RETURN r1-r10 ;---------------------------------------------------------------------; uHALITCM_ENABLE(void) : Abilitazione delle ITCMuHALITCM_ENABLE STMFD sp!,{r0, r4, lr} ; Save registers ; Switch into SVC returns SPSR in r0 BL uHALir_EnterLockedSvcMode ENABLE_ITCM R4 ; Switch back to the mode we started BL uHALir_ExitSvcMode LDMFD sp!,{r0,r1} POP_RETURN_EXTEND r0, r4 ;---------------------------------------------------------------------; uHALITCM_DISABLE(void) : Disabilitazione delle ITCMuHALITCM_DISABLE STMFD sp!,{r0, r4, lr} ; Save registers ; Switch into SVC returns SPSR in r0 BL uHALir_EnterLockedSvcMode DISABLE_DTCM R4 ; Switch back to the mode we started BL uHALir_ExitSvcMode LDMFD sp!,{r0,r1} POP_RETURN_EXTEND r0, r4 END ; end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -