Esempio n. 1
0
long gioctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    struct vm_area_struct *vma;
#ifdef CONFIG_TIVO_DEVEL
    extern void sw_watchdog_threads_hold(void);
    extern void sw_watchdog_threads_release(void);
#endif
    if (!arg)
    {
        printk(KERN_ERR "[gen_ioctl] Invalid arg\n");
        return -EINVAL;
    }

    if (_IOC_TYPE(cmd) != GIOCTL_IOC_MAGIC)
    {
        printk(KERN_ERR "[gen_ioctl] cmd (0x%x) mismatch, " "called with 0x%x while expecting 0x%x\n", cmd, _IOC_TYPE(cmd),
               GIOCTL_IOC_MAGIC);
        return -EINVAL;
    }

    switch (cmd)
    {
#ifdef CONFIG_TIVO_MOJAVE
        case GO_BIST:
        {
                extern void emergency_sync(void);
                extern void _machine_restart(void);
                extern unsigned long get_RAM_size();
                unsigned long *p = (unsigned long *) (KSEG1+get_RAM_size()-PAGE_SIZE);

                /*
                 * flush all disk buffers
                 */ 
                emergency_sync();

                /*Disable Interrupts*/
                local_irq_disable();

                memset(p,0,PAGE_SIZE);
                *p++ = 0x42495354; /*BIST*/
                *p++ = 1; /*Version*/
                strcpy(p, arg); /*Boot Parameters*/
                
                _machine_restart();
                
        }
#endif
        case CRASHALLASSRT:
            return tivocrashallassert(arg);

#ifdef CONFIG_TICK_KILLER
        case TICK_KILLER:
            return tick_killer_start(arg);
#endif

        case UPDATE_EXEC_CTX:
            /*Ineffective ioctl. Handling for the backward compatibility purposes.
             * Has be removed.*/
            return 0;

#ifdef CONFIG_KSTACK_GUARD
        case TEST_KSTACK_GUARD:
            test_kstack_guard_check(current);
            return 0;
#endif
        case TEST_SGAT_DIO:
        {
            struct sgat_dio_fops gfops;
            sgat_dio_req dio_req;
            int c;
            int k = 'z';
            struct scatterlist *p;

            sgat_dio_get_default_fops(&gfops);

            if (sgat_dio_init_req(&gfops, &dio_req, (sgat_dio_hdr_t *) arg))
            {
                printk("Error: sgat_dio_init_req\n");
                return -EINVAL;
            }

            if (sgat_dio_build_sg_list(&gfops, &dio_req, 1))
            {
                printk("Error: sgat_dio_build_sg_list\n");
                return -EINVAL;
            }

            p = (struct scatterlist *)dio_req.sclist;
            for (c = 0; c < dio_req.k_useg; c++)
            {
                memset(p->address, k, p->length);
                p++;
            }
            sgat_dio_exit_req(&gfops, &dio_req, 1);
            return 0;
        }
#ifdef CONFIG_TIVO_SATA_HOTPLUG
        case SATA_UNPLUG_INT:
        {
            /* This is a blocking call */
            int port, offset, regvalue;

            port = 1;                            /* Currently hard coding to port 1 */

            if (port >= NUM_SATA_PORTS)
                return -EINVAL;

            /* SATA STATUS port */
            offset = MMIO_SATA_STATUS + port * PORT_OFFSET;

            /* Check the status */
            regvalue = mmio_inl(offset);
            regvalue &= PHY_IN_BIST;

            if (regvalue)
                return 0;

            /* If user request for non blocking */
            if (arg & 0x2)
            {
                /* Any positive number is treated error output of command (not ioctl error).
                 */
                return 1;
            }

            /* Now we have to wait for interrupt */
            //return sata_wait_for_IRQ(port, offset, PHY_IN_BIST);
            return 1;

        }

        case SATA_PLUG_INT:
        {
            /* This is a blocking call */
            int port, offset, regvalue;

            port = 1;                            /* Currently hard coding to port 1 */

            if (port >= NUM_SATA_PORTS)
                return -EINVAL;

            /* SATA STATUS port */
            offset = MMIO_SATA_STATUS + port * PORT_OFFSET;

            /* Check the status */
            regvalue = mmio_inl(offset);
            regvalue &= PHY_IS_RDY;

            if (regvalue)
                return 0;

            /* If user request for non blocking */
            if (arg & 0x2)
            {
                /* Any positive number is treated error output of command (not ioctl error).
                 */
                return 1;
            }
            /* Now we have to wait for interrupt */
            //return sata_wait_for_irq(port, offset, PHY_IS_RDY);
            return 1;
        }
#endif
        case LOCKMEM:
        {
             printk("Pretending to LOCKMEM %p\n", (void *)arg);
            //struct iovec *iovec = (struct iovec *) arg;
            //if ( pindown_pages(NULL, iovec, 1, 1, WRITE) )
            //    return -EINVAL;
            return 0;
        }
        
        case UNLOCKMEM:
        {
            printk("Pretending to UNLOCKMEM %p\n", (void *)arg);
            // struct iovec *iovec = (struct iovec *) arg;
            // struct page **page_list;
            // struct page **pg_list;
            // unsigned int pg_addr;
            // int pgcount,pg;

            // pgcount = (((u_long)iovec->iov_base) + 
            //     iovec->iov_len + PAGE_SIZE - 1)/PAGE_SIZE - 
            //     ((u_long)iovec->iov_base)/PAGE_SIZE;
            // pg_addr = (unsigned int )(iovec->iov_base) & (~(PAGE_SIZE-1));
            // page_list = kmalloc(sizeof(struct page **) * pgcount, GFP_KERNEL);
            // pg_list = page_list;
            // for ( pg = 0; pg < pgcount; pg++){
            //     *(pg_list++) = virt_to_page(pg_addr);
            //     pg_addr += PAGE_SIZE;
            // }
            // unlock_pages(page_list);
            // kfree(*page_list);
            return 0;
        }

        case IS_PM_FWUPGD_REQD:
        {
            int ret = -EINVAL;
#if SKIP_SATA_PM_FW_UPGD
            return -EACCES;
#endif
#ifdef CONFIG_TIVO_DEVEL
            /* Turn off sw watchdog for a while */
            sw_watchdog_threads_hold();
#endif
            if (is_fw_upgd_reqd)
                ret = is_fw_upgd_reqd();
#ifdef CONFIG_TIVO_DEVEL
            sw_watchdog_threads_release();
#endif
            return ret;
        }

        case DWNLD_SATA_PM_FW:
        {
            int ret = -EINVAL;
#if SKIP_SATA_PM_FW_UPGD
            return -EACCES;
#endif
#ifdef CONFIG_TIVO_DEVEL
            /* Turn off sw watchdog for a while until we complete
             * upgrading FW in blocking PIO mode
             */
            sw_watchdog_threads_hold();
#endif
            if (upgd_fw_init)
                ret = upgd_fw_init();
#ifdef CONFIG_TIVO_DEVEL
            /*Trun on sw wdog */
            sw_watchdog_threads_release();
#endif
            return ret;
        }

        case GET_VMA_INFO:
        {
            struct vma_info_struct s;
            
            copy_from_user(&s,(void *)arg,sizeof(s));

            down_read(&current->mm->mmap_sem);
            vma = find_vma(current->mm, s.address);
            
            if (!vma || vma->vm_start > s.address)
            {
                up_read(&current->mm->mmap_sem);
                return -ENOMEM;
            }    

            s.start = vma->vm_start;
            s.end = vma->vm_end-1;
            s.read = (vma->vm_flags & VM_READ)!=0;
            s.write = (vma->vm_flags & VM_WRITE)!=0;
            s.exec = (vma->vm_flags & VM_EXEC)!=0;
            s.shared = (vma->vm_flags & VM_SHARED)!=0;
            s.offset = vma->vm_pgoff*PAGE_SIZE;
            s.device=s.inode=0;
            if (vma->vm_file)
            {
                s.device=vma->vm_file->f_dentry->d_inode->i_rdev;
                s.inode=vma->vm_file->f_dentry->d_inode->i_ino;
            } 
            
            up_read(&current->mm->mmap_sem);
            copy_to_user((void *)arg, &s, sizeof(s));
            return 0;
        }

    }

    // none of the above...
    printk(KERN_ERR "gen_ioctl: Invalid command (0x%x)\n",cmd);
    return -EINVAL;
}
Esempio n. 2
0
void __init prom_init(int argc, const char **arg)
{
        int	hasBootParms = 0;
        char msg[500];
	 char pmon_kargs[CL_SIZE];
		
	uart_init(27000000);
//uart_puts("Inside prom_init\r\n");

	/* Fill in platform information */
	mips_machgroup = MACH_GROUP_BRCM;
	mips_machtype  = MACH_BCM93730;

	/* Boot arguments can be put here */
	/* Browse memory region to see if the boot rom deposits an argument there */
	{
		unsigned long sigAddr = KSEG1ADDR(LOAD_ADDRESS - BOOT_OPT_SIZE);
		unsigned long mapAddr = (sigAddr & 0xFFFFF000);
		unsigned long offset = sigAddr - mapAddr;
		char* pMap;
		char*	p;   /* Start address of bootParms including signature */

		char*	pBootParms; /* Actual start address of bootParms */
		int len = 0;
		int* plen;

//uart_puts( "Before ioremap\n");
		//pMap = ioremap_nocache(mapAddr, 4096);
		pMap = (char*) mapAddr;
		p = &pMap[offset];
//uart_puts("After ioremap\n");
#ifdef DEBUG_PROM
		sprintf(msg,"prom_init, mapped address %08lx at %08lx, pSig1=%08lx, sigAddr=%08lx\n",
			mapAddr, (unsigned long) pMap, (unsigned long) p, sigAddr);
		uart_puts(msg);
		printBootArgRegion(p);
#endif
		if (0 == memcmp(p, BOOT_OPT_SIG, 1+strlen(BOOT_OPT_SIG))) {
			len += BOOT_OPT_LEN_OFFSET;

			/* Rely on BOOT_OPT_LEN_OFFSET to place it at boundary */
			plen = (int*) &p[len];
			pBootParms = &p[len + sizeof(int)];
			/* Making sure that we don't run over any bounds as there is no guarantee
			 * that COMMAND_LINE_SIZE <= BOOT_OPT_SIZE minus the sig
			 */
			if (*plen <= COMMAND_LINE_SIZE && *plen <= (BOOT_OPT_SIZE - 2*BOOT_OPT_LEN_OFFSET)) {
				len += *plen + sizeof(int);
				if (0 == memcmp(&p[len], BOOT_OPT_SIG, 1+strlen(BOOT_OPT_SIG))) {
					hasBootParms = 1;

					printBootArgRegion(p); /* Force it to include the next line in the log */
					sprintf(msg, "Found bootargs=<%s>,%d bytes\n", pBootParms, *plen);
					uart_puts(msg);
					strncpy(pmon_kargs, pBootParms, *plen);

					/* Wipe out boot parameter, so that subsequent reboot would not have it */
					memset(p, 0, 1+strlen(BOOT_OPT_SIG) + *plen);
				}
				else {
					sprintf(msg, "2nd Signature do not match @%08x, ignoring kernel boot parameters\n", &p[len]);
					uart_puts(msg);
					printBootArgRegion(p);
				}
			}
			else {

				sprintf(msg, "Length %d of kernel parameter is larger than allowed min(%d,%d)\n",
					*plen, COMMAND_LINE_SIZE, (BOOT_OPT_SIZE - 2*BOOT_OPT_LEN_OFFSET));
				uart_puts(msg);	

				printBootArgRegion(p);
     		      }
		}
		else {

			printk(KERN_INFO "1st Signature do not match, ignoring kernel boot parameters\n");
			printBootArgRegion(p);

		}
    }
	/* Use default if we don't see a valid boot prom */
	/* We may use a more sophisticated scheme in filling out the parameters later, but for now
	 * just require that the boot loader procedure must provide the full command.  Ugly but
	 * better than nothing.
	 */
	if (hasBootParms && isRootSpecified(pmon_kargs)) {
		strcpy(arcs_cmdline, pmon_kargs);
	   	appendConsoleArg(arcs_cmdline);
	}
	else {
	/* Kernel default arguments */

#ifdef CONFIG_BLK_DEV_INITRD
	         strcpy(arcs_cmdline, "rw console=ttyS0,115200");

#elif defined(CONFIG_CMDLINE)
		char* p;
		char msg[256];

		strcpy(arcs_cmdline, CONFIG_CMDLINE);
		sprintf(msg, "Default command line = \'%s\'\n", CONFIG_CMDLINE);
		uart_puts(msg);
		p = &arcs_cmdline[0];
		while (p != NULL && *p != '\0') {
			if (!isspace(*p))
				break;
			p++;
		}
		if (p == NULL || *p == '\0') {
		sprintf(msg, "Defaulting to boot from HD\n", CONFIG_CMDLINE);
		uart_puts(msg);
			/* Default is to boot from HD */
			strcpy(arcs_cmdline,
				"root=/dev/hda1 rw console=tty0 console=ttyS0,115200");
		}
		else {
			/* Make sure that the boot params specify a console */
			appendConsoleArg(arcs_cmdline);
		}
#else /* No CONFIG_CMDLINE, and not Initrd */
		/* Default is to boot from HD */
		strcpy(arcs_cmdline,
			"root=/dev/hda1 rw console=tty0 console=ttyS0,115200");
#endif /* No CONFIG_CMDLINE */

		/*
		 * if root= is not on the command line, but user specified something else, tag it on
		 */
		if (hasBootParms && !isRootSpecified(pmon_kargs)) {
			strcat(arcs_cmdline, " ");
			strcat(arcs_cmdline, pmon_kargs);
        	}
	} /* End else no root= option is specified */
	uart_puts("Kernel boot options: ");
	uart_puts(arcs_cmdline);
	uart_puts("\r\n");

	{
		/*
		  * Support  mem=nn[KMG] on command line
		  */
		const char* p = (const char*) arcs_cmdline;
		const char* q = NULL;
		const char* sizep = NULL;
		int i, foundKeyword = 0, foundNumber = 0, foundUnit = 0, done = 0;
		unsigned int size = 0, unitShift = 0;
		unsigned int ramSizeMB;

		for (i = 0; i < strlen(p) - 6 && !done; i++) {
//sprintf(msg, "i=%d\n", i);
//uart_puts(msg);
			if (0 == strncmp(&p[i], "mem=", 4)) {
				/* Found key, now read in value */
				foundKeyword = 1;

//uart_puts("while\n");
				for (sizep = q = &p[i+4];*q != '\0' && !done; q++) {
					if (isdigit(*q)) {
						foundNumber = 1;
						continue;
					}

					if (foundNumber) {
//uart_puts("found number\n");

						switch (*q) {
						case 'k':
						case 'K':
							unitShift = 10; /* KB shift value*/
							foundUnit = 1;
							done = 1;
							break;
						case 'm':
						case 'M':
							unitShift = 20; /* MB shift value */
							foundUnit = 1;
							done = 1;
//uart_puts("found unit M\n");
//sprintf(msg, "q=%x\n", q);
//uart_puts(msg);

							break;
						case 'g':
						case 'G':
							/* Probably too big */
							unitShift = 30; /* GB shift value */
							foundUnit = 1;
							done = 1;
							break;
						default:
							done = 1;
							break;
						} 
					}
				}
			} 
		} 

		if (foundNumber) {
			if (foundUnit) {
//uart_puts("Size=");
//uart_puts(sizep);
//uart_puts("\n");
				size = bcm_atoi(sizep);
//sprintf(msg, "q=%x\n", q);
//uart_puts(msg);

				sprintf(msg, "Using %d %cB for memory\n", size, *(q-1));
				uart_puts(msg);
			}
			else {
				uart_puts("Syntax: mem=nn[KMG] Option ignored : No unit specified\n");
			}
		}
		else if (foundKeyword) {
			uart_puts("Syntax: mem=nn[KMG] Option ignored : No size specified\n");
		}

		g_board_RAM_size = get_RAM_size();
		ramSizeMB = g_board_RAM_size >> 20;

		{
			/* 
			  * Kernels on STBs with larger than 32MB, we only use 32MB RAM for the kernel
			  */

	  		if (foundNumber && foundUnit) {
				if (size <= ramSizeMB && size > 0) {
				/* Already output size above */
				} 
				else {
					uart_puts("Invalid size ignored, using default value of 32MB\n");
					size = 32;
					unitShift = 20;
				}
			}
			/* No mem=xxU specified, give the kernel 32MB of memory */
			else {
				uart_puts("Using 32MB for memory, overwrite by passing mem=xx\n");
				size = 32;
				unitShift = 20;
			}
		}
		
		/* Assert size and unit not 0 */
		add_memory_region(0, size << unitShift, BOOT_MEM_RAM);

		/* Register the reserved upper memory, in order to allow kernel to cache them */
		if (size < ramSizeMB) {
			add_memory_region(size << unitShift, (ramSizeMB-size) << unitShift, BOOT_MEM_RAM);
		}
	
	}
}
Esempio n. 3
0
void __init prom_init(void)
{

#ifdef CONFIG_MIPS_BRCM97XXX
	int hasCfeParms = 0;
	int res = -1;
	char msg[COMMAND_LINE_SIZE];
	extern void determineBootFromFlashOrRom(void);
#endif

	uart_init(27000000);

	/* jipeng - mask out UPG L2 interrupt here */
	BDEV_WR(BCHP_IRQ0_IRQEN, 0);

#ifdef CONFIG_TIVO_KONTIKI
	board_pinmux_setup();
#endif

	/* Fill in platform information */
	mips_machgroup = MACH_GROUP_BRCM;
	mips_machtype  = MACH_BRCM_STB;

#ifdef BRCM_SATA_SUPPORTED
	brcm_sata_enabled = 1;
#endif

#ifdef BRCM_ENET_SUPPORTED
	brcm_enet_enabled = 1;
#endif

#ifdef BRCM_EMAC_1_SUPPORTED
	brcm_emac_1_enabled = 1;
#endif

#ifdef BRCM_PCI_SUPPORTED
	brcm_pci_enabled = 1;
#endif

#ifdef CONFIG_SMP
	brcm_smp_enabled = 1;
#endif

#ifdef CONFIG_MIPS_BCM7118
	/* detect 7118RNG board */
	if( BDEV_RD(BCHP_CLKGEN_REG_START) == 0x1c )
		brcm_sata_enabled = 0;
	/* onchip DOCSIS owns the ENET */
	brcm_enet_enabled = 0;
#endif

#ifdef CONFIG_MIPS_BCM7405
	/* detect 7406 */
	if(BDEV_RD(BCHP_SUN_TOP_CTRL_OTP_OPTION_STATUS) &
		BCHP_SUN_TOP_CTRL_OTP_OPTION_STATUS_otp_option_sata_disable_MASK)
		brcm_sata_enabled = 0;
	switch(BDEV_RD(BCHP_SUN_TOP_CTRL_OTP_OPTION_STATUS) & 0xf) {
		case 0x0:
			/* 7405/7406 */
			break;
		case 0x1:
			/* 7466 */
			brcm_pci_enabled = 0;
			brcm_emac_1_enabled = 0;
			break;
		case 0x3:
			/* 7106 */
			brcm_emac_1_enabled = 0;
			brcm_smp_enabled = 0;
			break;
		case 0x4:
			/* 7205 */
			brcm_emac_1_enabled = 0;
			break;
	}
#endif
	
#if defined( CONFIG_MIPS_BCM7118 ) || defined( CONFIG_MIPS_BCM7401C0 )	\
 || defined( CONFIG_MIPS_BCM7402C0 ) || defined( CONFIG_MIPS_BCM3563 ) \
 || defined (CONFIG_MIPS_BCM3563C0)
    /*need set bus to async mode before enabling the following*/
	if(!(read_c0_diag4() & 0x400000))
	{
		int	val=read_c0_diag4();
		write_c0_diag4(val | 0x400000);
		sprintf(msg, "CP0 reg 22 sel 0 to 5: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", read_c0_diag(), read_c0_diag1(), read_c0_diag2(), read_c0_diag3(), read_c0_diag4(), read_c0_diag5());
		uart_puts(msg);
                write_c0_config(0x80008083);
                sprintf(msg, "CP0 reg 16 sel 0 to 1: 0x%08x 0x%08x \n", read_c0_config(), read_c0_config1());
                uart_puts(msg);
	}

	/* Enable write gathering (BCHP_MISB_BRIDGE_WG_MODE_N_TIMEOUT) */
	BDEV_WR(0x0000040c, 0x264);
	/* Enable Split Mode (BCHP_MISB_BRIDGE_MISB_SPLIT_MODE) */
	BDEV_WR(0x00000410, 0x1);
#elif defined( CONFIG_MIPS_BCM7440A0 )
	if(!(read_c0_diag4() & 0x400000))
	{
		int	val=read_c0_diag4();
		write_c0_diag4(val | 0x400000);
		sprintf(msg, "CP0 reg 22 sel 0 to 5: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", read_c0_diag(), read_c0_diag1(), read_c0_diag2(), read_c0_diag3(), read_c0_diag4(), read_c0_diag5());
		uart_puts(msg);
                write_c0_config(0x80008083);
                sprintf(msg, "CP0 reg 16 sel 0 to 1: 0x%08x 0x%08x \n", read_c0_config(), read_c0_config1());
                uart_puts(msg);
	}
	
	/* Enable write gathering (BCHP_MISB_BRIDGE_WG_MODE_N_TIMEOUT) */
	BDEV_WR(0x0000040c, 0x2803);
#endif
#ifdef CONFIG_TIVO_MOJAVE
        if ( cfe_seal != CFE_SEAL ){
                goto noncfe;
        }
#endif

	/* Kernel arguments */
#ifdef CONFIG_MIPS_BRCM97XXX
/* For the 97xxx series STB, process CFE boot parms */

  	{	
  		int i;

		for (i=0; i<MAX_HWADDR; i++) {
			gHwAddrs[i] = &privHwAddrs[i][0];
		}
  	}
  
#ifdef CONFIG_TIVO_KONTIKI
	res = get_cfe_boot_parms();
	hasCfeParms = (res == 0);
#if 1  /* ###JLF */
        if (gNumHwAddrs > 0)
        {
           printk("%s(): Got CFE MAC address "
                  "%02x:%02x:%02x:%02x:%02x:%02x\n",
                  __FUNCTION__,
                  gHwAddrs[0][0], gHwAddrs[0][1], gHwAddrs[0][2],
                  gHwAddrs[0][3], gHwAddrs[0][4], gHwAddrs[0][5]);
        }
#endif

#ifdef BRCM_MEMORY_STRAPS
	get_RAM_size();
#else
	if(brcm_dram0_size == 0)
		brcm_dram0_size = probe_memsize();
#ifndef CONFIG_DISCONTIGMEM
	if(brcm_dram0_size > (256 << 20)) {
		printk("Extra RAM beyond 256MB ignored.  Please "
			"use a kernel that supports DISCONTIG.\n");
		brcm_dram0_size = 256 << 20;
	}
#endif /* CONFIG_DISCONTIGMEM */
#endif /* BRCM_MEMORY_STRAPS */

	// Make sure cfeBootParms is not empty or contains all white space
	if (hasCfeParms) {
		int i;
		
		hasCfeParms = 0;
		for (i=0; i < strlen(cfeBootParms); i++) {
			if (isspace(cfeBootParms[i])) {
				continue;
			}
			else if (cfeBootParms[i] == '\0') {
				break; // and leave hasCfeParms false
			}
			else {
				hasCfeParms = 1;
				break;
			}
		}
	}

#else  /* if !defined(CONFIG_TIVO_KONTIKI) */
	res = get_cfe_boot_parms(cfeBootParms, &gNumHwAddrs, gHwAddrs);
	if(gNumHwAddrs <= 0) {
#if !defined(CONFIG_BRCM_PCI_SLAVE)
		unsigned int i, mac = FLASH_MACADDR_ADDR, ok = 0;

		for(i = 0; i < 3; i++) {
			u16 word = readw((void *)mac);

			if(word != 0x0000 && word != 0xffff)
				ok = 1;

			gHwAddrs[0][(i << 1)] = word & 0xff;
			gHwAddrs[0][(i << 1) + 1] = word >> 8;
			mac += 2;
		}

		/* display warning for all 00's, all ff's, or multicast */
		if(! ok || (gHwAddrs[0][1] & 1)) {
			printk(KERN_WARNING
				"WARNING: read invalid MAC address "
				"%02x:%02x:%02x:%02x:%02x:%02x from flash @ 0x%08x\n",
				gHwAddrs[0][0], gHwAddrs[0][1], gHwAddrs[0][2],
				gHwAddrs[0][3], gHwAddrs[0][4], gHwAddrs[0][5],
				FLASH_MACADDR_ADDR);
		}
#else
		/* PCI slave mode - no EBI/flash available */
		u8 fixed_macaddr[] = { 0x00, 0xc0, 0xa8, 0x74, 0x3b, 0x51 };

		memcpy(&gHwAddrs[0][0], fixed_macaddr, sizeof(fixed_macaddr));
#endif
		gNumHwAddrs = 1;
	}
Esempio n. 4
0
void __init prom_init(void)
{

#ifdef CONFIG_MIPS_BRCM97XXX
	int hasCfeParms = 0;
	int res = -1;
	extern void determineBootFromFlashOrRom(void);
#endif

	uart_init(27000000);

	/* jipeng - mask out UPG L2 interrupt here */
	BDEV_WR(BCHP_IRQ0_IRQEN, 0);

	board_pinmux_setup();

	/* Fill in platform information */
	mips_machgroup = MACH_GROUP_BRCM;
	mips_machtype  = MACH_BRCM_STB;

#ifdef BRCM_SATA_SUPPORTED
	brcm_sata_enabled = 1;
#endif

#ifdef BRCM_ENET_SUPPORTED
	brcm_enet_enabled = 1;
#endif

#ifdef BRCM_EMAC_1_SUPPORTED
	brcm_emac_1_enabled = 1;
#endif

#ifdef BRCM_PCI_SUPPORTED
	brcm_pci_enabled = 1;
#endif

#ifdef CONFIG_SMP
	brcm_smp_enabled = 1;
#endif

#ifdef CONFIG_MIPS_BCM7118
	/* detect 7118RNG board */
	if( BDEV_RD(BCHP_CLKGEN_REG_START) == 0x1c )
		brcm_sata_enabled = 0;
	/* onchip DOCSIS owns the ENET */
	brcm_enet_enabled = 0;
#endif

#ifdef CONFIG_MIPS_BCM7405
	/* detect 7406 */
	if(BDEV_RD(BCHP_SUN_TOP_CTRL_OTP_OPTION_STATUS) &
		BCHP_SUN_TOP_CTRL_OTP_OPTION_STATUS_otp_option_sata_disable_MASK)
		brcm_sata_enabled = 0;
	switch(BDEV_RD(BCHP_SUN_TOP_CTRL_OTP_OPTION_STATUS) & 0xf) {
		case 0x0:
			/* 7405/7406 */
			break;
		case 0x1:
			/* 7466 */
			brcm_pci_enabled = 0;
			brcm_emac_1_enabled = 0;
			break;
		case 0x3:
			/* 7106 */
			brcm_emac_1_enabled = 0;
			brcm_smp_enabled = 0;
			break;
		case 0x4:
		case 0x6:
			/* 7205/7213 */
			brcm_emac_1_enabled = 0;
			break;
	}
#endif
	
#if defined(CONFIG_BMIPS3300)
	// Set BIU to async mode
	set_c0_brcm_bus_pll(1 << 22);
	// Enable write gathering (BCHP_MISB_BRIDGE_WG_MODE_N_TIMEOUT)
	BDEV_WR(0x0000040c, 0x264);
	// Enable Split Mode (BCHP_MISB_BRIDGE_MISB_SPLIT_MODE)
	BDEV_WR(0x00000410, 0x1);
#endif

	/* Kernel arguments */
#ifdef CONFIG_MIPS_BRCM97XXX
/* For the 97xxx series STB, process CFE boot parms */

  	{	
  		int i;

		for (i=0; i<MAX_HWADDR; i++) {
			gHwAddrs[i] = &privHwAddrs[i][0];
		}
  	}
  
	res = get_cfe_boot_parms();
	hasCfeParms = (res == 0);

#ifdef BRCM_MEMORY_STRAPS
	get_RAM_size();
#else
	if(brcm_dram0_size == 0)
		brcm_dram0_size = probe_memsize();
#ifndef CONFIG_DISCONTIGMEM
	if(brcm_dram0_size > (256 << 20)) {
		printk("Extra RAM beyond 256MB ignored.  Please "
			"use a kernel that supports DISCONTIG.\n");
		brcm_dram0_size = 256 << 20;
	}
#endif /* CONFIG_DISCONTIGMEM */
#endif /* BRCM_MEMORY_STRAPS */

	if(gNumHwAddrs <= 0) {
#if !defined(CONFIG_BRCM_PCI_SLAVE)
		unsigned int i, mac = FLASH_MACADDR_ADDR, ok = 0;

		for(i = 0; i < 3; i++) {
			u16 word = readw((void *)mac);

			if(word != 0x0000 && word != 0xffff)
				ok = 1;

			gHwAddrs[0][(i << 1)] = word & 0xff;
			gHwAddrs[0][(i << 1) + 1] = word >> 8;
			mac += 2;
		}

		/* display warning for all 00's, all ff's, or multicast */
		if(! ok || (gHwAddrs[0][0] & 1)) {
			u8 fixed_macaddr[] = { 0x00,0x00,0xde,0xad,0xbe,0xef };
			printk(KERN_WARNING
				"WARNING: read invalid MAC address "
				"%02x:%02x:%02x:%02x:%02x:%02x from flash @ 0x%08x\n",
				gHwAddrs[0][0], gHwAddrs[0][1], gHwAddrs[0][2],
				gHwAddrs[0][3], gHwAddrs[0][4], gHwAddrs[0][5],
				FLASH_MACADDR_ADDR);
			memcpy(&gHwAddrs[0][0], fixed_macaddr,
				sizeof(fixed_macaddr));
		}
#else
		/* PCI slave mode - no EBI/flash available */
		u8 fixed_macaddr[] = { 0x00, 0xc0, 0xa8, 0x74, 0x3b, 0x51 };

		memcpy(&gHwAddrs[0][0], fixed_macaddr, sizeof(fixed_macaddr));
#endif
		gNumHwAddrs = 1;
	}