[U-Boot-Users] Request: s3c24xx getting its own start.S file ?

Harald Welte laforge at gnumonks.org
Mon Jul 7 10:01:08 CEST 2008


On Sun, Jul 06, 2008 at 08:44:52PM +0200, Wolfgang Denk wrote:

> > the attached patch, where the cpu/arm920t/start.S #includes a
> > cpu/arm920t/s3c24x0/start.S file.
> > 
> > It's not really nice, but otherwise I assure you anyone touching the
> > arm920t start.S file again will find itself in #ifdef/endif hell, once
> > all my s3c24xx related patches would be merged...
> 
> I really dislike the code duplication.

I am sympathetic to the cause.  For reference, I'm attaching the s3c24xx
specific start.S file of my internal tree _before_ s3c24a0, s3c2460,
s3c2412 and s3c2443 suppor is merged.  So this is for three CPU's, not
yet for seven.  And it has already way too many ifdefs for my taste.
Also, the number of lines of code that I duplicated is probably
something like 25-40 assembly instructions.  We're not talking about
massive amounts here.

I think the problem is a quite generic one.  The same one exists for
other ARM-core based SoCs, since multiple vendors use the same core, and
every vendor (samsung, ti, ...) may have an entire product line each
with their specific low-level initialization bits.

I'm having the same problem looking at the arm1136 based s3c6400 code...
It is quite different but still somehow related to the
cpu/arm1136/start.S code.

The only alternative to either having #ifdef hell or code duplication is
the extensive use of macros.  Either have one common start.S and put
macro placeholders throughout the code, have the actual bits implemented
per-cpu.  Or have one start.S for each cpu and macros for the shared
generic stuff.

Oh, and did I mention that samsung also shares code between s3c24xx and
s3c64xx?  This means that e.g. the boot-from-nand part of the s3c2443
and the s3c6400 might be identical, so we'd end up having code in
cpu/arm920t/s3c24xx/ including/linking to code in cpu/arm1136/s3c64xx...

I'll probably end up with something like 
cpu/arm920t/s3c24xx	2400, 2410, 2412, 24a0, 2460, 2440, 2442, 2443
cpu/s3c/		generic stuff that is shared
cpu/arm1136/s3c64xx	6400, later 6410

-- 
- Harald Welte <laforge at gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)
-------------- next part --------------
/*
 *  armboot - Startup Code for S3C24xx CPU-cores
 *
 *  Copyright (c) 2006-2008 Harald Welte <laforge at openmoko.org>
 *
 * S3C2410 NAND portions
 *  Copyright (c) 2001  MIZI Research, Inc.
 *
 */

#if defined(CONFIG_S3C2410)
#include <s3c2410.h>
#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
#include <s3c2440.h>
#endif

/* the actual start code */

start_code:
	/*
	 * set the cpu to SVC32 mode
	 */
	mrs	r0,cpsr
	bic	r0,r0,#0x1f
	orr	r0,r0,#0xd3
	msr	cpsr,r0

	/* in case we run from the s3c24xx NAND stepping stone, the symbols
	 * for LED support are in lib_arm/board.o, i.e. outside of the
	 * steppingstone */
#ifndef CONFIG_S3C2410_NAND_BOOT
	bl coloured_LED_init
	bl red_LED_on
#endif

	/* turn off the watchdog */

# if defined(CONFIG_S3C2400)
#  define pWTCON		0x15300000
#  define INTMSK		0x14400008	/* Interupt-Controller base addresses */
#  define CLKDIVN	0x14800014	/* clock divisor register */
#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
#  define pWTCON		0x53000000
#  define INTMSK		0x4A000008	/* Interupt-Controller base addresses */
#  define INTSUBMSK	0x4A00001C
#  define CLKDIVN	0x4C000014	/* clock divisor register */
# endif

