2 * HND MIPS boards setup routines
4 * Copyright (C) 2011, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: setup.c,v 1.23 2010-10-20 08:26:12 $
21 #include <linux/types.h>
22 #include <linux/config.h>
23 #include <linux/init.h>
24 #include <linux/kernel.h>
25 #include <linux/serial.h>
26 #include <linux/serialP.h>
27 #include <linux/serial_core.h>
28 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
29 #include <linux/blkdev.h>
30 #include <linux/ide.h>
32 #include <asm/bootinfo.h>
35 #include <asm/reboot.h>
37 #ifdef CONFIG_MTD_PARTITIONS
38 #include <linux/mtd/mtd.h>
39 #include <linux/mtd/partitions.h>
40 #include <linux/romfs_fs.h>
41 #include <linux/cramfs_fs.h>
42 #include <linux/squashfs_fs.h>
44 #ifdef CONFIG_BLK_DEV_INITRD
45 #include <linux/initrd.h>
54 #include <mips33_core.h>
55 #include <mips74k_core.h>
61 #include <ctf/hndctf.h>
64 #ifdef CONFIG_MTD_NFLASH
69 extern void bcm947xx_time_init(void);
70 extern void bcm947xx_timer_setup(struct irqaction
*irq
);
73 extern void set_debug_traps(void);
74 extern void rs_kgdb_hook(struct uart_port
*);
75 extern void breakpoint(void);
78 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
79 extern struct ide_ops std_ide_ops
;
82 /* Enable CPU wait or not */
83 extern int cpu_wait_enable
;
85 /* Global assert type */
86 extern uint32 g_assert_type
;
88 /* Global SB handle */
89 si_t
*bcm947xx_sih
= NULL
;
90 spinlock_t bcm947xx_sih_lock
= SPIN_LOCK_UNLOCKED
;
91 EXPORT_SYMBOL(bcm947xx_sih
);
92 EXPORT_SYMBOL(bcm947xx_sih_lock
);
96 EXPORT_SYMBOL(bcm947xx_cpu_clk
);
99 #define sih bcm947xx_sih
100 #define sih_lock bcm947xx_sih_lock
105 ctf_attach_t ctf_attach_fn
= NULL
;
106 EXPORT_SYMBOL(ctf_attach_fn
);
109 /* Kernel command line */
110 extern char arcs_cmdline
[CL_SIZE
];
111 static int lanports_enable
= 0;
114 bcm947xx_reboot_handler(void)
120 /* Reset the PCI(e) interfaces */
121 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
124 if (lanports_enable
) {
125 uint lp
= 1 << lanports_enable
;
127 si_gpioout(sih
, lp
, 0, GPIO_DRV_PRIORITY
);
128 si_gpioouten(sih
, lp
, lp
, GPIO_DRV_PRIORITY
);
133 /* gpio 0 is also valid wombo_reset */
134 if ((wombo_reset
= getgpiopin(NULL
, "wombo_reset", GPIO_PIN_NOTDEFINED
)) !=
135 GPIO_PIN_NOTDEFINED
) {
136 int reset
= 1 << wombo_reset
;
138 si_gpioout(sih
, reset
, 0, GPIO_DRV_PRIORITY
);
139 si_gpioouten(sih
, reset
, reset
, GPIO_DRV_PRIORITY
);
146 bcm947xx_machine_restart(char *command
)
148 printk("Please stand by while rebooting the system...\n");
150 /* Set the watchdog timer to reset immediately */
152 bcm947xx_reboot_handler();
157 bcm947xx_machine_halt(void)
159 printk("System halted\n");
161 /* Disable interrupts and watchdog and spin forever */
164 bcm947xx_reboot_handler();
168 #ifdef CONFIG_SERIAL_CORE
170 static struct uart_port rs
= {
172 flags
: ASYNC_BOOT_AUTOCONF
,
173 iotype
: SERIAL_IO_MEM
,
177 serial_add(void *regs
, uint irq
, uint baud_base
, uint reg_shift
)
181 rs
.uartclk
= baud_base
;
182 rs
.regshift
= reg_shift
;
184 early_serial_setup(&rs
);
190 serial_setup(si_t
*sih
)
192 si_serial_init(sih
, serial_add
);
195 /* Use the last port for kernel debugging */
201 #endif /* CONFIG_SERIAL_CORE */
208 /* Only support chipcommon revision == 38 or BCM4706 for now */
209 if ((CHIPID(sih
->chip
) == BCM4706_CHIP_ID
) || sih
->ccrev
== 38) {
210 if (sih
->ccrev
== 38 && (sih
->chipst
& (1 << 4)) != 0) {
211 /* This is NANDBOOT */
212 bootflags
= FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
;
214 else if ((val
= nvram_get("bootflags"))) {
215 bootflags
= simple_strtol(val
, NULL
, 0);
216 bootflags
&= FLASH_KERNEL_NFLASH
;
223 static int rootfs_mtdblock(void)
227 #ifdef CONFIG_FAILSAFE_UPGRADE
228 char *img_boot
= nvram_get(BOOTPARTITION
);
230 bootflags
= boot_flags();
233 if ((bootflags
& (FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
)) ==
234 (FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
))
235 #ifdef CONFIG_FAILSAFE_UPGRADE
237 if (img_boot
&& simple_strtol(img_boot
, NULL
, 10))
246 /* SFLASH/PFLASH only */
247 if ((bootflags
& (FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
)) == 0)
248 #ifdef CONFIG_FAILSAFE_UPGRADE
250 if (img_boot
&& simple_strtol(img_boot
, NULL
, 10))
262 #ifdef CONFIG_FAILSAFE_UPGRADE
263 if (img_boot
&& simple_strtol(img_boot
, NULL
, 10))
266 /* Boot from norflash and kernel in nandflash */
277 /* Get global SB handle */
278 sih
= si_kattach(SI_OSH
);
280 /* Initialize clocks and interrupts */
281 si_mips_init(sih
, SBMIPS_VIRTIRQ_BASE
);
283 if (BCM330X(current_cpu_data
.processor_id
) &&
284 (read_c0_diag() & BRCM_PFC_AVAIL
)) {
286 * Now that the sih is inited set the proper PFC value
288 printk("Setting the PFC to its default value\n");
289 enable_pfc(PFC_AUTO
);
293 #ifdef CONFIG_SERIAL_CORE
294 /* Initialize UARTs */
296 #endif /* CONFIG_SERIAL_CORE */
298 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
299 ide_ops
= &std_ide_ops
;
302 if (strncmp(arcs_cmdline
, "root=/dev/mtdblock", strlen("root=/dev/mtdblock")) == 0)
303 sprintf(arcs_cmdline
, "root=/dev/mtdblock%d console=ttyS0,115200", rootfs_mtdblock());
305 /* Override default command line arguments */
306 value
= nvram_get("kernel_args");
307 if (value
&& strlen(value
) && strncmp(value
, "empty", 5))
308 strncpy(arcs_cmdline
, value
, sizeof(arcs_cmdline
));
311 value
= nvram_get("assert_type");
312 if (value
&& strlen(value
))
313 g_assert_type
= simple_strtoul(value
, NULL
, 10);
316 if ((lanports_enable
= getgpiopin(NULL
, "lanports_enable", GPIO_PIN_NOTDEFINED
)) ==
320 /* Init gpio status for coma mode support via wps button */
321 leave_coma
= getgpiopin(NULL
, "leave_coma", GPIO_PIN_NOTDEFINED
);
322 if (leave_coma
!= GPIO_PIN_NOTDEFINED
) {
323 int leave_coma_mask
= 1 << leave_coma
;
325 si_gpioout(sih
, leave_coma_mask
, 0, GPIO_HI_PRIORITY
);
326 si_gpioouten(sih
, leave_coma_mask
, leave_coma_mask
, GPIO_HI_PRIORITY
);
329 /* Set gpio HIGH to turn on USB VBUS power */
330 disable_usb
= getgpiopin(NULL
, "disable_usb", GPIO_PIN_NOTDEFINED
);
331 if (disable_usb
!= GPIO_PIN_NOTDEFINED
) {
332 int disable_usb_mask
= 1 << disable_usb
;
334 si_gpioout(sih
, disable_usb_mask
, disable_usb_mask
, GPIO_DRV_PRIORITY
);
335 si_gpioouten(sih
, disable_usb_mask
, disable_usb_mask
, GPIO_DRV_PRIORITY
);
338 /* Check if we want to enable cpu wait */
339 if (nvram_match("wait", "1"))
343 _machine_restart
= bcm947xx_machine_restart
;
344 _machine_halt
= bcm947xx_machine_halt
;
345 pm_power_off
= bcm947xx_machine_halt
;
347 board_time_init
= bcm947xx_time_init
;
351 get_system_type(void)
356 sprintf(s
, "Broadcom BCM%X chip rev %d", bcm947xx_sih
->chip
,
357 bcm947xx_sih
->chiprev
);
361 return "Broadcom BCM947XX";
376 #ifdef CONFIG_MTD_PARTITIONS
378 static struct mutex
*mtd_mutex
= NULL
;
380 struct mutex
*partitions_mutex_init()
383 mtd_mutex
= (struct mutex
*)kzalloc(sizeof(struct mutex
), GFP_KERNEL
);
386 mutex_init(mtd_mutex
);
390 EXPORT_SYMBOL(partitions_mutex_init
);
392 /* Find out prom size */
393 static uint32
boot_partition_size(uint32 flash_phys
) {
394 uint32 bootsz
, *bisz
;
396 /* Default is 256K boot partition */
399 /* Do we have a self-describing binary image? */
400 bisz
= (uint32
*)KSEG1ADDR(flash_phys
+ BISZ_OFFSET
);
401 if (bisz
[BISZ_MAGIC_IDX
] == BISZ_MAGIC
) {
402 int isz
= bisz
[BISZ_DATAEND_IDX
] - bisz
[BISZ_TXTST_IDX
];
404 if (isz
> (1024 * 1024))
405 bootsz
= 2048 * 1024;
406 else if (isz
> (512 * 1024))
407 bootsz
= 1024 * 1024;
408 else if (isz
> (256 * 1024))
410 else if (isz
<= (128 * 1024))
417 #if defined(BCMCONFMTD)
427 #if defined(CONFIG_FAILSAFE_UPGRADE)
428 #define FAILSAFE_PARTS 2
430 #define FAILSAFE_PARTS 0
432 /* boot;nvram;kernel;rootfs;empty */
433 #define FLASH_PARTS_NUM (5+MTD_PARTS+PLC_PARTS+FAILSAFE_PARTS)
435 static struct mtd_partition bcm947xx_flash_parts
[FLASH_PARTS_NUM
] = {{0}};
437 static uint
lookup_flash_rootfs_offset(struct mtd_info
*mtd
, int *trx_off
, size_t size
)
439 struct romfs_super_block
*romfsb
;
440 struct cramfs_super
*cramfsb
;
441 struct squashfs_super_block
*squashfsb
;
442 struct trx_header
*trx
;
443 unsigned char buf
[512];
447 romfsb
= (struct romfs_super_block
*) buf
;
448 cramfsb
= (struct cramfs_super
*) buf
;
449 squashfsb
= (struct squashfs_super_block
*) buf
;
450 trx
= (struct trx_header
*) buf
;
452 /* Look at every 64 KB boundary */
453 for (off
= *trx_off
; off
< size
; off
+= (64 * 1024)) {
454 memset(buf
, 0xe5, sizeof(buf
));
457 * Read block 0 to test for romfs and cramfs superblock
459 if (mtd
->read(mtd
, off
, sizeof(buf
), &len
, buf
) ||
463 /* Try looking at TRX header for rootfs offset */
464 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
) {
466 if (trx
->offsets
[1] == 0)
469 * Read to test for romfs and cramfs superblock
471 off
+= le32_to_cpu(trx
->offsets
[1]);
472 memset(buf
, 0xe5, sizeof(buf
));
473 if (mtd
->read(mtd
, off
, sizeof(buf
), &len
, buf
) || len
!= sizeof(buf
))
477 /* romfs is at block zero too */
478 if (romfsb
->word0
== ROMSB_WORD0
&&
479 romfsb
->word1
== ROMSB_WORD1
) {
481 "%s: romfs filesystem found at block %d\n",
482 mtd
->name
, off
/ mtd
->erasesize
);
487 if (cramfsb
->magic
== CRAMFS_MAGIC
) {
489 "%s: cramfs filesystem found at block %d\n",
490 mtd
->name
, off
/ mtd
->erasesize
);
494 if (squashfsb
->s_magic
== SQUASHFS_MAGIC_LZMA
) {
496 "%s: squash filesystem with lzma found at block %d\n",
497 mtd
->name
, off
/ mtd
->erasesize
);
504 struct mtd_partition
*
505 init_mtd_partitions(struct mtd_info
*mtd
, size_t size
)
511 uint vmlz_off
, knl_size
;
514 #ifdef CONFIG_FAILSAFE_UPGRADE
515 char *img_boot
= nvram_get(BOOTPARTITION
);
516 char *imag_1st_offset
= nvram_get(IMAGE_FIRST_OFFSET
);
517 char *imag_2nd_offset
= nvram_get(IMAGE_SECOND_OFFSET
);
518 unsigned int image_first_offset
=0;
519 unsigned int image_second_offset
=0;
520 char dual_image_on
= 0;
522 /* The image_1st_size and image_2nd_size are necessary if the Flash does not have any
525 dual_image_on
= (img_boot
!= NULL
&& imag_1st_offset
!= NULL
&& imag_2nd_offset
!= NULL
);
528 image_first_offset
= simple_strtol(imag_1st_offset
, NULL
, 10);
529 image_second_offset
= simple_strtol(imag_2nd_offset
, NULL
, 10);
530 printk("The first offset=%x, 2nd offset=%x\n", image_first_offset
,
531 image_second_offset
);
536 bootflags
= boot_flags();
538 if ((bootflags
& FLASH_KERNEL_NFLASH
) != FLASH_KERNEL_NFLASH
) {
540 rfs_off
= lookup_flash_rootfs_offset(mtd
, &vmlz_off
, size
);
543 bcm947xx_flash_parts
[nparts
].name
= "boot";
544 bcm947xx_flash_parts
[nparts
].size
= vmlz_off
;
545 bcm947xx_flash_parts
[nparts
].offset
= top
;
546 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
549 /* Setup kernel MTD partition */
550 bcm947xx_flash_parts
[nparts
].name
= "linux";
551 #ifdef CONFIG_FAILSAFE_UPGRADE
553 bcm947xx_flash_parts
[nparts
].size
= image_second_offset
-image_first_offset
;
555 bcm947xx_flash_parts
[nparts
].size
= mtd
->size
- vmlz_off
;
557 /* Reserve for NVRAM */
558 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
);
560 /* Reserve for PLC */
561 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x1000, mtd
->erasesize
);
564 bcm947xx_flash_parts
[nparts
].size
-= (mtd
->erasesize
*4);
569 bcm947xx_flash_parts
[nparts
].size
= mtd
->size
- vmlz_off
;
572 /* Reserve for PLC */
573 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x1000, mtd
->erasesize
);
575 /* Reserve for NVRAM */
576 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
);
579 bcm947xx_flash_parts
[nparts
].size
-= (mtd
->erasesize
*4);
582 bcm947xx_flash_parts
[nparts
].offset
= vmlz_off
;
583 knl_size
= bcm947xx_flash_parts
[nparts
].size
;
584 offset
= bcm947xx_flash_parts
[nparts
].offset
+ knl_size
;
587 /* Setup rootfs MTD partition */
588 bcm947xx_flash_parts
[nparts
].name
= "rootfs";
589 bcm947xx_flash_parts
[nparts
].size
= knl_size
- (rfs_off
- vmlz_off
);
590 bcm947xx_flash_parts
[nparts
].offset
= rfs_off
;
591 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
593 #ifdef CONFIG_FAILSAFE_UPGRADE
595 offset
= image_second_offset
;
596 rfs_off
= lookup_flash_rootfs_offset(mtd
, &offset
, size
);
598 /* Setup kernel2 MTD partition */
599 bcm947xx_flash_parts
[nparts
].name
= "linux2";
600 bcm947xx_flash_parts
[nparts
].size
= mtd
->size
- image_second_offset
;
601 /* Reserve for NVRAM */
602 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
);
605 bcm947xx_flash_parts
[nparts
].size
-= (mtd
->erasesize
*4);
608 /* Reserve for PLC */
609 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x1000, mtd
->erasesize
);
611 bcm947xx_flash_parts
[nparts
].offset
= image_second_offset
;
612 knl_size
= bcm947xx_flash_parts
[nparts
].size
;
613 offset
= bcm947xx_flash_parts
[nparts
].offset
+ knl_size
;
616 /* Setup rootfs MTD partition */
617 bcm947xx_flash_parts
[nparts
].name
= "rootfs2";
618 bcm947xx_flash_parts
[nparts
].size
= knl_size
- (rfs_off
- image_second_offset
);
619 bcm947xx_flash_parts
[nparts
].offset
= rfs_off
;
620 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
626 bootsz
= boot_partition_size(SI_FLASH2
);
627 printk("Boot partition size = %d(0x%x)\n", bootsz
, bootsz
);
629 bcm947xx_flash_parts
[nparts
].name
= "pmon";
630 bcm947xx_flash_parts
[nparts
].size
= bootsz
;
631 bcm947xx_flash_parts
[nparts
].offset
= top
;
632 //bcm947xx_flash_parts[nparts].mask_flags = MTD_WRITEABLE; /* forces on read only */
633 offset
= bcm947xx_flash_parts
[nparts
].size
;
638 /* Setup CONF MTD partition */
639 bcm947xx_flash_parts
[nparts
].name
= "confmtd";
640 bcm947xx_flash_parts
[nparts
].size
= mtd
->erasesize
* 4;
641 bcm947xx_flash_parts
[nparts
].offset
= offset
;
642 offset
= bcm947xx_flash_parts
[nparts
].offset
+ bcm947xx_flash_parts
[nparts
].size
;
644 #endif /* BCMCONFMTD */
647 /* Setup plc MTD partition */
648 bcm947xx_flash_parts
[nparts
].name
= "plc";
649 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(0x1000, mtd
->erasesize
);
650 bcm947xx_flash_parts
[nparts
].offset
= size
- (ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
) + ROUNDUP(0x1000, mtd
->erasesize
));
654 /* Setup nvram MTD partition */
655 bcm947xx_flash_parts
[nparts
].name
= "nvram";
656 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
);
657 bcm947xx_flash_parts
[nparts
].offset
= size
- bcm947xx_flash_parts
[nparts
].size
;
660 return bcm947xx_flash_parts
;
663 EXPORT_SYMBOL(init_mtd_partitions
);
665 #ifdef CONFIG_MTD_NFLASH
666 #define NFLASH_PARTS_NUM 6
667 static struct mtd_partition bcm947xx_nflash_parts
[NFLASH_PARTS_NUM
] = {{0}};
669 static uint
lookup_nflash_rootfs_offset(struct mtd_info
*mtd
, int offset
, size_t size
)
671 struct romfs_super_block
*romfsb
;
672 struct cramfs_super
*cramfsb
;
673 struct squashfs_super_block
*squashfsb
;
674 struct trx_header
*trx
;
675 unsigned char buf
[NFL_SECTOR_SIZE
];
676 uint blocksize
, mask
, blk_offset
, off
, shift
= 0;
680 romfsb
= (struct romfs_super_block
*) buf
;
681 cramfsb
= (struct cramfs_super
*) buf
;
682 squashfsb
= (struct squashfs_super_block
*) buf
;
683 trx
= (struct trx_header
*) buf
;
685 if ((cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
)) == NULL
)
688 /* Look at every block boundary till 16MB; higher space is reserved for application data. */
689 blocksize
= mtd
->erasesize
;
690 printk("lookup_nflash_rootfs_offset: offset = 0x%x\n", offset
);
691 for (off
= offset
; off
< NFL_BOOT_OS_SIZE
; off
+= blocksize
) {
692 mask
= blocksize
- 1;
693 blk_offset
= off
& ~mask
;
694 if (nflash_checkbadb(sih
, cc
, blk_offset
) != 0)
696 memset(buf
, 0xe5, sizeof(buf
));
697 if ((ret
= nflash_read(sih
, cc
, off
, sizeof(buf
), buf
)) != sizeof(buf
)) {
699 "%s: nflash_read return %d\n", mtd
->name
, ret
);
703 /* Try looking at TRX header for rootfs offset */
704 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
) {
705 mask
= NFL_SECTOR_SIZE
- 1;
706 off
= offset
+ (le32_to_cpu(trx
->offsets
[1]) & ~mask
) - blocksize
;
707 shift
= (le32_to_cpu(trx
->offsets
[1]) & mask
);
708 romfsb
= (struct romfs_super_block
*)((unsigned char *)romfsb
+ shift
);
709 cramfsb
= (struct cramfs_super
*)((unsigned char *)cramfsb
+ shift
);
710 squashfsb
= (struct squashfs_super_block
*)((unsigned char *)squashfsb
+ shift
);
714 /* romfs is at block zero too */
715 if (romfsb
->word0
== ROMSB_WORD0
&&
716 romfsb
->word1
== ROMSB_WORD1
) {
718 "%s: romfs filesystem found at block %d\n",
719 mtd
->name
, off
/ blocksize
);
724 if (cramfsb
->magic
== CRAMFS_MAGIC
) {
726 "%s: cramfs filesystem found at block %d\n",
727 mtd
->name
, off
/ blocksize
);
731 if (squashfsb
->s_magic
== SQUASHFS_MAGIC_LZMA
) {
733 "%s: squash filesystem with lzma found at block %d\n",
734 mtd
->name
, off
/ blocksize
);
742 struct mtd_partition
* init_nflash_mtd_partitions(struct mtd_info
*mtd
, size_t size
)
750 #ifdef CONFIG_FAILSAFE_UPGRADE
751 char *img_boot
= nvram_get(BOOTPARTITION
);
752 char *imag_1st_offset
= nvram_get(IMAGE_FIRST_OFFSET
);
753 char *imag_2nd_offset
= nvram_get(IMAGE_SECOND_OFFSET
);
754 unsigned int image_first_offset
=0;
755 unsigned int image_second_offset
=0;
756 char dual_image_on
= 0;
758 /* The image_1st_size and image_2nd_size are necessary if the Flash does not have any
761 dual_image_on
= (img_boot
!= NULL
&& imag_1st_offset
!= NULL
&& imag_2nd_offset
!= NULL
);
764 image_first_offset
= simple_strtol(imag_1st_offset
, NULL
, 10);
765 image_second_offset
= simple_strtol(imag_2nd_offset
, NULL
, 10);
766 printk("The first offset=%x, 2nd offset=%x\n", image_first_offset
,
767 image_second_offset
);
772 bootflags
= boot_flags();
773 if ((bootflags
& FLASH_BOOT_NFLASH
) == FLASH_BOOT_NFLASH
) {
774 bootsz
= boot_partition_size(SI_FLASH1
);
775 if (bootsz
> mtd
->erasesize
) {
776 /* Prepare double space in case of bad blocks */
777 bootsz
= (bootsz
<< 1);
779 /* CFE occupies at least one block */
780 bootsz
= mtd
->erasesize
;
782 printk("Boot partition size = %d(0x%x)\n", bootsz
, bootsz
);
785 bcm947xx_nflash_parts
[nparts
].name
= "boot";
786 bcm947xx_nflash_parts
[nparts
].size
= bootsz
;
787 bcm947xx_nflash_parts
[nparts
].offset
= top
;
788 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
789 offset
= bcm947xx_nflash_parts
[nparts
].size
;
792 /* Setup NVRAM MTD partition */
793 bcm947xx_nflash_parts
[nparts
].name
= "nvram";
794 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_SIZE
- offset
;
795 bcm947xx_nflash_parts
[nparts
].offset
= offset
;
797 offset
= NFL_BOOT_SIZE
;
801 if ((bootflags
& FLASH_KERNEL_NFLASH
) == FLASH_KERNEL_NFLASH
) {
802 /* Setup kernel MTD partition */
803 bcm947xx_nflash_parts
[nparts
].name
= "linux";
804 #ifdef CONFIG_FAILSAFE_UPGRADE
806 bcm947xx_nflash_parts
[nparts
].size
= image_second_offset
- image_first_offset
;
809 bcm947xx_nflash_parts
[nparts
].size
= nparts
? (NFL_BOOT_OS_SIZE
- NFL_BOOT_SIZE
) : NFL_BOOT_OS_SIZE
;
810 bcm947xx_nflash_parts
[nparts
].offset
= offset
;
812 shift
= lookup_nflash_rootfs_offset(mtd
, offset
, bcm947xx_nflash_parts
[nparts
].size
);
814 #ifdef CONFIG_FAILSAFE_UPGRADE
816 offset
= image_second_offset
;
819 offset
= NFL_BOOT_OS_SIZE
;
822 /* Setup rootfs MTD partition */
823 bcm947xx_nflash_parts
[nparts
].name
= "rootfs";
824 #ifdef CONFIG_FAILSAFE_UPGRADE
826 bcm947xx_nflash_parts
[nparts
].size
= image_second_offset
- shift
;
829 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_OS_SIZE
- shift
;
830 bcm947xx_nflash_parts
[nparts
].offset
= shift
;
831 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
;
835 #ifdef CONFIG_FAILSAFE_UPGRADE
836 /* Setup 2nd kernel MTD partition */
838 bcm947xx_nflash_parts
[nparts
].name
= "linux2";
839 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_OS_SIZE
- image_second_offset
;
840 bcm947xx_nflash_parts
[nparts
].offset
= image_second_offset
;
841 shift
= lookup_nflash_rootfs_offset(mtd
, image_second_offset
,
842 bcm947xx_nflash_parts
[nparts
].size
);
844 /* Setup rootfs MTD partition */
845 bcm947xx_nflash_parts
[nparts
].name
= "rootfs2";
846 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_OS_SIZE
- shift
;
847 bcm947xx_nflash_parts
[nparts
].offset
= shift
;
848 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
;
855 return bcm947xx_nflash_parts
;
858 EXPORT_SYMBOL(init_nflash_mtd_partitions
);
859 #endif /* CONFIG_MTD_NFLASH */
861 #ifdef CONFIG_BLK_DEV_INITRD
864 /* The check_ramdisk_trx has more exact qualification to look at TRX header from end of linux */
866 check_ramdisk_trx(unsigned long offset
, unsigned long ram_size
)
868 struct trx_header
*trx
;
871 uint8
*ptr
= (uint8
*)offset
;
873 trx
= (struct trx_header
*)ptr
;
875 /* Not a TRX_MAGIC */
876 if (le32_to_cpu(trx
->magic
) != TRX_MAGIC
) {
877 printk("check_ramdisk_trx: not a valid TRX magic\n");
881 /* TRX len invalid */
882 len
= le32_to_cpu(trx
->len
);
883 if (offset
+ len
> ram_size
) {
884 printk("check_ramdisk_trx: not a valid TRX length\n");
888 /* Checksum over header */
889 crc
= hndcrc32((uint8
*) &trx
->flag_version
,
890 sizeof(struct trx_header
) - OFFSETOF(struct trx_header
, flag_version
),
893 /* Move ptr to data */
894 ptr
+= sizeof(struct trx_header
);
895 len
-= sizeof(struct trx_header
);
897 /* Checksum over data */
898 crc
= hndcrc32(ptr
, len
, crc
);
900 /* Verify checksum */
901 if (le32_to_cpu(trx
->crc32
) != crc
) {
902 printk("check_ramdisk_trx: checksum invalid\n");
909 void __init
init_ramdisk(unsigned long mem_end
)
911 struct trx_header
*trx
= NULL
;
912 char *from_rootfs
, *to_rootfs
;
913 unsigned long rootfs_size
= 0;
914 unsigned long ram_size
= mem_end
+ 0x80000000;
915 unsigned long offset
;
916 char *root_cmd
= "root=/dev/ram0 console=ttyS0,115200";
918 to_rootfs
= (char *)(((unsigned long)&_end
+ PAGE_SIZE
-1) & PAGE_MASK
);
919 offset
= ((unsigned long)&_end
+0xffff) & ~0xffff;
921 /* Look at TRX header from end of linux */
922 for (; offset
< ram_size
; offset
+= 0x10000) {
923 trx
= (struct trx_header
*)offset
;
924 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
&&
925 check_ramdisk_trx(offset
, ram_size
) == 0) {
927 "Found TRX image at %08lx\n", offset
);
928 from_rootfs
= (char *)((unsigned long)trx
+ le32_to_cpu(trx
->offsets
[1]));
929 rootfs_size
= le32_to_cpu(trx
->len
) - le32_to_cpu(trx
->offsets
[1]);
930 rootfs_size
= (rootfs_size
+ 0xffff) & ~0xffff;
931 printk("rootfs size is %ld bytes at 0x%p, copying to 0x%p\n", rootfs_size
, from_rootfs
, to_rootfs
);
932 memmove(to_rootfs
, from_rootfs
, rootfs_size
);
934 initrd_start
= (int)to_rootfs
;
935 initrd_end
= initrd_start
+ rootfs_size
;
936 strncpy(arcs_cmdline
, root_cmd
, sizeof(arcs_cmdline
));
939 * In case the system warm boot, the memory won't be zeroed.
940 * So we have to erase trx magic.
942 if (initrd_end
< (unsigned long)trx
)