Ejemplo n.º 1
0
/* Probe for NVRAM header */
static int
early_nvram_init(void)
{
	struct nvram_header *header;
	int i;
	u32 *src, *dst;
#ifdef CONFIG_MTD_NFLASH
	hndnand_t *nfl_info = NULL;
	uint32 blocksize;
#endif
	char *nvram_space_str;
	int bootdev;
	uint32 flash_base;
	uint32 lim = SI_FLASH_WINDOW;
	uint32 off;
	hndsflash_t *sfl_info;

	header = (struct nvram_header *)ram_nvram_buf;
	if (header->magic == NVRAM_MAGIC) {
		if (nvram_calc_crc(header) == (uint8)header->crc_ver_init) {
			nvram_inram = TRUE;
			goto found;
		}
	}

	bootdev = soc_boot_dev((void *)sih);
#ifdef CONFIG_MTD_NFLASH
	if (bootdev == SOC_BOOTDEV_NANDFLASH) {
		if ((nfl_info = hndnand_init(sih)) == NULL)
			return -1;
		flash_base = nfl_info->base;
		blocksize = nfl_info->blocksize;
		off = blocksize;
		for (; off < NFL_BOOT_SIZE; off += blocksize) {
			if (hndnand_checkbadb(nfl_info, off) != 0)
				continue;
			header = (struct nvram_header *)(flash_base + off);
			if (header->magic != NVRAM_MAGIC)
				continue;

			/* Read into the nand_nvram */
			if ((header = nand_find_nvram(nfl_info, off)) == NULL)
				continue;
			if (nvram_calc_crc(header) == (uint8)header->crc_ver_init)
				goto found;
		}
	}
	else
#endif
	if (bootdev == SOC_BOOTDEV_SFLASH ||
	    bootdev == SOC_BOOTDEV_ROM) {
		/* Boot from SFLASH or ROM */
		if ((sfl_info = hndsflash_init(sih)) == NULL)
			return -1;

		lim = sfl_info->size;

		BUG_ON(request_resource(&iomem_resource, &norflash_region));
	
		flash_base = sfl_info->base;
	
		BUG_ON(IS_ERR_OR_NULL((void *)flash_base));
		
		off = FLASH_MIN;
		while (off <= lim) {
			/* Windowed flash access */
			header = (struct nvram_header *)(flash_base + off - nvram_space);
			if (header->magic == NVRAM_MAGIC)
				if (nvram_calc_crc(header) == (uint8)header->crc_ver_init) {
					goto found;
				}
			off += DEF_NVRAM_SPACE;
		}
	}
	else {
		/* This is the case bootdev == SOC_BOOTDEV_PFLASH, not applied on NorthStar */
		ASSERT(0);
	}

	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
	header = (struct nvram_header *)(flash_base + 4 KB);
	if (header->magic == NVRAM_MAGIC)
		if (nvram_calc_crc(header) == (uint8)header->crc_ver_init) {
			goto found;
		}

	header = (struct nvram_header *)(flash_base + 1 KB);
	if (header->magic == NVRAM_MAGIC)
		if (nvram_calc_crc(header) == (uint8)header->crc_ver_init) {
			goto found;
		}

	return -1;

found:
	src = (u32 *)header;
	dst = (u32 *)nvram_buf;
	for (i = 0; i < sizeof(struct nvram_header); i += 4)
		*dst++ = *src++;
	for (; i < header->len && i < MAX_NVRAM_SPACE; i += 4)
		*dst++ = ltoh32(*src++);

	nvram_space_str = early_nvram_get("nvram_space");
	if (nvram_space_str)
		nvram_space = bcm_strtoul(nvram_space_str, NULL, 0);

	return 0;
}
Ejemplo n.º 2
0
static void
flash_init(void)
{
	newflash_probe_t fprobe;
	int bootdev;
	uint32 bootsz, *bisz;
	cfe_driver_t *drv = NULL;
	int j = 0;
	fl_size_t max_image_size = 0;
	int rom_envram_size;
#if defined(DUAL_IMAGE) || defined(FAILSAFE_UPGRADE)
	int need_commit = 0;
#endif
#ifdef CFG_NFLASH
	hndnand_t *nfl_info = NULL;
#endif
#if CFG_SFLASH
	hndsflash_t *sfl_info = NULL;
#endif

	memset(&fprobe, 0, sizeof(fprobe));

	bootdev = soc_boot_dev((void *)sih);

        if(!nvram_match("nospare", "0"))
                nospare = 1;
        else
                nospare = 0;

#ifdef CFG_NFLASH
	if (bootdev == SOC_BOOTDEV_NANDFLASH) {
		nfl_info = hndnand_init(sih);
		if (!nfl_info)
			return;

		fprobe.flash_phys = nfl_info->phybase;
		drv = &nflashdrv;
	} else
#endif	/* CFG_NFLASH */
#if CFG_SFLASH
	if (bootdev == SOC_BOOTDEV_SFLASH) {
		sfl_info = hndsflash_init(sih);
		if (!sfl_info)
			return;

		fprobe.flash_phys = sfl_info->phybase;
		drv = &sflashdrv;
	}
	else
#endif
#if CFG_FLASH
	{
		/* This might be wrong, but set pflash
		 * as default if nothing configured
		 */
		chipcregs_t *cc;

		if ((cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX)) == NULL)
			return;

		fprobe.flash_phys = SI_FLASH2;
		fprobe.flash_flags = FLASH_FLG_BUS16 | FLASH_FLG_DEV16;
		if (!(R_REG(NULL, &cc->flash_config) & CC_CFG_DS))
			fprobe.flash_flags = FLASH_FLG_BUS8 | FLASH_FLG_DEV16;
		drv = &newflashdrv;
	}