#if defined(CONFIG_S3C2410)
# define INTSUBMSK_val	0x7ff
# define MPLLCON_val	((0x90 << 12) + (0x7 << 4) + 0x0)	/* 202 MHz */
# define UPLLCON_val	((0x78 << 12) + (0x2 << 4) + 0x3)
# define CLKDIVN_val	3 /* FCLK:HCLK:PCLK = 1:2:4 */
#elif defined(CONFIG_S3C2440)
# define INTSUBMSK_val	0xffff
# if (CONFIG_SYS_CLK_FREQ == 16934400)
#  define MPLLCON_val	((0x61 << 12) + (0x1 << 4) + 0x2)	/* 296.35 MHz */
#  define UPLLCON_val	((0x3c << 12) + (0x4 << 4) + 0x2)	/*  47.98 MHz */
# else if (CONFIG_SYS_CLK_FREQ == 12000000)
#  define MPLLCON_val	((0x44 << 12) + (0x1 << 4) + 0x1)	/* 304.00 MHz */
#  define UPLLCON_val	((0x38 << 12) + (0x2 << 4) + 0x2)	/*  48.00 MHz */
# endif
# define CLKDIVN_val	7 /* FCLK:HCLK:PCLK = 1:3:6 */
# define CAMDIVN	0x4C000018
#elif defined(CONFIG_S3C2442)
# define INTSUBMSK_val        0xffff
# if (CONFIG_SYS_CLK_FREQ == 12000000)
#  define MPLLCON_val ((142 << 12) + (7 << 4) + 1)
#  define UPLLCON_val   (( 88 << 12) + (8 << 4) + 2)
# elif (CONFIG_SYS_CLK_FREQ == 16934400)
#  define MPLLCON_val   ((181 << 12) + (14<< 4) + 1)
#  define UPLLCON_val   (( 26 << 12) + (4 << 4) + 1)
# endif
# define CLKDIVN_val  7 /* FCLK:HCLK:PCLK = 1:3:6 */
# define CAMDIVN      0x4C000018
#endif

	ldr     r0, =pWTCON
	mov     r1, #0x0
	str     r1, [r0]

	/*
	 * mask all IRQs by setting all bits in the INTMR - default
	 */
	mov	r1, #0xffffffff
	ldr	r0, =INTMSK
	str	r1, [r0]
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
	ldr	r1, =INTSUBMSK_val
	ldr	r0, =INTSUBMSK
	str	r1, [r0]

# if defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
	/* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */
	ldr	r0, =CAMDIVN
	mov	r1, #0
	str	r1, [r0]
# endif

	/* Clock asynchronous mode */
	mrc	p15, 0, r1, c1, c0, 0
	orr	r1, r1, #0xc0000000
	mcr	p15, 0, r1, c1, c0, 0

