diff options
Diffstat (limited to 'release/src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c')
-rw-r--r-- | release/src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/release/src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c b/release/src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c new file mode 100644 index 00000000..c4983dc2 --- /dev/null +++ b/release/src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c @@ -0,0 +1,380 @@ +/* + * Generic setup routines for Broadcom MIPS boards + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: setup.c,v 1.7 2005/03/07 08:35:32 kanki Exp $ + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/serialP.h> +#include <linux/ide.h> +#include <asm/bootinfo.h> +#include <asm/time.h> +#include <asm/reboot.h> + +#ifdef CONFIG_MTD_PARTITIONS +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/minix_fs.h> +#include <linux/ext2_fs.h> +#include <linux/romfs_fs.h> +#include <linux/cramfs_fs.h> +#include <linux/squashfs_fs.h> +#endif + +#include <typedefs.h> +#include <bcmutils.h> +#include <bcmnvram.h> +#include <sbmips.h> +#include <sbutils.h> +#include <trxhdr.h> + +#include <cy_conf.h> + +extern void bcm947xx_time_init(void); +extern void bcm947xx_timer_setup(struct irqaction *irq); + +#ifdef CONFIG_REMOTE_DEBUG +extern void set_debug_traps(void); +extern void rs_kgdb_hook(struct serial_state *); +extern void breakpoint(void); +#endif + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +extern struct ide_ops std_ide_ops; +#endif + +#ifdef MULTILANG_SUPPORT +#endif + +/* Global SB handle */ +void *bcm947xx_sbh = NULL; +spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED; +EXPORT_SYMBOL(bcm947xx_sbh); +EXPORT_SYMBOL(bcm947xx_sbh_lock); + +/* Convenience */ +#define sbh bcm947xx_sbh +#define sbh_lock bcm947xx_sbh_lock + +/* Kernel command line */ +char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE; + +void +bcm947xx_machine_restart(char *command) +{ + printk("Please stand by while rebooting the system...\n"); + + /* Set the watchdog timer to reset immediately */ + __cli(); + sb_watchdog(sbh, 1); + while (1); +} + +void +bcm947xx_machine_halt(void) +{ + printk("System halted\n"); + + /* Disable interrupts and watchdog and spin forever */ + __cli(); + sb_watchdog(sbh, 0); + while (1); +} + +#ifdef CONFIG_SERIAL + +static struct serial_struct rs = { + line: 0, + flags: ASYNC_BOOT_AUTOCONF, + io_type: SERIAL_IO_MEM, +}; + +static void __init +serial_add(void *regs, uint irq, uint baud_base, uint reg_shift) +{ + rs.iomem_base = regs; + rs.irq = irq + 2; + rs.baud_base = baud_base / 16; + rs.iomem_reg_shift = reg_shift; + + early_serial_setup(&rs); + + rs.line++; +} + +static void __init +serial_setup(void *sbh) +{ + sb_serial_init(sbh, serial_add); + +#ifdef CONFIG_REMOTE_DEBUG + /* Use the last port for kernel debugging */ + if (rs.iomem_base) + rs_kgdb_hook(&rs); +#endif +} + +#endif /* CONFIG_SERIAL */ + +extern void check_enable_mips_pfc(int val); +void __init +brcm_setup(void) +{ + char *value; + uint pfc_val; + + /* Get global SB handle */ + sbh = sb_kattach(); + + /* Initialize clocks and interrupts */ + sb_mips_init(sbh); + + /* + * Now that the sbh is inited set the proper PFC value + */ + pfc_val = sb_mips_get_pfc(sbh); + printk("Setting the PFC value as 0x%x\n", pfc_val); + check_enable_mips_pfc(pfc_val); + + +#ifdef CONFIG_SERIAL + /* Initialize UARTs */ + serial_setup(sbh); +#endif + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ide_ops = &std_ide_ops; +#endif + + /* Override default command line arguments */ + value = nvram_get("kernel_args"); + if (value && strlen(value) && strncmp(value, "empty", 5)) + strncpy(arcs_cmdline, value, sizeof(arcs_cmdline)); + + + /* Generic setup */ + _machine_restart = bcm947xx_machine_restart; + _machine_halt = bcm947xx_machine_halt; + _machine_power_off = bcm947xx_machine_halt; + + board_time_init = bcm947xx_time_init; + board_timer_setup = bcm947xx_timer_setup; +} + +const char * +get_system_type(void) +{ + return "Broadcom BCM947XX"; +} + +void __init +bus_error_init(void) +{ +} + +#ifdef CONFIG_MTD_PARTITIONS + +static struct mtd_partition bcm947xx_parts[] = { + //{ name: "pmon", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, + { name: "boot", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, + { name: "linux", offset: 0, size: 0, }, + { name: "rootfs", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, +#ifdef MULTILANG_SUPPORT + { name: "lang", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, /* for multilang*/ +#endif + { name: "nvram", offset: 0, size: 0, }, + { name: NULL, }, +}; + +struct mtd_partition * __init +init_mtd_partitions(struct mtd_info *mtd, size_t size) +{ + struct minix_super_block *minixsb; + struct ext2_super_block *ext2sb; + struct romfs_super_block *romfsb; + struct cramfs_super *cramfsb; + struct squashfs_super_block *squashfsb; + struct trx_header *trx; + unsigned char buf[512]; + int off; +#ifdef MULTILANG_SUPPORT + struct lang_header *lang; /* for multilang */ + int off1; +#endif + size_t len; + + minixsb = (struct minix_super_block *) buf; + ext2sb = (struct ext2_super_block *) buf; + romfsb = (struct romfs_super_block *) buf; + cramfsb = (struct cramfs_super *) buf; + squashfsb = (struct squashfs_super_block *) buf; + trx = (struct trx_header *) buf; +#ifdef MULTILANG_SUPPORT + lang = (struct lang_header *) buf; /* for multilang */ +#endif + + /* Look at every 64 KB boundary */ + for (off = 0; off < size; off += (64 * 1024)) { + memset(buf, 0xe5, sizeof(buf)); + + /* + * Read block 0 to test for romfs and cramfs superblock + */ + if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || + len != sizeof(buf)) + continue; + + /* Try looking at TRX header for rootfs offset */ + if (le32_to_cpu(trx->magic) == TRX_MAGIC) { + bcm947xx_parts[1].offset = off; + if (le32_to_cpu(trx->offsets[1]) > off) + off = le32_to_cpu(trx->offsets[1]); + continue; + } + + /* romfs is at block zero too */ + if (romfsb->word0 == ROMSB_WORD0 && + romfsb->word1 == ROMSB_WORD1) { + printk(KERN_NOTICE + "%s: romfs filesystem found at block %d\n", + mtd->name, off / BLOCK_SIZE); + goto done; + } + + /* so is cramfs */ + if (cramfsb->magic == CRAMFS_MAGIC) { + printk(KERN_NOTICE + "%s: cramfs filesystem found at block %d\n", + mtd->name, off / BLOCK_SIZE); + goto done; + } + + /* squashfs is at block zero too */ + if (squashfsb->s_magic == SQUASHFS_MAGIC) { + printk(KERN_NOTICE + "%s: squashfs filesystem found at block %d\n", + mtd->name, off / BLOCK_SIZE); + goto done; + } + + /* + * Read block 1 to test for minix and ext2 superblock + */ + if (MTD_READ(mtd, off + BLOCK_SIZE, sizeof(buf), &len, buf) || + len != sizeof(buf)) + continue; + + /* Try minix */ + if (minixsb->s_magic == MINIX_SUPER_MAGIC || + minixsb->s_magic == MINIX_SUPER_MAGIC2) { + printk(KERN_NOTICE + "%s: Minix filesystem found at block %d\n", + mtd->name, off / BLOCK_SIZE); + goto done; + } + + /* Try ext2 */ + if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { + printk(KERN_NOTICE + "%s: ext2 filesystem found at block %d\n", + mtd->name, off / BLOCK_SIZE); + goto done; + } + } + + printk(KERN_NOTICE + "%s: Couldn't find valid ROM disk image\n", + mtd->name); + + done: +#if MULTILANG_SUPPORT +/* below for multilang */ + /* Look at every 64 KB boundary */ + for (off1 = 0; off1 < size; off1 += (64 * 1024)) { + memset(buf, 0xe5, sizeof(buf)); + + /* + * Read block 0 to test for romfs and cramfs superblock + */ + if (MTD_READ(mtd, off1, sizeof(buf), &len, buf) || + len != sizeof(buf)) + continue; + + /* Try looking at TRX header for rootfs offset */ + if (le32_to_cpu(trx->magic) == TRX_MAGIC) { + printk("le32_to_cpu(trx->magic)=0x%lx trx->magic=0x%lx\n", le32_to_cpu(trx->magic), trx->magic); + //bcm947xx_parts[1].offset = off1; + printk("bcm947xx_parts[1].offset=0x%lx trx->offsets[1]=0x%lx off\n", bcm947xx_parts[2].offset); + if (le32_to_cpu(trx->offsets[2]) > off1) { + off1 = le32_to_cpu(trx->offsets[2]); + printk("ok1 off1=0x%lx\n", off1); + } + continue; + } + + /* so is cramfs */ + if (cramfsb->magic == CRAMFS_MAGIC) { + printk(KERN_NOTICE + "%s: lang cramfs filesystem found at block %d (0x%lx)\n", + mtd->name, off1 / BLOCK_SIZE, off1); + goto done1; + } + + /* squashfs is at block zero too */ + if (squashfsb->s_magic == SQUASHFS_MAGIC) { + printk(KERN_NOTICE + "%s: lang squashfs filesystem found at block %d (0x%lx)\n", + mtd->name, off1 / BLOCK_SIZE, off1); + goto done1; + } + + } +done1: + printk("off=0x%lx off1=0x%lx size=0x%lx\n", off, off1, size); + + if(off1 == 0 || off1 == size ) + { + off1 = size - 0x60000; // 0x3d0000 only lang.js + printk("(Not Found Lang Block)off=0x%lx off1=0x%lx size=0x%lx\n", off, off1, size); + } +/* for multilang -> */ + bcm947xx_parts[4].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); + bcm947xx_parts[4].size = size - bcm947xx_parts[4].offset; + printk("nvram: offset=0x%lx size=0x%lx\n", bcm947xx_parts[4].offset, bcm947xx_parts[4].size); + + bcm947xx_parts[3].offset = off1; + bcm947xx_parts[3].size = bcm947xx_parts[4].offset - bcm947xx_parts[3].offset; +/* <- for multilang */ +#else + /* Find and size nvram */ + bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); + bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset; +#endif + /* Find and size rootfs */ + if (off < size) { + bcm947xx_parts[2].offset = off; + bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset; + } + + /* Size linux (kernel and rootfs) */ + bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset; + + /* Size pmon */ + bcm947xx_parts[0].size = bcm947xx_parts[1].offset - bcm947xx_parts[0].offset; + + return bcm947xx_parts; +} + +EXPORT_SYMBOL(init_mtd_partitions); + +#endif |