Skip to content
Snippets Groups Projects
start.S 14.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Wolfgang Denk's avatar
    Wolfgang Denk committed
    /*
     *  armboot - Startup Code for ARM720 CPU-core
     *
     *  Copyright (c) 2001	Marius Grger <mag@sysgo.de>
     *  Copyright (c) 2002	Alex Zpke <azu@sysgo.de>
     *
     * See file CREDITS for list of people who contributed to this
     * project.
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License as
     * published by the Free Software Foundation; either version 2 of
     * the License, or (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
    
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     * MA 02111-1307 USA
     */
    
    
    #include <config.h>
    #include <version.h>
    
    #include <asm/hardware.h>
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    /*
     *************************************************************************
     *
     * Jump vector table as in table 3.1 in [1]
     *
     *************************************************************************
     */
    
    
    .globl _start
    
    _start: b	reset
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ldr	pc, _undefined_instruction
    	ldr	pc, _software_interrupt
    	ldr	pc, _prefetch_abort
    	ldr	pc, _data_abort
    
    #ifdef CONFIG_LPC2292
    	.word	0xB4405F76 /* 2's complement of the checksum of the vectors */
    #else
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ldr	pc, _not_used
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ldr	pc, _irq
    	ldr	pc, _fiq
    
    
    _undefined_instruction: .word undefined_instruction
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    _software_interrupt:	.word software_interrupt
    _prefetch_abort:	.word prefetch_abort
    _data_abort:		.word data_abort
    _not_used:		.word not_used
    _irq:			.word irq
    _fiq:			.word fiq
    
    	.balignl 16,0xdeadbeef
    
    
    /*
     *************************************************************************
     *
     * Startup Code (reset vector)
     *
    
     * do important init only if we don't start from RAM!
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     * relocate armboot to ram
     * setup stack
     * jump to second stage
     *
     *************************************************************************
     */
    
    _TEXT_BASE:
    	.word	TEXT_BASE
    
    .globl _armboot_start
    _armboot_start:
    	.word _start
    
    /*
    
     * These are defined in the board-specific linker script.
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     */
    
    .globl _bss_start
    _bss_start:
    	.word __bss_start
    
    .globl _bss_end
    _bss_end:
    	.word _end
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    #ifdef CONFIG_USE_IRQ
    /* IRQ stack memory (calculated at run-time) */
    .globl IRQ_STACK_START
    IRQ_STACK_START:
    	.word	0x0badc0de
    
    /* IRQ stack memory (calculated at run-time) */
    .globl FIQ_STACK_START
    FIQ_STACK_START:
    	.word 0x0badc0de
    #endif
    
    
    /*
     * the actual reset code
     */
    
    reset:
    	/*
    	 * set the cpu to SVC32 mode
    	 */
    	mrs	r0,cpsr
    	bic	r0,r0,#0x1f
    	orr	r0,r0,#0x13
    	msr	cpsr,r0
    
    	/*
    	 * we do sys-critical inits only at reboot,
    	 * not when booting from ram!
    	 */
    
    #ifndef CONFIG_SKIP_LOWLEVEL_INIT
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	bl	cpu_init_crit
    #endif
    
    
    #ifndef CONFIG_SKIP_RELOCATE_UBOOT
    
    relocate:				/* relocate U-Boot to RAM	    */
    	adr	r0, _start		/* r0 <- current position of code   */
    	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
    
    	cmp	r0, r1			/* don't reloc during debug	    */
    	beq	stack_setup
    
    #if TEXT_BASE
    
    #ifndef CONFIG_LPC2292 /* already done in lowlevel_init */
    
    	ldr	r2, =0x0		/* Relocate the exception vectors   */
    	cmp	r1, r2			/* and associated data to address   */
    	ldmneia r0!, {r3-r10}		/* 0x0. Do nothing if TEXT_BASE is  */
    	stmneia r2!, {r3-r10}		/* 0x0. Copy the first 15 words.    */
    	ldmneia r0, {r3-r9}
    	stmneia r2, {r3-r9}
    	adrne	r0, _start		/* restore r0			    */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ldr	r2, _armboot_start
    
    	ldr	r3, _bss_start
    
    	sub	r2, r3, r2		/* r2 <- size of armboot	    */
    	add	r2, r0, r2		/* r2 <- source end address	    */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    copy_loop:
    
    	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
    	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
    	cmp	r0, r2			/* until source end addreee [r2]    */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ble	copy_loop
    
    
    #endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
    
    
    	/* Set up the stack						    */
    stack_setup:
    	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
    
    	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area			    */
    	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo			    */
    
    #ifdef CONFIG_USE_IRQ
    	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
    #endif
    	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	ldr	r0, _bss_start		/* find start of bss segment	    */
    	ldr	r1, _bss_end		/* stop here			    */
    	mov	r2, #0x00000000		/* clear			    */
    
    clbss_l:str	r2, [r0]		/* clear loop...		    */
    
    	add	r0, r0, #4
    	cmp	r0, r1
    
    	ble	clbss_l
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ldr	pc, _start_armboot
    
    
    _start_armboot: .word start_armboot
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    /*
     *************************************************************************
     *
     * CPU_init_critical registers
     *
     * setup important registers
     * setup memory timing
     *
     *************************************************************************
     */
    
    
    #if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    /* Interupt-Controller base addresses */
    INTMR1:		.word	0x80000280 @ 32 bit size
    INTMR2:		.word	0x80001280 @ 16 bit size
    INTMR3:		.word	0x80002280 @  8 bit size
    
    /* SYSCONs */
    SYSCON1:	.word	0x80000100
    SYSCON2:	.word	0x80001100
    SYSCON3:	.word	0x80002200
    
    #define CLKCTL	       0x6  /* mask */
    #define CLKCTL_18      0x0  /* 18.432 MHz */
    #define CLKCTL_36      0x2  /* 36.864 MHz */
    #define CLKCTL_49      0x4  /* 49.152 MHz */
    #define CLKCTL_73      0x6  /* 73.728 MHz */
    
    
    #elif defined(CONFIG_LPC2292)
    PLLCFG_ADR:	.word	PLLCFG
    PLLFEED_ADR:	.word	PLLFEED
    PLLCON_ADR:	.word	PLLCON
    PLLSTAT_ADR:	.word	PLLSTAT
    VPBDIV_ADR:	.word	VPBDIV
    MEMMAP_ADR:	.word	MEMMAP
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    cpu_init_crit:
    
    #if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/*
    	 * mask all IRQs by clearing all bits in the INTMRs
    	 */
    	mov	r1, #0x00
    	ldr	r0, INTMR1
    	str	r1, [r0]
    	ldr	r0, INTMR2
    	str	r1, [r0]
    	ldr	r0, INTMR3
    	str	r1, [r0]
    
    	/*
    	 * flush v4 I/D caches
    	 */
    	mov	r0, #0
    	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
    	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
    
    	/*
    	 * disable MMU stuff and caches
    	 */
    	mrc	p15,0,r0,c1,c0
    	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
    	bic	r0, r0, #0x0000008f	@ clear bits 7, 3:0 (B--- WCAM)
    	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
    	mcr	p15,0,r0,c1,c0
    
    #elif defined(CONFIG_NETARM)
    
    	/*
    	 * prior to software reset : need to set pin PORTC4 to be *HRESET
    	 */
    	ldr	r0, =NETARM_GEN_MODULE_BASE
    	ldr	r1, =(NETARM_GEN_PORT_MODE(0x10) | \
    			NETARM_GEN_PORT_DIR(0x10))
    	str	r1, [r0, #+NETARM_GEN_PORTC]
    	/*
    	 * software reset : see HW Ref. Guide 8.2.4 : Software Service register
    
    	 *		    for an explanation of this process
    
    	 */
    	ldr	r0, =NETARM_GEN_MODULE_BASE
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
    	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
    	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
    	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
    	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
    	/*
    	 * setup PLL and System Config
    	 */
    	ldr	r0, =NETARM_GEN_MODULE_BASE
    
    	ldr	r1, =(	NETARM_GEN_SYS_CFG_LENDIAN | \
    			NETARM_GEN_SYS_CFG_BUSFULL | \
    			NETARM_GEN_SYS_CFG_USER_EN | \
    			NETARM_GEN_SYS_CFG_ALIGN_ABORT | \
    			NETARM_GEN_SYS_CFG_BUSARB_INT | \
    			NETARM_GEN_SYS_CFG_BUSMON_EN )
    
    	str	r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL]
    
    
    #ifndef CONFIG_NETARM_PLL_BYPASS
    
    	ldr	r1, =(	NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \
    			NETARM_GEN_PLL_CTL_POLTST_DEF | \
    			NETARM_GEN_PLL_CTL_INDIV(1) | \
    			NETARM_GEN_PLL_CTL_ICP_DEF | \
    			NETARM_GEN_PLL_CTL_OUTDIV(2) )
    	str	r1, [r0, #+NETARM_GEN_PLL_CONTROL]
    
    	/*
    	 * mask all IRQs by clearing all bits in the INTMRs
    	 */
    	mov	r1, #0
    	ldr	r0, =NETARM_GEN_MODULE_BASE
    	str	r1, [r0, #+NETARM_GEN_INTR_ENABLE]
    
    
    #elif defined(CONFIG_S3C4510B)
    
    	/*
    	 * Mask off all IRQ sources
    	 */
    	ldr	r1, =REG_INTMASK
    	ldr	r0, =0x3FFFFF
    	str	r0, [r1]
    
    	/*
    	 * Disable Cache
    	 */
    	ldr r0, =REG_SYSCFG
    
    	ldr r1, =0x83ffffa0	/* cache-disabled  */
    
    	str r1, [r0]
    
    
    #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
    	/* No specific initialisation for IntegratorAP/CM720T as yet */
    
    #elif defined(CONFIG_LPC2292)
    	/* Set-up PLL */
    	mov	r3, #0xAA
    	mov	r4, #0x55
    
    	/* First disconnect and disable the PLL */
    
    	ldr	r0, PLLCON_ADR
    	mov	r1, #0x00
    	str	r1, [r0]
    	ldr	r0, PLLFEED_ADR /* start feed sequence */
    	str	r3, [r0]
    
    	str	r4, [r0]	/* feed sequence done */
    
    	/* Set new M and P values */
    	ldr	r0, PLLCFG_ADR
    	mov	r1, #0x23	/* M=4 and P=2 */
    	str	r1, [r0]
    	ldr	r0, PLLFEED_ADR /* start feed sequence */
    	str	r3, [r0]
    	str	r4, [r0]	/* feed sequence done */
    	/* Then enable the PLL */
    	ldr	r0, PLLCON_ADR
    	mov	r1, #0x01	/* PLL enable bit */
    	str	r1, [r0]
    	ldr	r0, PLLFEED_ADR /* start feed sequence */
    	str	r3, [r0]
    	str	r4, [r0]	/* feed sequence done */
    
    	/* Wait for the lock */
    
    	ldr	r0, PLLSTAT_ADR
    	mov	r1, #0x400	/* lock bit */
    
    	ldr	r2, [r0]
    	and	r2, r1, r2
    	cmp	r2, #0
    	beq	lock_loop
    	/* And finally connect the PLL */
    	ldr	r0, PLLCON_ADR
    	mov	r1, #0x03	/* PLL enable bit and connect bit */
    	str	r1, [r0]
    	ldr	r0, PLLFEED_ADR /* start feed sequence */
    	str	r3, [r0]
    
    	str	r4, [r0]	/* feed sequence done */
    
    	/* Set-up VPBDIV register */
    	ldr	r0, VPBDIV_ADR
    	mov	r1, #0x01	/* VPB clock is same as process clock */
    	str	r1, [r0]
    
    #else
    #error No cpu_init_crit() defined for current CPU type
    #endif
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    #ifdef CONFIG_ARM7_REVD
    	/* set clock speed */
    	/* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */
    	/* !!! not doing DRAM refresh properly! */
    	ldr	r0, SYSCON3
    	ldr	r1, [r0]
    	bic	r1, r1, #CLKCTL
    	orr	r1, r1, #CLKCTL_36
    	str	r1, [r0]
    #endif
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/*
    	 * before relocating, we have to setup RAM timing
    
    	 * because memory timing is board-dependent, you will
    
    	 * find a lowlevel_init.S in your board directory.
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	 */
    
    	bl	lowlevel_init
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	mov	lr, ip
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	mov	pc, lr
    
    
    /*
     *************************************************************************
     *
     * 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
    
    	add	r8, sp, #S_PC
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	ldr	r2, _armboot_start
    
    	sub	r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
    	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)	@ set base 2 words into abort stack
    
    	ldmia	r2, {r2 - r4}			@ get pc, cpsr, old_r0
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	add	r0, sp, #S_FRAME_SIZE		@ restore sp_SVC
    
    	add	r5, sp, #S_SP
    	mov	r1, lr
    
    	stmia	r5, {r0 - r4}			@ save sp_SVC, lr_SVC, pc, cpsr, old_r
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	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
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	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_start		@ setup our mode stack
    
    	sub	r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
    	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	str	lr, [r13]			@ save caller lr / spsr
    	mrs	lr, spsr
    
    	str	lr, [r13, #4]
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	mov	r13, #MODE_SVC			@ prepare SVC-Mode
    	msr	spsr_c, 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
     */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    undefined_instruction:
    	get_bad_stack
    	bad_save_user_regs
    
    	bl	do_undefined_instruction
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	.align	5
    software_interrupt:
    	get_bad_stack
    	bad_save_user_regs
    
    	bl	do_software_interrupt
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	.align	5
    prefetch_abort:
    	get_bad_stack
    	bad_save_user_regs
    
    	bl	do_prefetch_abort
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	.align	5
    data_abort:
    	get_bad_stack
    	bad_save_user_regs
    
    	bl	do_data_abort
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	.align	5
    not_used:
    	get_bad_stack
    	bad_save_user_regs
    
    	bl	do_not_used
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    #ifdef CONFIG_USE_IRQ
    
    	.align	5
    irq:
    	get_irq_stack
    	irq_save_user_regs
    
    	bl	do_irq
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	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
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	irq_restore_user_regs
    
    #else
    
    	.align	5
    irq:
    	get_bad_stack
    	bad_save_user_regs
    
    	bl	do_irq
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	.align	5
    fiq:
    	get_bad_stack
    	bad_save_user_regs
    
    	bl	do_fiq
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    #endif
    
    
    #if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	.align	5
    .globl reset_cpu
    reset_cpu:
    
    	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
    
    #elif defined(CONFIG_NETARM)
    	.align	5
    .globl reset_cpu
    reset_cpu:
    
    	ldr	r1, =NETARM_MEM_MODULE_BASE
    	ldr	r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR]
    	ldr	r1, =0xFFFFF000
    	and	r0, r1, r0
    	ldr	r1, =(relocate-TEXT_BASE)
    	add	r0, r1, r0
    	ldr	r4, =NETARM_GEN_MODULE_BASE
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
    	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
    	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
    	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
    	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
    	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
    	mov	pc, r0
    
    #elif defined(CONFIG_S3C4510B)
    /* Nothing done here as reseting the CPU is board specific, depending
     * on external peripherals such as watchdog timers, etc. */
    
    #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
    	/* No specific reset actions for IntegratorAP/CM720T as yet */
    
    #elif defined(CONFIG_LPC2292)
    	.align	5
    .globl reset_cpu
    reset_cpu:
    	mov	pc, r0
    
    #else
    #error No reset_cpu() defined for current CPU type