Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 1 | /* |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | * Rescue code, made to reside at the beginning of the |
| 3 | * flash-memory. when it starts, it checks a partition |
| 4 | * table at the first sector after the rescue sector. |
| 5 | * the partition table was generated by the product builder |
| 6 | * script and contains offsets, lengths, types and checksums |
| 7 | * for each partition that this code should check. |
| 8 | * |
| 9 | * If any of the checksums fail, we assume the flash is so |
| 10 | * corrupt that we cant use it to boot into the ftp flash |
| 11 | * loader, and instead we initialize the serial port to |
| 12 | * receive a flash-loader and new flash image. we dont include |
| 13 | * any flash code here, but just accept a certain amount of |
| 14 | * bytes from the serial port and jump into it. the downloaded |
| 15 | * code is put in the cache. |
| 16 | * |
| 17 | * The partitiontable is designed so that it is transparent to |
| 18 | * code execution - it has a relative branch opcode in the |
| 19 | * beginning that jumps over it. each entry contains extra |
| 20 | * data so we can add stuff later. |
| 21 | * |
| 22 | * Partition table format: |
| 23 | * |
| 24 | * Code transparency: |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 25 | * |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | * 2 bytes [opcode 'nop'] |
| 27 | * 2 bytes [opcode 'di'] |
| 28 | * 4 bytes [opcode 'ba <offset>', 8-bit or 16-bit version] |
| 29 | * 2 bytes [opcode 'nop', delay slot] |
| 30 | * |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 31 | * Table validation (at +10): |
| 32 | * |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 33 | * 2 bytes [magic/version word for partitiontable - 0xef, 0xbe] |
| 34 | * 2 bytes [length of all entries plus the end marker] |
| 35 | * 4 bytes [checksum for the partitiontable itself] |
| 36 | * |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 37 | * Entries, each with the following format, last has offset -1: |
| 38 | * |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 39 | * 4 bytes [offset in bytes, from start of flash] |
| 40 | * 4 bytes [length in bytes of partition] |
| 41 | * 4 bytes [checksum, simple longword sum] |
| 42 | * 2 bytes [partition type] |
| 43 | * 2 bytes [flags, only bit 0 used, ro/rw = 1/0] |
| 44 | * 16 bytes [reserved for future use] |
| 45 | * |
| 46 | * End marker |
| 47 | * |
| 48 | * 4 bytes [-1] |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 49 | * |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 50 | * 10 bytes [0, padding] |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 51 | * |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 52 | * Bit 0 in flags signifies RW or RO. The rescue code only bothers |
| 53 | * to check the checksum for RO partitions, since the others will |
| 54 | * change their data without updating the checksums. A 1 in bit 0 |
| 55 | * means RO, 0 means RW. That way, it is possible to set a partition |
| 56 | * in RO mode initially, and later mark it as RW, since you can always |
| 57 | * write 0's to the flash. |
| 58 | * |
| 59 | * During the wait for serial input, the status LED will flash so the |
| 60 | * user knows something went wrong. |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 61 | * |
| 62 | * Copyright (C) 1999-2007 Axis Communications AB |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 63 | */ |
| 64 | |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 65 | #ifdef CONFIG_ETRAX_AXISFLASHMAP |
| 66 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | #define ASSEMBLER_MACROS_ONLY |
Jesper Nilsson | 556dcee | 2008-10-21 17:45:58 +0200 | [diff] [blame] | 68 | #include <arch/sv_addr_ag.h> |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 | |
| 70 | ;; The partitiontable is looked for at the first sector after the boot |
| 71 | ;; sector. Sector size is 65536 bytes in all flashes we use. |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 72 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 73 | #define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR |
| 74 | #define PTABLE_MAGIC 0xbeef |
| 75 | |
| 76 | ;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0. |
Jesper Nilsson | 99bb22b | 2008-01-18 13:48:02 +0100 | [diff] [blame] | 77 | ;; That is not where we put our downloaded serial boot-code. |
| 78 | ;; The length is enough for downloading code that loads the rest |
| 79 | ;; of itself (after having setup the DRAM etc). |
| 80 | ;; It is the same length as the on-chip ROM loads, so the same |
| 81 | ;; host loader can be used to load a rescued product as well as |
| 82 | ;; one booted through the Etrax serial boot code. |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 83 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 84 | #define CODE_START 0x40000000 |
| 85 | #define CODE_LENGTH 784 |
| 86 | |
| 87 | #ifdef CONFIG_ETRAX_RESCUE_SER0 |
| 88 | #define SERXOFF R_SERIAL0_XOFF |
| 89 | #define SERBAUD R_SERIAL0_BAUD |
| 90 | #define SERRECC R_SERIAL0_REC_CTRL |
| 91 | #define SERRDAT R_SERIAL0_REC_DATA |
| 92 | #define SERSTAT R_SERIAL0_STATUS |
| 93 | #endif |
| 94 | #ifdef CONFIG_ETRAX_RESCUE_SER1 |
| 95 | #define SERXOFF R_SERIAL1_XOFF |
| 96 | #define SERBAUD R_SERIAL1_BAUD |
| 97 | #define SERRECC R_SERIAL1_REC_CTRL |
| 98 | #define SERRDAT R_SERIAL1_REC_DATA |
| 99 | #define SERSTAT R_SERIAL1_STATUS |
| 100 | #endif |
| 101 | #ifdef CONFIG_ETRAX_RESCUE_SER2 |
| 102 | #define SERXOFF R_SERIAL2_XOFF |
| 103 | #define SERBAUD R_SERIAL2_BAUD |
| 104 | #define SERRECC R_SERIAL2_REC_CTRL |
| 105 | #define SERRDAT R_SERIAL2_REC_DATA |
| 106 | #define SERSTAT R_SERIAL2_STATUS |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 107 | #endif |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 108 | #ifdef CONFIG_ETRAX_RESCUE_SER3 |
| 109 | #define SERXOFF R_SERIAL3_XOFF |
| 110 | #define SERBAUD R_SERIAL3_BAUD |
| 111 | #define SERRECC R_SERIAL3_REC_CTRL |
| 112 | #define SERRDAT R_SERIAL3_REC_DATA |
| 113 | #define SERSTAT R_SERIAL3_STATUS |
| 114 | #endif |
| 115 | |
| 116 | #define NOP_DI 0xf025050f |
| 117 | #define RAM_INIT_MAGIC 0x56902387 |
| 118 | |
| 119 | .text |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 120 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 | ;; This is the entry point of the rescue code |
| 122 | ;; 0x80000000 if loaded in flash (as it should be) |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 123 | ;; Since etrax actually starts at address 2 when booting from flash, we |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 124 | ;; put a nop (2 bytes) here first so we dont accidentally skip the di |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 125 | |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 126 | nop |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 127 | di |
| 128 | |
| 129 | jump in_cache ; enter cached area instead |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 130 | in_cache: |
| 131 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 132 | |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 133 | ;; First put a jump test to give a possibility of upgrading the |
| 134 | ;; rescue code without erasing/reflashing the sector. |
| 135 | ;; We put a longword of -1 here and if it is not -1, we jump using |
| 136 | ;; the value as jump target. Since we can always change 1's to 0's |
| 137 | ;; without erasing the sector, it is possible to add new |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 138 | ;; code after this and altering the jumptarget in an upgrade. |
| 139 | |
| 140 | jtcd: move.d [jumptarget], $r0 |
| 141 | cmp.d 0xffffffff, $r0 |
| 142 | beq no_newjump |
| 143 | nop |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 144 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 145 | jump [$r0] |
| 146 | |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 147 | jumptarget: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 148 | .dword 0xffffffff ; can be overwritten later to insert new code |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 149 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 150 | no_newjump: |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 151 | #ifdef CONFIG_ETRAX_ETHERNET |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 152 | ;; Start MII clock to make sure it is running when tranceiver is reset |
| 153 | move.d 0x3, $r0 ; enable = on, phy = mii_clk |
| 154 | move.d $r0, [R_NETWORK_GEN_CONFIG] |
| 155 | #endif |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 156 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 157 | ;; We need to setup the bus registers before we start using the DRAM |
| 158 | #include "../../lib/dram_init.S" |
| 159 | |
| 160 | ;; we now should go through the checksum-table and check the listed |
| 161 | ;; partitions for errors. |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 162 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 163 | move.d PTABLE_START, $r3 |
| 164 | move.d [$r3], $r0 |
| 165 | cmp.d NOP_DI, $r0 ; make sure the nop/di is there... |
| 166 | bne do_rescue |
| 167 | nop |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 168 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 169 | ;; skip the code transparency block (10 bytes). |
| 170 | |
| 171 | addq 10, $r3 |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 172 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 173 | ;; check for correct magic |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 174 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 175 | move.w [$r3+], $r0 |
| 176 | cmp.w PTABLE_MAGIC, $r0 |
| 177 | bne do_rescue ; didn't recognize - trig rescue |
| 178 | nop |
| 179 | |
| 180 | ;; check for correct ptable checksum |
| 181 | |
| 182 | movu.w [$r3+], $r2 ; ptable length |
| 183 | move.d $r2, $r8 ; save for later, length of total ptable |
| 184 | addq 28, $r8 ; account for the rest |
| 185 | move.d [$r3+], $r4 ; ptable checksum |
| 186 | move.d $r3, $r1 |
| 187 | jsr checksum ; r1 source, r2 length, returns in r0 |
| 188 | |
| 189 | cmp.d $r0, $r4 |
| 190 | bne do_rescue ; didn't match - trig rescue |
| 191 | nop |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 192 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 193 | ;; ptable is ok. validate each entry. |
| 194 | |
| 195 | moveq -1, $r7 |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 196 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 197 | ploop: move.d [$r3+], $r1 ; partition offset (from ptable start) |
| 198 | bne notfirst ; check if it is the partition containing ptable |
| 199 | nop ; yes.. |
| 200 | move.d $r8, $r1 ; for its checksum check, skip the ptable |
| 201 | move.d [$r3+], $r2 ; partition length |
| 202 | sub.d $r8, $r2 ; minus the ptable length |
| 203 | ba bosse |
| 204 | nop |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 205 | notfirst: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 206 | cmp.d -1, $r1 ; the end of the ptable ? |
| 207 | beq flash_ok ; if so, the flash is validated |
| 208 | move.d [$r3+], $r2 ; partition length |
| 209 | bosse: move.d [$r3+], $r5 ; checksum |
| 210 | move.d [$r3+], $r4 ; type and flags |
| 211 | addq 16, $r3 ; skip the reserved bytes |
| 212 | btstq 16, $r4 ; check ro flag |
| 213 | bpl ploop ; rw partition, skip validation |
| 214 | nop |
| 215 | btstq 17, $r4 ; check bootable flag |
| 216 | bpl 1f |
| 217 | nop |
| 218 | move.d $r1, $r7 ; remember boot partition offset |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 219 | 1: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 220 | add.d PTABLE_START, $r1 |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 221 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 222 | jsr checksum ; checksum the partition |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 223 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 224 | cmp.d $r0, $r5 |
| 225 | beq ploop ; checksums matched, go to next entry |
| 226 | nop |
| 227 | |
| 228 | ;; otherwise fall through to the rescue code. |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 229 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 230 | do_rescue: |
| 231 | ;; setup port PA and PB default initial directions and data |
| 232 | ;; (so we can flash LEDs, and so that DTR and others are set) |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 233 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 234 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 |
| 235 | move.b $r0, [R_PORT_PA_DIR] |
| 236 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 |
| 237 | move.b $r0, [R_PORT_PA_DATA] |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 238 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 239 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 |
| 240 | move.b $r0, [R_PORT_PB_DIR] |
| 241 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 |
| 242 | move.b $r0, [R_PORT_PB_DATA] |
| 243 | |
| 244 | ;; setup the serial port at 115200 baud |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 245 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 246 | moveq 0, $r0 |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 247 | move.d $r0, [SERXOFF] |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 248 | |
| 249 | move.b 0x99, $r0 |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 250 | move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 251 | |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 252 | move.b 0x40, $r0 ; rec enable |
| 253 | move.b $r0, [SERRECC] |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 254 | |
| 255 | moveq 0, $r1 ; "timer" to clock out a LED red flash |
| 256 | move.d CODE_START, $r3 ; destination counter |
| 257 | movu.w CODE_LENGTH, $r4; length |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 258 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 259 | wait_ser: |
| 260 | addq 1, $r1 |
| 261 | #ifndef CONFIG_ETRAX_NO_LEDS |
| 262 | #ifdef CONFIG_ETRAX_PA_LEDS |
| 263 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2 |
| 264 | #endif |
| 265 | #ifdef CONFIG_ETRAX_PB_LEDS |
| 266 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2 |
| 267 | #endif |
| 268 | move.d (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0 |
| 269 | btstq 16, $r1 |
| 270 | bpl 1f |
| 271 | nop |
| 272 | or.d $r0, $r2 ; set bit |
| 273 | ba 2f |
| 274 | nop |
| 275 | 1: not $r0 ; clear bit |
| 276 | and.d $r0, $r2 |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 277 | 2: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 278 | #ifdef CONFIG_ETRAX_PA_LEDS |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 279 | move.b $r2, [R_PORT_PA_DATA] |
| 280 | #endif |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 281 | #ifdef CONFIG_ETRAX_PB_LEDS |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 282 | move.b $r2, [R_PORT_PB_DATA] |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 283 | #endif |
| 284 | #ifdef CONFIG_ETRAX_90000000_LEDS |
| 285 | move.b $r2, [0x90000000] |
| 286 | #endif |
| 287 | #endif |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 288 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 289 | ;; check if we got something on the serial port |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 290 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 291 | move.b [SERSTAT], $r0 |
| 292 | btstq 0, $r0 ; data_avail |
| 293 | bpl wait_ser |
| 294 | nop |
| 295 | |
| 296 | ;; got something - copy the byte and loop |
| 297 | |
| 298 | move.b [SERRDAT], $r0 |
| 299 | move.b $r0, [$r3+] |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 300 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 301 | subq 1, $r4 ; decrease length |
| 302 | bne wait_ser |
| 303 | nop |
| 304 | |
| 305 | ;; jump into downloaded code |
| 306 | |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 307 | move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is |
| 308 | ; initialized |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 309 | jump CODE_START |
| 310 | |
| 311 | flash_ok: |
| 312 | ;; check r7, which contains either -1 or the partition to boot from |
| 313 | |
| 314 | cmp.d -1, $r7 |
| 315 | bne 1f |
| 316 | nop |
| 317 | move.d PTABLE_START, $r7; otherwise use the ptable start |
| 318 | 1: |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 319 | move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is |
| 320 | ; initialized |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 321 | jump $r7 ; boot! |
| 322 | |
| 323 | |
| 324 | ;; Helper subroutines |
| 325 | |
| 326 | ;; Will checksum by simple addition |
| 327 | ;; r1 - source |
| 328 | ;; r2 - length in bytes |
| 329 | ;; result will be in r0 |
| 330 | checksum: |
| 331 | moveq 0, $r0 |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 332 | moveq CONFIG_ETRAX_FLASH1_SIZE, $r6 |
| 333 | |
Jesper Nilsson | 99bb22b | 2008-01-18 13:48:02 +0100 | [diff] [blame] | 334 | ;; If the first physical flash memory is exceeded wrap to the |
| 335 | ;; second one |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 336 | btstq 26, $r1 ; Are we addressing first flash? |
| 337 | bpl 1f |
| 338 | nop |
| 339 | clear.d $r6 |
| 340 | |
| 341 | 1: test.d $r6 ; 0 = no wrapping |
| 342 | beq 2f |
| 343 | nop |
| 344 | lslq 20, $r6 ; Convert MB to bytes |
| 345 | sub.d $r1, $r6 |
| 346 | |
| 347 | 2: addu.b [$r1+], $r0 |
| 348 | subq 1, $r6 ; Flash memory left |
| 349 | beq 3f |
| 350 | subq 1, $r2 ; Length left |
| 351 | bne 2b |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 352 | nop |
| 353 | ret |
| 354 | nop |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 355 | |
| 356 | 3: move.d MEM_CSE1_START, $r1 ; wrap to second flash |
| 357 | ba 2b |
| 358 | nop |
Jesper Nilsson | 8c11bff | 2007-11-30 16:13:29 +0100 | [diff] [blame] | 359 | |
| 360 | #endif |