char * nvram_get(const char *name) { if (nvram_major >= 0) return real_nvram_get(name); else return early_nvram_get(name); }
/* 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; }
/* 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; }