From 41997d3d89ed72c49a2dc5ac7f0aaa15093f5aba Mon Sep 17 00:00:00 2001 From: Daniel Ankers Date: Thu, 31 Aug 2006 19:45:05 +0000 Subject: 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 --- firmware/SOURCES | 10 ++ firmware/app.lds | 10 +- firmware/boot.lds | 10 +- firmware/rom.lds | 11 ++ firmware/target/arm/crt0-pp.S | 375 ++++++++++++++++++++++++++++++++++++++++ firmware/target/arm/crt0.S | 232 +++++++++++++++++++++++++ firmware/target/coldfire/crt0.S | 260 ++++++++++++++++++++++++++++ firmware/target/sh/crt0.S | 214 +++++++++++++++++++++++ 8 files changed, 1116 insertions(+), 6 deletions(-) create mode 100644 firmware/target/arm/crt0-pp.S create mode 100644 firmware/target/arm/crt0.S create mode 100644 firmware/target/coldfire/crt0.S create mode 100644 firmware/target/sh/crt0.S diff --git a/firmware/SOURCES b/firmware/SOURCES index 07b8355662..9001535150 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -178,7 +178,17 @@ kernel.c rolo.c thread.c timer.c +#ifdef CPU_PP +target/arm/crt0-pp.S +#elif defined(CPU_ARM) +target/arm/crt0.S +#elif defined(CPU_COLDFIRE) +target/coldfire/crt0.S +#elif CONFIG_CPU == SH7034 +target/sh/crt0.S +#else crt0.S +#endif drivers/lcd.S #endif mp3_playback.c diff --git a/firmware/app.lds b/firmware/app.lds index 3ceb8543a9..173573b602 100644 --- a/firmware/app.lds +++ b/firmware/app.lds @@ -3,17 +3,21 @@ ENTRY(start) #ifdef CPU_COLDFIRE OUTPUT_FORMAT(elf32-m68k) -INPUT(crt0.o) +INPUT(target/coldfire/crt0.o) #elif CONFIG_CPU == TCC730 OUTPUT_FORMAT(elf32-calmrisc16) INPUT(crt0.o) #elif defined(CPU_ARM) OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) -INPUT(crt0.o) +#ifdef CPU_PP +INPUT(target/arm/crt0-pp.o) +#elif defined(CPU_ARM) +INPUT(target/arm/crt0.o) +#endif #else OUTPUT_FORMAT(elf32-sh) -INPUT(crt0.o) +INPUT(target/sh/crt0.o) #endif #if CONFIG_CPU == TCC730 diff --git a/firmware/boot.lds b/firmware/boot.lds index 56383d7723..f361e45e9e 100644 --- a/firmware/boot.lds +++ b/firmware/boot.lds @@ -3,18 +3,22 @@ ENTRY(start) #ifdef CPU_COLDFIRE OUTPUT_FORMAT(elf32-m68k) -INPUT(crt0.o) +INPUT(target/coldfire/crt0.o) #elif defined (CPU_ARM) OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) #ifndef IPOD_ARCH /* the ipods can't have the crt0.o mentioned here, but the others can't do without it! */ -INPUT(crt0.o) +#ifdef CPU_PP +INPUT(target/arm/crt0-pp.o) +#else +INPUT(target/arm/crt0.o) +#endif #endif #else OUTPUT_FORMAT(elf32-sh) -INPUT(crt0.o) +INPUT(target/sh/crt0.o) #endif #define DRAMSIZE (MEMORYSIZE * 0x100000) diff --git a/firmware/rom.lds b/firmware/rom.lds index 7e178ae2b2..29e72d70c0 100644 --- a/firmware/rom.lds +++ b/firmware/rom.lds @@ -6,7 +6,18 @@ OUTPUT_FORMAT(elf32-m68k) #else OUTPUT_FORMAT(elf32-sh) #endif +#ifdef CPU_COLDFIRE +INPUT(target/coldfire/crt0.o) +#elif defined(CPU_PP) +INPUT(target/arm/crt0-pp.o) +#elif defined(CPU_ARM) +INPUT(target/arm/crt0.o) +#elif CONFIG_CPU == SH7034 +INPUT(target/sh/crt0.o) +#else INPUT(crt0.o) +#endif + #if MEMORYSIZE >= 32 #define PLUGINSIZE 0xC0000 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 + * + */ +#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 + * + */ + + 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 -- cgit v1.2.3