示例#1
0
static int
nvram_valid(struct nvram_header *header)
{
	return (header->magic == NVRAM_MAGIC) &&
		(header->len >= sizeof(struct nvram_header)) && (header->len <= NVRAM_SPACE)
#if 0
		&& (nvram_calc_crc(header) == (uint8) header->crc_ver_init))
#endif
	;
}
示例#2
0
/* XXX: not marking as RECLAIMTEXT allows this fucntion to be fc-sectioned out when not referenced
 */
int
BCMINITFN(_nvram_commit)(struct nvram_header *header)
{
	char *ptr, *end;
	int i;
	struct nvram_tuple *t;

	/* Regenerate header */
	header->magic = NVRAM_MAGIC;
	header->crc_ver_init = (NVRAM_VERSION << 8);
	header->config_refresh = 0; /* for backward compatibility */
	header->config_ncdl = 0; /* for backward compatibility */

	/* Clear data area */
	ptr = (char *) header + sizeof(struct nvram_header);
	bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header));

	/* Leave space for a double NUL at the end */
	end = (char *) header + NVRAM_SPACE - 2;

	/* Write out all tuples */
	for (i = 0; i < ARRAYSIZE(nvram_hash); i++) {
		for (t = nvram_hash[i]; t; t = t->next) {
			if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end)
				break;
			ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1;
		}
	}

	/* End with a double NUL */
	ptr += 2;

	/* Set new length */
	header->len = ROUNDUP(ptr - (char *) header, 4);

	/* Set new CRC8 */
	header->crc_ver_init |= nvram_calc_crc(header);

	/* Reinitialize hash table */
	return nvram_rehash(header);
}
示例#3
0
/* Probe for NVRAM header */
static int
early_nvram_init(void)
{
	struct nvram_header *header;
	chipcregs_t *cc;
	int i;
	uint32 base, off, lim;
	u32 *src, *dst;
	uint32 fltype;
	char *nvram_space_str;
#ifdef NFLASH_SUPPORT
	hndnand_t *nfl_info = NULL;
	uint32 blocksize;
#endif
	hndsflash_t *sfl_info = NULL;

	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;
		}
	}

	if ((cc = si_setcore(sih, CC_CORE_ID, 0)) != NULL) {
#ifdef NFLASH_SUPPORT
		if ((sih->ccrev == 38) && ((sih->chipst & (1 << 4)) != 0)) {
			fltype = NFLASH;
			base = KSEG1ADDR(SI_FLASH1);
		} else
#endif
		{
			fltype = readl(&cc->capabilities) & CC_CAP_FLASH_MASK;
			base = KSEG1ADDR(SI_FLASH2);
		}
		switch (fltype) {
		case PFLASH:
			lim = SI_FLASH2_SZ;
			break;

		case SFLASH_ST:
		case SFLASH_AT:
			if ((sfl_info = hndsflash_init(sih)) == NULL)
				return -1;
			lim = sfl_info->size;
			break;
#ifdef NFLASH_SUPPORT
		case NFLASH:
			if ((nfl_info = hndnand_init(sih)) == NULL)
				return -1;
			lim = SI_FLASH1_SZ;
			break;
#endif
		case FLASH_NONE:
		default:
			return -1;
		}
	} else {
		/* extif assumed, Stop at 4 MB */
		base = KSEG1ADDR(SI_FLASH1);
		lim = SI_FLASH1_SZ;
	}
