summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorDaniel Ankers <dan@weirdo.org.uk>2006-08-31 19:45:05 +0000
committerDaniel Ankers <dan@weirdo.org.uk>2006-08-31 19:45:05 +0000
commit41997d3d89ed72c49a2dc5ac7f0aaa15093f5aba (patch)
tree38be931a85559b36a9fbfa85e6247e9b7d91a8d6 /firmware/target
parentc42f5d88da00f9dcf9369cc1235a3cf6dddadf28 (diff)
Clean up crt0.S and move it to the target tree
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10830 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/crt0-pp.S375
-rw-r--r--firmware/target/arm/crt0.S232
-rw-r--r--firmware/target/coldfire/crt0.S260
-rw-r--r--firmware/target/sh/crt0.S214
4 files changed, 1081 insertions, 0 deletions
diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S
new file mode 100644
index 0000000000..d847d9d943
--- /dev/null
+++ b/firmware/target/arm/crt0-pp.S
@@ -0,0 +1,375 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+
+ .section .init.text,"ax",%progbits
+
+ .global start
+start:
+
+/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux
+ * loader
+ *
+ * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
+ * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
+ *
+ */
+#if CONFIG_CPU == PP5002
+ .equ PROC_ID, 0xc4000000
+ .equ COP_CTRL, 0xcf004058
+ .equ COP_STATUS, 0xcf004050
+ .equ IIS_CONFIG, 0xc0002500
+ .equ SLEEP, 0xca
+ .equ WAKE, 0xce
+ .equ SLEEPING, 0x4000
+#else
+ .equ PROC_ID, 0x60000000
+ .equ COP_CTRL, 0x60007004
+ .equ COP_STATUS, 0x60007004
+ .equ IIS_CONFIG, 0x70002800
+ .equ SLEEP, 0x80000000
+ .equ WAKE, 0x0
+ .equ SLEEPING, 0x80000000
+#endif
+
+ msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
+
+#ifndef BOOTLOADER
+ b pad_skip
+.space 50*4 /* (more than enough) space for exception vectors */
+pad_skip:
+ /* We need to remap memory from wherever SDRAM is mapped natively, to
+ base address 0, so we can put our exception vectors there. We don't
+ want to do this remapping while executing from SDRAM, so we copy the
+ remapping code to IRAM, then execute from there. Hence, the following
+ code is compiled for address 0, but is currently executing at either
+ 0x28000000 or 0x10000000, depending on chipset version. Do not use any
+ absolute addresses until remapping has been done. */
+ ldr r1, =0x40000000
+ ldr r2, =remap_start
+ ldr r3, =remap_end
+
+ and r5, pc, #0xff000000 /* adjust for execute address */
+ orr r2, r2, r5
+ orr r3, r3, r5
+
+ /* copy the code to 0x40000000 */
+1:
+ ldr r4, [r2], #4
+ str r4, [r1], #4
+ cmp r2, r3
+ ble 1b
+
+ ldr r3, =0x3f84 /* r3 and r1 values here are magic, don't touch */
+ orr r3, r3, r5 /* adjust for execute address */
+ ldr r2, =0xf000f014
+ mov r1, #0x3a00
+ ldr r0, =0xf000f010
+ mov pc, #0x40000000
+
+remap_start:
+ str r1, [r0]
+ str r3, [r2]
+ ldr r0, L_post_remap
+ mov pc, r0
+L_post_remap: .word remap_end
+remap_end:
+
+ /* After doing the remapping, send the COP to sleep.
+ On wakeup it will go to cop_init */
+ ldr r0, =PROC_ID
+ ldr r0, [r0]
+ and r0, r0, #0xff
+ cmp r0, #0x55
+ beq 1f
+
+ /* put us (co-processor) to sleep */
+ ldr r4, =COP_CTRL
+ mov r3, #SLEEP
+ str r3, [r4]
+
+ ldr pc, =cop_init
+
+1:
+
+#ifndef DEBUG
+ /* Copy exception handler code to address 0 */
+ ldr r2, =_vectorsstart
+ ldr r3, =_vectorsend
+ ldr r4, =_vectorscopy
+1:
+ cmp r3, r2
+ ldrhi r5, [r4], #4
+ strhi r5, [r2], #4
+ bhi 1b
+#else
+ ldr r1, =vectors
+ ldr r0, =irq_handler
+ str r0, [r1, #24]
+ ldr r0, =fiq_handler
+ str r0, [r1, #28]
+#endif
+
+#ifndef STUB
+ /* Zero out IBSS */
+ ldr r2, =_iedata
+ ldr r3, =_iend
+ mov r4, #0
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /* Copy the IRAM */
+ ldr r2, =_iramcopy
+ ldr r3, =_iramstart
+ ldr r4, =_iramend
+1:
+ cmp r4, r3
+ ldrhi r5, [r2], #4
+ strhi r5, [r3], #4
+ bhi 1b
+#endif /* !STUB */
+#endif /* !BOOTLOADER */
+
+ /* Initialise bss section to zero */
+ ldr r2, =_edata
+ ldr r3, =_end
+ mov r4, #0
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /* Set up some stack and munge it with 0xdeadbeef */
+ ldr sp, =stackend
+ mov r3, sp
+ ldr r2, =stackbegin
+ ldr r4, =0xdeadbeef
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+#ifdef BOOTLOADER
+ /* TODO: the high part of the address is probably dependent on CONFIG_CPU.
+ Since we tend to use ifdefs for each chipset target
+ anyway, we might as well just hardcode it here.
+ */
+
+ /* get the high part of our execute address */
+ ldr r0, =0xff000000
+ and r8, pc, r0 @ r8 is used later
+
+ /* Find out which processor we are */
+ mov r0, #PROC_ID
+ ldr r0, [r0]
+ and r0, r0, #0xff
+ cmp r0, #0x55
+ beq 1f
+
+ /* put us (co-processor) to sleep */
+ ldr r4, =COP_CTRL
+ mov r3, #SLEEP
+ str r3, [r4]
+ ldr pc, =cop_wake_start
+
+cop_wake_start:
+ /* jump the COP to startup */
+ ldr r0, =startup_loc
+ ldr pc, [r0]
+
+1:
+
+ /* get the high part of our execute address */
+ ldr r2, =0xffffff00
+ and r4, pc, r2
+
+ /* Copy bootloader to safe area - 0x40000000 */
+ mov r5, #0x40000000
+ ldr r6, = _dataend
+ sub r0, r6, r5 /* length of loader */
+ add r0, r4, r0 /* r0 points to start of loader */
+1:
+ cmp r5, r6
+ ldrcc r2, [r4], #4
+ strcc r2, [r5], #4
+ bcc 1b
+
+ ldr pc, =start_loc /* jump to the relocated start_loc: */
+
+start_loc:
+
+ /* execute the loader - this will load an image to 0x10000000 */
+ bl main
+
+ /* Wake up the coprocessor before executing the firmware */
+
+ /* save the startup address for the COP */
+ ldr r1, =startup_loc
+ str r0, [r1]
+
+ /* make sure COP is sleeping */
+ ldr r4, =COP_STATUS
+1:
+ ldr r3, [r4]
+ ands r3, r3, #SLEEPING
+ beq 1b
+
+ /* wake up COP */
+ ldr r4, =COP_CTRL
+ mov r3, #WAKE
+ str r3, [r4]
+
+ /* jump to start location */
+ mov pc, r0
+
+startup_loc:
+ .word 0x0
+
+.align 8 /* starts at 0x100 */
+.global boot_table
+boot_table:
+ /* here comes the boot table, don't move its offset */
+ .space 400
+
+#else /* BOOTLOADER */
+
+ /* Set up stack for IRQ mode */
+ msr cpsr_c, #0xd2
+ ldr sp, =irq_stack
+ /* Set up stack for FIQ mode */
+ msr cpsr_c, #0xd1
+ ldr sp, =fiq_stack
+ /* We'll load the banked FIQ mode registers with useful values here.
+ These values will be used in the FIQ handler in pcm_playback.c */
+ ldr r12, =IIS_CONFIG
+
+ ldr r11, =p
+
+ /* Let abort and undefined modes use IRQ stack */
+ msr cpsr_c, #0xd7
+ ldr sp, =irq_stack
+ msr cpsr_c, #0xdb
+ ldr sp, =irq_stack
+ /* Switch to supervisor mode */
+ msr cpsr_c, #0xd3
+ ldr sp, =stackend
+ bl main
+ /* main() should never return */
+
+cop_init:
+ ldr sp, =cop_stackend
+ mov r3, sp
+ ldr r2, =cop_stackbegin
+ ldr r4, =0xdeadbeef
+2:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 2b
+
+ ldr sp, =cop_stackend
+ bl cop_main
+
+/* Exception handlers. Will be copied to address 0 after memory remapping */
+ .section .vectors,"aw"
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+
+ /* Exception vectors */
+ .global vectors
+vectors:
+ .word start
+ .word undef_instr_handler
+ .word software_int_handler
+ .word prefetch_abort_handler
+ .word data_abort_handler
+ .word reserved_handler
+ .word irq_handler
+ .word fiq_handler
+
+ .text
+
+#ifndef STUB
+ .global irq
+ .global fiq
+ .global UIE
+#endif
+
+/* All illegal exceptions call into UIE with exception address as first
+ parameter. This is calculated differently depending on which exception
+ we're in. Second parameter is exception number, used for a string lookup
+ in UIE.
+ */
+undef_instr_handler:
+ mov r0, lr
+ mov r1, #0
+ b UIE
+
+/* We run supervisor mode most of the time, and should never see a software
+ exception being thrown. Perhaps make it illegal and call UIE?
+ */
+software_int_handler:
+reserved_handler:
+ movs pc, lr
+
+prefetch_abort_handler:
+ sub r0, lr, #4
+ mov r1, #1
+ b UIE
+
+fiq_handler:
+ @ Branch straight to FIQ handler in pcm_playback.c. This also handles the
+ @ the correct return sequence.
+ ldr pc, =fiq
+
+data_abort_handler:
+ sub r0, lr, #8
+ mov r1, #2
+ b UIE
+
+irq_handler:
+#ifndef STUB
+ stmfd sp!, {r0-r3, r12, lr}
+ bl irq
+ ldmfd sp!, {r0-r3, r12, lr}
+#endif
+ subs pc, lr, #4
+
+#ifdef STUB
+UIE:
+ b UIE
+#endif
+
+/* 256 words of IRQ stack */
+ .space 256*4
+irq_stack:
+
+/* 256 words of FIQ stack */
+ .space 256*4
+fiq_stack:
+
+#endif /* BOOTLOADER */
diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S
new file mode 100644
index 0000000000..82b7c31f92
--- /dev/null
+++ b/firmware/target/arm/crt0.S
@@ -0,0 +1,232 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+
+ .section .init.text,"ax",%progbits
+
+ .global start
+start:
+
+/* Arm bootloader and startup code based on startup.s from the iPodLinux loader
+ *
+ * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
+ * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
+ *
+ */
+
+ msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
+
+#ifndef BOOTLOADER
+#if CONFIG_CPU == PNX0101
+
+#ifndef DEBUG
+ ldr r0, =0x80105000
+ mov r1, #1
+ str r1, [r0, #4]
+ mov r1, #0
+ str r1, [r0, #4]
+1: ldr r1, [r0]
+ cmp r1, #0
+ bne 1b
+ mov r1, #0x74
+ str r1, [r0, #8]
+ mov r1, #2
+ str r1, [r0, #0x18]
+ mov r1, #0x120
+ str r1, [r0, #0x30]
+ mov r1, #6
+ str r1, [r0, #4]
+ ldr r0, =1f
+ mov r15, r0
+1:
+#endif /* !DEBUG */
+#endif /* chipset specific */
+
+#ifndef DEBUG
+ /* Copy exception handler code to address 0 */
+ ldr r2, =_vectorsstart
+ ldr r3, =_vectorsend
+ ldr r4, =_vectorscopy
+1:
+ cmp r3, r2
+ ldrhi r5, [r4], #4
+ strhi r5, [r2], #4
+ bhi 1b
+#else
+ ldr r1, =vectors
+ ldr r0, =irq_handler
+ str r0, [r1, #24]
+ ldr r0, =fiq_handler
+ str r0, [r1, #28]
+#endif
+
+#ifndef STUB
+ /* Zero out IBSS */
+ ldr r2, =_iedata
+ ldr r3, =_iend
+ mov r4, #0
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /* Copy the IRAM */
+ ldr r2, =_iramcopy
+ ldr r3, =_iramstart
+ ldr r4, =_iramend
+1:
+ cmp r4, r3
+ ldrhi r5, [r2], #4
+ strhi r5, [r3], #4
+ bhi 1b
+#endif /* !STUB */
+#endif /* !BOOTLOADER */
+
+ /* Initialise bss section to zero */
+ ldr r2, =_edata
+ ldr r3, =_end
+ mov r4, #0
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /* Set up some stack and munge it with 0xdeadbeef */
+ ldr sp, =stackend
+ mov r3, sp
+ ldr r2, =stackbegin
+ ldr r4, =0xdeadbeef
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+#ifdef BOOTLOADER
+/* Code for ARM bootloader targets other than iPod go here */
+
+#if CONFIG_CPU == S3C2440
+ bl main
+#endif
+
+#else /* BOOTLOADER */
+
+ /* Set up stack for IRQ mode */
+ msr cpsr_c, #0xd2
+ ldr sp, =irq_stack
+ /* Set up stack for FIQ mode */
+ msr cpsr_c, #0xd1
+ ldr sp, =fiq_stack
+
+ /* Let abort and undefined modes use IRQ stack */
+ msr cpsr_c, #0xd7
+ ldr sp, =irq_stack
+ msr cpsr_c, #0xdb
+ ldr sp, =irq_stack
+ /* Switch to supervisor mode */
+ msr cpsr_c, #0xd3
+ ldr sp, =stackend
+ bl main
+ /* main() should never return */
+
+/* Exception handlers. Will be copied to address 0 after memory remapping */
+ .section .vectors,"aw"
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+ ldr pc, [pc, #24]
+
+ /* Exception vectors */
+ .global vectors
+vectors:
+ .word start
+ .word undef_instr_handler
+ .word software_int_handler
+ .word prefetch_abort_handler
+ .word data_abort_handler
+ .word reserved_handler
+ .word irq_handler
+ .word fiq_handler
+
+ .text
+
+#ifndef STUB
+ .global irq
+ .global fiq
+ .global UIE
+#endif
+
+/* All illegal exceptions call into UIE with exception address as first
+ parameter. This is calculated differently depending on which exception
+ we're in. Second parameter is exception number, used for a string lookup
+ in UIE.
+ */
+undef_instr_handler:
+ mov r0, lr
+ mov r1, #0
+ b UIE
+
+/* We run supervisor mode most of the time, and should never see a software
+ exception being thrown. Perhaps make it illegal and call UIE?
+ */
+software_int_handler:
+reserved_handler:
+ movs pc, lr
+
+prefetch_abort_handler:
+ sub r0, lr, #4
+ mov r1, #1
+ b UIE
+
+fiq_handler:
+ @ Branch straight to FIQ handler in pcm_playback.c. This also handles the
+ @ the correct return sequence.
+ ldr pc, =fiq
+
+data_abort_handler:
+ sub r0, lr, #8
+ mov r1, #2
+ b UIE
+
+irq_handler:
+#ifndef STUB
+ stmfd sp!, {r0-r3, r12, lr}
+ bl irq
+ ldmfd sp!, {r0-r3, r12, lr}
+#endif
+ subs pc, lr, #4
+
+#ifdef STUB
+UIE:
+ b UIE
+#endif
+
+/* 256 words of IRQ stack */
+ .space 256*4
+irq_stack:
+
+/* 256 words of FIQ stack */
+ .space 256*4
+fiq_stack:
+
+#endif /* BOOTLOADER */
diff --git a/firmware/target/coldfire/crt0.S b/firmware/target/coldfire/crt0.S
new file mode 100644
index 0000000000..a0e948486e
--- /dev/null
+++ b/firmware/target/coldfire/crt0.S
@@ -0,0 +1,260 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+
+ .section .init.text,"ax",@progbits
+
+ .global start
+start:
+
+ move.w #0x2700,%sr
+
+ move.l #vectors,%d0
+ movec.l %d0,%vbr
+
+ move.l #MBAR+1,%d0
+ movec.l %d0,%mbar
+
+ move.l #MBAR2+1,%d0
+ movec.l %d0,%mbar2
+
+ lea MBAR,%a0
+ lea MBAR2,%a1
+
+ clr.l (0x180,%a1) /* PLLCR = 0 */
+
+ /* 64K DMA-capable SRAM at 0x10000000
+ DMA is enabled and has priority in both banks
+ All types of accesses are allowed
+ (We might want to restrict that to save power) */
+ move.l #0x10000e01,%d0
+ movec.l %d0,%rambar1
+
+ /* 32K Non-DMA SRAM at 0x10010000
+ All types of accesses are allowed
+ (We might want to restrict that to save power) */
+ move.l #0x10010001,%d0
+ movec.l %d0,%rambar0
+
+ /* Chip select 0 - Flash ROM */
+ moveq.l #0x00,%d0 /* CSAR0 - Base = 0x00000000 */
+ move.l %d0,(0x080,%a0)
+ move.l #FLASH_SIZE-0x10000+1,%d0 /* CSMR0 - All access */
+ move.l %d0,(0x084,%a0)
+ move.l #0x00000180,%d0 /* CSCR0 - no wait states, 16 bits, no bursts */
+ move.l %d0,(0x088,%a0)
+
+ /* Chip select 1 - LCD controller */
+ move.l #0xf0000000,%d0 /* CSAR1 - Base = 0xf0000000 */
+ move.l %d0,(0x08c,%a0)
+ moveq.l #0x1,%d0 /* CSMR1 - 64K */
+ move.l %d0,(0x090,%a0)
+ move.l #0x00000180,%d0 /* CSCR1 - no wait states, 16 bits, no bursts */
+ move.l %d0,(0x094,%a0)
+
+ /* Chip select 2 - ATA controller */
+ move.l #0x20000000,%d0 /* CSAR2 - Base = 0x20000000 */
+ move.l %d0,(0x098,%a0)
+ move.l #0x000f0001,%d0 /* CSMR2 - 64K, Only data access */
+ move.l %d0,(0x09c,%a0)
+ move.l #0x00000080,%d0 /* CSCR2 - no wait states, 16 bits, no bursts */
+ move.l %d0,(0x0a0,%a0) /* NOTE: I'm not sure about the wait states.
+ We have to be careful with the access times,
+ since IORDY isn't connected to the HDD. */
+
+#if CONFIG_USBOTG == USBOTG_ISP1362
+ /* Chip select 3 - USBOTG controller */
+ move.l #0xc0000000,%d0 /* CSAR3 - Base = 0xc0000000 */
+ move.l %d0,(0x0a4,%a0)
+ moveq.l #0x1,%d0 /* CSMR3 - 64K */
+ move.l %d0,(0x0a8,%a0)
+ move.l #0x00000180,%d0 /* CSCR3 - no wait states, 16 bits, no bursts */
+ move.l %d0,(0x0ac,%a0)
+#endif
+
+#ifdef BOOTLOADER
+ /* Check if original firmware is still present */
+ lea 0x00001000,%a2
+ move.l (%a2),%d0
+ move.l #0xfbfbfbf1,%d1
+ cmp.l %d0,%d1
+ beq.b .ignorecookie
+
+ /* The cookie is not reset. This must mean that the boot loader
+ has crashed. Let's start the original firmware immediately. */
+ lea 0x10017ffc,%a2
+ move.l (%a2),%d0
+ move.l #0xc0015a17,%d1
+ cmp.l %d0,%d1
+ bne.b .nocookie
+ /* Clear the cookie again */
+ clr.l (%a2)
+ jmp 8
+
+.nocookie:
+ /* Set the cookie */
+ move.l %d1,(%a2)
+.ignorecookie:
+
+ /* Set up the DRAM controller. The refresh is based on the 11.2896MHz
+ clock (5.6448MHz bus frequency). We haven't yet started the PLL */
+#if MEM < 32
+ move.w #0x8004,%d0 /* DCR - Synchronous, 80 cycle refresh */
+#else
+ move.w #0x8001,%d0 /* DCR - Synchronous, 32 cycle refresh */
+#endif
+ move.w %d0,(0x100,%a0)
+
+ /* Note on 32Mbyte models:
+ We place the SDRAM on an 0x1000000 (16M) offset because
+ the 5249 BGA chip has a fault which disables the use of A24. The
+ suggested workaround by FreeScale is to offset the base address by
+ half the DRAM size and increase the mask to the double.
+ In our case this means that we set the base address 16M ahead and
+ use a 64M mask.
+ */
+#if MEM < 32
+ move.l #0x31002324,%d0 /* DACR0 - Base 0x31000000, Banks on 21 and up,
+ CAS latency 1, Page mode, No refresh yet */
+ move.l %d0,(0x108,%a0)
+ move.l #0x00fc0001,%d0 /* Size: 16M */
+ move.l %d0,(0x10c,%a0) /* DMR0 - 32Mb */
+#else
+ move.l #0x31002524,%d0 /* DACR0 - Base 0x31000000, Banks on 23 and up,
+ CAS latency 1, Page mode, No refresh yet */
+ move.l %d0,(0x108,%a0)
+ move.l #0x03fc0001,%d0 /* Size: 64M because of workaround above */
+ move.l %d0,(0x10c,%a0) /* DMR0 - 32Mb */
+#endif
+
+ /* Precharge */
+ moveq.l #8,%d0
+ or.l %d0,(0x108,%a0) /* DACR0[IP] = 1, next access will issue a
+ Precharge command */
+ move.l #0xabcd1234,%d0
+ move.l %d0,0x31000000 /* Issue precharge command */
+
+ move.l #0x8000,%d0
+ or.l %d0,(0x108,%a0) /* Enable refresh */
+
+ /* Let it refresh */
+ move.l #500,%d0
+.delayloop:
+ subq.l #1,%d0
+ bne.b .delayloop
+
+ /* Mode Register init */
+ moveq.l #0x40,%d0 /* DACR0[IMRS] = 1, next access will set the
+ Mode Register */
+ or.l %d0,(0x108,%a0)
+
+ move.l #0xabcd1234,%d0
+ move.l %d0,0x31000800 /* A12=1 means CASL=1 (a0 is not connected) */
+
+ /* DACR0[IMRS] gets deactivated by the SDRAM controller */
+#endif /* BOOTLOADER */
+
+ /* Invalicate cache */
+ move.l #0x01000000,%d0
+ movec.l %d0,%cacr
+
+ /* Enable cache, default=non-cacheable,no buffered writes */
+ move.l #0x80000000,%d0
+ movec.l %d0,%cacr
+
+ /* Cache enabled in SDRAM only, buffered writes enabled */
+ move.l #0x3103c020,%d0
+ movec.l %d0,%acr0
+ moveq.l #0,%d0
+ movec.l %d0,%acr1
+
+#ifndef BOOTLOADER
+ /* zero out .ibss */
+ lea _iedata,%a2
+ lea _iend,%a4
+ bra.b .iedatastart
+.iedataloop:
+ clr.l (%a2)+
+.iedatastart:
+ cmp.l %a2,%a4
+ bhi.b .iedataloop
+
+ /* copy the .iram section */
+ lea _iramcopy,%a2
+ lea _iramstart,%a3
+ lea _iramend,%a4
+ bra.b .iramstart
+.iramloop:
+ move.l (%a2)+,(%a3)+
+.iramstart:
+ cmp.l %a3,%a4
+ bhi.b .iramloop
+#endif /* !BOOTLOADER */
+
+#ifdef IRIVER_H300_SERIES
+ /* Set KEEP_ACT before doing the lengthy copy and zero-fill operations */
+ move.l #0x00080000,%d0
+ or.l %d0,(0xb4,%a1)
+ or.l %d0,(0xb8,%a1)
+ or.l %d0,(0xbc,%a1)
+#endif
+
+ /* zero out bss */
+ lea _edata,%a2
+ lea _end,%a4
+ bra.b .edatastart
+.edataloop:
+ clr.l (%a2)+
+.edatastart:
+ cmp.l %a2,%a4
+ bhi.b .edataloop
+
+ /* copy the .data section */
+ lea _datacopy,%a2
+ lea _datastart,%a3
+ cmp.l %a2,%a3
+ beq.b .nodatacopy /* Don't copy if src and dest are equal */
+ lea _dataend,%a4
+ bra.b .datastart
+.dataloop:
+ move.l (%a2)+,(%a3)+
+.datastart:
+ cmp.l %a3,%a4
+ bhi.b .dataloop
+.nodatacopy:
+
+ /* Munge the main stack */
+ lea stackbegin,%a2
+ lea stackend,%a4
+ move.l %a4,%sp
+ move.l #0xdeadbeef,%d0
+.mungeloop:
+ move.l %d0,(%a2)+
+ cmp.l %a2,%a4
+ bhi.b .mungeloop
+
+ jsr main
+.hoo:
+ bra.b .hoo
+
+ .section .resetvectors
+vectors:
+ .long stackend
+ .long start
diff --git a/firmware/target/sh/crt0.S b/firmware/target/sh/crt0.S
new file mode 100644
index 0000000000..87cef56e96
--- /dev/null
+++ b/firmware/target/sh/crt0.S
@@ -0,0 +1,214 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+
+ .section .init.text,"ax",@progbits
+
+ .global start
+start:
+
+ mov.l .vbr_k,r1
+#ifdef DEBUG
+ /* If we have built our code to be loaded via the standalone GDB
+ * stub, we will have out VBR at some other location than 0x9000000.
+ * We must copy the trap vectors for the GDB stub to our vector table. */
+ mov.l .orig_vbr_k,r2
+
+ /* Move the invalid instruction vector (4) */
+ mov #4,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the invalid slot vector (6) */
+ mov #6,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the bus error vector (9) */
+ mov #9,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the DMA bus error vector (10) */
+ mov #10,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the NMI vector as well (11) */
+ mov #11,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the UserBreak vector as well (12) */
+ mov #12,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the breakpoint trap vector (32) */
+ mov #32,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the IO trap vector (33) */
+ mov #33,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the serial Rx interrupt vector (105) */
+ mov #105,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+
+ /* Move the single step trap vector (127) */
+ mov #127,r0
+ shll2 r0
+ mov.l @(r0,r2),r3
+ mov.l r3,@(r0,r1)
+#endif /* DEBUG */
+ ldc r1,vbr
+
+ mov #0,r0
+ ldc r0,gbr
+
+ /* zero out .ibss */
+ mov.l .iedata_k,r0
+ mov.l .iend_k,r1
+ bra .iedatastart
+ mov #0,r2
+.iedataloop: /* backwards is faster and shorter */
+ mov.l r2,@-r1
+.iedatastart:
+ cmp/hi r0,r1
+ bt .iedataloop
+
+ /* copy the .iram section */
+ mov.l .iramcopy_k,r0
+ mov.l .iram_k,r1
+ mov.l .iramend_k,r2
+ /* Note: We cannot put a PC relative load into the delay slot of a 'bra'
+ instruction (the offset would be wrong), but there is nothing else to
+ do before the loop, so the delay slot would be 'nop'. The cmp / bf
+ sequence is the same length, but more efficient. */
+ cmp/hi r1,r2
+ bf .noiramcopy
+.iramloop:
+ mov.l @r0+,r3
+ mov.l r3,@r1
+ add #4,r1
+ cmp/hi r1,r2
+ bt .iramloop
+.noiramcopy:
+
+ /* zero out bss */
+ mov.l .edata_k,r0
+ mov.l .end_k,r1
+ bra .edatastart
+ mov #0,r2
+.edataloop: /* backwards is faster and shorter */
+ mov.l r2,@-r1
+.edatastart:
+ cmp/hi r0,r1
+ bt .edataloop
+
+ /* copy the .data section, for rombased execution */
+ mov.l .datacopy_k,r0
+ mov.l .data_k,r1
+ cmp/eq r0,r1
+ bt .nodatacopy /* Don't copy if src and dest are equal */
+ mov.l .dataend_k,r2
+ cmp/hi r1,r2
+ bf .nodatacopy
+.dataloop:
+ mov.l @r0+,r3
+ mov.l r3,@r1
+ add #4,r1
+ cmp/hi r1,r2
+ bt .dataloop
+.nodatacopy:
+
+ /* Munge the main thread stack */
+ mov.l .stackbegin_k,r0
+ mov.l .stackend_k,r1
+ mov r1,r15
+ mov.l .deadbeef_k,r2
+.mungeloop: /* backwards is faster and shorter */
+ mov.l r2,@-r1
+ cmp/hi r0,r1
+ bt .mungeloop
+
+ /* call the mainline */
+ mov.l .main_k,r0
+ jsr @r0
+ nop
+.hoo:
+ bra .hoo
+ nop
+
+ .align 2
+.vbr_k:
+ .long vectors
+#ifdef DEBUG
+.orig_vbr_k:
+ .long 0x09000000
+#endif
+.iedata_k:
+ .long _iedata
+.iend_k:
+ .long _iend
+.iramcopy_k:
+ .long _iramcopy
+.iram_k:
+ .long _iramstart
+.iramend_k:
+ .long _iramend
+.edata_k:
+ .long _edata
+.end_k:
+ .long _end
+.datacopy_k:
+ .long _datacopy
+.data_k:
+ .long _datastart
+.dataend_k:
+ .long _dataend
+.stackbegin_k:
+ .long _stackbegin
+.stackend_k:
+ .long _stackend
+.deadbeef_k:
+ .long 0xdeadbeef
+.main_k:
+ .long _main
+
+ .section .resetvectors
+vectors:
+ .long start
+ .long _stackend
+ .long start
+ .long _stackend