#endif /* CFG_FLASH */

	ASSERT(drv);

	/* Default is 256K boot partition */
	bootsz = 256 * 1024;

	/* Do we have a self-describing binary image? */
	bisz = (uint32 *)UNCADDR(fprobe.flash_phys + BISZ_OFFSET);
	if (bisz[BISZ_MAGIC_IDX] == BISZ_MAGIC) {
		int isz = bisz[BISZ_DATAEND_IDX] - bisz[BISZ_TXTST_IDX];

		if (isz > (1024 * 1024))
			bootsz = 2048 * 1024;
		else if (isz > (512 * 1024))
			bootsz = 1024 * 1024;
		else if (isz > (256 * 1024))
			bootsz = 512 * 1024;
		else if (isz <= (128 * 1024))
			bootsz = 128 * 1024;
	}
	printf("Boot partition size = %d(0x%x)\n", bootsz, bootsz);
#if CFG_NFLASH
	if (nfl_info) {
		fl_size_t flash_size = 0;

		if (bootsz > nfl_info->blocksize) {
			/* Prepare double space in case of bad blocks */
			bootsz = (bootsz << 1);
		} else {
			/* CFE occupies at least one block */
			bootsz = nfl_info->blocksize;
		}

		/* Because sometimes we want to program the entire device */
		fprobe.flash_nparts = 0;
		cfe_add_device(drv, 0, 0, &fprobe);

#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
		max_image_size = calculate_max_image_size("nflash0", nfl_boot_size(nfl_info), 0,
			&need_commit, nfl_boot_os_size(nfl_info));
#endif
		/* Because sometimes we want to program the entire device */
		/* Because CFE can only boot from the beginning of a partition */
		j = 0;
		fprobe.flash_parts[j].fp_size = bootsz;
		fprobe.flash_parts[j++].fp_name = "boot";
		fprobe.flash_parts[j].fp_size = (nfl_boot_size(nfl_info) - bootsz);
		fprobe.flash_parts[j++].fp_name = "nvram";

		fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
		fprobe.flash_parts[j++].fp_name = "trx";
		fprobe.flash_parts[j].fp_size = max_image_size ?
		        max_image_size - sizeof(struct trx_header) : 0;
		fprobe.flash_parts[j++].fp_name = "os";
#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
		if (max_image_size) {
			fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
			fprobe.flash_parts[j++].fp_name = "trx2";
			fprobe.flash_parts[j].fp_size = max_image_size;
			fprobe.flash_parts[j++].fp_name = "os2";
		}
#endif

		fprobe.flash_nparts = j;
		cfe_add_device(drv, 0, 0, &fprobe);

		/* Because CFE can only flash an entire partition */
		j = 0;
		fprobe.flash_parts[j].fp_size = bootsz;
		fprobe.flash_parts[j++].fp_name = "boot";
		fprobe.flash_parts[j].fp_size = (nfl_boot_size(nfl_info) - bootsz);
		fprobe.flash_parts[j++].fp_name = "nvram";
		fprobe.flash_parts[j].fp_size = max_image_size;
		fprobe.flash_parts[j++].fp_name = "trx";
#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
		if (max_image_size) {
			fprobe.flash_parts[j].fp_size =
				nfl_boot_os_size(nfl_info) - nfl_boot_size(nfl_info)
				- max_image_size;
			fprobe.flash_parts[j++].fp_name = "trx2";
		}
#endif
		flash_size = get_flash_size("nflash0") - nfl_boot_os_size(nfl_info);
#ifdef DUAL_TRX
                fprobe.flash_parts[j].fp_size = NFL_BOOT_OS_SIZE;
                fprobe.flash_parts[j++].fp_name = "trx2";
		flash_size -= NFL_BOOT_OS_SIZE;
#endif

		if (flash_size > 0) {
			fprobe.flash_parts[j].fp_size = flash_size;
			fprobe.flash_parts[j++].fp_name = "brcmnand";
		}

		fprobe.flash_nparts = j;
		cfe_add_device(drv, 0, 0, &fprobe);

		/* Change nvram device name for NAND boot */
		flashdrv_nvram = "nflash0.nvram";
	} else