#define LOCKTIME	0x4c000000
#define UPLLCON		0x4c000008

	ldr	r0, =LOCKTIME
	mov	r1, #0xffffff
	str	r1, [r0]

	ldr	r0, =UPLLCON
	ldr	r1, =UPLLCON_val
	str	r1, [r0]

	/* Page 7-19, seven nops between UPLL and MPLL */
	nop
	nop
	nop
	nop
	nop
	nop
	nop

	ldr	r1, =MPLLCON_val
	str	r1, [r0, #-4]		/* MPLLCON */
#endif /* CONFIG_S3C2410 || CONFIG_S3C2440 */

	/* FCLK:HCLK:PCLK = 1:2:4 */
	ldr	r0, =CLKDIVN
	mov	r1, #CLKDIVN_val
	str	r1, [r0]

	/*
	 * we do sys-critical inits only at reboot,
	 * not when booting from ram!
	 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
#ifndef CONFIG_LL_INIT_FLASH_ONLY
	/* we don't init_crit here since we don't know yet
	 * if we are running from flash or RAM */
	bl	cpu_init_crit
#endif
#endif


#ifndef CONFIG_SKIP_RELOCATE_UBOOT
	adr	r0, _start		/* r0 <- current position of code   */
#ifdef CONFIG_S3C2410_NAND_BOOT
#define	BWSCON	0x48000000
	ldr	r1, =BWSCON		/*  = CPU booted from NAND	*/
	ldr	r1, [r1]
	tst	r1, #6			/* BWSCON[2:1] - OM[1:0]	*/
	teqeq	r0, #0			/* Z &= running at address 0	*/
	beq	nand_load
#endif /* CONFIG_S3C2410_NAND_BOOT

relocate:
	teq	r0, #0			/* running at address 0 ?	    */
	bleq	may_resume		/* yes -> do low-level setup	    */

	adr	r0, _start		/* the above may have clobbered r0  */

	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
	cmp     r0, r1                  /* don't reloc during debug         */
	beq     done_relocate

	ldr	r2, _armboot_start
	ldr	r3, _bss_start
	sub	r2, r3, r2		/* r2 <- size of armboot            */
	add	r2, r0, r2		/* r2 <- source end address         */

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 address [r2]    */
	ble	copy_loop
	mov	r0, #0			/* flush v3/v4 cache */
	mcr	p15, 0, r0, c7, c7, 0
	ldr	pc, _done_relocate	/* jump to relocated code */
_done_relocate:
	.word	done_relocate

#ifdef CONFIG_S3C2410_NAND_BOOT
nand_load:
	bl	may_resume		/* low-level setup and resume */

	/* mov	r10, lr */

	@ reset NAND
#if defined(CONFIG_S3C2410)
	mov	r1, #S3C2410_NAND_BASE
	ldr	r2, =0xf842		@ initial value enable tacls=3,rph0=6,rph1=0
	str	r2, [r1, #oNFCONF]
	ldr	r2, [r1, #oNFCONF]
	bic	r2, r2, #0x800		@ enable chip
	str	r2, [r1, #oNFCONF]
	mov	r2, #0xff		@ RESET command
	strb	r2, [r1, #oNFCMD]
	mov	r3, #0			@ wait
1:	add	r3, r3, #0x1
	cmp	r3, #0xa
	blt	1b
2:	ldr	r2, [r1, #oNFSTAT]	@ wait ready
	tst	r2, #0x1
	beq	2b
	ldr	r2, [r1, #oNFCONF]
	orr	r2, r2, #0x800		@ disable chip
	str	r2, [r1, #oNFCONF]
#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
	mov	r1, #S3C2440_NAND_BASE
	ldr	r2, =0xfff0		@ initial value tacls=3,rph0=7,rph1=7
	ldr	r3, [r1, #oNFCONF]
	orr	r3, r3, r2
	str	r3, [r1, #oNFCONF]

	ldr	r3, [r1, #oNFCONT]
	orr	r3, r3, #1		@ enable nand controller
	str	r3, [r1, #oNFCONT]
#endif /* CONFIG_S3C2440 || CONFIG_S3C2442 */

	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
	sub	r0, r0, #CFG_MALLOC_LEN	/* malloc area                      */
	sub	r0, r0, #CFG_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    */

	@ copy u-boot to RAM
	ldr	r0, _TEXT_BASE
	mov     r1, #0x0
	mov	r2, #CFG_UBOOT_SIZE
	bl	nand_read_ll

	tst	r0, #0x0
	beq	ok_nand_read
bad_nand_read:
1:	b	1b		@ infinite loop

ok_nand_read:
	@ verify
	mov	r0, #0
	@ldr	r1, =0x33f00000
	ldr	r1, _TEXT_BASE
	mov	r2, #0x400	@ 4 bytes * 1024 = 4K-bytes
go_next:
	ldr	r3, [r0], #4
	ldr	r4, [r1], #4
	teq	r3, r4
	bne	notmatch
	subs	r2, r2, #4
	beq	done_nand_read
	bne	go_next
notmatch:
1:	b	1b
done_nand_read:
#endif /* CONFIG_S3C2410_NAND_BOOT */
done_relocate:

#if defined(CONFIG_USE_IRQ)
	/* In the case we've somehow magically (JTAG, ...) ended up in RAM,
	   then that ram is mapped to 0x30000000 and not 0.
	   So we need to copy the interrupt vectors, etc.  */

	mov	r0, #0
	ldr	r1, _TEXT_BASE
	mov	r2, #0x40
irqvec_cpy_next:
	ldr	r3, [r1], #4
	str	r3, [r0], #4
	subs	r2, r2, #4
	bne	irqvec_cpy_next
#endif /* CONFIG_USE_IRQ */

#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */

	/* Set up the stack						    */
stack_setup:
	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
	sub	r0, r0, #CFG_MALLOC_LEN	/* malloc area                      */
	sub	r0, r0, #CFG_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    */

clear_bss:
	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

	ldr	pc, _start_armboot

_start_armboot:	.word start_armboot


/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */


#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
	/*
	 * 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, 0
	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
	mcr	p15, 0, r0, c1, c0, 0

	/*
	 * before relocating, we have to setup RAM timing
	 * because memory timing is board-dependend, you will
	 * find a lowlevel_init.S in your board directory.
	 */
	mov	ip, lr

	bl	lowlevel_init

	mov	lr, ip
	mov	pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

/*************************************************************************
 * may_resume
 * Bring up memory and check if we're coming out of suspend.
 *************************************************************************/
may_resume:
	mov	r10, lr			/* we may call cpu_init_crit */

	/* take sdram out of power down */
	ldr	r0, =0x56000080		/* misccr */
	ldr	r1, [ r0 ]
	bic	r1, r1, #(S3C2410_MISCCR_nEN_SCLK0 | S3C2410_MISCCR_nEN_SCLK1 | S3C2410_MISCCR_nEN_SCLKE)
	str	r1, [ r0 ]

	/* ensure signals stabalise */
	mov	r1, #128
1:	subs	r1, r1, #1
	bpl	1b

#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && defined(CONFIG_LL_INIT_FLASH_ONLY)
	bl	cpu_init_crit
#endif
	/* ensure some refresh has happened */
	ldr	r1, =0xfffff
1:	subs	r1, r1, #1
	bpl	1b

	/* test for resume */
	ldr	r1, =0x560000B4		/* gstatus2 */
	ldr	r0, [ r1 ]
	tst	r0, #0x02		/* is this resume from power down */
	ldrne	pc, [r1, #4]		/* gstatus3 */

	mov	pc, r10



-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.denx.de/pipermail/u-boot/attachments/20080707/2f15ce00/attachment.pgp 


More information about the U-Boot mailing list