diff options
Diffstat (limited to 'rbutil/mkimxboot/dualboot')
-rw-r--r-- | rbutil/mkimxboot/dualboot/Makefile | 41 | ||||
-rw-r--r-- | rbutil/mkimxboot/dualboot/dualboot.S | 118 | ||||
-rw-r--r-- | rbutil/mkimxboot/dualboot/dualboot.c | 167 | ||||
-rw-r--r-- | rbutil/mkimxboot/dualboot/dualboot.lds | 1 |
4 files changed, 191 insertions, 136 deletions
diff --git a/rbutil/mkimxboot/dualboot/Makefile b/rbutil/mkimxboot/dualboot/Makefile index 6386b7c622..4bad3a4a12 100644 --- a/rbutil/mkimxboot/dualboot/Makefile +++ b/rbutil/mkimxboot/dualboot/Makefile @@ -1,33 +1,38 @@ CC=gcc -CROSS_PREFIX=arm-elf-eabi -# Edit the following variables (plus copy/paste another set of rules) when -# adding a new target. mkimxboot.c also needs to be edited to refer to these -# new images. - -BOOTOBJS = dualboot_fuzeplus.o dualboot_zenxfi2.o dualboot_zenxfi3.o -BOOTBINS = dualboot_fuzeplus.arm-bin dualboot_zenxfi2.arm-bin dualboot_zenxfi3.arm-bin +LD=ld +OC=objcopy +CROSS_PREFIX=arm-elf-eabi- +REGS_PATH=../../../firmware/target/arm/imx233/regs +CFLAGS=-mcpu=arm926ej-s -std=gnu99 -I. -I$(REGS_PATH) -nostdlib -ffreestanding -fomit-frame-pointer -O +# Edit the following variables when adding a new target. +# mkimxboot.c also needs to be edited to refer to these +# To add a new target x you need to: +# 1) add x to the list in TARGETS +# 2) create a variable named OPT_x of the form: +# OPT_x=target specific defines +TARGETS=fuzeplus zenxfi2 zenxfi3 +OPT_fuzeplus=-DSANSA_FUZEPLUS -DIMX233_SUBTARGET=3780 +OPT_zenxfi2=-DCREATIVE_ZENXFI2 -DIMX233_SUBTARGET=3780 +OPT_zenxfi3=-DCREATIVE_ZENXFI3 -DIMX233_SUBTARGET=3780 + +BOOTOBJS=$(patsubst %, dualboot_%.o, $(TARGETS)) +BOOTBINS=$(patsubst %, dualboot_%.arm-bin, $(TARGETS)) all: ../dualboot.h ../dualboot.c # Dualboot bootloaders -dualboot_fuzeplus.o: dualboot.S - $(CROSS_PREFIX)-$(CC) -mcpu=arm926ej-s -DSANSA_FUZEPLUS -c -o dualboot_fuzeplus.o dualboot.S - -dualboot_zenxfi2.o: dualboot.S - $(CROSS_PREFIX)-$(CC) -mcpu=arm926ej-s -DCREATIVE_ZENXFI2 -c -o dualboot_zenxfi2.o dualboot.S +dualboot_%.o: dualboot.c + $(CROSS_PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.o=%)) -c -o $@ $^ -dualboot_zenxfi3.o: dualboot.S - $(CROSS_PREFIX)-$(CC) -mcpu=arm926ej-s -DCREATIVE_ZENXFI3 -c -o dualboot_zenxfi3.o dualboot.S +dualboot_%.arm-elf: dualboot_%.o + $(CROSS_PREFIX)$(LD) $(LDFLAGS) -Tdualboot.lds -o $@ $< # Rules for the ARM code embedded in mkamsboot - assemble, link, then extract # the binary code and finally convert to .h for building in mkamsboot -%.arm-elf: %.o - $(CROSS_PREFIX)-ld -Tdualboot.lds -o $@ $< - %.arm-bin: %.arm-elf - $(CROSS_PREFIX)-objcopy -O binary $< $@ + $(CROSS_PREFIX)$(OC) -O binary $< $@ ../dualboot.c ../dualboot.h: $(BOOTBINS) bin2c ./bin2c ../dualboot $(BOOTBINS) diff --git a/rbutil/mkimxboot/dualboot/dualboot.S b/rbutil/mkimxboot/dualboot/dualboot.S deleted file mode 100644 index 0508f7e16a..0000000000 --- a/rbutil/mkimxboot/dualboot/dualboot.S +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2011 by Amaury Pouly - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -.text -.global start -@ int start(uint32_t arg, uint32_t *result_id) -start: -#if defined(SANSA_FUZEPLUS) - /* If volume down key is hold, return so that the OF can boot */ - ldr r2, =0x80018610 @ HW_PINCTRL_DIN1 - ldr r2, [r2] - tst r2, #0x40000000 @ bit 30, active low - moveq r0, #0 @ return 0, continue boot - bxeq lr - /* save registers for the ROM */ - stmfd sp!, {r4-r6,lr} - /* if the power source was 5v (ie usb), bypass the power button delay */ - ldr r2, =0x800440c0 @ HW_POWER_STS - ldr r2, [r2] - mov r2, r2, lsl#2 - mov r2, r2, lsr#26 @ extract PWRUP_SOURCE - tst r2, #0x20 @ bit 5: five volts - bne boot_rockbox - /* otherwise monitor the power button for a short time */ - ldr r2, =550000 @ loop count - ldr r4, =0 @ number of times PSWITCH was 1 -pswitch_monitor_loop: - ldr r3, =0x800440c0 @ HW_POWER_STS - ldr r3, [r3] - mov r3, r3, lsl#10 - mov r3, r3, lsr#30 @ extract PSWITCH - cmp r3, #1 - addeq r4, r3 @ add one if PSWITCH=1 (means power hold) - subs r2, #1 - bne pswitch_monitor_loop - /* power down if power wasn't hold long enough */ - ldr r2, =400000 - cmp r4, r2 - bcc power_down - /* jump to section given as argument */ -boot_rockbox: - str r0, [r1] - mov r0, #1 - ldmfd sp!, {r4-r6,pc} -power_down: - ldr r0, =0x80044100 @ HW_POWER_RESET - ldr r1, =0x3E770001 @ unlock key + power down - str r1, [r0] - b power_down -#elif defined(CREATIVE_ZENXFI2) - /* We are lacking buttons on the Zen X-Fi2 because on USB, the select button - * enters recovery mode ! So we can only use power but power is used to power up - * on normal boots and then select is free ! Thus use a non-uniform scheme: - * - normal boot: - * - no key: Rockbox - * - select: OF - * - USB boot: - * - no key: Rockbox - * - power: OF - */ - /* if the power source was 5v (ie usb), check for power (pswitch) */ - ldr r2, =0x800440c0 @ HW_POWER_STS - ldr r2, [r2] - mov r2, r2, lsl#2 - mov r2, r2, lsr#26 @ extract PWRUP_SOURCE - tst r2, #0x20 @ bit 5: five volts - beq boot_normal - /* check pswitch*/ - ldr r2, =0x800440c0 @ HW_POWER_STS - ldr r2, [r2] - mov r2, r2, lsl#10 - mov r2, r2, lsr#30 @ extract PSWITCH - cmp r2, #1 - moveq r0, #0 @ 1 => boot OF - b do_boot -boot_normal: - /* If select key is hold, return so that the OF can boot */ - ldr r2, =0x80018600 @ HW_PINCTRL_DIN0 - ldr r2, [r2] - tst r2, #0x4000 @ bit 14, active low - moveq r0, #0 @ return 0, continue boot - /* r0 must contain the 0 to boot OF and 1 to boot RB */ -do_boot: - bxeq lr - str r0, [r1] - mov r0, #1 - bx lr -#elif defined(CREATIVE_ZENXFI3) - /* If volume down key is hold, return so that the OF can boot */ - ldr r2, =0x80018620 @ HW_PINCTRL_DIN2 - ldr r2, [r2] - tst r2, #0x80 @ bit 7, active low - moveq r0, #0 @ return 0, continue boot - bxeq lr - str r0, [r1] - mov r0, #1 - bx lr -#else -#error No target defined ! -#endif diff --git a/rbutil/mkimxboot/dualboot/dualboot.c b/rbutil/mkimxboot/dualboot/dualboot.c new file mode 100644 index 0000000000..301eca87ad --- /dev/null +++ b/rbutil/mkimxboot/dualboot/dualboot.c @@ -0,0 +1,167 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2013 by Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "regs-pinctrl.h" +#include "regs-power.h" + +#define BOOT_ROM_CONTINUE 0 /* continue boot */ +#define BOOT_ROM_SECTION 1 /* switch to new section *result_id */ + +typedef unsigned long uint32_t; + +// target specific boot context +enum context_t +{ + CONTEXT_NORMAL, /* normal boot */ + CONTEXT_USB, /* USB plugged boot */ + CONTEXT_RTC, /* RTC wake up boot */ +}; +// target specific boot decision +enum boot_t +{ + BOOT_STOP, /* power down */ + BOOT_ROCK, /* boot to Rockbox */ + BOOT_OF, /* boot to OF */ +}; + +/** + * Helper functions + */ + +static inline int __attribute__((always_inline)) read_gpio(int bank, int pin) +{ + return (HW_PINCTRL_DINn(bank) >> pin) & 1; +} + +static inline int __attribute__((always_inline)) read_pswitch(void) +{ +#if IMX233_SUBTARGET >= 3700 + return BF_RD(POWER_STS, PSWITCH); +#else + return BF_RD(DIGCTL_STATUS, PSWITCH); +#endif +} + +static inline void __attribute__((noreturn)) power_down() +{ +#ifdef SANSA_FUZEPLUS + /* B0P09: this pin seems to be important to shutdown the hardware properly */ + HW_PINCTRL_MUXSELn_SET(0) = 3 << 18; + HW_PINCTRL_DOEn(0) = 1 << 9; + HW_PINCTRL_DOUTn(0) = 1 << 9; +#endif + /* power down */ + HW_POWER_RESET = BM_OR2(POWER_RESET, UNLOCK, PWD); + while(1); +} + +/** + * Boot decision functions + */ + +#if defined(SANSA_FUZEPLUS) +static enum boot_t boot_decision(enum context_t context) +{ + /* if volume down is hold, boot to OF */ + if(!read_gpio(1, 30)) + return BOOT_OF; + /* on normal boot, make sure power button is hold long enough */ + if(context == CONTEXT_NORMAL) + { + // monitor PSWITCH + int count = 0; + for(int i = 0; i < 550000; i++) + if(read_pswitch() == 1) + count++; + if(count < 400000) + return BOOT_STOP; + } + return BOOT_ROCK; +} +#elif defined(CREATIVE_ZENXFI2) +static int boot_decision(int context) +{ + /* We are lacking buttons on the Zen X-Fi2 because on USB, the select button + * enters recovery mode ! So we can only use power but power is used to power up + * on normal boots and then select is free ! Thus use a non-uniform scheme: + * - normal boot/RTC: + * - no key: Rockbox + * - select: OF + * - USB boot: + * - no key: Rockbox + * - power: OF + */ + if(context == CONTEXT_USB) + return read_pswitch() == 1 ? BOOT_OF : BOOT_ROCK; + else + return !read_gpio(0, 14) ? BOOT_OF : BOOT_ROCK; +} +#elif defined(CREATIVE_ZENXFI3) +static int boot_decision(int context) +{ + /* if volume down is hold, boot to OF */ + return !read_gpio(2, 7) ? BOOT_OF : BOOT_ROCK; +} +#else +#warning You should define a target specific boot decision function +static int boot_decision(int context) +{ + return BOOT_ROCK; +} +#endif + +/** + * Context functions + */ +static inline enum context_t get_context(void) +{ +#if IMX233_SUBTARGET >= 3780 + /* On the imx233 it's easy because we know the power up source */ + unsigned pwrup_src = BF_RD(POWER_STS, PWRUP_SOURCE); + if(pwrup_src & (1 << 5)) + return CONTEXT_USB; + else if(pwrup_src & (1 << 4)) + return CONTEXT_RTC; + else + return CONTEXT_NORMAL; +#else + /* On the other targets, we need to poke a few more registers */ +#endif +} + +int main(uint32_t arg, uint32_t *result_id) +{ + switch(boot_decision(get_context())) + { + case BOOT_ROCK: + *result_id = arg; + return BOOT_ROM_SECTION; + case BOOT_OF: + return BOOT_ROM_CONTINUE; + case BOOT_STOP: + default: + power_down(); + } +} + +int __attribute__((section(".start"))) start(uint32_t arg, uint32_t *result_id) +{ + return main(arg, result_id); +}
\ No newline at end of file diff --git a/rbutil/mkimxboot/dualboot/dualboot.lds b/rbutil/mkimxboot/dualboot/dualboot.lds index caaff1a41d..09739aee15 100644 --- a/rbutil/mkimxboot/dualboot/dualboot.lds +++ b/rbutil/mkimxboot/dualboot/dualboot.lds @@ -11,6 +11,7 @@ SECTIONS { .text 0 : { + *(.start*) *(.text*) } > OCRAM } |