#endif /* CFG_NFLASH */
	{
		/* Because sometimes we want to program the entire device */
		fprobe.flash_nparts = 0;
		cfe_add_device(drv, 0, 0, &fprobe);

#ifdef CFG_ROMBOOT
		if (board_bootdev_rom(sih)) {
			rom_envram_size = ROM_ENVRAM_SPACE;
		}
		else
#endif
		{
			rom_envram_size = 0;
		}

#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
		/* If the kernel is not in nand flash, split up the sflash */
		if (soc_knl_dev((void *)sih) != SOC_KNLDEV_NANDFLASH) {
			max_image_size = calculate_max_image_size("flash0",
				bootsz, MAX_NVRAM_SPACE+rom_envram_size, &need_commit, 0);
		}
#endif

		/* Because CFE can only boot from the beginning of a partition */
		j = 0;
		fprobe.flash_parts[j].fp_size = bootsz;
		fprobe.flash_parts[j++].fp_name = "boot";
		fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
		fprobe.flash_parts[j++].fp_name = "trx";
		fprobe.flash_parts[j].fp_size = max_image_size ?
		        max_image_size - sizeof(struct trx_header) : 0;
		fprobe.flash_parts[j++].fp_name = "os";
#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
		if (max_image_size) {
			fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
			fprobe.flash_parts[j++].fp_name = "trx2";
			fprobe.flash_parts[j].fp_size = 0;
			fprobe.flash_parts[j++].fp_name = "os2";
		}
#endif
#ifdef CFG_ROMBOOT
		if (rom_envram_size) {
			fprobe.flash_parts[j].fp_size = rom_envram_size;
			fprobe.flash_parts[j++].fp_name = "envram";
		}
#endif

#ifdef BCM_DEVINFO
                fprobe.flash_parts[j].fp_size = 0x80000;
                fprobe.flash_parts[j++].fp_name = "fs_rw";

                fprobe.flash_parts[j].fp_size = 0x10000;
                fprobe.flash_parts[j++].fp_name = "devinfo";
#endif  /* BCM_DEVINFO */

		fprobe.flash_parts[j].fp_size = MAX_NVRAM_SPACE;
		fprobe.flash_parts[j++].fp_name = "nvram";
		fprobe.flash_nparts = j;
		cfe_add_device(drv, 0, 0, &fprobe);

		/* Because CFE can only flash an entire partition */
		j = 0;
		fprobe.flash_parts[j].fp_size = bootsz;
		fprobe.flash_parts[j++].fp_name = "boot";
		fprobe.flash_parts[j].fp_size = max_image_size;
		fprobe.flash_parts[j++].fp_name = "trx";
#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
		if (max_image_size) {
			fprobe.flash_parts[j].fp_size = 0;
			fprobe.flash_parts[j++].fp_name = "trx2";
		}
#endif
#ifdef CFG_ROMBOOT
		if (rom_envram_size) {
			fprobe.flash_parts[j].fp_size = rom_envram_size;
			fprobe.flash_parts[j++].fp_name = "envram";
		}
#endif

#ifdef BCM_DEVINFO
                fprobe.flash_parts[j].fp_size = 0x80000;
                fprobe.flash_parts[j++].fp_name = "fs_rw";

                fprobe.flash_parts[j].fp_size = 0x10000;
                fprobe.flash_parts[j++].fp_name = "devinfo";
#endif  /* BCM_DEVINFO */

		fprobe.flash_parts[j].fp_size = MAX_NVRAM_SPACE;
		fprobe.flash_parts[j++].fp_name = "nvram";
		fprobe.flash_nparts = j;
		cfe_add_device(drv, 0, 0, &fprobe);
	}

