summaryrefslogtreecommitdiffstats
path: root/rbutil/mkimxboot/dualboot
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/mkimxboot/dualboot')
-rw-r--r--rbutil/mkimxboot/dualboot/Makefile41
-rw-r--r--rbutil/mkimxboot/dualboot/dualboot.S118
-rw-r--r--rbutil/mkimxboot/dualboot/dualboot.c167
-rw-r--r--rbutil/mkimxboot/dualboot/dualboot.lds1
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
}