#ifdef NFLASH_SUPPORT
	if (nfl_info != NULL) {
		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 *) KSEG1ADDR(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 /* NFLASH_SUPPORT */
	{
		off = FLASH_MIN;

#ifdef RTN66U_NVRAM_64K_SUPPORT
		header = (struct nvram_header *) KSEG1ADDR(base + lim - 0x8000);
		if(header->magic==0xffffffff) {
			header = (struct nvram_header *) KSEG1ADDR(base + 1 KB);
			if (nvram_calc_crc(header) == (uint8) header->crc_ver_init) {
				nvram_32_reset=1;
				goto found;
			}
		}
#endif

		while (off <= lim) {
			/* Windowed flash access */
			header = (struct nvram_header *) KSEG1ADDR(base + off - MAX_NVRAM_SPACE);
			if (header->magic == NVRAM_MAGIC)
				if (nvram_calc_crc(header) == (uint8) header->crc_ver_init) {
					goto found;
				}
			off += DEF_NVRAM_SPACE;
		}
	}

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

	header = (struct nvram_header *) KSEG1ADDR(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;
}
示例#4
0
static int cfe_update(const char *keyword, const char *value)
{
        struct nvram_header *header;
        uint8 crc;
        int ret;
        int found = 0;
        char *str, *end, *mv_target = NULL, *mv_start = NULL;

        if(keyword == NULL || *keyword == 0)
                return 0;

        if(cfe_buf == NULL||cfe_mtd == NULL)
                if((ret = cfe_init()))
                        return ret;

        header = cfe_nvram_header;

	printk("cfe_update: before %x %x\n", header->len,  cfe_nvram_header->crc_ver_init&0xff);
        str = (char *) &header[1];
        end = (char *) header + cfe_embedded_size - 2;
        end[0] = end[1] = '\0';

        for (; *str; str += strlen(str) + 1)
        {
                if(!found)
                {
                        if(strncmp(str, keyword, strlen(keyword)) == 0 && str[strlen(keyword)] == '=')
                        {
                                printk("cfe_update: !!!! found !!!!\n");
                                found = 1;
                                if(value != NULL && strlen(str) == strlen(keyword) + 1 + strlen(value))
                                {//string length is the same
                                        strcpy(str+strlen(keyword)+1, value);
                                }
                                else
                                {
                                        mv_target = str;
                                        mv_start = str + strlen(str) + 1;
                                }
                        }
                }
        }
        /* str point to the end of all embedded nvram settings */

        if(mv_target != NULL)
        { /* need to move string */
                int str_len = strlen(mv_target);
                //printk("cfe_update: mv_target(%08x) mv_start(%08x) str(%08x) str_len(%d)\n", (unsigned int)mv_target, (unsigned int)mv_start, (unsigned int)str, str_len);
                if(value != NULL && (str + strlen(keyword) + 1 + strlen(value) + 1 - (str_len + 1)) > end)
                        return -ENOSPC;
                memmove(mv_target, mv_start, str - mv_start);
                //printk("cfe_update: memmove done\n");
                str -= (str_len + 1); /* /set str to the end for placing incoming keyword and value there */
        }

        if(value == NULL)
        {
                //printk("cfe_update: do unset\n");
        }
        else if(!found || mv_target != NULL) /*new or movement */
        { /* append the keyword and value here */
                //printk("cfe_update: str(%08x)\n", (unsigned int) str);
                if((str + strlen(keyword) + 1 + strlen(value) + 1) > end)
                        return -ENOSPC;
                str += sprintf(str, "%s=%s", keyword, value) + 1;
                //printk("cfe_update: append string\n");
        }
/* calc length */
        memset(str, 0, cfe_embedded_size+(char *)header - str);
        str += 2;
        header->len = ROUNDUP(str - (char *) header, 4);
        //printk("cfe_update: header len: %x\n", header->len);
/*/calc crc */
        crc = nvram_calc_crc(header);
        //printk("cfe_update: nvram_calc_crc(header) = 0x%02x\n", crc);
        header->crc_ver_init = (header->crc_ver_init & NVRAM_CRC_VER_MASK)|crc;
        //printk("cfe_update: after %x %x\n", header->crc_ver_init&0xFF, crc);
 
        return 0;
}
示例#5
0
/* Probe for NVRAM header */
static int
early_nvram_init(void)
{
	struct nvram_header *header;
	chipcregs_t *cc;
	struct sflash *info = NULL;
	int i;
	uint32 base, off, lim;
	u32 *src, *dst;
	uint32 fltype;
#ifdef NFLASH_SUPPORT
	struct nflash *nfl_info = NULL;
	uint32 blocksize;
#endif
	header = (struct nvram_header *)ram_nvram_buf;

	if ((cc = si_setcore(sih, CC_CORE_ID, 0)) != NULL) {
#ifdef NFLASH_SUPPORT
		if ((sih->ccrev == 38) && ((sih->chipst & (1 << 4)) != 0)) {
			fltype = NFLASH;
			base = KSEG1ADDR(SI_FLASH1);
		} else
#endif
		{
			fltype = readl(&cc->capabilities) & CC_CAP_FLASH_MASK;
			base = KSEG1ADDR(SI_FLASH2);
		}
		switch (fltype) {
		case PFLASH:
			lim = SI_FLASH2_SZ;
			break;

		case SFLASH_ST:
		case SFLASH_AT:
			if ((info = sflash_init(sih, cc)) == NULL)
				return -1;
			lim = info->size;
			break;
#ifdef NFLASH_SUPPORT
		case NFLASH:
			if ((nfl_info = nflash_init(sih, cc)) == NULL)
				return -1;
			lim = SI_FLASH1_SZ;
			break;
#endif
		case FLASH_NONE:
		default:
			return -1;
		}
	} else {
		/* extif assumed, Stop at 4 MB */
		base = KSEG1ADDR(SI_FLASH1);
		lim = SI_FLASH1_SZ;
	}
#ifdef NFLASH_SUPPORT
	if (nfl_info != NULL) {
		blocksize = nfl_info->blocksize;
		off = blocksize;
		while (off <= lim) {
			if (nflash_checkbadb(sih, cc, off) != 0) {
				off += blocksize;
				continue;
			}
			header = (struct nvram_header *) KSEG1ADDR(base + off);
			if (header->magic == NVRAM_MAGIC)
				if (nvram_calc_crc(header) == (uint8) header->crc_ver_init) {
					goto found;
				}
			off += blocksize;
		}
	} else
#endif
	off = FLASH_MIN;

#ifdef RTN66U_NVRAM_64K_SUPPORT
	header = (struct nvram_header *) KSEG1ADDR(base + lim - 0x8000);
	if(header->magic==0xffffffff) {
        	header = (struct nvram_header *) KSEG1ADDR(base + 1 KB);
	        if (nvram_valid(header))
        	        goto found;
	}
#endif

	while (off <= lim) {
		/* Windowed flash access */
		header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
		if (nvram_valid(header))
			goto found;
		off <<= 1;
	}

	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
	header = (struct nvram_header *) KSEG1ADDR(base + 4 KB);
	if (nvram_valid(header))
		goto found;
	header = (struct nvram_header *) KSEG1ADDR(base + 1 KB);
	if (nvram_valid(header))
		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 < NVRAM_SPACE; i += 4)
		*dst++ = ltoh32(*src++);

	return 0;
}
示例#6
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;
}
示例#7
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);
}
示例#8
0
/* Probe for NVRAM header */
static int
early_nvram_init(void)
{
	struct nvram_header *header;
	chipcregs_t *cc;
	struct sflash *info = NULL;
	int i;
	uint32 base, off, lim;
	u32 *src, *dst;

	if ((cc = si_setcore(sih, CC_CORE_ID, 0)) != NULL) {
		base = KSEG1ADDR(SI_FLASH2);
		switch (readl(&cc->capabilities) & CC_CAP_FLASH_MASK) {
		case PFLASH:
			lim = SI_FLASH2_SZ;
			break;

		case SFLASH_ST:
		case SFLASH_AT:
			if ((info = sflash_init(sih, cc)) == NULL)
				return -1;
			lim = info->size;
			break;

		case FLASH_NONE:
		default:
			return -1;
		}
	} else {
		/* extif assumed, Stop at 4 MB */
		base = KSEG1ADDR(SI_FLASH1);
		lim = SI_FLASH1_SZ;
	}

	off = FLASH_MIN;
	while (off <= lim) {
		/* Windowed flash access */
		header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
		if (header->magic == NVRAM_MAGIC)
			if (nvram_calc_crc(header) == (uint8) header->crc_ver_init) {
				goto found;
			}
		off <<= 1;
	}

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

	header = (struct nvram_header *) KSEG1ADDR(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 < NVRAM_SPACE; i += 4)
		*dst++ = ltoh32(*src++);

	return 0;
}