summaryrefslogtreecommitdiffstats
path: root/rbutil/mkamsboot/dualboot.S
blob: 471158e9a84f3a69ba229659603171af3088adf5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
.text

/* This is the size of the Clip's RAM, but there is nothing to be gained
   (at the moment) by making use of the larger RAM of other targets */

.set DRAM_SIZE, 0x50000

.set GPIOA,     0xC80B0000
.set GPIOB,     0xC80C0000
.set GPIOC,     0xC80D0000
.set GPIOD,     0xC80E0000
.set CGU_PERI,  0xC80F0014


/* Vectors */
        ldr   pc, =start
.word   0
.word   0
.word   0
.word   0
.word   0
.word   0
.word   0

/* These values are filled in by mkamsboot - don't move them from offset 0x20 */
uclunpack_end:   .word   0 /* End of the ucl_unpack function */
uclunpack_size:  .word   0 /* Size in bytes of the ucl_unpack function */

ucl_of_end:      .word   0 /* End of the ucl-compressed OF image */
ucl_of_size:     .word   0 /* Size in bytes of the compressed OF image */

ucl_rb_end:      .word   0 /* End of the ucl-compressed RB image */
ucl_rb_size:     .word   0 /* Size in bytes of the compressed RB image */


start:
        /* First copy the UCL unpack function to the end of RAM */
        ldr   r0, uclunpack_end     /* Source */
        ldr   r1, uclunpack_size    /* Source length */
        sub   r2, r0, r1            /* Source start - 1*/

        ldr   r3, =(DRAM_SIZE-1)    /* Destination end */

uclcopy:
        ldrb  r4, [r0], #-1
        strb  r4, [r3], #-1
        cmp   r2, r3
        bne   uclcopy

        add   r5, r2, #2            /* r5 is entry point of copy of uclunpack */
                                    /* function, plus one (for thumb mode */

        /* enable gpio clock */
        ldr   r0, =CGU_PERI
        ldr   r1, [r0]
        orr   r1, r1, #(1<<16)
        str   r1, [r0]

        /* we check A3 unconditionally of the model because it seems to be */
        /* either hold, either usb on every model */

        ldr   r0, =GPIOA
        mov   r1, #0
        str   r1, [r0, #0x400]
        ldr   r1, [r0, #0x20]    /* read pin A3 */

        cmp   r1, #0
        bne   boot_of

        /* here are model specific tests, for dual boot without a computer */

#ifdef SANSA_CLIP
        /* HOME button */
        ldr   r0, =GPIOB
        mov   r1, #0
        str   r1, [r0, #0x400]
        ldr   r1, [r0, #0x10]   /* read pin B2 */

        cmp   r1, #0
        bne   boot_of
#elif defined(SANSA_E200V2)
        /* DOWN button */
        ldr   r0, =GPIOC
        mov   r1, #0
        str   r1, [r0, #0x400]
        ldr   r1, [r0, #0x100]   /* read pin C6 */

        cmp   r1, #0             /* C6 = #0 means button pressed */
        beq   boot_of
#else
        #error No target-specific key check defined!
#endif

        /* No button was held, so we boot rockbox */
        ldr   r0, ucl_rb_end   /* Address of compressed image */
        ldr   r1, ucl_rb_size    /* Compressed size */
        b     decompress

boot_of:
        ldr   r0, ucl_of_end     /* Address of compressed image */
        ldr   r1, ucl_of_size    /* Compressed size */


decompress:
        /* At this point:                                              */
        /* r5 = entry point (plus one for thumb) of uclunpack function */
        /* r3 = destination_end for copy of UCL image                  */
        /* r0 = source_end for UCL image to copy                       */
        /* r1 = size of UCL image to copy                              */

        sub   r4, r3, r1      /* r4 := destination_start - 1 */
        
fw_copy:
        ldrb  r2, [r0], #-1
        strb  r2, [r3], #-1
        cmp   r3, r4          /* Stop when we reached dest_start-1 */
        bne   fw_copy

        /* Call the ucl decompress function, which will branch to 0x0 */
        /* on completion */
        add   r0, r3, #1      /* r0 := Start of compressed image */
                              /* r1 already contains compressed size */
        mov   r2, #0          /* r2 := Destination for unpacking */
        bx    r5              /* Branch to uclunpack, switching to thumb */

        /* never reached */