📄 startup.s
字号:
;
; Copyright (c) Microsoft Corporation. All rights reserved.
;
;
; Use of this source code is subject to the terms of the Microsoft end-user
; license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
; If you did not accept the terms of the EULA, you are not authorized to use
; this source code. For a copy of the EULA, please see the LICENSE.RTF on your
; install media.
;
;------------------------------------------------------------------------------
;
; File: startup.s
;
; Kernel startup routine for Samsung SMDK2443 board. Hardware is
; initialized in boot loader - so there isn't much code at all.
;
;------------------------------------------------------------------------------
INCLUDE kxarm.h
INCLUDE s3c2443.inc
IMPORT OALClearUTLB
IMPORT OALFlushICache
IMPORT OALFlushDCache
;-------------------------------------------------------------------------------
;MemoryMap EQU 0x2a4
;BANK_SIZE EQU 0x00100000 ; 1MB per bank in MemoryMap array
BANK_SHIFT EQU 20
; Define RAM space for the Page Tables:
;
PHYBASE EQU 0x30000000 ; physical start
PTs EQU 0x30010000 ; 1st level page table address (PHYBASE + 0x10000)
; save room for interrupt vectors.
;-------------------------------------------------------------------------------
; Data Cache Characteristics.
;
DCACHE_LINES_PER_SET_BITS EQU 6
DCACHE_LINES_PER_SET EQU 64
DCACHE_NUM_SETS EQU 8
DCACHE_SET_INDEX_BIT EQU (32 - DCACHE_LINES_PER_SET_BITS)
DCACHE_LINE_SIZE EQU 32
SLEEPDATA_BASE_VIRTUAL EQU 0xA0028000 ; keep in sync w/ config.bib
SLEEPDATA_BASE_PHYSICAL EQU 0x30028000
SleepState_Data_Start EQU (0)
SleepState_WakeAddr EQU (SleepState_Data_Start )
SleepState_MMUCTL EQU (SleepState_WakeAddr + WORD_SIZE )
SleepState_MMUTTB EQU (SleepState_MMUCTL + WORD_SIZE )
SleepState_MMUDOMAIN EQU (SleepState_MMUTTB + WORD_SIZE )
SleepState_SVC_SP EQU (SleepState_MMUDOMAIN + WORD_SIZE )
SleepState_SVC_SPSR EQU (SleepState_SVC_SP + WORD_SIZE )
SleepState_FIQ_SPSR EQU (SleepState_SVC_SPSR + WORD_SIZE )
SleepState_FIQ_R8 EQU (SleepState_FIQ_SPSR + WORD_SIZE )
SleepState_FIQ_R9 EQU (SleepState_FIQ_R8 + WORD_SIZE )
SleepState_FIQ_R10 EQU (SleepState_FIQ_R9 + WORD_SIZE )
SleepState_FIQ_R11 EQU (SleepState_FIQ_R10 + WORD_SIZE )
SleepState_FIQ_R12 EQU (SleepState_FIQ_R11 + WORD_SIZE )
SleepState_FIQ_SP EQU (SleepState_FIQ_R12 + WORD_SIZE )
SleepState_FIQ_LR EQU (SleepState_FIQ_SP + WORD_SIZE )
SleepState_ABT_SPSR EQU (SleepState_FIQ_LR + WORD_SIZE )
SleepState_ABT_SP EQU (SleepState_ABT_SPSR + WORD_SIZE )
SleepState_ABT_LR EQU (SleepState_ABT_SP + WORD_SIZE )
SleepState_IRQ_SPSR EQU (SleepState_ABT_LR + WORD_SIZE )
SleepState_IRQ_SP EQU (SleepState_IRQ_SPSR + WORD_SIZE )
SleepState_IRQ_LR EQU (SleepState_IRQ_SP + WORD_SIZE )
SleepState_UND_SPSR EQU (SleepState_IRQ_LR + WORD_SIZE )
SleepState_UND_SP EQU (SleepState_UND_SPSR + WORD_SIZE )
SleepState_UND_LR EQU (SleepState_UND_SP + WORD_SIZE )
SleepState_SYS_SP EQU (SleepState_UND_LR + WORD_SIZE )
SleepState_SYS_LR EQU (SleepState_SYS_SP + WORD_SIZE )
SleepState_Data_End EQU (SleepState_SYS_LR + WORD_SIZE )
SLEEPDATA_SIZE EQU ((SleepState_Data_End - SleepState_Data_Start) / 4)
;---------------------------------------------------------------------------
;
; Macro to feed the LED Reg (The GPIO) with the value desired for debugging.
; Uses physical address
;
; GPFDAT [7:4] is assigned to LEDs.
MACRO
LED_ON $data
LDR r10, =GPFUDP
LDR r11, =0x5500 ;Pull-Up-Down Disable
STR r11, [r10]
LDR r10, =GPFCON
LDR r11, =0x5500 ; GPF[7:4] Output .
STR r11, [r10]
LDR r10, =GPFDAT
LDR r11, =$data
MOV r11, r11, lsl #4 ; [7:4]
STR r11, [r10]
MEND
; LED_ON using virtual address
;
MACRO
VLED_ON $data
LDR r10, =vGPFUDP
LDR r11, =0x5500 ;Pull-Up-Down Disable
STR r11, [r10]
LDR r10, =vGPFCON
LDR r11, =0x5500 ; GPF[7:4] Output .
STR r11, [r10]
LDR r10, =vGPFDAT
LDR r11, =$data
MOV r11, r11, lsl #4 ; [7:4]
STR r11, [r10]
MEND
;---------------------------------------------------------------------------
TEXTAREA
IMPORT Max1718_Init
IMPORT Max1718_Set
IMPORT main
; Include memory configuration file with g_oalAddressTable
INCLUDE oemaddrtab_cfg.inc
LEAF_ENTRY StartUp
; Compute the OEMAddressTable's physical address and
; load it into r0. KernelStart expects r0 to contain
; the physical address of this table. The MMU isn't
; turned on until well into KernelStart.
; Jump over power-off code.
1 b ResetHandler
b %B1 ;HandlerUndef ;handler for Undefined mode
b %B1 ;HandlerSWI ;handler for SWI interrupt
b %B1 ;HandlerPabort ;handler for PAbort
b %B1 ;HandlerDabort ;handler for DAbort
b %B1 ; ;reserved
b %B1 ;HandlerIRQ ;handler for IRQ interrupt
b %B1 ;HandlerFIQ ;handler for FIQ interrupt
ResetHandler
; Make sure that TLB & cache are consistent
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 ; flush both TLB
mcr p15, 0, r0, c7, c5, 0 ; invalidate instruction cache
mcr p15, 0, r0, c7, c6, 0 ; invalidate data cache
ldr r0, =WTCON ; disable the watchdog timer.
mov r1,#0
str r1, [r0]
;;;;;;;;;;;; set voltage test
; bl Max1718_Init
; mov r0, #0x1
; mov r1, #125
; mov r1, #130
; mov r1, #135
; bl Max1718_Set
; ldr r0, =EBICON ; EBI
; ldr r1, =EBICON_VAL ; Refer s3c2443.inc
; str r1,[r0]
ldr r0, = GPACDH
ldr r1, = 0xAA8A
str r1, [r0]
ldr r0, = GPFCON
ldr r1, = 0x5500
str r1, [r0]
ldr r0, =INTMSK ; mask all first-level interrupts.
ldr r1, =0xffffffff
str r1, [r0]
ldr r0, =INTSUBMSK ; mask all second-level interrupts.
ldr r1, =0x1fffffff
str r1, [r0]
ldr r0, = INTMOD
mov r1, #0x0 ; set all interrupt as IRQ
str r1, [r0]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; When the Eboot is already, No need to set again.
;; IF set as "FALSE", The FCLK,HCLK,PCLK Clock will detect automatically in OS.
;; IF set as "TRUE", The FCLK,HCLK,PCLK Clock and Memory setting will be set again here and detect automatically in OS.
[ CHANGE_CLK_EBOOT=1 ; Refer the S3c2443.inc.
ldr r0,=CLKDIV0 ; Set Clock Divider
ldr r1,[r0]
bic r1,r1,#0x37 ; clear HCLKDIV, PREDIV, PCLKDIV
bic r1,r1,#(0xf<<9) ; clear ARMCLKDIV
ldr r2,=((Startup_ARMCLKdiv<<9)+(Startup_PREdiv<<4)+(Startup_PCLKdiv<<2)+(Startup_HCLKdiv))
orr r1,r1,r2
str r1,[r0]
ldr r0,=LOCKCON0 ; Set lock time of MPLL. added by junon
mov r1,#0xe10 ; Fin = 12MHz - 0x800, 16.9844MHz - 0xA00
str r1,[r0]
ldr r0,=LOCKCON1 ; Set lock time of EPLL. added by junon
mov r1,#0x800 ; Fin = 12MHz - 0x800, 16.9844MHz - 0xA00
str r1,[r0]
ldr r0,=MPLLCON ; Set MPLL
ldr r1,=((0<<24)+(Startup_Mdiv<<16)+(Startup_Pdiv<<8)+(Startup_Sdiv))
str r1,[r0]
ldr r0,=EPLLCON ; Set EPLL
ldr r1,=((0<<24)+(Startup_EMdiv<<16)+(Startup_EPdiv<<8)+(Startup_ESdiv))
str r1,[r0]
ldr r0,=CLKSRC ; Select MPLL clock out for SYSCLK
ldr r1,[r0]
orr r1,r1,#0x50
str r1,[r0]
bl MMU_SetAsyncBusMode
; bl InitMEM
bl InitSSMC
] ; End of PLL setting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; set clkout1 - HCLK
ldr r0,=MISCCR
ldr r1,[r0]
bic r1,r1, #0x770
orr r1,r1,#0x320
str r1,[r0]
ldr r0,=GPHCON
ldr r1,[r0]
bic r1,r1, #0x3C000000
orr r1,r1, #0x28000000
str r1,[r0]
;;;;;;;;;;;;;;;;;;
;bl loop_led
[ {FALSE}
; Clear RAM.
;
mov r1,#0
mov r2,#0
mov r3,#0
mov r4,#0
mov r5,#0
mov r6,#0
mov r7,#0
mov r8,#0
ldr r0,=0x30100000 ; Start address (physical 0x3000.0000).
;ldr r9,=0x00E00000 ; 64MB of RAM.
ldr r9,=0x03F00000 ; 64MB of RAM.
20
stmia r0!, {r1-r8}
subs r9, r9, #32
bne %B20
]
; Compute physical address of the OEMAddressTable.
20 add r11, pc, #g_oalAddressTable - (. + 8)
ldr r10, =PTs ; (r10) = 1st level page table
; Setup 1st level page table (using section descriptor)
; Fill in first level page table entries to create "un-mapped" regions
; from the contents of the MemoryMap array.
;
; (r10) = 1st level page table
; (r11) = ptr to MemoryMap array
add r10, r10, #0x2000 ; (r10) = ptr to 1st PTE for "unmapped space"
mov r0, #0x0E ; (r0) = PTE for 0: 1MB cachable bufferable
orr r0, r0, #0x400 ; set kernel r/w permission
25 mov r1, r11 ; (r1) = ptr to MemoryMap array
30 ldr r2, [r1], #4 ; (r2) = virtual address to map Bank at
ldr r3, [r1], #4 ; (r3) = physical address to map from
ldr r4, [r1], #4 ; (r4) = num MB to map
cmp r4, #0 ; End of table?
beq %f40
ldr r5, =0x1FF00000
and r2, r2, r5 ; VA needs 512MB, 1MB aligned.
ldr r5, =0xFFF00000
and r3, r3, r5 ; PA needs 4GB, 1MB aligned.
add r2, r10, r2, LSR #18
add r0, r0, r3 ; (r0) = PTE for next physical page
35 str r0, [r2], #4
add r0, r0, #0x00100000 ; (r0) = PTE for next physical page
sub r4, r4, #1 ; Decrement number of MB left
cmp r4, #0
bne %b35 ; Map next MB
bic r0, r0, #0xF0000000 ; Clear Section Base Address Field
bic r0, r0, #0x0FF00000 ; Clear Section Base Address Field
b %b30 ; Get next element
40 tst r0, #8
bic r0, r0, #0x0C ; clear cachable & bufferable bits in PTE
add r10, r10, #0x0800 ; (r10) = ptr to 1st PTE for "unmapped uncached space"
bne %b25 ; go setup PTEs for uncached space
sub r10, r10, #0x3000 ; (r10) = restore address of 1st level page table
; 1. Setup mmu to map (VA == 0) to (PA == 0x30000000).
; 1-1. cached area.
ldr r0, =PTs ; PTE entry for VA = 0
ldr r1, =0x3000040E ; cache/buffer/rw, PA base == 0x30000000
;ldr r1, =0x30000402 ; cache/buffer/rw, PA base == 0x30000000
str r1, [r0]
; 1-2. uncached area.
add r0, r0, #0x0800 ; PTE entry for VA = 0x0200.0000 , uncached
ldr r1, =0x30000402 ; uncache/unbuffer/rw, base == 0x30000000
str r1, [r0]
; Comment:
; The following loop is to direct map RAM VA == PA. i.e.
; VA == 0x30XXXXXX => PA == 0x30XXXXXX for S3C2400
; Fill in 8 entries to have a direct mapping for DRAM
;
ldr r10, =PTs ; restore address of 1st level page table
ldr r0, =PHYBASE
add r10, r10, #(0x3000 / 4) ; (r10) = ptr to 1st PTE for 0x30000000
add r0, r0, #0x1E ; 1MB cachable bufferable
orr r0, r0, #0x400 ; set kernel r/w permission
mov r1, #0
mov r3, #64
45 mov r2, r1 ; (r2) = virtual address to map Bank at
cmp r2, #0x20000000:SHR:BANK_SHIFT
add r2, r10, r2, LSL #BANK_SHIFT-18
strlo r0, [r2]
add r0, r0, #0x00100000 ; (r0) = PTE for next physical page
subs r3, r3, #1
add r1, r1, #1
bgt %b45
ldr r10, =PTs ; (r10) = restore address of 1st level page table
; The page tables and exception vectors are setup.
; Initialize the MMU and turn it on.
mov r1, #1
mcr p15, 0, r1, c3, c0, 0 ; setup access to domain 0
mcr p15, 0, r10, c2, c0, 0
mcr p15, 0, r0, c8, c7, 0 ; flush I+D TLBs
mrc p15,0,r1,c1,c0,0
orr r1, r1, #0x0071 ; Enable: MMU
orr r1, r1, #0x0004 ; Enable the cache
ldr r0, =VirtualStart
cmp r0, #0 ; make sure no stall on "mov pc,r0" below
mcr p15, 0, r1, c1, c0, 0
mov pc, r0 ; & jump to new virtual address
nop
; MMU & caches now enabled.
; (r10) = physcial address of 1st level page table
;
VirtualStart
mov sp, #0x80000000 ; have to be modefied. refer oemaddrtab_cfg.inc, DonGo
add sp, sp, #0x30000 ; arbitrary initial super-page stack pointer
b main
ENTRY_END
LEAF_ENTRY OALCPUPowerOff
; 1. Push SVC state onto our stack
stmdb sp!, {r4-r12}
stmdb sp!, {lr}
; 2. Save MMU & CPU Register to RAM
ldr r3, =SLEEPDATA_BASE_VIRTUAL ; base of Sleep mode storage
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -