static void nvram_format(void) { struct chrp_nvram_hdr *h; unsigned int offset = 0; prerror("NVRAM: Re-initializing\n"); memset(nvram_image, 0, nvram_size); /* Create private partition */ h = nvram_image + offset; h->sig = NVRAM_SIG_FW_PRIV; h->len = NVRAM_SIZE_FW_PRIV >> 4; strcpy(h->name, NVRAM_NAME_FW_PRIV); h->cksum = chrp_nv_cksum(h); offset += NVRAM_SIZE_FW_PRIV; /* Create common partition */ h = nvram_image + offset; h->sig = NVRAM_SIG_SYSTEM; h->len = NVRAM_SIZE_COMMON >> 4; strcpy(h->name, NVRAM_NAME_COMMON); h->cksum = chrp_nv_cksum(h); offset += NVRAM_SIZE_COMMON; /* Create free space partition */ h = nvram_image + offset; h->sig = NVRAM_SIG_FREE; h->len = (nvram_size - offset) >> 4; strncpy(h->name, NVRAM_NAME_FREE, 12); h->cksum = chrp_nv_cksum(h); /* Write the whole thing back */ if (platform.nvram_write) platform.nvram_write(0, nvram_image, nvram_size); }
int nvram_format(void *nvram_image, uint32_t nvram_size) { struct chrp_nvram_hdr *h; unsigned int offset = 0; prerror("NVRAM: Re-initializing\n"); memset(nvram_image, 0, nvram_size); /* Create private partition */ if (nvram_size - offset < NVRAM_SIZE_FW_PRIV) return -1; h = nvram_image + offset; h->sig = NVRAM_SIG_FW_PRIV; h->len = NVRAM_SIZE_FW_PRIV >> 4; strcpy(h->name, NVRAM_NAME_FW_PRIV); h->cksum = chrp_nv_cksum(h); offset += NVRAM_SIZE_FW_PRIV; /* Create common partition */ if (nvram_size - offset < NVRAM_SIZE_COMMON) return -1; h = nvram_image + offset; h->sig = NVRAM_SIG_SYSTEM; h->len = NVRAM_SIZE_COMMON >> 4; strcpy(h->name, NVRAM_NAME_COMMON); h->cksum = chrp_nv_cksum(h); offset += NVRAM_SIZE_COMMON; /* Create free space partition */ if (nvram_size - offset < sizeof(struct chrp_nvram_hdr)) return -1; h = nvram_image + offset; h->sig = NVRAM_SIG_FREE; h->len = (nvram_size - offset) >> 4; /* We have the full 12 bytes here */ memcpy(h->name, NVRAM_NAME_FREE, 12); h->cksum = chrp_nv_cksum(h); return 0; }
/* * Check that the nvram partition layout is sane and that it * contains our required partitions. If not, we re-format the * lot of it */ int nvram_check(void *nvram_image, const uint32_t nvram_size) { unsigned int offset = 0; bool found_common = false; bool found_skiboot = false; while (offset + sizeof(struct chrp_nvram_hdr) < nvram_size) { struct chrp_nvram_hdr *h = nvram_image + offset; if (chrp_nv_cksum(h) != h->cksum) { prerror("NVRAM: Partition at offset 0x%x" " has bad checksum\n", offset); goto failed; } if (h->len < 1) { prerror("NVRAM: Partition at offset 0x%x" " has incorrect 0 length\n", offset); goto failed; } if (h->sig == NVRAM_SIG_SYSTEM && strcmp(h->name, NVRAM_NAME_COMMON) == 0) found_common = true; if (h->sig == NVRAM_SIG_FW_PRIV && strcmp(h->name, NVRAM_NAME_FW_PRIV) == 0) found_skiboot = true; offset += h->len << 4; if (offset > nvram_size) { prerror("NVRAM: Partition at offset 0x%x" " extends beyond end of nvram !\n", offset); goto failed; } } if (!found_common) { prerror("NVRAM: Common partition not found !\n"); goto failed; } if (!found_skiboot) { prerror("NVRAM: Skiboot private partition " "not found !\n"); goto failed; } prerror("NVRAM: Layout appears sane\n"); return 0; failed: return -1; }