[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