1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Karl Kurbjun
12 * Arm bootloader and startup code based on startup.s from the iPodLinux
14 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
15 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
25 ****************************************************************************/
30 #define CACHE_ALL 0x0C
32 /****************************************************************************/
33 #ifdef TOSHIBA_GIGABEAT_F
35 /* Clock and Power Management setup values */
36 #define VAL_CLKDIV 0x7
37 #define VAL_UPLLCON 0x0003C042
38 #define VAL_MPLLCON 0x000C9042
40 /* Memory Controller setup */
41 /* Memory setup (taken from 0x5070) */
45 * Bus width 01 (16 bit)
51 * Buswidth 10 (32 bit)
55 * Buswidth 10 (32 bit)
59 * Buswidth 10 (32 bit)
67 * Buswidth 10 (32 bit)
75 #define VAL_BWSCON 0x01055102
77 * Pagemode: normal (1 data) 00
78 * Pagemode access cycle: 2 clocks 00
79 * Address hold: 2 clocks 10
80 * Chip selection hold time: 1 clock 10
81 * Access cycle: 8 clocks 101
82 * Chip select setup time: 1 clock 01
83 * Address setup time: 0 clock 00
85 #define VAL_BANKCON0 0x00000D60
87 * Pagemode: normal (1 data) 00
88 * Pagemode access cycle: 2 clocks 00
89 * Address hold: 0 clocks 00
90 * Chip selection hold time: 0 clock 00
91 * Access cycle: 1 clocks 000
92 * Chip select setup time: 0 clocks 00
93 * Address setup time: 0 clocks 00
95 #define VAL_BANKCON1 0x00000000
97 * Pagemode: normal (1 data) 00
98 * Pagemode access cycle: 2 clocks 00
99 * Address hold: 2 clocks 10
100 * Chip selection hold time: 2 clocks 10
101 * Access cycle: 14 clocks 111
102 * Chip select setup time: 4 clocks 11
103 * Address setup time: 0 clocks 00
105 #define VAL_BANKCON2 0x00001FA0
106 #define VAL_BANKCON3 0x00001D80
107 #define VAL_BANKCON4 0x00001D80
108 #define VAL_BANKCON5 0x00000000
119 #define VAL_BANKCON6 0x00018005
120 #define VAL_BANKCON7 0x00018005
122 #define VAL_REFRESH 0x00980501
124 * BK76MAP: 32M/32M 000
125 * Reserved: 0 0 (was 1)
126 * SCLK_EN: always 1 (was 0)
129 * BURST_EN: enabled 1
131 #define VAL_BANKSIZE 0x00000090
132 #define VAL_MRSRB6 0x00000030
133 #define VAL_MRSRB7 0x00000030
134 #define VAL_GPACON 0x00FFFFFF
136 /****************************************************************************/
137 #elif defined (MINI2440)
139 /* For Mini2440 board or compatible */
140 /* Clock and Power Management setup values */
141 /* NB: clock settings must match values in s3c2440/system-target.h */
142 #define VAL_CLKDIV 0x5 /* HCLK = FCLK/4, PCLK = HCLK/2 */
143 #define VAL_UPLLCON 0x00038022 /* UCLK = 48 MHz */
144 #define VAL_MPLLCON 0x000C3041 /* FCLK = 406 MHz */
147 /* Memory Controller setup */
148 #define VAL_BWSCON 0x22111112
149 #define VAL_BANKCON0 0x00002F50
150 #define VAL_BANKCON1 0x00000700
151 #define VAL_BANKCON2 0x00000700
152 #define VAL_BANKCON3 0x00000700
153 #define VAL_BANKCON4 0x00000700
154 #define VAL_BANKCON5 0x0007FFFC
155 #define VAL_BANKCON6 0x00018009
156 #define VAL_BANKCON7 0x00018009
158 #define VAL_REFRESH 0x008E04EB
159 #define VAL_BANKSIZE 0x000000B2
160 #define VAL_MRSRB6 0x00000030
161 #define VAL_MRSRB7 0x00000030
163 #define VAL_GPACON 0x00FFFFFF
164 #define VAL_GPFCON 0x000055AA
165 #define VAL_GPGCON 0xAA2A0128
166 #define VAL_GPGDAT 0x0000
169 #error Unknown target
171 /****************************************************************************/
173 /* Exception Handlers */
174 .section .vectors,"ax",%progbits
180 b undef_instr_handler
181 b software_int_handler
182 b prefetch_abort_handler
188 /* This branch is used to make sure that we know where the shutdown routine
189 * is located in flash (0x040A0020)
193 /* Add some strings to detect the bootloader in flash and give it a version
194 * number. (0x040A0028, 0x040A002C)
200 * Function: word_copy
207 .section .init.text, "ax", %progbits
210 .type word_copy, %function
218 .size word_copy, .-word_copy
227 .section .init.text,"ax",%progbits
233 /* Get the execute address; R0 is used to store the address and it should
234 * not be written to till the rest of the execution checks are done below.
235 * This is done first thing since we have to check if the code was started
236 * with the old rockbox bootloader that offset the image by 100 bytes.
241 /************************** DO NOT WRITE TO R0 ***************************/
243 #ifdef TOSHIBA_GIGABEAT_F
244 /* Check if the code is running from flash. If not skip all these checks */
248 /* Point LCDSADDR1 to the boot logo for lcd_init_device in lcd-meg-fx.c */
253 /* Did an RTC event wake the player up? */
256 ands r1, r1, #0x40000000
258 /* Store a flag in GSTATUS3 to indicate that the bootloader is flashed */
262 /* Woke up with the alarm? - store a flag in GSTATUS3 */
267 /* Set GPG up to read power and menu status */
273 /* Check if menu is held down */
278 /* Check if power is held down */
282 /* Set GPF up to read charger connection if power is not held down */
287 /* Check if charger is connected */
293 /* power is not down || menu is held || the charger is not connected */
298 /* enter supervisor mode, disable IRQ */
301 /* Disable the watchdog */
306 /* Mask all Interupts to be safe */
315 #ifdef TOSHIBA_GIGABEAT_F
316 /* Check if loaded by the old bootloader or by the OF. This copy routine
317 * cannot run/copy properly until the memory has been initialized, so the
318 * copy routine later is still necessary. The old bootloader/OF will
319 * initialize the memory.
322 /* Calculate the length of the code needed to run/copy */
323 ldr r1, = _vectorstart
324 ldr r2, = _initdata_end
327 add r3, r2, #0x30000000
329 /* Is there enough space to copy without overwriting? */
332 /* There's enough space, skip copying */
335 /* Is this code running from 0xA0000? If so skip copy. */
339 /****************************** OK TO USE R0 *****************************/
341 /* There's not enough space to copy without overwriting, copy to safe
344 mov r1, #0x31000000 /* copy location */
352 /* Initial Clock Setup */
353 /* set Bus to Asynchronous mode (full speed) */
355 mrc p15, 0, r0, c1, c0, 0
358 mcr p15, 0, r0, c1, c0, 0
406 ldr r2, =VAL_BANKCON0
410 ldr r2, =VAL_BANKCON1
414 ldr r2, =VAL_BANKCON2
418 ldr r2, =VAL_BANKCON3
424 ldr r2, =VAL_BANKCON5
428 ldr r2, =VAL_BANKCON6
438 ldr r2, =VAL_BANKSIZE
447 /* RMC: I guess this is some notes about Gigabeat */
468 /* Copy from current location (from NOR Flash if bootloader, load buffer if
471 /* Gigabeat: The builds have two potential load addresses, one being from flash,
472 * and the other from some "unknown" location right now the assumption
473 * is that the code is not at 0x3000000.
475 /* get the high part of our execute address (where am I) */
477 and r0, pc, r0 /* copy from address */
479 /* SDRAM starts at 0x30000000 (physical address) */
480 ldr r1, =0x30000000 /* copy To address */
481 ldr r2, = _vectorstart
482 ldr r3, = _initdata_end
483 sub r2, r3, r2 /* length of loader */
489 bx r1 /* The code is located where we want it so jump */
493 /* Setup the MMU, start by disabling */
495 mrc p15, 0, r0, c1, c0, 0
496 bic r0, r0, #0x5 /* disable mmu and dcache */
497 bic r0, r0, #0x1000 /* disable icache */
498 mcr p15, 0, r0, c1, c0, 0
514 ldr r0, =LCD_FRAME_ADDR /* LCD Frame buffer */
522 /* Initialise bss section to zero */
531 /* Set up some stack and munge it with 0xdeadbeef */
541 /* Set up stack for IRQ mode */
544 /* Set up stack for FIQ mode */
548 /* Let abort and undefined modes use IRQ stack */
553 /* Switch to supervisor mode */
557 /* Start the main function */
561 /* Should never get here, but let's restart in case (also needed for
566 /* All illegal exceptions call into UIE with exception address as first
567 parameter. This is calculated differently depending on which exception
568 we're in. Second parameter is exception number, used for a string lookup
576 /* We run supervisor mode most of the time, and should never see a software
577 exception being thrown. Perhaps make it illegal and call UIE?
579 software_int_handler:
583 prefetch_abort_handler:
593 #if defined(BOOTLOADER)
601 /* TODO: Review this function - is it target dependent? */
603 * Function: rom_shutdown
608 .section .init.text, "ax", %progbits
611 .type rom_shutdown, %function
613 /* Turn off the MMU */
614 mrc p15, 0, r1, c1, c0, 0
616 mcr p15, 0, r1, c1, c0, 0
618 /* Taken from 0x10010 */
619 ldr r2, =0x56000014 //GPBDAT
620 ldr r1, =0x56000010 //GPBCON
622 ldr r8, =0x56000024 //GPCDAT
623 ldr r10, =0x56000020 //GPCCON
625 ldr r6, =0x56000024 //GPDDAT
626 ldr r7, =0x56000030 //GPDCON
627 ldr r12, =0x56000044 //GPEDAT
628 ldr lr, =0x56000040 //GPECON
629 ldr r0, =0x56000054 //GPFDAT
644 str r4, [r0],#(0x56000064-0x56000054) //(GPGDAT - GPFDAT)
645 add r12, r12, #(0x56000060-0x56000044)//(GPGCON - GPEDAT)
646 ldr r1, =0x56000050 //GPFCON
649 str r3, [r1],#(0x56000074-0x56000050)// (GPHDAT - GPFCON)
650 str r4, [r0],#(0x56000060-0x56000054)// (GPGCON - GPFDAT)
655 ldr r12, =0x4A000008 //INTMSK
657 // mov r3, #0x200000 // disable EINT13
660 str r2, [r0] // GPFDAT=0x140A5
661 ldr r2, =0x56000088 //EXTINT0
662 ldr r0, =0x4A000010 //INTPND
664 add r1, r1, #(0x56000068 - 0x56000050) // (GPGUP - GPFCON) (0x18)
665 str lr, [r12] /* INTMSK = 0xFFFFFFFF */
666 str r3, [r2],#(0x560000A4 - 0x56000088) // (EINTMASK - EXTINT0) disable EINT13 (0x1C)
667 // mov r3, #0xFFFFFECF
669 str r5, [r1],#(0x56000074-0x56000058) //(GPHDAT - GPFUP) (0x1C) DCLKCON
676 // add r3, r3, #0x00000100
678 str r3, [r12] // disable INT_TICK
681 add r2, r2, #(0x560000B0-0x56000088) //(GSTATUS1 - EXTINT0) //; 0x600 (0x28)
686 str r3, [r2] // GSTATUS1 = 0x600 /* what for ??? */
688 ldr r12, =0x56000080 //MISCCr
689 mov r2, #0x58000000 //ADCCON
691 add r2, r2, #(0x4D000000-0x58000000) //(LCDCON1 - ADCCON) // LCDCON1 (0xF5000000)
693 ldr r0, =0x48000024 // REFRESH
694 bic r3, r3, #0x700000
696 orr r3, r3, #0x600000
698 str r3, [r12] // MISCCR = (MISCCR & ~0x100000) | 0x603000;
699 /* clear [20] BATTFLT_FUNC - BATT_FLT function On/Off.
700 * 0, Battery fault function will be turned on.
701 * set [21] BATTFLT_INTR - BATT_FLT Interrupt On/Off.
702 * 1, Battery fault interrupt will be masked by hardware.
703 * set [13] SEL_SUSPND1 - USB Port 1 Suspend mode
705 * set [12] SEL_SUSPND0 - USB Port 0 Suspend mode
708 mov r3, #0x4C000000 // LOCKTIME
713 ldr lr, =0x4C00000C // CLKCON
714 // str r1, [r11,#-0x28]
716 // str r2, [r11,#-0x28]
718 orr r3, r3, #0x00C00000
720 * [22] TREFMD - SDRAM Refresh Mode
726 /* [3] SLEEP - Control SLEEP mode of S3C2440X.
727 * [4] NAND - Control HCLK into NAND Flash Controller block.
728 * [14] RTC - Control PCLK into RTC control block.
730 orr r2, r2, #0x000E0000
731 /* [17] nEN_SCLK0 - SCLK0 output enable (1: SCLK 0 = 0)
732 * [18] nEN_SCLK1 - SCLK1 output enable (1: SCLK 1 = 0)
733 * [19] OFFREFRESH - Self refresh retain enable after wake-up from sleep
742 .size rom_shutdown, .-rom_shutdown
745 /* 256 words of IRQ stack */
749 /* 256 words of FIQ stack */