⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmu.s

📁 FIC8120方案的 StartCell_Driver
💻 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 2006/04/18 07:34:53 ivan 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 map

uHALr_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
	NOP
27
	; 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
	
	ENDIF
40
	; 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 -> spsr

41
	POP_RETURN_EXTEND	r0, r4-r6


;-------------------------------------------------------------------
; Shell routines around MMU/cache query macros

uHALir_MMUSupported
	CHECK_FOR_MMU	r0
	RETURN	lr


uHALir_MPUSupported
	CHECK_FOR_MPU	r0
	RETURN	lr


uHALir_CacheSupported
	CHECK_CACHE	r0
	RETURN	lr


uHALir_CheckUnifiedCache
	CHECK_UNIFIED	r0
	RETURN	lr


uHALir_BranchPredSupported
	CHECK_FOR_BRANCH_PRED	r0
	RETURN	lr


;-------------------------------------------------------------------
; unsigned int uHALir_ReadCacheMode(void)
;
; Routine to read the mmu state from the Co-processor

uHALir_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 r0

uHALir_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 -> spsr
42
	POP_RETURN_EXTEND	r0, r4-r6


;-------------------------------------------------------------------
; void uHALir_WriteCacheMode(unsigned int)
;
; Routine to write the mmu state to the Co-processor

uHALir_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 -> spsr

43
	POP_RETURN_EXTEND	r0, r4-r6


;-------------------------------------------------------------------
; void uHALir_DisableICache(void)
;
; Routine to flush and disable the I Cache

uHALir_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 -> spsr

44
	POP_RETURN_EXTEND	r0, r4-r5


;-------------------------------------------------------------------
; void uHALir_DisableDCache(void)
;
; Routine to flush and disable the D Cache

uHALir_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 -> spsr
45
	POP_RETURN_EXTEND	r0, r4-r5


;-------------------------------------------------------------------
; void uHALir_DisableWriteBuffer(void)
;
; Routine to disable the Write Buffer

uHALir_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 -> spsr

46
	POP_RETURN_EXTEND	r0, r4-r5


;-------------------------------------------------------------------
;void uHALir_CleanDCacheEntry (void *)
;
; Routine to clean (at least) one Data Cache entry

uHALir_CleanDCacheEntry
 	STMFD	sp!,{r0-r1, lr}	; Save registers

	WRCACHE_CleanDCentry	r0

	POP_RETURN	r0-r1


;-------------------------------------------------------------------
; void uHALir_CleanDCache(void) 
;
; Routine to clean D cache

uHALir_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 caches

uHALir_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 + -