rt-thread-official/libcpu/arm/s3c24x0/start_rvds.s

473 lines
16 KiB
ArmAsm
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;/*****************************************************************************/
;/* S3C2440.S: Startup file for Samsung S3C440 */
;/*****************************************************************************/
;/* <<< Use Configuration Wizard in Context Menu >>> */
;/*****************************************************************************/
;/* This file is part of the uVision/ARM development tools. */
;/* Copyright (c) 2005-2008 Keil Software. All rights reserved. */
;/* This software may only be used under the terms of a valid, current, */
;/* end user licence from KEIL for a compatible version of KEIL software */
;/* development tools. Nothing else gives you the right to use this software. */
;/*****************************************************************************/
;/*
; * The S3C2440.S code is executed after CPU Reset. This file may be
; * translated with the following SET symbols. In uVision these SET
; * symbols are entered under Options - ASM - Define.
; *
; * NO_CLOCK_SETUP: when set the startup code will not initialize Clock
; * (used mostly when clock is aLReady initialized from script .ini
; * file).
; *
; * NO_MC_SETUP: when set the startup code will not initialize Memory
; * Controller (used mostly when clock is aLReady initialized from script
; * .ini file).
; *
; * NO_GP_SETUP: when set the startup code will not initialize General Ports
; * (used mostly when clock is aLReady initialized from script .ini
; * file).
; *
; * RAM_INTVEC: when set the startup code copies exception vectors
; * from execution address to on-chip RAM.
; */
;/*
; * File : start_rvds.s
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2006, RT-Thread Development Team
; *
; * The license and diSTRibution terms for this file may be
; * found in the file LICENSE in this diSTRibution or at
; * http://openlab.rt-thread.com/license/LICENSE
; *
; * Change Logs:
; * Date Author Notes
; * 2010-01-12 Gary Lee Change the STRucture of the code,
; the configuration file's name is config.inc
; * 2010-01-22 Gary Lee Add interrupt config for startup 2440
; * 2010-01-23 Gary Lee Add copy myself for startup from nand
; */
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
GET config.inc
PRESERVE8
AREA RESET, CODE, READONLY
ARM
EXPORT Entry_Point
Entry_Point
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
FIQ_Handler B FIQ_Handler
;=========================================================================
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
BL WatchDog_Config ; shutdown watchdog
BL Interrupt_Config ; shutdown interrupt
BL SysClock_Config ; setup system clock, default value is 400MHz
BL SDRAM_Config ; setup sdram clock, default value is 100MHz
;BL Copymyself_Config ; copy myself from 0x1000 with size of 1MB to sdram address of 0x30000000
BL GPIO_Config ; setup gpio
BL RAM_INTVEC_Config ; install interrupt handler to sdram
BL Stack_Config ; setup stack for every mode
; a technology about trampoline
LDR R1, =ON_THE_RAM
ADD PC, R1, #0
NOP
NOP
1
B %B1
ON_THE_RAM
; setup by APCS
MOV FP, #0 ; no previous frame, so fp=0
MOV a2, #0 ; set argv to NULL
IMPORT __main
BL __main ; call main
MOV R0, #FLASH_BASE_ADDR
MOV PC, R0 ; otherwise, reboot
;=========================================================================
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrput_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_hw_trap_irq
IMPORT nand_read_ll
IRQ_Handler PROC
EXPORT IRQ_Handler
STMFD SP!, {R0-R12,LR}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
LDR R0, =rt_thread_switch_interrput_flag
LDR R1, [R0]
CMP R1, #1
BEQ rt_hw_context_switch_interrupt_do
LDMFD SP!, {R0-R12,LR}
SUBS PC, LR, #4
ENDP
rt_hw_context_switch_interrupt_do PROC
EXPORT rt_hw_context_switch_interrupt_do
MOV R1, #0 ; clear flag
STR R1, [R0]
LDMFD SP!, {R0-R12,LR}; reload saved registers
STMFD SP!, {R0-R3} ; save R0-R3
MOV R1, SP
ADD SP, SP, #16 ; restore SP
SUB R2, LR, #4 ; save old task's PC to R2
MRS R3, SPSR ; get cpsr of interrupt thread
; switch to SVC mode and no interrupt
MSR cpsr_c, #I_Bit|F_Bit|Mode_SVC
STMFD SP!, {R2} ; push old task's PC
STMFD SP!, {r4-R12,LR}; push old task's LR,R12-r4
MOV r4, R1 ; SPecial optimised code below
MOV r5, R3
LDMFD r4!, {R0-R3}
STMFD SP!, {R0-R3} ; push old task's R3-R0
STMFD SP!, {r5} ; push old task's cpsr
MRS r4, SPSR
STMFD SP!, {r4} ; push old task's SPsr
LDR r4, =rt_interrupt_from_thread
LDR r5, [r4]
STR SP, [r5] ; store SP in preempted tasks's TCB
LDR r6, =rt_interrupt_to_thread
LDR r6, [r6]
LDR SP, [r6] ; get new task's stack pointer
LDMFD SP!, {r4} ; pop new task's SPsr
MSR SPSR_cxsf, r4
LDMFD SP!, {r4} ; pop new task's psr
MSR cpsr_cxsf, r4
LDMFD SP!, {R0-R12,LR} ; pop new task's R0-R12,LR & PC
LDMFD SP!, {PC}
ENDP
; Use microlib
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
;=========================================================================
; Subroutines
WatchDog_Config PROC
IF WT_SETUP != 0
LDR R0, =WT_BASE
LDR R1, =WTCON_Val
LDR R2, =WTDAT_Val
STR R2, [R0, #WTCNT_OFS]
STR R2, [R0, #WTDAT_OFS]
STR R1, [R0, #WTCON_OFS]
ENDIF
BX LR
ENDP
Interrupt_Config PROC
LDR R0,=INTMSK
LDR R1,=0xffffffff ;/*all interrupt disable<6C>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> */
STR R1,[R0]
LDR R0,=INTSUBMSK
LDR R1,=0x7fff ;/*all sub interrupt disable<6C>ر<EFBFBD><D8B1><EFBFBD><EFBFBD>ж<EFBFBD> */
STR R1,[R0]
BX LR
ENDP
SysClock_Config PROC
IF (:LNOT:(:DEF:NO_CLOCK_SETUP)):LAND:(CLOCK_SETUP != 0)
LDR R0, =CLOCK_BASE
LDR R1, =LOCKTIME_Val
STR R1, [R0, #LOCKTIME_OFS]
MOV R1, #CLKDIVN_Val
STR R1, [R0, #CLKDIVN_OFS]
LDR R1, =CAMDIVN_Val
STR R1, [R0, #CAMDIVN_OFS]
LDR R1, =MPLLCON_Val
STR R1, [R0, #MPLLCON_OFS]
LDR R1, =UPLLCON_Val
STR R1, [R0, #UPLLCON_OFS]
MOV R1, #CLKSLOW_Val
STR R1, [R0, #CLKSLOW_OFS]
LDR R1, =CLKCON_Val
STR R1, [R0, #CLKCON_OFS]
ENDIF
BX LR
ENDP
Copymyself_Config PROC
MOV R1, #NAND_CTL_BASE ; inital NAND<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
LDR R2, =((7<<12)|(7<<8)|(7<<4)|(0<<0)) ; initial value
STR R2, [R1, #oNFCONF]
; reset nand flash ; <20><>λNAND
LDR R2, [R1, #oNFCONF]
LDR R2, =((1<<4)|(0<<1)|(1<<0)) ; nFCE active
STR R2, [R1, #oNFCONT]
LDR R2, [R1, #oNFCONT]
LDR R2, =(0x6) ; RnB Clear
STR R2, [R1, #oNFSTAT]
LDR R2, [R1, #oNFSTAT]
MOV R2, #0xff ; reset command
STRB R2, [R1, #oNFCMD]
; <20><>ʱ
MOV R3, #0x0A
1
SUBS R3, R3, #1
BNE %B1
; wait idle state <20><><EFBFBD><EFBFBD>
2
LDR R2, [R1, #oNFSTAT]
TST R2, #0x04
BEQ %B2
LDR R2, [R1, #oNFCONF]
ORR R2, R2, #0x2 ; nFCE inactive
STR R2, [R1, #oNFCONF]
LDR SP, =4096 ; nand_read.c needed
LDR R0, =0x30000000 ; nand_read_ll argument 1 buffer addr
MOV R1, #4096 ; nand_read_ll argument 2 start addr
MOV R2, #0x100000 ; nand_read_ll argument 3 copy size
; 1MB enough for this example
BL nand_read_ll
BX LR
ENDP
SDRAM_Config PROC
IF (:LNOT:(:DEF:NO_MC_SETUP)):LAND:(CLOCK_SETUP != 0)
LDR R0, =MC_BASE
LDR R1, =BWSCON_Val
STR R1, [R0, #BWSCON_OFS]
LDR R1, =BANKCON0_Val
STR R1, [R0, #BANKCON0_OFS]
LDR R1, =BANKCON1_Val
STR R1, [R0, #BANKCON1_OFS]
LDR R1, =BANKCON2_Val
STR R1, [R0, #BANKCON2_OFS]
LDR R1, =BANKCON3_Val
STR R1, [R0, #BANKCON3_OFS]
LDR R1, =BANKCON4_Val
STR R1, [R0, #BANKCON4_OFS]
LDR R1, =BANKCON5_Val
STR R1, [R0, #BANKCON5_OFS]
LDR R1, =BANKCON6_Val
STR R1, [R0, #BANKCON6_OFS]
LDR R1, =BANKCON7_Val
STR R1, [R0, #BANKCON7_OFS]
LDR R1, =REFRESH_Val
STR R1, [R0, #REFRESH_OFS]
MOV R1, #BANKSIZE_Val
STR R1, [R0, #BANKSIZE_OFS]
MOV R1, #MRSRB6_Val
STR R1, [R0, #MRSRB6_OFS]
MOV R1, #MRSRB7_Val
STR R1, [R0, #MRSRB7_OFS]
ENDIF
BX LR
ENDP
GPIO_Config PROC
IF (:LNOT:(:DEF:NO_GP_SETUP)):LAND:(GP_SETUP != 0)
IF GPA_SETUP != 0
LDR R0, =GPA_BASE
LDR R1, =GPACON_Val
STR R1, [R0, #GPCON_OFS]
ENDIF
IF GPB_SETUP != 0
LDR R0, =GPB_BASE
LDR R1, =GPBCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPBUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPC_SETUP != 0
LDR R0, =GPC_BASE
LDR R1, =GPCCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPCUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPD_SETUP != 0
LDR R0, =GPD_BASE
LDR R1, =GPDCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPDUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPE_SETUP != 0
LDR R0, =GPE_BASE
LDR R1, =GPECON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPEUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPF_SETUP != 0
LDR R0, =GPF_BASE
LDR R1, =GPFCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPFUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPG_SETUP != 0
LDR R0, =GPG_BASE
LDR R1, =GPGCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPGUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPH_SETUP != 0
LDR R0, =GPH_BASE
LDR R1, =GPHCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPHUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPJ_SETUP != 0
LDR R0, =GPJ_BASE
LDR R1, =GPJCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPJUP_Val
STR R1, [R0, #GPUP_OFS]
ENDIF
ENDIF
BX LR
ENDP
RAM_INTVEC_Config PROC
IF :DEF:RAM_INTVEC
ADR R8, Vectors ; Source
LDR R9, =IRAM_BASE ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
ENDIF
BX LR
ENDP
Stack_Config PROC
LDR R0, =Stack_Top
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
BX LR
ENDP
END