source: src/linux/universal/linux-3.5/arch/arm/mach-brcm-hnd/board_ns.c @ 31672

Last change on this file since 31672 was 31672, checked in by brainslayer, 4 months ago

fix fs detection

File size: 23.7 KB
Line 
1
2#include <linux/types.h>
3#include <linux/version.h>
4#include <linux/init.h>
5#include <linux/platform_device.h>
6
7#include <asm/setup.h>
8#include <asm/mach-types.h>
9#include <asm/mach/arch.h>
10#include <asm/mach/time.h>
11#include <asm/clkdev.h>
12#include <asm/hardware/gic.h>
13
14#include <mach/clkdev.h>
15#include <mach/memory.h>
16#include <mach/io_map.h>
17
18#include <plat/bsp.h>
19#include <plat/mpcore.h>
20#include <plat/plat-bcm5301x.h>
21
22#ifdef CONFIG_MTD
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25#include <linux/mtd/nand.h>
26#include <linux/romfs_fs.h>
27#include <linux/cramfs_fs.h>
28#include <linux/squashfs_fs.h>
29#endif
30
31#include <typedefs.h>
32#include <osl.h>
33#include <bcmutils.h>
34#include <bcmnvram.h>
35#include <bcmendian.h>
36#include <hndsoc.h>
37#include <siutils.h>
38#include <hndcpu.h>
39#include <hndpci.h>
40#include <pcicfg.h>
41#include <bcmdevs.h>
42#include <trxhdr.h>
43#ifdef HNDCTF
44#include <ctf/hndctf.h>
45#endif /* HNDCTF */
46#include <hndsflash.h>
47#ifdef CONFIG_MTD_NFLASH
48#include <hndnand.h>
49#endif
50
51extern char __initdata saved_root_name[];
52
53/* Global SB handle */
54si_t *bcm947xx_sih = NULL;
55DEFINE_SPINLOCK(bcm947xx_sih_lock);
56EXPORT_SYMBOL(bcm947xx_sih);
57EXPORT_SYMBOL(bcm947xx_sih_lock);
58
59/* Convenience */
60#define sih bcm947xx_sih
61#define sih_lock bcm947xx_sih_lock
62
63#ifdef HNDCTF
64ctf_t *kcih = NULL;
65EXPORT_SYMBOL(kcih);
66ctf_attach_t ctf_attach_fn = NULL;
67EXPORT_SYMBOL(ctf_attach_fn);
68#endif /* HNDCTF */
69
70
71
72/* This is the main reference clock 25MHz from external crystal */
73static struct clk clk_ref = {
74        .name = "Refclk",
75        .rate = 25 * 1000000,   /* run-time override */
76        .fixed = 1,
77        .type   = CLK_XTAL,
78};
79
80
81static struct clk_lookup board_clk_lookups[] = {
82        {
83        .con_id         = "refclk",
84        .clk            = &clk_ref,
85        }
86};
87
88extern int _memsize;
89
90#if 0
91#include <mach/uncompress.h>
92
93void printch(int c)
94{
95putc(c);
96flush();
97}
98#endif
99void __init board_map_io(void)
100{
101early_printk("board_map_io\n");
102        /* Install clock sources into the lookup table */
103        clkdev_add_table(board_clk_lookups,
104                        ARRAY_SIZE(board_clk_lookups));
105
106        /* Map SoC specific I/O */
107        soc_map_io( &clk_ref );
108}
109
110
111void __init board_init_irq(void)
112{
113early_printk("board_init_irq\n");
114        soc_init_irq();
115       
116        /* serial_setup(sih); */
117}
118
119void board_init_timer(void)
120{
121early_printk("board_init_timer\n");
122        soc_init_timer();
123}
124
125static int __init rootfs_mtdblock(void)
126{
127        int bootdev;
128        int knldev;
129        int block = 0;
130#ifdef CONFIG_FAILSAFE_UPGRADE
131        char *img_boot = nvram_get(BOOTPARTITION);
132#endif
133
134        bootdev = soc_boot_dev((void *)sih);
135        knldev = soc_knl_dev((void *)sih);
136
137        /* NANDBOOT */
138        if (bootdev == SOC_BOOTDEV_NANDFLASH &&
139            knldev == SOC_KNLDEV_NANDFLASH) {
140#ifdef CONFIG_FAILSAFE_UPGRADE
141                if (img_boot && simple_strtol(img_boot, NULL, 10))
142                        return 5;
143                else
144                        return 3;
145#else
146                return 3;
147#endif
148        }
149
150        /* SFLASH/PFLASH only */
151        if (bootdev != SOC_BOOTDEV_NANDFLASH &&
152            knldev != SOC_KNLDEV_NANDFLASH) {
153#ifdef CONFIG_FAILSAFE_UPGRADE
154                if (img_boot && simple_strtol(img_boot, NULL, 10))
155                        return 4;
156                else
157                        return 2;
158#else
159                return 2;
160#endif
161        }
162
163#ifdef BCMCONFMTD
164        block++;
165#endif
166#ifdef CONFIG_FAILSAFE_UPGRADE
167        if (img_boot && simple_strtol(img_boot, NULL, 10))
168                block += 2;
169#endif
170        /* Boot from norflash and kernel in nandflash */
171        return block+3;
172}
173
174#define WATCHDOG_MIN    3000    /* milliseconds */
175extern int panic_timeout;
176extern int panic_on_oops;
177static int watchdog = 0;
178
179static void __init brcm_setup(void)
180{
181        /* Get global SB handle */
182        sih = si_kattach(SI_OSH);
183
184//      if (strncmp(boot_command_line, "root=/dev/mtdblock", strlen("root=/dev/mtdblock")) == 0)
185//              sprintf(saved_root_name, "/dev/mtdblock%d", rootfs_mtdblock());
186        /* Set watchdog interval in ms */
187        watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0);
188
189        /* Ensure at least WATCHDOG_MIN */
190        if ((watchdog > 0) && (watchdog < WATCHDOG_MIN))
191                watchdog = WATCHDOG_MIN;
192
193}
194
195void soc_watchdog(void)
196{
197        if (watchdog > 0)
198                si_watchdog_ms(sih, watchdog);
199 }
200
201void __init board_init(void)
202{
203early_printk("board_init\n");
204        brcm_setup();
205        /*
206         * Add common platform devices that do not have board dependent HW
207         * configurations
208         */
209        soc_add_devices();
210
211        return;
212}
213
214void __init board_fixup(struct tag *t, char **cmdline,struct meminfo *mi)
215{
216        early_printk("board_fixup\n" );
217       
218        u32 mem_size, lo_size ;
219        early_printk("board_fixup\n" );
220
221        /* Fuxup reference clock rate */
222//      if (desc->nr == MACH_TYPE_BRCM_NS_QT )
223//              clk_ref.rate = 17594;   /* Emulator ref clock rate */
224
225
226        mem_size = _memsize;
227
228        early_printk("board_fixup: mem=%uMiB\n", mem_size >> 20);
229
230        lo_size = min(mem_size, DRAM_MEMORY_REGION_SIZE);
231
232        mi->bank[0].start = PHYS_OFFSET;
233        mi->bank[0].size = lo_size;
234        mi->nr_banks++;
235
236        if (lo_size == mem_size)
237                return;
238
239        mi->bank[1].start = DRAM_LARGE_REGION_BASE + lo_size;
240        mi->bank[1].size = mem_size - lo_size;
241        mi->nr_banks++;
242}
243
244static struct sys_timer board_timer = {
245   .init = board_init_timer,
246};
247
248//#if (( (IO_BASE_VA >>18) & 0xfffc) != 0x3c40)
249//#error IO_BASE_VA
250//#endif
251
252void brcm_reset(char mode, const char *cmd)
253{
254#ifdef CONFIG_OUTER_CACHE_SYNC
255        outer_cache.sync = NULL;
256#endif
257        hnd_cpu_reset(sih);
258}
259
260
261MACHINE_START(BRCM_NS, "Northstar Prototype")
262//   .phys_io =                                         /* UART I/O mapping */
263//      IO_BASE_PA,
264//   .io_pg_offst =                             /* for early debug */
265//      (IO_BASE_VA >>18) & 0xfffc,
266   .fixup = board_fixup,                        /* Opt. early setup_arch() */
267   .map_io = board_map_io,                      /* Opt. from setup_arch() */
268   .init_irq = board_init_irq,                  /* main.c after setup_arch() */
269   .timer  = &board_timer,                      /* main.c after IRQs */
270   .init_machine = board_init,                  /* Late archinitcall */
271   .atag_offset = CONFIG_BOARD_PARAMS_PHYS,
272    .handle_irq = gic_handle_irq,
273    .restart    = brcm_reset,
274
275MACHINE_END
276
277#ifdef  CONFIG_MACH_BRCM_NS_QT
278MACHINE_START(BRCM_NS_QT, "Northstar Emulation Model")
279//   .phys_io =                                         /* UART I/O mapping */
280//      IO_BASE_PA,
281//   .io_pg_offst =                             /* for early debug */
282//      (IO_BASE_VA >>18) & 0xfffc,
283   .fixup = board_fixup,                        /* Opt. early setup_arch() */
284   .map_io = board_map_io,                      /* Opt. from setup_arch() */
285   .init_irq = board_init_irq,                  /* main.c after setup_arch() */
286   .timer  = &board_timer,                      /* main.c after IRQs */
287   .init_machine = board_init,                  /* Late archinitcall */
288   .atag_offset = CONFIG_BOARD_PARAMS_PHYS,
289    .handle_irq = gic_handle_irq,
290    .restart    = brcm_reset,
291MACHINE_END
292#endif
293
294
295#ifdef CONFIG_MTD
296
297static spinlock_t *bcm_mtd_lock = NULL;
298
299spinlock_t *partitions_lock_init(void)
300{
301        if (!bcm_mtd_lock) {
302                bcm_mtd_lock = (spinlock_t *)kzalloc(sizeof(spinlock_t), GFP_KERNEL);
303                if (!bcm_mtd_lock)
304                        return NULL;
305
306                spin_lock_init( bcm_mtd_lock );
307        }
308        return bcm_mtd_lock;
309}
310EXPORT_SYMBOL(partitions_lock_init);
311
312static struct nand_hw_control *nand_hwcontrol = NULL;
313struct nand_hw_control *nand_hwcontrol_lock_init(void)
314{
315        if (!nand_hwcontrol) {
316                nand_hwcontrol = (struct nand_hw_control *)kzalloc(sizeof(struct nand_hw_control), GFP_KERNEL);
317                if (!nand_hwcontrol)
318                        return NULL;
319
320                spin_lock_init(&nand_hwcontrol->lock);
321                init_waitqueue_head(&nand_hwcontrol->wq);
322        }
323        return nand_hwcontrol;
324}
325EXPORT_SYMBOL(nand_hwcontrol_lock_init);
326
327
328/* Find out prom size */
329static uint32 boot_partition_size(uint32 flash_phys) {
330        uint32 bootsz, *bisz;
331
332        /* Default is 256K boot partition */
333        bootsz = 256 * 1024;
334
335        /* Do we have a self-describing binary image? */
336        bisz = (uint32 *)(flash_phys + BISZ_OFFSET);
337        if (bisz[BISZ_MAGIC_IDX] == BISZ_MAGIC) {
338                int isz = bisz[BISZ_DATAEND_IDX] - bisz[BISZ_TXTST_IDX];
339
340                if (isz > (1024 * 1024))
341                        bootsz = 2048 * 1024;
342                else if (isz > (512 * 1024))
343                        bootsz = 1024 * 1024;
344                else if (isz > (256 * 1024))
345                        bootsz = 512 * 1024;
346                else if (isz <= (128 * 1024))
347                        bootsz = 128 * 1024;
348        }
349        return bootsz;
350}
351
352size_t rootfssize=0;
353
354#if defined(BCMCONFMTD)
355#define MTD_PARTS 1
356#else
357#define MTD_PARTS 0
358#endif
359#if defined(PLC)
360#define PLC_PARTS 1
361#else
362#define PLC_PARTS 0
363#endif
364#if defined(CONFIG_FAILSAFE_UPGRADE)
365#define FAILSAFE_PARTS 2
366#else
367#define FAILSAFE_PARTS 0
368#endif
369/* boot;nvram;kernel;rootfs;empty */
370#define FLASH_PARTS_NUM (6+MTD_PARTS+PLC_PARTS+FAILSAFE_PARTS)
371
372static struct mtd_partition bcm947xx_flash_parts[FLASH_PARTS_NUM+1] = {{0}};
373static uint lookup_flash_rootfs_offset(struct mtd_info *mtd, int *trx_off, size_t size)
374{
375        struct romfs_super_block *romfsb;
376        struct cramfs_super *cramfsb;
377        struct squashfs_super_block *squashfsb;
378        struct trx_header *trx;
379        unsigned char buf[512];
380        int off;
381        size_t len;
382
383        romfsb = (struct romfs_super_block *) buf;
384        cramfsb = (struct cramfs_super *) buf;
385        squashfsb = (void *) buf;
386        trx = (struct trx_header *) buf;
387
388        /* Look at every 64 KB boundary */
389        for (off = 0; off < size; off += (64 * 1024)) {
390                memset(buf, 0xe5, sizeof(buf));
391
392                /*
393                 * Read block 0 to test for romfs and cramfs superblock
394                 */
395                if (mtd_read(mtd, off, sizeof(buf), &len, buf) ||
396                    len != sizeof(buf))
397                        continue;
398
399                /* Try looking at TRX header for rootfs offset */
400                if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
401                        *trx_off = off;
402                        if (trx->offsets[1] == 0)
403                                continue;
404                        /*
405                         * Read to test for romfs and cramfs superblock
406                         */
407                        off += le32_to_cpu(trx->offsets[1]);
408                        memset(buf, 0xe5, sizeof(buf));
409                        if (mtd_read(mtd, off, sizeof(buf), &len, buf) || len != sizeof(buf))
410                                continue;
411                }
412
413                /* romfs is at block zero too */
414                if (romfsb->word0 == ROMSB_WORD0 &&
415                    romfsb->word1 == ROMSB_WORD1) {
416                        printk(KERN_NOTICE
417                               "%s: romfs filesystem found at block %d\n",
418                               mtd->name, off / mtd->erasesize);
419                        break;
420                }
421
422                /* so is cramfs */
423                if (cramfsb->magic == CRAMFS_MAGIC) {
424                        printk(KERN_NOTICE
425                               "%s: cramfs filesystem found at block %d\n",
426                               mtd->name, off / mtd->erasesize);
427                        break;
428                }
429
430                if (squashfsb->s_magic == SQUASHFS_MAGIC) {
431                        rootfssize = le64_to_cpu(squashfsb->bytes_used);;
432                        printk(KERN_NOTICE
433                               "%s: squash filesystem found at block %d\n",
434                               mtd->name, off / mtd->erasesize);
435                        break;
436                }
437        }
438
439        return off;
440}
441
442struct mtd_partition *
443init_mtd_partitions(hndsflash_t *sfl_info, struct mtd_info *mtd, size_t size)
444{
445        int bootdev;
446        int knldev;
447        int nparts = 0;
448        uint32 offset = 0;
449        uint rfs_off = 0;
450        uint vmlz_off, knl_size;
451        uint32 top = 0;
452        uint32 bootsz;
453        uint32 maxsize=0;
454#ifdef CONFIG_FAILSAFE_UPGRADE
455        char *img_boot = nvram_get(BOOTPARTITION);
456        char *imag_1st_offset = nvram_get(IMAGE_FIRST_OFFSET);
457        char *imag_2nd_offset = nvram_get(IMAGE_SECOND_OFFSET);
458        unsigned int image_first_offset = 0;
459        unsigned int image_second_offset = 0;
460        char dual_image_on = 0;
461
462        /* The image_1st_size and image_2nd_size are necessary if the Flash does not have any
463         * image
464         */
465        dual_image_on = (img_boot != NULL && imag_1st_offset != NULL && imag_2nd_offset != NULL);
466
467        if (dual_image_on) {
468                image_first_offset = simple_strtol(imag_1st_offset, NULL, 10);
469                image_second_offset = simple_strtol(imag_2nd_offset, NULL, 10);
470                printk("The first offset=%x, 2nd offset=%x\n", image_first_offset,
471                        image_second_offset);
472
473        }
474#endif  /* CONFIG_FAILSAFE_UPGRADE */
475       
476        if (nvram_match("boardnum","24") && nvram_match("boardtype", "0x0646")
477            && nvram_match("boardrev", "0x1110")
478            && nvram_match("gpio7", "wps_button")) {
479            maxsize = 0x200000;
480            size = maxsize;
481        }
482
483
484        bootdev = soc_boot_dev((void *)sih);
485        knldev = soc_knl_dev((void *)sih);
486
487        if (bootdev == SOC_BOOTDEV_NANDFLASH) {
488                /* Do not init MTD partitions on NOR flash when NAND boot */
489                return NULL;   
490        }
491
492        if (knldev != SOC_KNLDEV_NANDFLASH) {
493                rfs_off = lookup_flash_rootfs_offset(mtd, &vmlz_off, size);
494
495                /* Size pmon */
496                bcm947xx_flash_parts[nparts].name = "boot";
497                bcm947xx_flash_parts[nparts].size = vmlz_off;
498                bcm947xx_flash_parts[nparts].offset = top;
499                bcm947xx_flash_parts[nparts].mask_flags = MTD_WRITEABLE; /* forces on read only */
500                nparts++;
501
502                /* Setup kernel MTD partition */
503                bcm947xx_flash_parts[nparts].name = "linux";
504#ifdef CONFIG_FAILSAFE_UPGRADE
505                if (dual_image_on) {
506                        bcm947xx_flash_parts[nparts].size = image_second_offset-image_first_offset;
507                } else {
508                        bcm947xx_flash_parts[nparts].size = mtd->size - vmlz_off;
509
510                        /* Reserve for NVRAM */
511                        bcm947xx_flash_parts[nparts].size -= ROUNDUP(NVRAM_SPACE, mtd->erasesize);
512#ifdef PLC
513                        /* Reserve for PLC */
514                        bcm947xx_flash_parts[nparts].size -= ROUNDUP(0x1000, mtd->erasesize);
515#endif
516#ifdef BCMCONFMTD
517                        bcm947xx_flash_parts[nparts].size -= (mtd->erasesize *4);
518#endif
519                }
520#else
521
522                bcm947xx_flash_parts[nparts].size = mtd->size - vmlz_off;
523               
524#ifdef PLC
525                /* Reserve for PLC */
526                bcm947xx_flash_parts[nparts].size -= ROUNDUP(0x1000, mtd->erasesize);
527#endif
528                /* Reserve for NVRAM */
529                bcm947xx_flash_parts[nparts].size -= ROUNDUP(NVRAM_SPACE, mtd->erasesize);
530
531#ifdef BCMCONFMTD
532                bcm947xx_flash_parts[nparts].size -= (mtd->erasesize *4);
533#endif
534#endif  /* CONFIG_FAILSAFE_UPGRADE */
535                bcm947xx_flash_parts[nparts].offset = vmlz_off;
536                knl_size = bcm947xx_flash_parts[nparts].size;
537                offset = bcm947xx_flash_parts[nparts].offset + knl_size;
538                nparts++;
539               
540                /* Setup rootfs MTD partition */
541                bcm947xx_flash_parts[nparts].name = "rootfs";
542                bcm947xx_flash_parts[nparts].offset = rfs_off;
543                bcm947xx_flash_parts[nparts].size = rootfssize;
544                size_t offs = bcm947xx_flash_parts[nparts].offset + bcm947xx_flash_parts[nparts].size;
545                offs += (mtd->erasesize - 1);
546                offs &= ~(mtd->erasesize - 1);
547                offs -= bcm947xx_flash_parts[nparts].offset;
548                bcm947xx_flash_parts[nparts].size = offs;
549
550                bcm947xx_flash_parts[nparts].mask_flags = MTD_WRITEABLE; /* forces on read only */
551                nparts++;
552#ifdef CONFIG_FAILSAFE_UPGRADE
553                if (dual_image_on) {
554                        offset = image_second_offset;
555                        rfs_off = lookup_flash_rootfs_offset(mtd, &offset, size);
556                        vmlz_off = offset;
557                        /* Setup kernel2 MTD partition */
558                        bcm947xx_flash_parts[nparts].name = "linux2";
559                        bcm947xx_flash_parts[nparts].size = mtd->size - image_second_offset;
560                        /* Reserve for NVRAM */
561                        bcm947xx_flash_parts[nparts].size -= ROUNDUP(NVRAM_SPACE, mtd->erasesize);
562
563#ifdef BCMCONFMTD
564                        bcm947xx_flash_parts[nparts].size -= (mtd->erasesize *4);
565#endif
566#ifdef PLC
567                        /* Reserve for PLC */
568                        bcm947xx_flash_parts[nparts].size -= ROUNDUP(0x1000, mtd->erasesize);
569#endif
570                        bcm947xx_flash_parts[nparts].offset = image_second_offset;
571                        knl_size = bcm947xx_flash_parts[nparts].size;
572                        offset = bcm947xx_flash_parts[nparts].offset + knl_size;
573                        nparts++;
574
575                        /* Setup rootfs MTD partition */
576                        bcm947xx_flash_parts[nparts].name = "rootfs2";
577                        bcm947xx_flash_parts[nparts].size =
578                                knl_size - (rfs_off - image_second_offset);
579                        bcm947xx_flash_parts[nparts].offset = rfs_off;
580                        /* forces on read only */
581                        bcm947xx_flash_parts[nparts].mask_flags = MTD_WRITEABLE;
582                        nparts++;
583                }
584#endif  /* CONFIG_FAILSAFE_UPGRADE */
585
586        } else {
587                bootsz = boot_partition_size(sfl_info->base);
588                printk("Boot partition size = %d(0x%x)\n", bootsz, bootsz);
589                /* Size pmon */
590                if (maxsize)
591                    bootsz = maxsize;
592                bcm947xx_flash_parts[nparts].name = "boot";
593                bcm947xx_flash_parts[nparts].size = bootsz;
594                bcm947xx_flash_parts[nparts].offset = top;
595                bcm947xx_flash_parts[nparts].mask_flags = MTD_WRITEABLE; /* forces on read only */
596                offset = bcm947xx_flash_parts[nparts].size;
597                nparts++;
598        }
599
600#ifdef BCMCONFMTD
601        /* Setup CONF MTD partition */
602        bcm947xx_flash_parts[nparts].name = "confmtd";
603        bcm947xx_flash_parts[nparts].size = mtd->erasesize * 4;
604        bcm947xx_flash_parts[nparts].offset = offset;
605        offset = bcm947xx_flash_parts[nparts].offset + bcm947xx_flash_parts[nparts].size;
606        nparts++;
607#endif  /* BCMCONFMTD */
608
609#ifdef PLC
610        /* Setup plc MTD partition */
611        bcm947xx_flash_parts[nparts].name = "plc";
612        bcm947xx_flash_parts[nparts].size = ROUNDUP(0x1000, mtd->erasesize);
613        bcm947xx_flash_parts[nparts].offset =
614                size - (ROUNDUP(NVRAM_SPACE, mtd->erasesize) + ROUNDUP(0x1000, mtd->erasesize));
615        nparts++;
616#endif
617        if (rootfssize)
618        {
619        bcm947xx_flash_parts[nparts].name = "ddwrt";
620        bcm947xx_flash_parts[nparts].offset = bcm947xx_flash_parts[2].offset + bcm947xx_flash_parts[2].size;
621        bcm947xx_flash_parts[nparts].offset += (mtd->erasesize - 1);
622        bcm947xx_flash_parts[nparts].offset &= ~(mtd->erasesize - 1);
623        bcm947xx_flash_parts[nparts].size = (size - bcm947xx_flash_parts[nparts].offset) - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
624        nparts++;       
625        }
626        /* Setup nvram MTD partition */
627        bcm947xx_flash_parts[nparts].name = "nvram";
628        bcm947xx_flash_parts[nparts].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
629        if (maxsize)
630            bcm947xx_flash_parts[nparts].offset = (size - 0x10000) - bcm947xx_flash_parts[nparts].size;
631            else
632            bcm947xx_flash_parts[nparts].offset = size - bcm947xx_flash_parts[nparts].size;
633        nparts++;
634
635        return bcm947xx_flash_parts;
636}
637
638EXPORT_SYMBOL(init_mtd_partitions);
639
640#endif /* CONFIG_MTD_PARTITIONS */
641
642#ifdef CONFIG_MTD_NFLASH
643#define NFLASH_PARTS_NUM 7
644static struct mtd_partition bcm947xx_nflash_parts[NFLASH_PARTS_NUM] = {{0}};
645
646static uint
647lookup_nflash_rootfs_offset(hndnand_t *nfl, struct mtd_info *mtd, int offset, size_t size)
648{
649        struct romfs_super_block *romfsb;
650        struct cramfs_super *cramfsb;
651        struct squashfs_super_block *squashfsb;
652        struct squashfs_super_block *squashfsb2;
653        struct trx_header *trx;
654        unsigned char *buf;
655        uint blocksize, pagesize, mask, blk_offset, off, shift = 0;
656        int ret;
657
658        pagesize = nfl->pagesize;
659        buf = (unsigned char *)kmalloc(pagesize, GFP_KERNEL);
660        if (!buf) {
661                printk("lookup_nflash_rootfs_offset: kmalloc fail\n");
662                return 0;
663        }
664
665        romfsb = (struct romfs_super_block *) buf;
666        cramfsb = (struct cramfs_super *) buf;
667        squashfsb = (void *) buf;
668        squashfsb2 = (void *) &buf[0x60];
669        trx = (struct trx_header *) buf;
670
671        /* Look at every block boundary till 16MB; higher space is reserved for application data. */
672       
673        blocksize = mtd->erasesize;//65536;
674
675        if (nvram_match("boardnum","24") && nvram_match("boardtype", "0x0646")
676            && nvram_match("boardrev", "0x1110")
677            && nvram_match("gpio7", "wps_button")) {
678                printk(KERN_INFO "DIR-686L Hack for detecting filesystems\n");
679                blocksize = 65536;
680        }
681
682
683        printk("lookup_nflash_rootfs_offset: offset = 0x%x\n", offset);
684        for (off = offset; off < offset + size; off += blocksize) {
685                mask = blocksize - 1;
686                blk_offset = off & ~mask;
687                if (hndnand_checkbadb(nfl, blk_offset) != 0)
688                        continue;
689                memset(buf, 0xe5, pagesize);
690                if ((ret = hndnand_read(nfl, off, pagesize, buf)) != pagesize) {
691                        printk(KERN_NOTICE
692                               "%s: nflash_read return %d\n", mtd->name, ret);
693                        continue;
694                }
695
696                /* Try looking at TRX header for rootfs offset */
697                if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
698                        mask = pagesize - 1;
699                        off = offset + (le32_to_cpu(trx->offsets[1]) & ~mask) - blocksize;
700                        shift = (le32_to_cpu(trx->offsets[1]) & mask);
701                        romfsb = (struct romfs_super_block *)((unsigned char *)romfsb + shift);
702                        cramfsb = (struct cramfs_super *)((unsigned char *)cramfsb + shift);
703                        squashfsb = (struct squashfs_super_block *)
704                                ((unsigned char *)squashfsb + shift);
705                        squashfsb2 = NULL;
706                        printk(KERN_INFO "found TRX Header on nflash!\n");
707                        continue;
708                }
709
710                /* romfs is at block zero too */
711                if (romfsb->word0 == ROMSB_WORD0 &&
712                    romfsb->word1 == ROMSB_WORD1) {
713                        printk(KERN_NOTICE
714                               "%s: romfs filesystem found at block %d\n",
715                               mtd->name, off / blocksize);
716                        break;
717                }
718
719                /* so is cramfs */
720                if (cramfsb->magic == CRAMFS_MAGIC) {
721                        printk(KERN_NOTICE
722                               "%s: cramfs filesystem found at block %d\n",
723                               mtd->name, off / blocksize);
724                        break;
725                }
726               
727                if (squashfsb->s_magic == SQUASHFS_MAGIC) {
728                        rootfssize = le64_to_cpu(squashfsb->bytes_used);;
729                        printk(KERN_NOTICE
730                               "%s: squash filesystem with lzma found at block %d\n",
731                               mtd->name, off / blocksize);
732                        break;
733                }
734                if (squashfsb2 && squashfsb2->s_magic == SQUASHFS_MAGIC) {
735                        rootfssize = le64_to_cpu(squashfsb2->bytes_used);;
736                        off+=0x60;
737                        printk(KERN_NOTICE
738                               "%s: squash filesystem with lzma found at block %d\n",
739                               mtd->name, off / blocksize);
740                        break;
741                }
742
743        }
744
745        if (buf)
746                kfree(buf);
747
748        return shift + off;
749}
750
751struct mtd_partition *
752init_nflash_mtd_partitions(hndnand_t *nfl, struct mtd_info *mtd, size_t size)
753{
754        int bootdev;
755        int knldev;
756        int nparts = 0;
757        uint32 offset = 0;
758        uint shift = 0;
759        uint32 top = 0;
760        uint32 bootsz;
761#ifdef CONFIG_FAILSAFE_UPGRADE
762        char *img_boot = nvram_get(BOOTPARTITION);
763        char *imag_1st_offset = nvram_get(IMAGE_FIRST_OFFSET);
764        char *imag_2nd_offset = nvram_get(IMAGE_SECOND_OFFSET);
765        unsigned int image_first_offset = 0;
766        unsigned int image_second_offset = 0;
767        char dual_image_on = 0;
768
769        /* The image_1st_size and image_2nd_size are necessary if the Flash does not have any
770         * image
771         */
772        dual_image_on = (img_boot != NULL && imag_1st_offset != NULL && imag_2nd_offset != NULL);
773
774        if (dual_image_on) {
775                image_first_offset = simple_strtol(imag_1st_offset, NULL, 10);
776                image_second_offset = simple_strtol(imag_2nd_offset, NULL, 10);
777                printk("The first offset=%x, 2nd offset=%x\n", image_first_offset,
778                        image_second_offset);
779
780        }
781#endif  /* CONFIG_FAILSAFE_UPGRADE */
782
783        bootdev = soc_boot_dev((void *)sih);
784        knldev = soc_knl_dev((void *)sih);
785
786        if (bootdev == SOC_BOOTDEV_NANDFLASH) {
787                bootsz = boot_partition_size(nfl->base);
788                if (bootsz > mtd->erasesize) {
789                        /* Prepare double space in case of bad blocks */
790                        bootsz = (bootsz << 1);
791                } else {
792                        /* CFE occupies at least one block */
793                        bootsz = mtd->erasesize;
794                }
795                printk("Boot partition size = %d(0x%x)\n", bootsz, bootsz);
796
797                /* Size pmon */
798                bcm947xx_nflash_parts[nparts].name = "boot";
799                bcm947xx_nflash_parts[nparts].size = bootsz;
800                bcm947xx_nflash_parts[nparts].offset = top;
801                bcm947xx_nflash_parts[nparts].mask_flags = MTD_WRITEABLE; /* forces on read only */
802                offset = bcm947xx_nflash_parts[nparts].size;
803                nparts++;
804
805                /* Setup NVRAM MTD partition */
806                bcm947xx_nflash_parts[nparts].name = "nvram";
807                bcm947xx_nflash_parts[nparts].size = NFL_BOOT_SIZE - offset;
808                bcm947xx_nflash_parts[nparts].offset = offset;
809
810                offset = NFL_BOOT_SIZE;
811                nparts++;
812        }
813
814        if (knldev == SOC_KNLDEV_NANDFLASH) {
815                /* Setup kernel MTD partition */
816                bcm947xx_nflash_parts[nparts].name = "linux";
817#ifdef CONFIG_FAILSAFE_UPGRADE
818                if (dual_image_on) {
819                        bcm947xx_nflash_parts[nparts].size =
820                                image_second_offset - image_first_offset;
821                } else
822#endif
823                {
824                        bcm947xx_nflash_parts[nparts].size =
825                                nparts ? (NFL_BOOT_OS_SIZE - NFL_BOOT_SIZE) : NFL_BOOT_OS_SIZE;
826                }
827                bcm947xx_nflash_parts[nparts].offset = offset;
828
829                shift = lookup_nflash_rootfs_offset(nfl, mtd, offset,
830                        bcm947xx_nflash_parts[nparts].size);
831
832#ifdef CONFIG_FAILSAFE_UPGRADE
833                if (dual_image_on)
834                        offset = image_second_offset;
835                else
836#endif
837                offset = NFL_BOOT_OS_SIZE;
838                nparts++;
839
840                /* Setup rootfs MTD partition */
841                bcm947xx_nflash_parts[nparts].name = "rootfs";
842#ifdef CONFIG_FAILSAFE_UPGRADE
843                if (dual_image_on)
844                        bcm947xx_nflash_parts[nparts].size = image_second_offset - shift;
845                else
846#endif
847                bcm947xx_nflash_parts[nparts].size = NFL_BOOT_OS_SIZE - shift;
848                bcm947xx_nflash_parts[nparts].offset = shift;
849                bcm947xx_nflash_parts[nparts].mask_flags = MTD_WRITEABLE;
850
851                nparts++;
852
853#ifdef CONFIG_FAILSAFE_UPGRADE
854                /* Setup 2nd kernel MTD partition */
855                if (dual_image_on) {
856                        bcm947xx_nflash_parts[nparts].name = "linux2";
857                        bcm947xx_nflash_parts[nparts].size = NFL_BOOT_OS_SIZE - image_second_offset;
858                        bcm947xx_nflash_parts[nparts].offset = image_second_offset;
859                        shift = lookup_nflash_rootfs_offset(nfl, mtd, image_second_offset,
860                                                            bcm947xx_nflash_parts[nparts].size);
861                        nparts++;
862                        /* Setup rootfs MTD partition */
863                        bcm947xx_nflash_parts[nparts].name = "rootfs2";
864                        bcm947xx_nflash_parts[nparts].size = NFL_BOOT_OS_SIZE - shift;
865                        bcm947xx_nflash_parts[nparts].offset = shift;
866                        bcm947xx_nflash_parts[nparts].mask_flags = MTD_WRITEABLE;
867                        nparts++;
868                }
869#endif  /* CONFIG_FAILSAFE_UPGRADE */
870
871        }
872#if 0
873        if (rootfssize)
874        {
875        bcm947xx_nflash_parts[nparts].name = "ddwrt";
876        bcm947xx_nflash_parts[nparts].offset = bcm947xx_nflash_parts[3].offset + bcm947xx_nflash_parts[3].size;
877        bcm947xx_nflash_parts[nparts].offset += (mtd->erasesize - 1);
878        bcm947xx_nflash_parts[nparts].offset &= ~(mtd->erasesize - 1);
879        bcm947xx_nflash_parts[nparts].size = (size - bcm947xx_nflash_parts[nparts].offset) - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
880        nparts++;       
881        }
882#endif
883        return bcm947xx_nflash_parts;
884}
885
886EXPORT_SYMBOL(init_nflash_mtd_partitions);
887#endif /* CONFIG_MTD_NFLASH */
Note: See TracBrowser for help on using the repository browser.