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 <[EMAIL PROTECTED]>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)
/*
 *  armboot - Startup Code for S3C24xx CPU-cores
 *
 *  Copyright (c) 2006-2008 Harald Welte <[EMAIL PROTECTED]>
 *
 * 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



Attachment: signature.asc
Description: Digital signature

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
U-Boot-Users mailing list
U-Boot-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/u-boot-users

Reply via email to