📄 tahiti_init_caches_enabled.s
字号:
;/* tahiti_init_caches_enabled.s */
;;; Copyright ARM Ltd 2000. All rights reserved.
;
; This module performs ROM/RAM remapping (if required), initializes stack pointers and
; interrupts for each mode, and finally branches to __main in the C library (which
; eventually calls main()).
;
; On reset, the ARM core starts up in Supervisor (SVC) mode, in ARM state, with IRQ and FIQ disabled.
AREA Init, CODE, READONLY
; --- Standard definitions of mode bits and interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UNDEF EQU 0x1B
Mode_SYS EQU 0x1F ; available on ARM Arch 4 and later
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
; --- System memory locations
RAM_Limit EQU 0xC0010000 ; For Tahiti
;RAM_Limit EQU 0x08010000 ; For DBMX1 ADS
SVC_Stack EQU RAM_Limit ; 4096 byte SVC stack at top of memory
USR_Stack EQU SVC_Stack-4096 ; followed by IRQ stack
IRQ_Stack EQU USR_Stack-4096 ; followed by SVC stack
FIQ_Stack EQU IRQ_Stack-4096 ; followed by USR stack
ROM_Start EQU 0x00000000 ; Base address of ROM after remapping
Instruct_2 EQU ROM_Start + 4 ; Address of second instruction in ROM
;CM_ctl_reg EQU 0x1000000C ; Address of Core Module Control Register
;Remap_bit EQU 0x04 ; Bit 2 is remap bit of CM_ctl
ENTRY
;MX1 EQU 0x1
;; --- Perform ROM/RAM remapping, if required
; IF :DEF: ROM_RAM_REMAP
;
;; On reset, an aliased copy of ROM is at 0x0.
;; Continue execution from 'real' ROM rather than aliased copy
; LDR pc, =Instruct_2
;
;; Remap by setting Remap bit of the CM_ctl register
; LDR r1, =CM_ctl_reg
; LDR r0, [r1]
; ORR r0, r0, #Remap_bit
; STR r0, [r1]
;
;; RAM is now at 0x0.
;; The exception vectors (in vectors.s) must be copied from ROM to the RAM
;; The copying is done later by the C library code inside __main
;
; ENDIF
EXPORT Reset_Handler
Reset_Handler
bl MMU_Setup
bl PrvFlushCacheAndTLB_AND_DisableCaches
;; enable I/D caches and MMU
MRC p15,0,r1,c1,c0,0
LDR r2, =(0x00001005)
orr r1,r2,r1
MCR p15,0,r1,c1,c0,0
; --- Initialise stack pointer registers
; Enter SVC mode and set up the SVC stack pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
LDR SP, =SVC_Stack
; Enter IRQ mode and set up the IRQ stack pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
LDR SP, =IRQ_Stack
; Enter FIQ mode and set up the FIQ stack pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; No interrupts
LDR SP, =FIQ_Stack
; Set up other stack pointers if necessary
; ...
; --- Initialise memory system
; ...
; --- Initialise critical IO devices
; ...
; --- Initialise interrupt system variables here
; ...
; --- Now change to User mode and set up User mode stack.
; MSR CPSR_c, #Mode_USR:OR:I_Bit:OR:F_Bit ; No interrupts
; LDR SP, =USR_Stack
; Finally, Re-Enter SVC mode
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
LDR SP, =SVC_Stack
IMPORT __main
; --- Now enter the C code
B __main ; note use B not BL, because an application will never return this way
LTORG ;// place LTORG here, before the MMU translation table, but after all other LDR commands
GBLA XCount
MMUTranslationTable
IF :DEF: MX1
;// DBMX1 translation table
XCount SETA (0x0000007E)
DCD XCount
XCount SETA (0x0010007E)
DCD XCount
XCount SETA (0x00200072)
DCD XCount
;XCount SETA (0x00300072) ; Use 0x72 for non-cacheable, non-bufferable
XCount SETA (0x0030007A) ; Use 0x7A for cacheable only
;XCount SETA (0x0030007E) ; Use 0x7E for both cacheable and bufferable.
WHILE XCount < (0x10000000)
DCD XCount
XCount SETA (XCount + 0x00100000)
WEND
XCount SETA (0x1000007A) ; Use 0x7A for cacheable only
WHILE XCount < (0xFFF00000)
DCD XCount
XCount SETA (XCount + 0x00100000)
WEND
;// 0xFFF00000 to end of memory map
XCount SETA (0xFFF0007E) ; Use 0x7E for both cacheable and bufferable.
DCD XCount
ELSE
;// DBMX21 translation table
;// 0x0 to 0x0FFFFFFF
XCount SETA (0x0000007E) ; Use 0x7E for both cacheable and bufferable.
WHILE XCount < (0x10000000)
DCD XCount
XCount SETA (XCount + 0x00100000)
WEND
;// 0x10000000 to 0xBFFFFFFF
XCount SETA (0x10000072) ; Use 0x72 for non-cacheable, non-bufferable
WHILE XCount < (0xC0000000)
DCD XCount
XCount SETA (XCount + 0x00100000)
WEND
;// 0xC0000000 to 0xDFFFFFFF
XCount SETA (0xC000007E) ; Use 0x7E for both cacheable and bufferable.
WHILE XCount < (0xE0000000)
DCD XCount
XCount SETA (XCount + 0x00100000)
WEND
;// 0xE0000000 to 0xFFEFFFFF
XCount SETA (0xE000007E) ; Use 0x7E for both cacheable and bufferable.
WHILE XCount < (0xFFF00000)
DCD XCount
XCount SETA (XCount + 0x00100000)
WEND
;// 0xFFF00000 to end of memory map
XCount SETA (0xFFF0007E) ; Use 0x7E for both cacheable and bufferable.
DCD XCount
ENDIF
EndOfTables
MMU_Setup
LDR r0, =0x4000 ; target address = 0x4000
IF :DEF: MX1
;// i.MX1 SDRAM location
add r0, r0, #0x0B000000; Physical target address, fourth bank of SDRAM
ELSE
;// i.MX21 SDRAM location
add r0, r0, #0xC3000000; Physical target address, fourth bank of SDRAM
ENDIF
ADRL r1, MMUTranslationTable ; source address
ADR r2, EndOfTables ; limit of source
copyloop1
ldmia r1!, {r3-r7}
stmia r0!, {r3-r7}
subs r3, r1, r2
blt copyloop1
LDR r0, =0x555555f1
MCR p15, 0, r0, c3, c0, 0
;; make the translation table base ptr point to our table
IF :DEF: MX1
;// i.MX1 SDRAM location
LDR r0, =0x0B004000 ;MMUTranslationTableAddr
ELSE
;// i.MX21 SDRAM location
LDR r0, =0xC3004000 ;MMUTranslationTableAddr
ENDIF
MCR p15, 0, r0, c2, c0, 0
bx lr
PrvFlushCacheAndTLB_AND_DisableCaches
ldr r1, =0x00000000
;; Drain the write buffer
mcr p15, 0, r1, c7, c10, 4
;; Clean and Flush the Cache
mcr p15, 0, r1, c7, c7, 0
;; Flush the TLB
mcr p15, 0, r1, c8, c7, 0
;; Read the coprocessor control register
mrc p15, 0, r1, c1, c0, 0
mov r2, #0x00001000
add r2, r2, #0x4
bic r1, r1, r2
;write to control register
mcr p15, 0, r1, c1, c0, 0
BX lr
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -