2 * HND MIPS boards setup routines
4 * Copyright (C) 2012, 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/version.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 #include <linux/serial_8250.h> /* for early_serial_setup */
29 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
30 #include <linux/config.h>
32 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
33 #include <linux/blkdev.h>
34 #include <linux/ide.h>
36 #include <asm/bootinfo.h>
39 #include <asm/reboot.h>
41 #ifdef CONFIG_MTD_PARTITIONS
42 #include <linux/mtd/mtd.h>
43 #include <linux/mtd/partitions.h>
44 #include <linux/romfs_fs.h>
45 #include <linux/cramfs_fs.h>
46 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
47 #include <linux/squashfs_fs.h>
49 /* #include <magic.h> */
52 #ifdef CONFIG_BLK_DEV_INITRD
53 #include <linux/initrd.h>
62 #include <mips33_core.h>
63 #include <mips74k_core.h>
69 #include <ctf/hndctf.h>
72 #ifdef CONFIG_MTD_NFLASH
77 extern void bcm947xx_time_init(void);
78 extern void bcm947xx_timer_setup(struct irqaction
*irq
);
81 extern void set_debug_traps(void);
82 extern void rs_kgdb_hook(struct uart_port
*);
83 extern void breakpoint(void);
86 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
87 extern struct ide_ops std_ide_ops
;
90 struct dummy_super_block
{
94 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
95 /* Enable CPU wait or not */
96 extern int cpu_wait_enable
;
98 int coherentio
; /* init to 0 => no DMA cache coherency (may be set by user) */
99 int hw_coherentio
;/* init to 0 => no HW DMA cache coherency (reflects real HW) */
102 /* Global SB handle */
103 si_t
*bcm947xx_sih
= NULL
;
104 spinlock_t bcm947xx_sih_lock
= SPIN_LOCK_UNLOCKED
;
105 EXPORT_SYMBOL(bcm947xx_sih
);
106 EXPORT_SYMBOL(bcm947xx_sih_lock
);
109 #define sih bcm947xx_sih
110 #define sih_lock bcm947xx_sih_lock
115 ctf_attach_t ctf_attach_fn
= NULL
;
116 EXPORT_SYMBOL(ctf_attach_fn
);
119 /* Kernel command line */
120 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
121 extern char arcs_cmdline
[CL_SIZE
];
123 static int lanports_enable
= 0;
126 EXPORT_SYMBOL( si_router_coma
); /* for loadable modules */
127 EXPORT_SYMBOL( hnd_jtagm_init
);
128 EXPORT_SYMBOL( hnd_jtagm_disable
);
129 EXPORT_SYMBOL( jtag_scan
);
132 bcm947xx_reboot_handler(void)
138 /* Reset the PCI(e) interfaces */
139 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
142 if (lanports_enable
) {
143 uint lp
= 1 << lanports_enable
;
145 si_gpioout(sih
, lp
, 0, GPIO_DRV_PRIORITY
);
146 si_gpioouten(sih
, lp
, lp
, GPIO_DRV_PRIORITY
);
151 /* gpio 0 is also valid wombo_reset */
152 if ((wombo_reset
= getgpiopin(NULL
, "wombo_reset", GPIO_PIN_NOTDEFINED
)) !=
153 GPIO_PIN_NOTDEFINED
) {
154 int reset
= 1 << wombo_reset
;
156 si_gpioout(sih
, reset
, 0, GPIO_DRV_PRIORITY
);
157 si_gpioouten(sih
, reset
, reset
, GPIO_DRV_PRIORITY
);
164 bcm947xx_machine_restart(char *command
)
166 printk("Please stand by while rebooting the system...\n");
168 /* Set the watchdog timer to reset immediately */
170 bcm947xx_reboot_handler();
175 bcm947xx_machine_halt(void)
177 printk("System halted\n");
179 /* Disable interrupts and watchdog and spin forever */
182 bcm947xx_reboot_handler();
186 #ifdef CONFIG_SERIAL_CORE
188 static struct uart_port rs
= {
190 flags
: ASYNC_BOOT_AUTOCONF
,
191 iotype
: SERIAL_IO_MEM
,
195 serial_add(void *regs
, uint irq
, uint baud_base
, uint reg_shift
)
199 rs
.uartclk
= baud_base
;
200 rs
.regshift
= reg_shift
;
202 early_serial_setup(&rs
);
208 serial_setup(si_t
*sih
)
210 si_serial_init(sih
, serial_add
);
213 /* Use the last port for kernel debugging */
219 #endif /* CONFIG_SERIAL_CORE */
221 static int boot_flags(void)
226 /* Only support chipcommon revision == 38 or BCM4706 for now */
227 if ((CHIPID(sih
->chip
) == BCM4706_CHIP_ID
) || sih
->ccrev
== 38) {
228 if (sih
->ccrev
== 38 && (sih
->chipst
& (1 << 4)) != 0) {
229 /* This is NANDBOOT */
230 bootflags
= FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
;
232 else if ((val
= nvram_get("bootflags"))) {
233 bootflags
= simple_strtol(val
, NULL
, 0);
234 bootflags
&= FLASH_KERNEL_NFLASH
;
241 static int rootfs_mtdblock(void)
246 bootflags
= boot_flags();
249 if ((bootflags
& (FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
)) ==
250 (FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
))
253 /* SFLASH/PFLASH only */
254 if ((bootflags
& (FLASH_BOOT_NFLASH
| FLASH_KERNEL_NFLASH
)) == 0)
260 /* Boot from norflash and kernel in nandflash */
269 /* Get global SB handle */
270 sih
= si_kattach(SI_OSH
);
272 /* Initialize clocks and interrupts */
273 si_mips_init(sih
, SBMIPS_VIRTIRQ_BASE
);
275 if (BCM330X(current_cpu_data
.processor_id
) &&
276 (read_c0_diag() & BRCM_PFC_AVAIL
)) {
278 * Now that the sih is inited set the proper PFC value
280 printk("Setting the PFC to its default value\n");
281 enable_pfc(PFC_AUTO
);
285 #ifdef CONFIG_SERIAL_CORE
286 /* Initialize UARTs */
288 #endif /* CONFIG_SERIAL_CORE */
290 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
291 ide_ops
= &std_ide_ops
;
294 sprintf(arcs_cmdline
, "root=/dev/mtdblock%d console=ttyS0,115200 init=/sbin/preinit", rootfs_mtdblock());
296 /* Override default command line arguments */
297 value
= nvram_get("kernel_args");
298 if (value
&& strlen(value
) && strncmp(value
, "empty", 5))
299 strncpy(arcs_cmdline
, value
, sizeof(arcs_cmdline
));
302 if ((lanports_enable
= getgpiopin(NULL
, "lanports_enable", GPIO_PIN_NOTDEFINED
)) ==
307 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
308 /* Check if we want to enable cpu wait */
309 if (nvram_match("wait", "1"))
314 _machine_restart
= bcm947xx_machine_restart
;
315 _machine_halt
= bcm947xx_machine_halt
;
316 pm_power_off
= bcm947xx_machine_halt
;
318 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
319 board_time_init
= bcm947xx_time_init
;
324 get_system_type(void)
329 sprintf(s
, "Broadcom BCM%X chip rev %d", bcm947xx_sih
->chip
,
330 bcm947xx_sih
->chiprev
);
334 return "Broadcom BCM947XX";
349 #ifdef CONFIG_MTD_PARTITIONS
351 static struct mutex
*mtd_mutex
= NULL
;
353 struct mutex
*partitions_mutex_init(void)
356 mtd_mutex
= (struct mutex
*)kzalloc(sizeof(struct mutex
), GFP_KERNEL
);
359 mutex_init(mtd_mutex
);
363 EXPORT_SYMBOL(partitions_mutex_init
);
365 /* Find out prom size */
366 static uint32
boot_partition_size(uint32 flash_phys
) {
367 uint32 bootsz
, *bisz
;
369 /* Default is 256K boot partition */
372 /* Do we have a self-describing binary image? */
373 bisz
= (uint32
*)KSEG1ADDR(flash_phys
+ BISZ_OFFSET
);
374 if (bisz
[BISZ_MAGIC_IDX
] == BISZ_MAGIC
) {
375 int isz
= bisz
[BISZ_DATAEND_IDX
] - bisz
[BISZ_TXTST_IDX
];
377 if (isz
> (1024 * 1024))
378 bootsz
= 2048 * 1024;
379 else if (isz
> (512 * 1024))
380 bootsz
= 1024 * 1024;
381 else if (isz
> (256 * 1024))
383 else if (isz
<= (128 * 1024))
389 #if defined(BCMCONFMTD) && defined(PLC)
390 #define FLASH_PARTS_NUM 7
391 #elif defined(BCMCONFMTD) || defined(PLC)
392 #define FLASH_PARTS_NUM 6
394 #define FLASH_PARTS_NUM 5 /* boot;nvram;kernel;rootfs;empty */
397 static struct mtd_partition bcm947xx_flash_parts
[FLASH_PARTS_NUM
] = {{0}};
399 static uint
lookup_flash_rootfs_offset(struct mtd_info
*mtd
, int *trx_off
, size_t size
)
401 struct romfs_super_block
*romfsb
;
402 struct cramfs_super
*cramfsb
;
403 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
404 struct squashfs_super_block
*squashfsb
;
406 struct dummy_super_block
*squashfsb
;
408 struct trx_header
*trx
;
409 unsigned char buf
[512];
413 romfsb
= (struct romfs_super_block
*) buf
;
414 cramfsb
= (struct cramfs_super
*) buf
;
415 squashfsb
= (void *) buf
;
416 trx
= (struct trx_header
*) buf
;
418 /* Look at every 64 KB boundary */
419 for (off
= 0; off
< size
; off
+= (64 * 1024)) {
420 memset(buf
, 0xe5, sizeof(buf
));
423 * Read block 0 to test for romfs and cramfs superblock
425 if (mtd
->read(mtd
, off
, sizeof(buf
), &len
, buf
) ||
429 /* Try looking at TRX header for rootfs offset */
430 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
) {
432 if (trx
->offsets
[1] == 0)
435 * Read to test for romfs and cramfs superblock
437 off
+= le32_to_cpu(trx
->offsets
[1]);
438 memset(buf
, 0xe5, sizeof(buf
));
439 if (mtd
->read(mtd
, off
, sizeof(buf
), &len
, buf
) || len
!= sizeof(buf
))
443 /* romfs is at block zero too */
444 if (romfsb
->word0
== ROMSB_WORD0
&&
445 romfsb
->word1
== ROMSB_WORD1
) {
447 "%s: romfs filesystem found at block %d\n",
448 mtd
->name
, off
/ mtd
->erasesize
);
453 if (cramfsb
->magic
== CRAMFS_MAGIC
) {
455 "%s: cramfs filesystem found at block %d\n",
456 mtd
->name
, off
/ mtd
->erasesize
);
459 if (squashfsb
->s_magic
== SQUASHFS_MAGIC
) {
461 "%s: squash filesystem found at block %d\n",
462 mtd
->name
, off
/ mtd
->erasesize
);
469 struct mtd_partition
*
470 init_mtd_partitions(struct mtd_info
*mtd
, size_t size
)
476 uint vmlz_off
, knl_size
;
480 bootflags
= boot_flags();
482 if ((bootflags
& FLASH_KERNEL_NFLASH
) != FLASH_KERNEL_NFLASH
) {
483 rfs_off
= lookup_flash_rootfs_offset(mtd
, &vmlz_off
, size
);
486 bcm947xx_flash_parts
[nparts
].name
= "boot";
487 bcm947xx_flash_parts
[nparts
].size
= vmlz_off
;
488 bcm947xx_flash_parts
[nparts
].offset
= top
;
489 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
492 /* Setup kernel MTD partition */
493 bcm947xx_flash_parts
[nparts
].name
= "linux";
494 bcm947xx_flash_parts
[nparts
].size
= mtd
->size
- vmlz_off
;
497 /* Reserve for PLC */
498 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x1000, mtd
->erasesize
);
500 /* Reserve for NVRAM */
501 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
);
504 bcm947xx_flash_parts
[nparts
].size
-= (mtd
->erasesize
*4);
506 bcm947xx_flash_parts
[nparts
].offset
= vmlz_off
;
507 knl_size
= bcm947xx_flash_parts
[nparts
].size
;
508 offset
= bcm947xx_flash_parts
[nparts
].offset
+ knl_size
;
511 /* Setup rootfs MTD partition */
512 bcm947xx_flash_parts
[nparts
].name
= "rootfs";
513 bcm947xx_flash_parts
[nparts
].size
= knl_size
- (rfs_off
- vmlz_off
);
514 bcm947xx_flash_parts
[nparts
].offset
= rfs_off
;
515 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
518 bootsz
= boot_partition_size(SI_FLASH2
);
519 printk("Boot partition size = %d(0x%x)\n", bootsz
, bootsz
);
521 bcm947xx_flash_parts
[nparts
].name
= "boot";
522 bcm947xx_flash_parts
[nparts
].size
= bootsz
;
523 bcm947xx_flash_parts
[nparts
].offset
= top
;
524 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
525 offset
= bcm947xx_flash_parts
[nparts
].size
;
530 /* Setup CONF MTD partition */
531 bcm947xx_flash_parts
[nparts
].name
= "confmtd";
532 bcm947xx_flash_parts
[nparts
].size
= mtd
->erasesize
* 4;
533 bcm947xx_flash_parts
[nparts
].offset
= offset
;
534 offset
= bcm947xx_flash_parts
[nparts
].offset
+ bcm947xx_flash_parts
[nparts
].size
;
536 #endif /* BCMCONFMTD */
539 /* Setup plc MTD partition */
540 bcm947xx_flash_parts
[nparts
].name
= "plc";
541 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(0x1000, mtd
->erasesize
);
542 bcm947xx_flash_parts
[nparts
].offset
= size
- (ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
) + ROUNDUP(0x1000, mtd
->erasesize
));
546 /* Setup nvram MTD partition */
547 bcm947xx_flash_parts
[nparts
].name
= "nvram";
548 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(NVRAM_SPACE
, mtd
->erasesize
);
549 bcm947xx_flash_parts
[nparts
].offset
= size
- bcm947xx_flash_parts
[nparts
].size
;
552 return bcm947xx_flash_parts
;
555 EXPORT_SYMBOL(init_mtd_partitions
);
557 #ifdef CONFIG_MTD_NFLASH
558 #define NFLASH_PARTS_NUM 6
559 static struct mtd_partition bcm947xx_nflash_parts
[NFLASH_PARTS_NUM
] = {{0}};
561 static uint
lookup_nflash_rootfs_offset(struct mtd_info
*mtd
, int offset
, size_t size
)
563 struct romfs_super_block
*romfsb
;
564 struct cramfs_super
*cramfsb
;
565 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
566 struct squashfs_super_block
*squashfsb
;
568 struct dummy_super_block
*squashfsb
;
570 struct trx_header
*trx
;
571 unsigned char buf
[NFL_SECTOR_SIZE
];
572 uint blocksize
, mask
, blk_offset
, off
, shift
= 0;
576 romfsb
= (struct romfs_super_block
*) buf
;
577 cramfsb
= (struct cramfs_super
*) buf
;
578 squashfsb
= (void *) buf
;
579 trx
= (struct trx_header
*) buf
;
581 if ((cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
)) == NULL
)
584 /* Look at every block boundary till 16MB; higher space is reserved for application data. */
585 blocksize
= mtd
->erasesize
;
586 printk("lookup_nflash_rootfs_offset: offset = 0x%x\n", offset
);
587 for (off
= offset
; off
< NFL_BOOT_OS_SIZE
; off
+= blocksize
) {
588 mask
= blocksize
- 1;
589 blk_offset
= off
& ~mask
;
590 if (nflash_checkbadb(sih
, cc
, blk_offset
) != 0)
592 memset(buf
, 0xe5, sizeof(buf
));
593 if ((ret
= nflash_read(sih
, cc
, off
, sizeof(buf
), buf
)) != sizeof(buf
)) {
595 "%s: nflash_read return %d\n", mtd
->name
, ret
);
599 /* Try looking at TRX header for rootfs offset */
600 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
) {
601 mask
= NFL_SECTOR_SIZE
- 1;
602 off
= offset
+ (le32_to_cpu(trx
->offsets
[1]) & ~mask
) - blocksize
;
603 shift
= (le32_to_cpu(trx
->offsets
[1]) & mask
);
604 romfsb
= (struct romfs_super_block
*)((unsigned char *)romfsb
+ shift
);
605 cramfsb
= (struct cramfs_super
*)((unsigned char *)cramfsb
+ shift
);
606 squashfsb
= (void *)((unsigned char *)squashfsb
+ shift
);
610 /* romfs is at block zero too */
611 if (romfsb
->word0
== ROMSB_WORD0
&&
612 romfsb
->word1
== ROMSB_WORD1
) {
614 "%s: romfs filesystem found at block %d\n",
615 mtd
->name
, off
/ blocksize
);
620 if (cramfsb
->magic
== CRAMFS_MAGIC
) {
622 "%s: cramfs filesystem found at block %d\n",
623 mtd
->name
, off
/ blocksize
);
627 if (squashfsb
->s_magic
== SQUASHFS_MAGIC
) {
629 "%s: squash filesystem found at block %d\n",
630 mtd
->name
, off
/ blocksize
);
637 struct mtd_partition
* init_nflash_mtd_partitions(struct mtd_info
*mtd
, size_t size
)
646 bootflags
= boot_flags();
647 if ((bootflags
& FLASH_BOOT_NFLASH
) == FLASH_BOOT_NFLASH
) {
648 bootsz
= boot_partition_size(SI_FLASH1
);
649 if (bootsz
> mtd
->erasesize
) {
650 /* Prepare double space in case of bad blocks */
651 bootsz
= (bootsz
<< 1);
653 /* CFE occupies at least one block */
654 bootsz
= mtd
->erasesize
;
656 printk("Boot partition size = %d(0x%x)\n", bootsz
, bootsz
);
659 bcm947xx_nflash_parts
[nparts
].name
= "boot";
660 bcm947xx_nflash_parts
[nparts
].size
= bootsz
;
661 bcm947xx_nflash_parts
[nparts
].offset
= top
;
662 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
663 offset
= bcm947xx_nflash_parts
[nparts
].size
;
666 /* Setup NVRAM MTD partition */
667 bcm947xx_nflash_parts
[nparts
].name
= "nvram";
668 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_SIZE
- offset
;
669 bcm947xx_nflash_parts
[nparts
].offset
= offset
;
671 offset
= NFL_BOOT_SIZE
;
675 if ((bootflags
& FLASH_KERNEL_NFLASH
) == FLASH_KERNEL_NFLASH
) {
676 /* Setup kernel MTD partition */
677 bcm947xx_nflash_parts
[nparts
].name
= "linux";
678 bcm947xx_nflash_parts
[nparts
].size
= nparts
? (NFL_BOOT_OS_SIZE
- NFL_BOOT_SIZE
) : NFL_BOOT_OS_SIZE
;
679 bcm947xx_nflash_parts
[nparts
].offset
= offset
;
681 shift
= lookup_nflash_rootfs_offset(mtd
, offset
, size
);
683 offset
= NFL_BOOT_OS_SIZE
;
686 /* Setup rootfs MTD partition */
687 bcm947xx_nflash_parts
[nparts
].name
= "rootfs";
688 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_OS_SIZE
- shift
;
689 bcm947xx_nflash_parts
[nparts
].offset
= shift
;
690 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
;
695 return bcm947xx_nflash_parts
;
698 EXPORT_SYMBOL(init_nflash_mtd_partitions
);
699 #endif /* CONFIG_MTD_NFLASH */
701 #ifdef CONFIG_BLK_DEV_INITRD
704 /* The check_ramdisk_trx has more exact qualification to look at TRX header from end of linux */
706 check_ramdisk_trx(unsigned long offset
, unsigned long ram_size
)
708 struct trx_header
*trx
;
711 uint8
*ptr
= (uint8
*)offset
;
713 trx
= (struct trx_header
*)ptr
;
715 /* Not a TRX_MAGIC */
716 if (le32_to_cpu(trx
->magic
) != TRX_MAGIC
) {
717 printk("check_ramdisk_trx: not a valid TRX magic\n");
721 /* TRX len invalid */
722 len
= le32_to_cpu(trx
->len
);
723 if (offset
+ len
> ram_size
) {
724 printk("check_ramdisk_trx: not a valid TRX length\n");
728 /* Checksum over header */
729 crc
= hndcrc32((uint8
*) &trx
->flag_version
,
730 sizeof(struct trx_header
) - OFFSETOF(struct trx_header
, flag_version
),
733 /* Move ptr to data */
734 ptr
+= sizeof(struct trx_header
);
735 len
-= sizeof(struct trx_header
);
737 /* Checksum over data */
738 crc
= hndcrc32(ptr
, len
, crc
);
740 /* Verify checksum */
741 if (le32_to_cpu(trx
->crc32
) != crc
) {
742 printk("check_ramdisk_trx: checksum invalid\n");
749 void __init
init_ramdisk(unsigned long mem_end
)
751 struct trx_header
*trx
= NULL
;
752 char *from_rootfs
, *to_rootfs
;
753 unsigned long rootfs_size
= 0;
754 unsigned long ram_size
= mem_end
+ 0x80000000;
755 unsigned long offset
;
756 char *root_cmd
= "root=/dev/ram0 console=ttyS0,115200 rdinit=/sbin/preinit";
758 to_rootfs
= (char *)(((unsigned long)&_end
+ PAGE_SIZE
-1) & PAGE_MASK
);
759 offset
= ((unsigned long)&_end
+0xffff) & ~0xffff;
761 /* Look at TRX header from end of linux */
762 for (; offset
< ram_size
; offset
+= 0x10000) {
763 trx
= (struct trx_header
*)offset
;
764 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
&&
765 check_ramdisk_trx(offset
, ram_size
) == 0) {
767 "Found TRX image at %08lx\n", offset
);
768 from_rootfs
= (char *)((unsigned long)trx
+ le32_to_cpu(trx
->offsets
[1]));
769 rootfs_size
= le32_to_cpu(trx
->len
) - le32_to_cpu(trx
->offsets
[1]);
770 rootfs_size
= (rootfs_size
+ 0xffff) & ~0xffff;
771 printk("rootfs size is %ld bytes at 0x%p, copying to 0x%p\n", rootfs_size
, from_rootfs
, to_rootfs
);
772 memmove(to_rootfs
, from_rootfs
, rootfs_size
);
774 initrd_start
= (int)to_rootfs
;
775 initrd_end
= initrd_start
+ rootfs_size
;
776 strncpy(arcs_cmdline
, root_cmd
, sizeof(arcs_cmdline
));
778 * In case the system warm boot, the memory won't be zeroed.
779 * So we have to erase trx magic.
781 if (initrd_end
< (unsigned long)trx
)