From c876d3bbefe0dc00c27ca0c12d29da5874946962 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Wed, 15 Dec 2021 21:04:28 +0100 Subject: rbutil: Merge rbutil with utils folder. rbutil uses several components from the utils folder, and can be considered part of utils too. Having it in a separate folder is an arbitrary split that doesn't help anymore these days, so merge them. This also allows other utils to easily use libtools.make without the need to navigate to a different folder. Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21 --- utils/mkzenboot/dualboot/Makefile | 51 +++++++++++++ utils/mkzenboot/dualboot/bin2c.c | 140 ++++++++++++++++++++++++++++++++++ utils/mkzenboot/dualboot/config.h | 22 ++++++ utils/mkzenboot/dualboot/dualboot.c | 136 +++++++++++++++++++++++++++++++++ utils/mkzenboot/dualboot/dualboot.lds | 32 ++++++++ 5 files changed, 381 insertions(+) create mode 100644 utils/mkzenboot/dualboot/Makefile create mode 100644 utils/mkzenboot/dualboot/bin2c.c create mode 100644 utils/mkzenboot/dualboot/config.h create mode 100644 utils/mkzenboot/dualboot/dualboot.c create mode 100644 utils/mkzenboot/dualboot/dualboot.lds (limited to 'utils/mkzenboot/dualboot') diff --git a/utils/mkzenboot/dualboot/Makefile b/utils/mkzenboot/dualboot/Makefile new file mode 100644 index 0000000000..752cc3ca28 --- /dev/null +++ b/utils/mkzenboot/dualboot/Makefile @@ -0,0 +1,51 @@ +CC=gcc +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 +LDFLAGS= +# 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=zenmozaic zenxfi zen zenv +OPT_zenmozaic=-DCREATIVE_ZENMOZAIC -DIMX233_SUBTARGET=3700 +OPT_zenxfi=-DCREATIVE_ZENXFI -DIMX233_SUBTARGET=3700 +OPT_zen=-DCREATIVE_ZEN -DIMX233_SUBTARGET=3700 +OPT_zenv=-DCREATIVE_ZENV -DIMX233_SUBTARGET=3600 + +BOOTLDS=$(patsubst %, dualboot_%.lds, $(TARGETS)) +BOOTOBJS=$(patsubst %, dualboot_%.o, $(TARGETS)) +BOOTBINS=$(patsubst %, dualboot_%.arm-bin, $(TARGETS)) +BOOTELFS=$(patsubst %, dualboot_%.arm-elf, $(TARGETS)) + +all: ../dualboot.h ../dualboot.c $(BOOTELFS) + +# Dualboot bootloaders + +dualboot_%.o: dualboot.c + $(CROSS_PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.o=%)) -c -o $@ $^ + +dualboot_%.lds: dualboot.lds + $(CROSS_PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.lds=%)) -E -x c - < $< | sed '/#/d' > $@ + +dualboot_%.arm-elf: dualboot_%.o dualboot_%.lds + $(CROSS_PREFIX)$(LD) $(LDFLAGS) -T$(@:dualboot_%.arm-elf=dualboot_%.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-bin: %.arm-elf + $(CROSS_PREFIX)$(OC) -O binary $< $@ + +../dualboot.c ../dualboot.h: $(BOOTBINS) bin2c + ./bin2c ../dualboot $(BOOTBINS) + +bin2c: bin2c.c + $(CC) -o bin2c bin2c.c + +clean: + rm -f *~ bin2c $(BOOTBINS) $(BOOTOBJS) $(BOOTELFS) $(BOOTLDS) diff --git a/utils/mkzenboot/dualboot/bin2c.c b/utils/mkzenboot/dualboot/bin2c.c new file mode 100644 index 0000000000..b02af88a4d --- /dev/null +++ b/utils/mkzenboot/dualboot/bin2c.c @@ -0,0 +1,140 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Dave Chapman + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static off_t filesize(int fd) +{ + struct stat buf; + + fstat(fd,&buf); + return buf.st_size; +} + +static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name) +{ + int i; + + fprintf(fp,"unsigned char %s[%ld] = {",name,len); + + for (i=0;i orig_len) + memset(buf+orig_len, 0, len-orig_len); + + /* remove file extension */ + ext = strchr (array, '.'); + if (ext != NULL) + *ext = '\0'; + write_cfile (buf, len, cfile, array); + fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len); + + close(fd); + } + + fclose(cfile); + fclose(hfile); + + return 0; +} diff --git a/utils/mkzenboot/dualboot/config.h b/utils/mkzenboot/dualboot/config.h new file mode 100644 index 0000000000..ff59cee710 --- /dev/null +++ b/utils/mkzenboot/dualboot/config.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ + +/** empty, used by register files */ diff --git a/utils/mkzenboot/dualboot/dualboot.c b/utils/mkzenboot/dualboot/dualboot.c new file mode 100644 index 0000000000..0b32772afb --- /dev/null +++ b/utils/mkzenboot/dualboot/dualboot.c @@ -0,0 +1,136 @@ +/*************************************************************************** + * __________ __ ___. + * 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" +#include "regs-lradc.h" +#include "regs-digctl.h" + +typedef unsigned long uint32_t; + +// 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 +} + +/* only works for channels <=7, always divide by 2, never accumulates */ +static inline void __attribute__((always_inline)) setup_lradc(int src) +{ + BF_CLR(LRADC_CTRL0, SFTRST); + BF_CLR(LRADC_CTRL0, CLKGATE); + /* don't bother changing the source, we are early enough at boot so that + * channel x is mapped to source x */ + HW_LRADC_CHn_CLR(src) = BM_OR2(LRADC_CHn, NUM_SAMPLES, ACCUMULATE); + BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << src); +} + +#define BP_LRADC_CTRL1_LRADCx_IRQ(x) (x) +#define BM_LRADC_CTRL1_LRADCx_IRQ(x) (1 << (x)) + +static inline int __attribute__((always_inline)) read_lradc(int src) +{ + BF_CLR(LRADC_CTRL1, LRADCx_IRQ(src)); + BF_SETV(LRADC_CTRL0, SCHEDULE, 1 << src); + while(!BF_RD(LRADC_CTRL1, LRADCx_IRQ(src))); + return BF_RDn(LRADC_CHn, src, VALUE); +} + +static inline void __attribute__((noreturn)) power_down() +{ + /* power down */ + HW_POWER_RESET = BM_OR2(POWER_RESET, UNLOCK, PWD); + while(1); +} + +/** + * Boot decision functions + */ + +#if defined(CREATIVE_ZENMOZAIC) || defined(CREATIVE_ZEN) || defined(CREATIVE_ZENXFI) \ + || defined(CREATIVE_ZENV) +static enum boot_t boot_decision() +{ + setup_lradc(0); // setup LRADC channel 0 to read keys + /* make a decision */ + /* read keys */ + int val = read_lradc(0); + /* if back is pressed, boot to OF + * otherwise boot to RB */ + if(val >= 2650 && val < 2750) // conveniently, all players use the same value + return BOOT_OF; + return BOOT_ROCK; +} +#else +#warning You should define a target specific boot decision function +static int boot_decision() +{ + return BOOT_ROCK; +} +#endif + +static int main(uint32_t rb_addr, uint32_t of_addr) +{ + switch(boot_decision()) + { + case BOOT_ROCK: + return rb_addr; + case BOOT_OF: + /* fix back the loading address + /* NOTE: see mkzenboot for more details */ + *(uint32_t *)0x20 = of_addr; + return 0; + case BOOT_STOP: + default: + power_down(); + } +} + +/** Glue for the linker mostly */ + +extern uint32_t of_vector; +extern uint32_t rb_vector; +extern uint32_t boot_arg; + +void __attribute__((section(".start"))) start() +{ + uint32_t addr = main(rb_vector, of_vector); + ((void (*)(uint32_t))addr)(boot_arg); +} diff --git a/utils/mkzenboot/dualboot/dualboot.lds b/utils/mkzenboot/dualboot/dualboot.lds new file mode 100644 index 0000000000..7444a1e427 --- /dev/null +++ b/utils/mkzenboot/dualboot/dualboot.lds @@ -0,0 +1,32 @@ +ENTRY(start) +OUTPUT_FORMAT(elf32-littlearm) +OUTPUT_ARCH(arm) + +MEMORY +{ + /* keep this consistent with the address in mkzenboot.c */ +#if IMX233_SUBTARGET == 3700 + RAM : ORIGIN = 0x41000000, LENGTH = 0x8000 +#elif IMX233_SUBTARGET == 3600 + RAM : ORIGIN = 0x61000000, LENGTH = 0x8000 +#else +#error define me +#endif +} + +SECTIONS +{ + .text : + { + *(.start*) + *(.text*) + . = ALIGN(4); + LONG(0x1ceb00da) + of_vector = .; + . += 4; + rb_vector = .; + . += 4; + boot_arg = .; + . += 4; + } > RAM +} -- cgit v1.2.3