root/ar5315_microredboot/microredboot/boot/src/misc_lzma.c

Revision 12325, 30.1 kB (checked in by BrainSlayer, 5 months ago)

increase lzma decoder speed by 2

Line 
1 /*
2  * misc_lzma.c
3  * originally written for xscale based linux kernel decompression
4  * now adapted for AR531X based redboot stub and kernel loader
5  * copyright 2009 Sebastian Gottschall / NewMedia-NET GmbH / DD-WRT.COM
6  * licensed under GPL conditions
7  * this stub will load and decompress redboot if the reset button is pushed, otherwise it parses the redboot directory for a partition named linux*, vmlinux* or kernel*
8  * if such a partition has been found, it will be decompressed and executed, if not. redboot is started. if a decompression error occures while loading the linux partition,
9  * the redboot is started too.
10  * take care about the ramconfig.h header since it must contain the correct ram size and gpio button value for the reset button
11  * this code is partially based on redboot and linux sources
12  */
13
14 #ifdef STANDALONE_DEBUG
15 #define putstr printf
16 #else
17
18 #include <linux/kernel.h>
19
20 #include <asm/uaccess.h>
21 #include "ramconfig.h"
22 #ifdef AR5312
23 #include "uncompress-ar5312.h"
24 #else
25 #include "uncompress-ar5315.h"
26 #endif
27 #include "spiflash.h"
28 #include "printf.h"
29
30 #endif
31
32 #define __ptr_t void *
33
34 typedef unsigned char uch;
35 typedef unsigned short ush;
36 typedef unsigned long ulg;
37
38 static uch *inbuf;              /* input buffer */
39 static unsigned int nvramdetect = 0;
40
41 static unsigned insize = 0;     /* valid bytes in inbuf */
42 static unsigned inptr = 0;      /* index of next byte to be processed in inbuf */
43 static unsigned outcnt;         /* bytes in output buffer */
44
45 static void fill_inbuf(void);
46
47 static inline unsigned char get_byte(void)
48 {
49         static unsigned int vall;
50
51         if (((unsigned int)inptr % 4) == 0) {
52                 vall = *(unsigned int *)inbuf;
53                 inbuf += 4;
54         }
55         return *(((unsigned char *)&vall) + (inptr++ & 3));
56 }
57
58 //#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
59
60 static void flush_window(void);
61 static void error(char *m);
62
63 extern unsigned char input_data[];
64 extern unsigned char input_data_end[];
65
66 static ulg output_ptr = 0;
67 static uch *output_data;
68 static ulg bytes_out;
69
70 extern int end;
71 static ulg free_mem_ptr;
72 static ulg free_mem_ptr_end;
73
74 #define _LZMA_IN_CB
75
76 #include "lib/LzmaDecode.h"
77 static unsigned int icnt = 0;
78 static inline int read_byte(unsigned char **buffer, UInt32 * bufferSize)
79 {
80         static unsigned char val;
81         *bufferSize = 1;
82         val = get_byte();
83         *buffer = &val;
84         if (icnt++ % (1024 * 10) == 0)
85                 putc('.');
86         return LZMA_RESULT_OK;
87 }
88
89 #include "lib/LzmaDecode.c"
90
91 int bootoffset = 0x800004bc;
92
93 /*
94  * Do the lzma decompression
95  */
96
97 static int disaster = 0;
98 static int lzma_unzip(void)
99 {
100
101         unsigned int i;
102         unsigned int uncompressedSize = 0;
103         unsigned char *workspace;
104         unsigned int lc, lp, pb;
105         if (inptr >= insize)
106                 fill_inbuf();
107
108         // lzma args
109         i = get_byte();
110         lc = i % 9, i = i / 9;
111         lp = i % 5, pb = i / 5;
112
113         // skip dictionary size
114         for (i = 0; i < 4; i++)
115                 get_byte();
116         // get uncompressed size
117         int a, b, c, d;
118         a = get_byte();
119         b = get_byte();
120         c = get_byte();
121         d = get_byte();
122         uncompressedSize = (a) + (b << 8) + (c << 16) + (d << 24);
123         if (uncompressedSize > 0x400000 || lc > 3 || pb > 3 || lp > 3) {
124                 if (disaster) {
125                         error
126                             ("\ndata corrupted in recovery RedBoot too, this is a disaster condition. please re-jtag\n");
127                 }
128                 disaster = 1;
129                 puts("\ndata corrupted!\nswitching to recovery RedBoot\nloading");
130                 inbuf = input_data;
131                 insize = &input_data_end[0] - &input_data[0];
132                 inptr = 0;
133                 output_data = (uch *) 0x80000400;
134                 bootoffset = 0x800004bc;
135                 return lzma_unzip();
136
137         }
138         workspace = output_data + uncompressedSize;
139         // skip high order bytes
140         for (i = 0; i < 4; i++)
141                 get_byte();
142         // decompress kernel
143         if (LzmaDecode
144             (workspace, ~0, lc, lp, pb, (unsigned char *)output_data,
145              uncompressedSize, &i) == LZMA_RESULT_OK) {
146                 if (i != uncompressedSize) {
147                         if (disaster) {
148                                 error
149                                     ("data corrupted in recovery RedBoot too, this is a disaster condition. please re-jtag\n");
150                         }
151                         disaster = 1;
152                         puts("\ndata corrupted!\nswitching to recovery RedBoot\nloading");
153                         inbuf = input_data;
154                         insize = &input_data_end[0] - &input_data[0];
155                         inptr = 0;
156                         output_data = (uch *) 0x80000400;
157                         bootoffset = 0x800004bc;
158                         return lzma_unzip();
159                 }
160                 //copy it back to low_buffer
161                 bytes_out = i;
162                 output_ptr = i;
163                 return 0;
164         }
165         return 1;
166 }
167
168 /*if (((unsigned int)offset % 4) == 0) {
169         vall = *(unsigned int *)buffer;
170         buffer += 4;
171 }
172     if (buffer>=BufferLim)
173         {
174         ExtraBytes=1;
175         return 0xff;
176         }
177   return *(((unsigned char *)&vall) + (offset++ & 3));
178 */
179
180 struct fis_image_desc {
181         unsigned char name[16]; // Null terminated name
182         unsigned long flash_base;       // Address within FLASH of image
183         unsigned long mem_base; // Address in memory where it executes
184         unsigned long size;     // Length of image
185         unsigned long entry_point;      // Execution entry point
186         unsigned long data_length;      // Length of actual data
187         unsigned char _pad[256 - (16 + 7 * sizeof(unsigned long))];
188         unsigned long desc_cksum;       // Checksum over image descriptor
189         unsigned long file_cksum;       // Checksum over image data
190 };
191
192 #ifdef AR5312
193 static unsigned int sectorsize = 0x10000;
194 static unsigned int linuxaddr = 0xbe010000;
195 static unsigned int flashbase = 0xbe000000;
196 static unsigned int flashsize = 0x800000;
197 #else
198 static unsigned int sectorsize = 0x10000;
199 static unsigned int linuxaddr = 0xbfc10000;
200 static unsigned int flashbase = 0xa8000000;
201 static unsigned int flashsize = 0x800000;
202 #endif
203 /*
204  * searches for a directory entry named linux* vmlinux* or kernel and returns its flash address (it also initializes entrypoint and load address)
205  */
206 static unsigned int getLinux(void)
207 {
208         int count = 0;
209         unsigned char *p =
210             (unsigned char *)(flashbase + flashsize - (sectorsize * 2));
211         struct fis_image_desc *fis = (struct fis_image_desc *)p;
212         while (fis->name[0] != 0xff && count < 10) {
213                 if (!strncmp(fis->name, "linux", 5)
214                     || !strncmp(fis->name, "vmlinux", 7)
215                     || !strcmp(fis->name, "kernel")) {
216                         printf
217                             ("found bootable image: [%s] at [0x%08X] EP [0x%08X]\n",
218                              fis->name, fis->flash_base, fis->entry_point);
219                         bootoffset = fis->entry_point;
220                         output_data = (uch *) fis->mem_base;
221 //#ifdef AR5312
222                         return fis->flash_base;
223 //#else
224 //                      memcpy((unsigned char *)ZCACHEADDR,
225 //                             (unsigned char *)fis->flash_base,
226 //                             1 * 1024 * 1024);
227 //                      return ZCACHEADDR;
228 //#endif
229                 }
230                 p += 256;
231                 fis = (struct fis_image_desc *)p;
232                 count++;
233         }
234         puts("no bootable image found, try default location 0xbfc10000\n");
235         bootoffset = 0x80041000;
236         output_data = (uch *) 0x80041000;
237         return 0xbfc10000;
238 }
239
240 /* ===========================================================================
241  * Fill the input buffer. This is called only when the buffer is empty
242  * and at least one byte is really needed.
243  */
244 static int resettrigger = 0;
245
246 static void fill_inbuf(void)
247 {
248         if (insize != 0)
249                 error("ran out of input data");
250         if (resettrigger) {
251                 inbuf = (uch *) linuxaddr;
252                 insize = 0x400000;
253                 inptr = 0;
254         } else {
255                 inbuf = input_data;
256                 insize = &input_data_end[0] - &input_data[0];
257                 inptr = 0;
258         }
259         return;
260 }
261
262 /* ===========================================================================
263  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
264  * (Used for the decompressed data only.)
265  */
266
267 #ifndef arch_error
268 #define arch_error(x)
269 #endif
270
271 static void error(char *x)
272 {
273         arch_error(x);
274
275         printf("\n\n%s\n\n -- System halted", x);
276
277         while (1) ;             /* Halt */
278 }
279
280 /*void __div0(void)
281 {
282         error("division by zero");
283 }*/
284
285 #ifdef AR5312
286
287 #define AR531X_APBBASE  0xbc000000
288 #define AR531X_GPIO     (AR531X_APBBASE + 0x2000)
289 #define AR531X_GPIO_DI      (AR531X_GPIO + 0x04)
290
291 static int getGPIO(int nr)
292 {
293         volatile unsigned int *gpio = (unsigned int *)AR531X_GPIO_DI;
294         if ((*gpio & 1 << nr) == (1 << nr))
295                 return 1;
296         return 0;
297 }
298
299 #else
300
301 #define AR2316_DSLBASE          0xB1000000      /* RESET CONTROL MMR */
302 #define AR2316_GPIO_DI          (AR2316_DSLBASE + 0x0088)
303
304 static int getGPIO(int nr)
305 {
306         volatile unsigned int *gpio = (unsigned int *)AR2316_GPIO_DI;
307         if ((*gpio & 1 << nr) == (1 << nr))
308                 return 1;
309         return 0;
310 }
311 #endif
312 /*
313  * checks if the reset button is pressed, return 1 if the button is pressed and 0 if not
314  */
315 static int resetTouched(void)
316 {
317         int trigger = getGPIO(RESETBUTTON & 0x0f);
318         if (RESETBUTTON & 0xf0)
319                 trigger = 1 - trigger;
320         return trigger;
321 }
322
323 #define RTC_DENOMINATOR 100
324 #define RTC_PERIOD 110000000 / RTC_DENOMINATOR
325
326 #define MACRO_START do {
327 #define MACRO_END   } while (0)
328 static unsigned int cyg_hal_clock_period;
329
330 #define HAL_CLOCK_INITIALIZE( _period_ )        \
331 MACRO_START                                 \
332     asm volatile (                              \
333         "mtc0 $0,$9\n"                          \
334         "nop; nop; nop\n"                       \
335         "mtc0 %0,$11\n"                         \
336         "nop; nop; nop\n"                       \
337         :                                       \
338         : "r"(_period_)                         \
339         );                                      \
340     cyg_hal_clock_period = _period_;            \
341 MACRO_END
342
343 #define HAL_CLOCK_RESET( _vector_, _period_ )   \
344 MACRO_START                                 \
345     asm volatile (                              \
346         "mtc0 $0,$9\n"                          \
347         "nop; nop; nop\n"                       \
348         "mtc0 %0,$11\n"                         \
349         "nop; nop; nop\n"                       \
350         :                                       \
351         : "r"(_period_)                         \
352         );                                      \
353 MACRO_END
354
355 #define HAL_CLOCK_READ( _pvalue_ )              \
356 MACRO_START                                 \
357     register unsigned int result;                 \
358     asm volatile (                              \
359         "mfc0   %0,$9\n"                        \
360         : "=r"(result)                          \
361         );                                      \
362     *(_pvalue_) = result;                       \
363 MACRO_END
364
365 /*
366  * udelay implementation based on cpu cycle counter
367  */
368 static void udelay(int us)
369 {
370         unsigned int val1, val2;
371         int diff;
372         long usticks;
373         long ticks;
374
375         // Calculate the number of counter register ticks per microsecond.
376
377         usticks = (RTC_PERIOD * RTC_DENOMINATOR) / 1000000;
378
379         // Make sure that the value is not zero. This will only happen if the
380         // CPU is running at < 2MHz.
381         if (usticks == 0)
382                 usticks = 1;
383
384         while (us > 0) {
385                 int us1 = us;
386
387                 // Wait in bursts of less than 10000us to avoid any overflow
388                 // problems in the multiply.
389                 if (us1 > 10000)
390                         us1 = 10000;
391
392                 us -= us1;
393
394                 ticks = us1 * usticks;
395
396                 HAL_CLOCK_READ(&val1);
397                 while (ticks > 0) {
398                         do {
399                                 HAL_CLOCK_READ(&val2);
400                         }
401                         while (val1 == val2);
402                         diff = val2 - val1;
403                         if (diff < 0)
404                                 diff += RTC_PERIOD;
405                         ticks -= diff;
406                         val1 = val2;
407                 }
408         }
409 }
410
411 #ifndef STANDALONE_DEBUG
412
413 typedef unsigned int AR531X_REG;
414
415 #undef sysRegRead
416 #undef sysRegWrite
417 #define sysRegRead(phys)        \
418         (*(volatile AR531X_REG *)(KSEG1|phys))
419
420 #define sysRegWrite(phys, val)  \
421         ((*(volatile AR531X_REG *)(KSEG1|phys)) = (val))
422
423 #ifndef AR5312
424
425 #define RESET_WARM_WLAN0_MAC        0x00000001  /* warm reset WLAN0 MAC */
426 #define RESET_WARM_WLAN0_BB         0x00000002  /* warm reset WLAN0 BaseBand */
427 #define RESET_MPEGTS_RSVD           0x00000004  /* warm reset MPEG-TS */
428 #define RESET_PCIDMA                0x00000008  /* warm reset PCI ahb/dma */
429 #define RESET_MEMCTL                0x00000010  /* warm reset memory controller */
430 #define RESET_LOCAL                 0x00000020  /* warm reset local bus */
431 #define RESET_I2C_RSVD              0x00000040  /* warm reset I2C bus */
432 #define RESET_SPI                   0x00000080  /* warm reset SPI interface */
433 #define RESET_UART0                 0x00000100  /* warm reset UART0 */
434 #define RESET_IR_RSVD               0x00000200  /* warm reset IR interface */
435 #define RESET_EPHY0                 0x00000400  /* cold reset ENET0 phy */
436 #define RESET_ENET0                 0x00000800  /* cold reset ENET0 mac */
437
438 #define IF_TS_LOCAL                 2
439 #define AR2316_DSLBASE          0xB1000000      /* RESET CONTROL MMR */
440 #define AR2316_RESET            (AR2316_DSLBASE + 0x0004)
441 #define AR2316_IF_CTL           (AR2316_DSLBASE + 0x0018)
442 #define AR2316_ENDIAN_CTL       (AR2316_DSLBASE + 0x000c)
443
444 #define CONFIG_ETHERNET             0x00000040  /* Ethernet byteswap */
445
446 #define AR2316_AHB_ARB_CTL      (AR2316_DSLBASE + 0x0008)
447 #define ARB_CPU                     0x00000001  /* CPU, default */
448 #define ARB_WLAN                    0x00000002  /* WLAN */
449 #define ARB_MPEGTS_RSVD             0x00000004  /* MPEG-TS */
450 #define ARB_LOCAL                   0x00000008  /* LOCAL */
451 #define ARB_PCI                     0x00000010  /* PCI */
452 #define ARB_ETHERNET                0x00000020  /* Ethernet */
453 #define ARB_RETRY                   0x00000100  /* retry policy, debug only */
454
455 #define AR531XPLUS_SPI              0xB1300000  /* SPI FLASH MMR */
456
457 #define FLASH_1MB  1
458 #define FLASH_2MB  2
459 #define FLASH_4MB  3
460 #define FLASH_8MB  4
461 #define FLASH_16MB 5
462 #define MAX_FLASH  6
463
464 #define STM_PAGE_SIZE           256
465
466 #define SFI_WRITE_BUFFER_SIZE   4
467 #define SFI_FLASH_ADDR_MASK     0x00ffffff
468
469 #define STM_8MBIT_SIGNATURE     0x13
470 #define STM_M25P80_BYTE_COUNT   1048576
471 #define STM_M25P80_SECTOR_COUNT 16
472 #define STM_M25P80_SECTOR_SIZE  0x10000
473
474 #define STM_16MBIT_SIGNATURE    0x14
475 #define STM_M25P16_BYTE_COUNT   2097152
476 #define STM_M25P16_SECTOR_COUNT 32
477 #define STM_M25P16_SECTOR_SIZE  0x10000
478
479 #define STM_32MBIT_SIGNATURE    0x15
480 #define STM_M25P32_BYTE_COUNT   4194304
481 #define STM_M25P32_SECTOR_COUNT 64
482 #define STM_M25P32_SECTOR_SIZE  0x10000
483
484 #define STM_64MBIT_SIGNATURE    0x16
485 #define STM_M25P64_BYTE_COUNT   8388608
486 #define STM_M25P64_SECTOR_COUNT 128
487 #define STM_M25P64_SECTOR_SIZE  0x10000
488
489 #define STM_128MBIT_SIGNATURE   0x17
490 #define STM_M25P128_BYTE_COUNT   16777216
491 #define STM_M25P128_SECTOR_COUNT 256
492 #define STM_M25P128_SECTOR_SIZE  0x10000
493
494 #define STM_1MB_BYTE_COUNT   STM_M25P80_BYTE_COUNT
495 #define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT
496 #define STM_1MB_SECTOR_SIZE  STM_M25P80_SECTOR_SIZE
497 #define STM_2MB_BYTE_COUNT   STM_M25P16_BYTE_COUNT
498 #define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT
499 #define STM_2MB_SECTOR_SIZE  STM_M25P16_SECTOR_SIZE
500 #define STM_4MB_BYTE_COUNT   STM_M25P32_BYTE_COUNT
501 #define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT
502 #define STM_4MB_SECTOR_SIZE  STM_M25P32_SECTOR_SIZE
503 #define STM_8MB_BYTE_COUNT   STM_M25P64_BYTE_COUNT
504 #define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT
505 #define STM_8MB_SECTOR_SIZE  STM_M25P64_SECTOR_SIZE
506 #define STM_16MB_BYTE_COUNT   STM_M25P128_BYTE_COUNT
507 #define STM_16MB_SECTOR_COUNT STM_M25P128_SECTOR_COUNT
508 #define STM_16MB_SECTOR_SIZE  STM_M25P128_SECTOR_SIZE
509
510 #define SPI_FLASH_MMR           AR531XPLUS_SPI_MMR
511
512 #define SPI_WRITE_ENABLE    0
513 #define SPI_WRITE_DISABLE   1
514 #define SPI_RD_STATUS       2
515 #define SPI_WR_STATUS       3
516 #define SPI_RD_DATA         4
517 #define SPI_FAST_RD_DATA    5
518 #define SPI_PAGE_PROGRAM    6
519 #define SPI_SECTOR_ERASE    7
520 #define SPI_BULK_ERASE      8
521 #define SPI_DEEP_PWRDOWN    9
522 #define SPI_RD_SIG          10
523 #define SPI_MAX_OPCODES     11
524
525 struct flashconfig {
526         __u32 byte_cnt;
527         __u32 sector_cnt;
528         __u32 sector_size;
529         __u32 cs_addrmask;
530 } static flashconfig_tbl[MAX_FLASH] = {
531         {0, 0, 0, 0},           //
532         {STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE, 0x0},   //
533         {STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE, 0x0},   //
534         {STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE, 0x0},   //
535         {STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT, STM_8MB_SECTOR_SIZE, 0x0},   //
536         {STM_16MB_BYTE_COUNT, STM_16MB_SECTOR_COUNT, STM_16MB_SECTOR_SIZE, 0x0} //
537 };
538
539 struct opcodes {
540         __u16 code;
541         __s8 tx_cnt;
542         __s8 rx_cnt;
543 } static stm_opcodes[] = {
544         {STM_OP_WR_ENABLE, 1, 0},       //
545         {STM_OP_WR_DISABLE, 1, 0},      //
546         {STM_OP_RD_STATUS, 1, 1},       //
547         {STM_OP_WR_STATUS, 1, 0},       //
548         {STM_OP_RD_DATA, 4, 4}, //
549         {STM_OP_FAST_RD_DATA, 5, 0},    //
550         {STM_OP_PAGE_PGRM, 8, 0},       //
551         {STM_OP_SECTOR_ERASE, 4, 0},    //
552         {STM_OP_BULK_ERASE, 1, 0},      //
553         {STM_OP_DEEP_PWRDOWN, 1, 0},    //
554         {STM_OP_RD_SIG, 4, 1},  //
555 };
556
557 static __u32 spiflash_regread32(int reg)
558 {
559         volatile __u32 *data = (__u32 *)(AR531XPLUS_SPI + reg);
560
561         return (*data);
562 }
563
564 static void spiflash_regwrite32(int reg, __u32 data)
565 {
566         volatile __u32 *addr = (__u32 *)(AR531XPLUS_SPI + reg);
567
568         *addr = data;
569         return;
570 }
571
572 #define busy_wait(condition, wait) \
573         do { \
574                 while (condition) { \
575                         if (!wait) \
576                             udelay(1); \
577                         else \
578                             udelay(wait*1000); \
579                 } \
580         } while (0)
581
582 static __u32 spiflash_sendcmd(int op, u32 addr)
583 {
584         u32 reg;
585         u32 mask;
586         struct opcodes *ptr_opcode;
587
588         ptr_opcode = &stm_opcodes[op];
589         busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0);
590
591         spiflash_regwrite32(SPI_FLASH_OPCODE,
592                             ((u32)ptr_opcode->code) | (addr << 8));
593
594         reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt |
595             (ptr_opcode->rx_cnt << 4) | SPI_CTL_START;
596
597         spiflash_regwrite32(SPI_FLASH_CTL, reg);
598
599         busy_wait(spiflash_regread32(SPI_FLASH_CTL) & SPI_CTL_BUSY, 0);
600
601         if (!ptr_opcode->rx_cnt)
602                 return 0;
603
604         reg = (__u32)spiflash_regread32(SPI_FLASH_DATA);
605
606         switch (ptr_opcode->rx_cnt) {
607         case 1:
608                 mask = 0x000000ff;
609                 break;
610         case 2:
611                 mask = 0x0000ffff;
612                 break;
613         case 3:
614                 mask = 0x00ffffff;
615                 break;
616         default:
617                 mask = 0xffffffff;
618                 break;
619         }
620         reg &= mask;
621
622         return reg;
623 }
624
625 static int spiflash_probe_chip(void)
626 {
627         unsigned int sig;
628         int flash_size;
629
630         sig = spiflash_sendcmd(SPI_RD_SIG, 0);
631
632         switch (sig) {
633         case STM_8MBIT_SIGNATURE:
634                 flash_size = FLASH_1MB;
635                 break;
636         case STM_16MBIT_SIGNATURE:
637                 flash_size = FLASH_2MB;
638                 break;
639         case STM_32MBIT_SIGNATURE:
640                 flash_size = FLASH_4MB;
641                 break;
642         case STM_64MBIT_SIGNATURE:
643                 flash_size = FLASH_8MB;
644                 break;
645         case STM_128MBIT_SIGNATURE:
646                 flash_size = FLASH_16MB;
647                 break;
648         default:
649                 puts("Read of flash device signature failed!\n");
650                 return (0);
651         }
652
653         return (flash_size);
654 }
655
656 static int flash_erase_nvram(unsigned int flashsize, unsigned int blocksize)
657 {
658         unsigned int res;
659         unsigned int offset = nvramdetect;
660         struct opcodes *ptr_opcode;
661         __u32 temp, reg;
662         if (!nvramdetect) {
663                 puts("nvram can and will not erased, since nvram was not detected on this device (maybe dd-wrt isnt installed)!\n");
664                 return;
665         }
666         printf("erasing nvram at [0x%08X]\n", nvramdetect);
667
668         ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE];
669
670         temp = ((__u32)offset << 8) | (__u32)(ptr_opcode->code);
671         spiflash_sendcmd(SPI_WRITE_ENABLE, 0);
672         busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0);
673
674         spiflash_regwrite32(SPI_FLASH_OPCODE, temp);
675
676         reg =
677             (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt |
678             SPI_CTL_START;
679         spiflash_regwrite32(SPI_FLASH_CTL, reg);
680
681         busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20);
682
683         puts("done\n");
684         return 0;
685 }
686
687 static int flashdetected = 0;
688 static int flashdetect(void)
689 {
690         if (flashdetected)
691                 return 0;
692         flashsize = 8 * 1024 * 1024;
693         flashbase = 0xa8000000;
694         int index = 0;
695         if (!(index = spiflash_probe_chip())) {
696                 puts("Found no serial flash device, cannot reset to factory defaults\n");
697                 return -1;
698         } else {
699                 flashsize = flashconfig_tbl[index].byte_cnt;
700                 sectorsize = flashconfig_tbl[index].sector_size;
701                 if (flashsize == 8 * 1024 * 1024)
702                         flashbase = 0xa8000000;
703                 else
704                         flashbase = 0xbfc00000;
705                 printf
706                     ("Found Flash device SIZE=0x%08X SECTORSIZE=0x%08X FLASHBASE=0x%08X\n",
707                      flashsize, sectorsize, flashbase);
708         }
709         flashdetected = 1;
710         return 0;
711
712 }
713 #else
714
715 typedef unsigned char FLASH_DATA_T;
716 #define FLASH_P2V( _a_ ) ((volatile FLASH_DATA_T *)((unsigned int)((_a_))))
717 #define FLASH_BLANKVALUE                (FLASH_DATA_T)(0xff)
718 #define FLASHWORD(x)                    ((FLASH_DATA_T)(x))
719 #define FLASH_POLLING_TIMEOUT   (3000000)
720 #define FLASH_READ_ID                   FLASHWORD( 0x90 )
721 #define FLASH_WP_STATE                  FLASHWORD( 0x90 )
722 #define FLASH_RESET                     FLASHWORD( 0xF0 )
723 #define FLASH_PROGRAM                   FLASHWORD( 0xA0 )
724 #define FLASH_BLOCK_ERASE               FLASHWORD( 0x30 )
725 #define FLASH_Query                                             FLASHWORD( 0x98 )       // Add by Jason for CFI support
726
727 #define FLASH_DATA                      FLASHWORD( 0x80 )       // Data complement
728 #define FLASH_BUSY                      FLASHWORD( 0x40 )       // "Toggle" bit
729 #define FLASH_ERR                       FLASHWORD( 0x20 )
730 #define FLASH_SECTOR_ERASE_TIMER        FLASHWORD( 0x08 )
731
732 #define FLASH_UNLOCKED                  FLASHWORD( 0x00 )
733 #define FLASH_WP_ADDR                   (4)
734
735 #define FLASH_SETUP_ADDR1               (0xAAA)
736 #define FLASH_SETUP_ADDR2               (0x555)
737 #define FLASH_VENDORID_ADDR             (0x0)
738 #define FLASH_DEVICEID_ADDR             (0x2)
739 #define FLASH_DEVICEID_ADDR2            (0x1c)
740 #define FLASH_DEVICEID_ADDR3            (0x1e)
741 //#define FLASH_WP_ADDR                         (0x12)
742 #define FLASH_SETUP_CODE1               FLASHWORD( 0xAA )
743 #define FLASH_SETUP_CODE2               FLASHWORD( 0x55 )
744 #define FLASH_SETUP_ERASE               FLASHWORD( 0x80 )
745 #define FLASH_ERR_OK                    0x0
746 #define FLASH_ERR_DRV_TIMEOUT           -1
747
748 /*static void
749 flash_query(void* data)
750 {
751     volatile FLASH_DATA_T *ROM;
752     volatile FLASH_DATA_T *f_s1, *f_s2;
753     FLASH_DATA_T* id = (FLASH_DATA_T*) data;
754     FLASH_DATA_T w;
755     long timeout = 50000;
756
757     ROM = (volatile FLASH_DATA_T*) ((unsigned int)nvramdetect & ~(0x800000-1));
758     *(FLASH_P2V(ROM)) = FLASH_RESET;
759
760     f_s1 = FLASH_P2V(ROM+FLASH_SETUP_ADDR1);
761     f_s2 = FLASH_P2V(ROM+FLASH_SETUP_ADDR2);
762
763     *f_s1 = FLASH_RESET;
764     w = *(FLASH_P2V(ROM));
765
766     *f_s1 = FLASH_SETUP_CODE1;
767     *f_s2 = FLASH_SETUP_CODE2;
768     *f_s1 = FLASH_READ_ID;
769
770     id[0] = -1;
771     id[1] = -1;
772
773     // Manufacturers' code
774     id[0] = *(FLASH_P2V(ROM+FLASH_VENDORID_ADDR));
775     // Part number
776     id[1] = *(FLASH_P2V(ROM+FLASH_DEVICEID_ADDR));
777     id[2] = *(FLASH_P2V(ROM+FLASH_DEVICEID_ADDR2));
778     id[3] = *(FLASH_P2V(ROM+FLASH_DEVICEID_ADDR3));
779
780     *(FLASH_P2V(ROM)) = FLASH_RESET;
781
782     // Stall, waiting for flash to return to read mode.
783     while ((--timeout != 0) && (w != *(FLASH_P2V(ROM)))) ;
784 }
785 */
786
787 #define AR531X_FLASHCTL 0xb8400000
788 #define AR531X_FLASHCTL0        (AR531X_FLASHCTL + 0x00)
789 #define AR531X_FLASHCTL1        (AR531X_FLASHCTL + 0x04)
790 #define AR531X_FLASHCTL2        (AR531X_FLASHCTL + 0x08)
791 #define FLASHCTL_IDCY   0x0000000f      /* Idle cycle turn around time */
792 #define FLASHCTL_IDCY_S 0
793 #define FLASHCTL_WST1   0x000003e0      /* Wait state 1 */
794 #define FLASHCTL_WST1_S 5
795 #define FLASHCTL_RBLE   0x00000400      /* Read byte lane enable */
796 #define FLASHCTL_WST2   0x0000f800      /* Wait state 2 */
797 #define FLASHCTL_WST2_S 11
798 #define FLASHCTL_AC     0x00070000      /* Flash address check (added) */
799 #define FLASHCTL_AC_S   16
800 #define FLASHCTL_AC_128K 0x00000000
801 #define FLASHCTL_AC_256K 0x00010000
802 #define FLASHCTL_AC_512K 0x00020000
803 #define FLASHCTL_AC_1M   0x00030000
804 #define FLASHCTL_AC_2M   0x00040000
805 #define FLASHCTL_AC_4M   0x00050000
806 #define FLASHCTL_AC_8M   0x00060000
807 #define FLASHCTL_AC_RES  0x00070000     /* 16MB is not supported */
808 #define FLASHCTL_E      0x00080000      /* Flash bank enable (added) */
809 #define FLASHCTL_BUSERR 0x01000000      /* Bus transfer error status flag */
810 #define FLASHCTL_WPERR  0x02000000      /* Write protect error status flag */
811 #define FLASHCTL_WP     0x04000000      /* Write protect */
812 #define FLASHCTL_BM     0x08000000      /* Burst mode */
813 #define FLASHCTL_MW     0x30000000      /* Memory width */
814 #define FLASHCTL_MWx8   0x00000000      /* Memory width x8 */
815 #define FLASHCTL_MWx16  0x10000000      /* Memory width x16 */
816 #define FLASHCTL_MWx32  0x20000000      /* Memory width x32 (not supported) */
817 #define FLASHCTL_ATNR   0x00000000      /* Access type == no retry */
818 #define FLASHCTL_ATR    0x80000000      /* Access type == retry every */
819 #define FLASHCTL_ATR4   0xc0000000      /* Access type == retry every 4 */
820
821 static int flash_erase_nvram(unsigned int flashsize, unsigned int blocksize)
822 {
823         int i, ticks;
824         unsigned short val;
825         if (!nvramdetect) {
826                 puts("nvram can and will not erased, since nvram was not detected on this device (maybe dd-wrt isnt installed)!\n");
827                 return;
828         }
829         unsigned int flash_ctl = sysRegRead(AR531X_FLASHCTL0);
830
831         FLASH_DATA_T id[4];
832 //    puts("read id\n");
833 //    flash_query(id);
834 //    printf("FLASH MANID: %X DEVID: %X DEVID2: %X DEVID3: %X\n",id[0],id[1],id[2],id[3]);
835
836         printf("erasing nvram at [0x%08X]\n", nvramdetect);
837
838         volatile FLASH_DATA_T *ROM, *BANK;
839         volatile FLASH_DATA_T *b_p = (FLASH_DATA_T *) (nvramdetect);
840         volatile FLASH_DATA_T *b_v;
841         volatile FLASH_DATA_T *f_s0, *f_s1, *f_s2;
842         int timeout = 50000;
843         FLASH_DATA_T state;
844         int len;
845         BANK = ROM =
846             (volatile FLASH_DATA_T *)((unsigned long)nvramdetect &
847                                       ~(0x800000 - 1));
848         f_s0 = FLASH_P2V(BANK);
849         f_s1 = FLASH_P2V(BANK + FLASH_SETUP_ADDR1);
850         f_s2 = FLASH_P2V(BANK + FLASH_SETUP_ADDR2);
851         len = blocksize;
852         int res = FLASH_ERR_OK;
853
854         *f_s1 = FLASH_SETUP_CODE1;
855         *f_s2 = FLASH_SETUP_CODE2;
856         *f_s1 = FLASH_WP_STATE;
857         state = *FLASH_P2V(b_p + FLASH_WP_ADDR);
858         *f_s0 = FLASH_RESET;
859
860         if (FLASH_UNLOCKED != state) {
861                 *FLASH_P2V(ROM) = FLASH_RESET;
862         }
863
864         b_v = FLASH_P2V(b_p);
865
866         *f_s1 = FLASH_SETUP_CODE1;
867         *f_s2 = FLASH_SETUP_CODE2;
868         *f_s1 = FLASH_SETUP_ERASE;
869         *f_s1 = FLASH_SETUP_CODE1;
870         *f_s2 = FLASH_SETUP_CODE2;
871         *b_v = FLASH_BLOCK_ERASE;
872         timeout = FLASH_POLLING_TIMEOUT;
873         while (1) {
874                 state = *b_v;
875                 if ((state & FLASH_SECTOR_ERASE_TIMER)
876                     == FLASH_SECTOR_ERASE_TIMER)
877                         break;
878                 udelay(1);
879                 if (--timeout == 0) {
880                         puts("flash erase timeout\n");
881                         res = FLASH_ERR_DRV_TIMEOUT;
882                         break;
883                 }
884         }
885         if (FLASH_ERR_OK == res) {
886                 timeout = FLASH_POLLING_TIMEOUT;
887                 while (1) {
888                         state = *b_v;
889                         if (FLASH_BLANKVALUE == state) {
890                                 break;
891                         }
892                         udelay(1);
893                         if (--timeout == 0) {
894                                 puts("flash erase timeout while waiting for erase complete\n");
895                                 res = FLASH_ERR_DRV_TIMEOUT;
896                                 break;
897                         }
898                 }
899         }
900
901         if (FLASH_ERR_OK != res)
902                 *FLASH_P2V(ROM) = FLASH_RESET;
903
904         b_v = FLASH_P2V(b_p++);
905         if (*b_v != FLASH_BLANKVALUE) {
906                 if (FLASH_ERR_OK == res) {
907                         puts("erase verify failed\n");
908                 } else {
909                         puts("nvram erase done\n");
910                 }
911                 return 0;
912         }
913
914 }
915
916 #endif
917 struct nvram_header {
918         __u32 magic;
919         __u32 len;
920         __u32 crc_ver_init;     /* 0:7 crc, 8:15 ver, 16:27 init, mem. test 28, 29-31 reserved */
921         __u32 config_refresh;   /* 0:15 config, 16:31 refresh */
922         __u32 config_ncdl;      /* ncdl values for memc */
923 };
924
925 struct nvram_tuple {
926         char *name;
927         char *value;
928         struct nvram_tuple *next;
929 };
930
931 #define NVRAM_SPACE 0x10000
932 #define NVRAM_MAGIC                     0x48534C46      /* 'NVFL' */
933
934 static char nvram_buf[65536] __attribute__((aligned(4096))) = {
935 0};                             //
936
937 /*
938  * simple dd-wrt nvram implementation (read only)
939  */
940 static void nvram_init(void)
941 {
942         struct nvram_header *header;
943         __u32 off, lim;
944         int i;
945 #ifndef AR5312
946         flashdetect();
947 #endif
948         for (i = 0; i < 4; i++) {
949                 header =
950                     (struct nvram_header *)(flashbase + flashsize -
951                                             (sectorsize * (3 + i)));
952                 if (header->magic == NVRAM_MAGIC && header->len > 0
953                     && header->len <= NVRAM_SPACE) {
954                         printf
955                             ("DD-WRT NVRAM with size = %d found on [0x%08X]\n",
956                              header->len, header);
957                         nvramdetect = (unsigned int)header;
958                         unsigned int *src = header;
959                         unsigned int *dst = nvram_buf;
960                         for (i = 0; i < NVRAM_SPACE / 4; i++)
961                                 dst[i] = src[i];
962                         return;
963                 }
964         }
965 }
966
967 static char *nvram_get(const char *name)
968 {
969         char *var, *value, *end, *eq;
970
971         if (!name)
972                 return NULL;
973
974         if (!nvram_buf[0])
975                 nvram_init();
976
977         /* Look for name=value and return value */
978         var = &nvram_buf[sizeof(struct nvram_header)];
979         end = nvram_buf + sizeof(nvram_buf) - 2;
980         end[0] = end[1] = '\0';
981         for (; *var; var = value + strlen(value) + 1) {
982                 if (!(eq = strchr(var, '=')))
983                         break;
984                 value = eq + 1;
985                 if ((eq - var) == strlen(name)
986                     && strncmp(var, name, (eq - var)) == 0)
987                         return value;
988         }
989
990         return NULL;
991 }
992
993 ulg
994 decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p)
995 {
996         output_data = (uch *) output_start;
997         free_mem_ptr = free_mem_ptr_p;
998         free_mem_ptr_end = free_mem_ptr_end_p;
999 #ifdef AR5312
1000 #define AR531X_APBBASE  0xbc000000
1001 #define AR531X_RESETTMR (AR531X_APBBASE + 0x3000)
1002 #define AR531X_WDC      (AR531X_RESETTMR + 0x0008)
1003         sysRegWrite(AR531X_WDC, 0);
1004 #endif
1005         arch_decomp_setup();
1006         printf("MicroRedBoot v1.2, (c) 2009 DD-WRT.COM (%s)\n", __DATE__);
1007         nvram_init();
1008         char *ddboard = nvram_get("DD_BOARD");
1009         if (ddboard)
1010                 printf("Board: %s\n", ddboard);
1011         char *resetbutton = nvram_get("resetbutton_enable");
1012         if (resetbutton && !strcmp(resetbutton, "1"))
1013                 puts("reset button manual override detected! (nvram var resetbutton_enable=1)\n");
1014         if (resetTouched() || (resetbutton && !strcmp(resetbutton, "1"))) {
1015                 puts("Reset Button triggered\nBooting Recovery RedBoot\n");
1016
1017                 int count = 5;
1018                 while (count--) {
1019                         if (!resetTouched())    // check if reset button is unpressed again
1020                                 break;
1021                         udelay(1000000);
1022                 }
1023                 if (count <= 0) {
1024                         puts("reset button 5 seconds pushed, erasing nvram\n");
1025
1026 #ifndef AR5312
1027                         if (!flashdetect())
1028 #endif
1029                                 flash_erase_nvram(flashsize, sectorsize);
1030                 }
1031
1032                 bootoffset = 0x800004bc;
1033                 resettrigger = 0;
1034         } else {
1035 #ifndef AR5312
1036                 flashdetect();
1037 #endif
1038                 linuxaddr = getLinux();
1039                 puts("Booting Linux\n");
1040                 resettrigger = 1;
1041                 /* initialize clock */
1042                 HAL_CLOCK_INITIALIZE(RTC_PERIOD);
1043
1044                 /* important, enable ethernet bus, if the following lines are not initialized linux will not be able to use the ethernet mac, taken from redboot source */
1045 #ifdef AR5312
1046 #define RESET_ENET0          0x00000020 /* cold reset ENET0 mac */
1047 #define RESET_EPHY0          0x00000008 /* cold reset ENET0 phy */
1048                 unsigned int mask = RESET_ENET0 | RESET_EPHY0;
1049                 unsigned int regtmp;
1050 #define AR531X_APBBASE  0xbc000000
1051 #define AR531X_RESETTMR (AR531X_APBBASE + 0x3000)
1052 #define AR531X_RESET    (AR531X_RESETTMR + 0x0020)
1053 #define AR531X_ENABLE   (AR531X_RESETTMR + 0x0080)
1054 #define ENABLE_ENET0              0x0002
1055
1056                 regtmp = sysRegRead(AR531X_RESET);
1057                 sysRegWrite(AR531X_RESET, regtmp | mask);
1058                 udelay(15000);
1059
1060                 /* Pull out of reset */
1061                 regtmp = sysRegRead(AR531X_RESET);
1062                 sysRegWrite(AR531X_RESET, regtmp & ~mask);
1063                 udelay(25);
1064                 mask = ENABLE_ENET0;
1065                 regtmp = sysRegRead(AR531X_ENABLE);
1066                 sysRegWrite(AR531X_ENABLE, regtmp | mask);
1067
1068 #else
1069                 unsigned int mask = RESET_ENET0 | RESET_EPHY0;
1070                 unsigned int regtmp;
1071                 regtmp = sysRegRead(AR2316_AHB_ARB_CTL);
1072                 regtmp |= ARB_ETHERNET;
1073                 sysRegWrite(AR2316_AHB_ARB_CTL, regtmp);
1074
1075                 regtmp = sysRegRead(AR2316_RESET);
1076                 sysRegWrite(AR2316_RESET, regtmp | mask);
1077                 udelay(10000);
1078
1079                 regtmp = sysRegRead(AR2316_RESET);
1080                 sysRegWrite(AR2316_RESET, regtmp & ~mask);
1081                 udelay(10000);
1082
1083                 regtmp = sysRegRead(AR2316_IF_CTL);
1084                 regtmp |= IF_TS_LOCAL;
1085                 sysRegWrite(AR2316_IF_CTL, regtmp);
1086
1087                 regtmp = sysRegRead(AR2316_ENDIAN_CTL);
1088                 regtmp &= ~CONFIG_ETHERNET;
1089                 sysRegWrite(AR2316_ENDIAN_CTL, regtmp);
1090 #endif
1091
1092         }
1093         puts("loading");
1094         lzma_unzip();
1095         puts("\n\n\n");
1096
1097         return output_ptr;
1098 }
1099 #else
1100
1101 char output_buffer[1500 * 1024];
1102
1103 int main()
1104 {
1105         output_data = output_buffer;
1106         puts("Uncompressing Linux...");
1107         lzma_unzip();
1108         puts("done.\r\n");
1109         return 0;
1110 }
1111 #endif
Note: See TracBrowser for help on using the browser.