3
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
#define I_BIT 0x80
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
ldr r2, _armboot_end
add r2, r2, #CONFIG_STACKSIZE
sub r2, r2, #8
ldmia r2, {r2 - r3} @ get pc, cpsr
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_end @ setup our mode stack
add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
sub r13, r13, #8
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
str lr, [r13, #4]
mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13
mov lr, pc
movs pc, lr
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#ifdef CONFIG_PM
WakeupStart:
@ Clear sleep reset bit
ldr r0, PMST_ADDR
mov r1, #(1<<1) @ PMST_SMR
str r1, [r0]
@ Release the SDRAM signal protections
ldr r0, PMCTL1_ADDR
ldr r1, [r0]
bic r1, r1, #((1<<17)|(1<<18)|(1<<19)) @ (SCLKE | SCLK1 | SCLK0)
str r1, [r0]
@ Go...
ldr r0, PMSR0_ADDR @ read a return address
ldr r1, [r0]
mov pc, r1
nop
nop
1: b 1b @ infinite loop
#endif
.align 5
.globl reset_cpu
reset_cpu:
#ifdef CONFIG_S3C2400
bl disable_interrupts
# ifdef CONFIG_TRAB
bl disable_vfd
# endif
ldr r1, _rWTCON
ldr r2, _rWTCNT
/* Disable watchdog */
mov r3, #0x0000
str r3, [r1]
/* Initialize watchdog timer count register */
mov r3, #0x0001
str r3, [r2]
/* Enable watchdog timer; assert reset at timer timeout */
mov r3, #0x0021
str r3, [r1]
_loop_forever:
b _loop_forever
_rWTCON:
.word 0x15300000
_rWTCNT:
.word 0x15300008
#else /* ! CONFIG_S3C2400 */
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
bic ip, ip, #0x000f @ ............wcam
bic ip, ip, #0x2100 @ ..v....s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
mov pc, r0
#endif /* CONFIG_S3C2400 */
#ifndef CONFIG_S3C2440A_JTAG_BOOT
#ifdef CONFIG_S3C2440A_NAND_BOOT
copy_myself:
ldr r0, =GPFDAT
ldr r1, =0x10
str r1,[r0]
mov r10, lr @ save return address
@ get ready to call C functions
ldr sp, uboot_stack_pointer @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
bl copy_uboot_to_ram
tst r0, #0x0
bne copy_myself_failed
ldr r0, =GPFDAT
ldr r1, =0x20
str r1,[r0]
mov r0, #0
ldr r1, uboot_ram_base_addr
mov r2, #0x400 @ compare first 4-K bytes
1001: ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne 1002f @ not matched
subs r2, r2, #4
beq 1003f
b 1001b
1002:
ldr r0, =GPFDAT
ldr r1, =0x30
str r1,[r0]
1: b 1b
1003:
ldr r0, =GPFDAT
ldr r1, =0x40
str r1,[r0]
@ jump to ram
ldr r0, uboot_ram_base_addr
add pc, r10, r0 /* fake ^^; return here. */
copy_myself_failed:
1: b 1b
#endif
#endif
.ltorg
.align 2
@ addresses
uboot_stack_pointer: .long (STACK_BASE + STACK_SIZE - 4)
uboot_ram_base_addr: .long UBOOT_BASE
.align 4
mem_cfg_val:
.long vBSWCON
.long vBANKCON0
.long vBANKCON1
.long vBANKCON2
.long vBANKCON3
.long vBANKCON4
.long vBANKCON5
.long vBANKCON6
.long vBANKCON7
.long vREFRESH
.long vBANKSIZE
.long vMRSRB6
.long vMRSRB7
#ifdef CONFIG_PM
.align 4
PMCTL1_ADDR:
.long 0x56000080
PMST_ADDR:
.long 0x560000B4
PMSR0_ADDR:
.long 0x560000B8
#endif |