diff options
Diffstat (limited to 'utils/mkzenboot/dualboot')
-rw-r--r-- | utils/mkzenboot/dualboot/Makefile | 51 | ||||
-rw-r--r-- | utils/mkzenboot/dualboot/bin2c.c | 140 | ||||
-rw-r--r-- | utils/mkzenboot/dualboot/config.h | 22 | ||||
-rw-r--r-- | utils/mkzenboot/dualboot/dualboot.c | 136 | ||||
-rw-r--r-- | utils/mkzenboot/dualboot/dualboot.lds | 32 |
5 files changed, 381 insertions, 0 deletions
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 @@ | |||
1 | CC=gcc | ||
2 | LD=ld | ||
3 | OC=objcopy | ||
4 | CROSS_PREFIX=arm-elf-eabi- | ||
5 | REGS_PATH=../../../firmware/target/arm/imx233/regs | ||
6 | CFLAGS=-mcpu=arm926ej-s -std=gnu99 -I. -I$(REGS_PATH) -nostdlib -ffreestanding -fomit-frame-pointer -O | ||
7 | LDFLAGS= | ||
8 | # Edit the following variables when adding a new target. | ||
9 | # mkimxboot.c also needs to be edited to refer to these | ||
10 | # To add a new target x you need to: | ||
11 | # 1) add x to the list in TARGETS | ||
12 | # 2) create a variable named OPT_x of the form: | ||
13 | # OPT_x=target specific defines | ||
14 | TARGETS=zenmozaic zenxfi zen zenv | ||
15 | OPT_zenmozaic=-DCREATIVE_ZENMOZAIC -DIMX233_SUBTARGET=3700 | ||
16 | OPT_zenxfi=-DCREATIVE_ZENXFI -DIMX233_SUBTARGET=3700 | ||
17 | OPT_zen=-DCREATIVE_ZEN -DIMX233_SUBTARGET=3700 | ||
18 | OPT_zenv=-DCREATIVE_ZENV -DIMX233_SUBTARGET=3600 | ||
19 | |||
20 | BOOTLDS=$(patsubst %, dualboot_%.lds, $(TARGETS)) | ||
21 | BOOTOBJS=$(patsubst %, dualboot_%.o, $(TARGETS)) | ||
22 | BOOTBINS=$(patsubst %, dualboot_%.arm-bin, $(TARGETS)) | ||
23 | BOOTELFS=$(patsubst %, dualboot_%.arm-elf, $(TARGETS)) | ||
24 | |||
25 | all: ../dualboot.h ../dualboot.c $(BOOTELFS) | ||
26 | |||
27 | # Dualboot bootloaders | ||
28 | |||
29 | dualboot_%.o: dualboot.c | ||
30 | $(CROSS_PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.o=%)) -c -o $@ $^ | ||
31 | |||
32 | dualboot_%.lds: dualboot.lds | ||
33 | $(CROSS_PREFIX)$(CC) $(CFLAGS) $(OPT_$(@:dualboot_%.lds=%)) -E -x c - < $< | sed '/#/d' > $@ | ||
34 | |||
35 | dualboot_%.arm-elf: dualboot_%.o dualboot_%.lds | ||
36 | $(CROSS_PREFIX)$(LD) $(LDFLAGS) -T$(@:dualboot_%.arm-elf=dualboot_%.lds) -o $@ $< | ||
37 | |||
38 | # Rules for the ARM code embedded in mkamsboot - assemble, link, then extract | ||
39 | # the binary code and finally convert to .h for building in mkamsboot | ||
40 | |||
41 | %.arm-bin: %.arm-elf | ||
42 | $(CROSS_PREFIX)$(OC) -O binary $< $@ | ||
43 | |||
44 | ../dualboot.c ../dualboot.h: $(BOOTBINS) bin2c | ||
45 | ./bin2c ../dualboot $(BOOTBINS) | ||
46 | |||
47 | bin2c: bin2c.c | ||
48 | $(CC) -o bin2c bin2c.c | ||
49 | |||
50 | clean: | ||
51 | 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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 Dave Chapman | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdio.h> | ||
23 | #include <string.h> | ||
24 | #include <sys/types.h> | ||
25 | #include <sys/stat.h> | ||
26 | #include <unistd.h> | ||
27 | #include <fcntl.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <libgen.h> | ||
30 | |||
31 | #ifndef O_BINARY | ||
32 | #define O_BINARY 0 | ||
33 | #endif | ||
34 | |||
35 | static off_t filesize(int fd) | ||
36 | { | ||
37 | struct stat buf; | ||
38 | |||
39 | fstat(fd,&buf); | ||
40 | return buf.st_size; | ||
41 | } | ||
42 | |||
43 | static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name) | ||
44 | { | ||
45 | int i; | ||
46 | |||
47 | fprintf(fp,"unsigned char %s[%ld] = {",name,len); | ||
48 | |||
49 | for (i=0;i<len;i++) { | ||
50 | if ((i % 16) == 0) { | ||
51 | fprintf(fp,"\n "); | ||
52 | } | ||
53 | if (i == (len-1)) { | ||
54 | fprintf(fp,"0x%02x",buf[i]); | ||
55 | } else if ((i % 16) == 15) { | ||
56 | fprintf(fp,"0x%02x,",buf[i]); | ||
57 | } else { | ||
58 | fprintf(fp,"0x%02x, ",buf[i]); | ||
59 | } | ||
60 | } | ||
61 | fprintf(fp,"\n};\n"); | ||
62 | } | ||
63 | |||
64 | int main (int argc, char* argv[]) | ||
65 | { | ||
66 | char* cname; | ||
67 | int i; | ||
68 | FILE *cfile, *hfile; | ||
69 | char cfilename[256], hfilename[256]; | ||
70 | |||
71 | if (argc < 3) { | ||
72 | fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n"); | ||
73 | return 1; | ||
74 | } | ||
75 | |||
76 | cname=argv[1]; | ||
77 | |||
78 | snprintf(cfilename,256,"%s.c",cname); | ||
79 | cfile = fopen(cfilename,"w+"); | ||
80 | if (cfile == NULL) { | ||
81 | fprintf(stderr,"Couldn't open %s\n",cfilename); | ||
82 | return 2; | ||
83 | } | ||
84 | |||
85 | snprintf(hfilename,256,"%s.h",cname); | ||
86 | hfile = fopen(hfilename,"w+"); | ||
87 | if (hfile == NULL) { | ||
88 | fprintf(stderr,"Couldn't open %s\n",hfilename); | ||
89 | fclose(cfile); | ||
90 | return 3; | ||
91 | } | ||
92 | |||
93 | fprintf(cfile,"/* Generated by bin2c */\n\n"); | ||
94 | fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename)); | ||
95 | fprintf(hfile,"/* Generated by bin2c */\n\n"); | ||
96 | |||
97 | for(i=0; i < argc - 2; i++) { | ||
98 | unsigned char* buf; | ||
99 | off_t len; | ||
100 | off_t orig_len; | ||
101 | char *ext; | ||
102 | char *array = argv[2+i]; | ||
103 | |||
104 | int fd = open(array,O_RDONLY|O_BINARY); | ||
105 | if (fd < 0) { | ||
106 | fprintf(stderr,"Can not open %s\n",argv[2+i]); | ||
107 | fclose(cfile); | ||
108 | fclose(hfile); | ||
109 | return 4; | ||
110 | } | ||
111 | |||
112 | orig_len = filesize(fd); | ||
113 | /* pad to 32bit */ | ||
114 | len = (orig_len + 3) & ~3; | ||
115 | |||
116 | buf = malloc(len); | ||
117 | if (read(fd,buf,orig_len) < orig_len) { | ||
118 | fprintf(stderr,"Short read, aborting\n"); | ||
119 | return 5; | ||
120 | } | ||
121 | |||
122 | /* pad to 32bit with zeros */ | ||
123 | if (len > orig_len) | ||
124 | memset(buf+orig_len, 0, len-orig_len); | ||
125 | |||
126 | /* remove file extension */ | ||
127 | ext = strchr (array, '.'); | ||
128 | if (ext != NULL) | ||
129 | *ext = '\0'; | ||
130 | write_cfile (buf, len, cfile, array); | ||
131 | fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len); | ||
132 | |||
133 | close(fd); | ||
134 | } | ||
135 | |||
136 | fclose(cfile); | ||
137 | fclose(hfile); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2013 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | /** 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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2013 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "regs-pinctrl.h" | ||
22 | #include "regs-power.h" | ||
23 | #include "regs-lradc.h" | ||
24 | #include "regs-digctl.h" | ||
25 | |||
26 | typedef unsigned long uint32_t; | ||
27 | |||
28 | // target specific boot decision | ||
29 | enum boot_t | ||
30 | { | ||
31 | BOOT_STOP, /* power down */ | ||
32 | BOOT_ROCK, /* boot to Rockbox */ | ||
33 | BOOT_OF, /* boot to OF */ | ||
34 | }; | ||
35 | |||
36 | /** | ||
37 | * Helper functions | ||
38 | */ | ||
39 | |||
40 | static inline int __attribute__((always_inline)) read_gpio(int bank, int pin) | ||
41 | { | ||
42 | return (HW_PINCTRL_DINn(bank) >> pin) & 1; | ||
43 | } | ||
44 | |||
45 | static inline int __attribute__((always_inline)) read_pswitch(void) | ||
46 | { | ||
47 | #if IMX233_SUBTARGET >= 3700 | ||
48 | return BF_RD(POWER_STS, PSWITCH); | ||
49 | #else | ||
50 | return BF_RD(DIGCTL_STATUS, PSWITCH); | ||
51 | #endif | ||
52 | } | ||
53 | |||
54 | /* only works for channels <=7, always divide by 2, never accumulates */ | ||
55 | static inline void __attribute__((always_inline)) setup_lradc(int src) | ||
56 | { | ||
57 | BF_CLR(LRADC_CTRL0, SFTRST); | ||
58 | BF_CLR(LRADC_CTRL0, CLKGATE); | ||
59 | /* don't bother changing the source, we are early enough at boot so that | ||
60 | * channel x is mapped to source x */ | ||
61 | HW_LRADC_CHn_CLR(src) = BM_OR2(LRADC_CHn, NUM_SAMPLES, ACCUMULATE); | ||
62 | BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << src); | ||
63 | } | ||
64 | |||
65 | #define BP_LRADC_CTRL1_LRADCx_IRQ(x) (x) | ||
66 | #define BM_LRADC_CTRL1_LRADCx_IRQ(x) (1 << (x)) | ||
67 | |||
68 | static inline int __attribute__((always_inline)) read_lradc(int src) | ||
69 | { | ||
70 | BF_CLR(LRADC_CTRL1, LRADCx_IRQ(src)); | ||
71 | BF_SETV(LRADC_CTRL0, SCHEDULE, 1 << src); | ||
72 | while(!BF_RD(LRADC_CTRL1, LRADCx_IRQ(src))); | ||
73 | return BF_RDn(LRADC_CHn, src, VALUE); | ||
74 | } | ||
75 | |||
76 | static inline void __attribute__((noreturn)) power_down() | ||
77 | { | ||
78 | /* power down */ | ||
79 | HW_POWER_RESET = BM_OR2(POWER_RESET, UNLOCK, PWD); | ||
80 | while(1); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * Boot decision functions | ||
85 | */ | ||
86 | |||
87 | #if defined(CREATIVE_ZENMOZAIC) || defined(CREATIVE_ZEN) || defined(CREATIVE_ZENXFI) \ | ||
88 | || defined(CREATIVE_ZENV) | ||
89 | static enum boot_t boot_decision() | ||
90 | { | ||
91 | setup_lradc(0); // setup LRADC channel 0 to read keys | ||
92 | /* make a decision */ | ||
93 | /* read keys */ | ||
94 | int val = read_lradc(0); | ||
95 | /* if back is pressed, boot to OF | ||
96 | * otherwise boot to RB */ | ||
97 | if(val >= 2650 && val < 2750) // conveniently, all players use the same value | ||
98 | return BOOT_OF; | ||
99 | return BOOT_ROCK; | ||
100 | } | ||
101 | #else | ||
102 | #warning You should define a target specific boot decision function | ||
103 | static int boot_decision() | ||
104 | { | ||
105 | return BOOT_ROCK; | ||
106 | } | ||
107 | #endif | ||
108 | |||
109 | static int main(uint32_t rb_addr, uint32_t of_addr) | ||
110 | { | ||
111 | switch(boot_decision()) | ||
112 | { | ||
113 | case BOOT_ROCK: | ||
114 | return rb_addr; | ||
115 | case BOOT_OF: | ||
116 | /* fix back the loading address | ||
117 | /* NOTE: see mkzenboot for more details */ | ||
118 | *(uint32_t *)0x20 = of_addr; | ||
119 | return 0; | ||
120 | case BOOT_STOP: | ||
121 | default: | ||
122 | power_down(); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | /** Glue for the linker mostly */ | ||
127 | |||
128 | extern uint32_t of_vector; | ||
129 | extern uint32_t rb_vector; | ||
130 | extern uint32_t boot_arg; | ||
131 | |||
132 | void __attribute__((section(".start"))) start() | ||
133 | { | ||
134 | uint32_t addr = main(rb_vector, of_vector); | ||
135 | ((void (*)(uint32_t))addr)(boot_arg); | ||
136 | } | ||
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 @@ | |||
1 | ENTRY(start) | ||
2 | OUTPUT_FORMAT(elf32-littlearm) | ||
3 | OUTPUT_ARCH(arm) | ||
4 | |||
5 | MEMORY | ||
6 | { | ||
7 | /* keep this consistent with the address in mkzenboot.c */ | ||
8 | #if IMX233_SUBTARGET == 3700 | ||
9 | RAM : ORIGIN = 0x41000000, LENGTH = 0x8000 | ||
10 | #elif IMX233_SUBTARGET == 3600 | ||
11 | RAM : ORIGIN = 0x61000000, LENGTH = 0x8000 | ||
12 | #else | ||
13 | #error define me | ||
14 | #endif | ||
15 | } | ||
16 | |||
17 | SECTIONS | ||
18 | { | ||
19 | .text : | ||
20 | { | ||
21 | *(.start*) | ||
22 | *(.text*) | ||
23 | . = ALIGN(4); | ||
24 | LONG(0x1ceb00da) | ||
25 | of_vector = .; | ||
26 | . += 4; | ||
27 | rb_vector = .; | ||
28 | . += 4; | ||
29 | boot_arg = .; | ||
30 | . += 4; | ||
31 | } > RAM | ||
32 | } | ||