#if (CFG_FLASH || CFG_SFLASH)
	flash_memory_size_config(sih, (void *)&fprobe);
#endif /* (CFG_FLASH || CFG_SFLASH) */

#ifdef CFG_NFLASH
	/* If boot from sflash, try to init partition for JFFS2 anyway */
	if (nfl_info == NULL)
		flash_nflash_init();
#endif /* CFG_NFLASH */

#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
	if (need_commit)
		nvram_commit();
#endif
}
Ejemplo n.º 3
0
static struct nvram_header *
BCMINITFN(find_nvram)(si_t *sih, bool embonly, bool *isemb)
{
	struct nvram_header *nvh;
	uint32 off, lim = SI_FLASH2_SZ;
	uint32 flbase = SI_FLASH2;
	int bootdev;
#ifdef NFLASH_SUPPORT
	hndnand_t *nfl_info = NULL;
#endif
#ifdef _CFE_
	hndsflash_t *sfl_info = NULL;
#endif

	bootdev = soc_boot_dev((void *)sih);
#ifdef NFLASH_SUPPORT
	if (bootdev == SOC_BOOTDEV_NANDFLASH) {
		/* Init nand anyway */
		nfl_info = hndnand_init(sih);
		if (nfl_info)
			flbase = nfl_info->phybase;
	}
	else
#endif /* NFLASH_SUPPORT */
	if (bootdev == SOC_BOOTDEV_SFLASH) {
#ifdef _CFE_
		/* Init nand anyway */
		sfl_info = hndsflash_init(sih);
		if (sfl_info) {
			flbase = sfl_info->phybase;
			lim = sfl_info->size;
		}
#else
	if (sih->ccrev == 42)
		flbase = SI_NS_NORFLASH;
#endif
	}

	if (!embonly) {
		*isemb = FALSE;
#ifdef NFLASH_SUPPORT
		if (nfl_info) {
			uint32 blocksize;

			blocksize = nfl_info->blocksize;
			off = blocksize;
			for (; off < nfl_boot_size(nfl_info); off += blocksize) {
				if (hndnand_checkbadb(nfl_info, off) != 0)
					continue;
				nvh = (struct nvram_header *)OSL_UNCACHED(flbase + off);
				if (nvh->magic != NVRAM_MAGIC)
					continue;

				/* Read into the nand_nvram */
				if ((nvh = nand_find_nvram(nfl_info, off)) == NULL)
					continue;
				if (nvram_calc_crc(nvh) == (uint8)nvh->crc_ver_init)
					return nvh;
			}
		}
		else
#endif /* NFLASH_SUPPORT */
		{
			off = FLASH_MIN;
			while (off <= lim) {
				nvh = (struct nvram_header *)
					OSL_UNCACHED(flbase + off - MAX_NVRAM_SPACE);
				if (nvh->magic == NVRAM_MAGIC) {
					if (nvram_calc_crc(nvh) == (uint8) nvh->crc_ver_init) {
						return (nvh);
					}
				}
				off <<= 1;
			}
		}
#ifdef BCMDBG
		printf("find_nvram: nvram not found, trying embedded nvram next\n");
#endif /* BCMDBG */
	}

	/*
	 * Provide feedback to user when nvram corruption detected.
	 * Must be non-BCMDBG for customer release.
	 */
	printf("Corrupt NVRAM found, trying embedded NVRAM next.\n");

	/* Now check embedded nvram */
	*isemb = TRUE;
	nvh = (struct nvram_header *)OSL_UNCACHED(flbase + (4 * 1024));
	if (nvh->magic == NVRAM_MAGIC)
		return (nvh);
	nvh = (struct nvram_header *)OSL_UNCACHED(flbase + 1024);
	if (nvh->magic == NVRAM_MAGIC)
		return (nvh);
#ifdef _CFE_
	nvh = (struct nvram_header *)embedded_nvram;
	if (nvh->magic == NVRAM_MAGIC)
		return (nvh);
#endif
	printf("find_nvram: no nvram found\n");
	return (NULL);
}