1/* 2 * BCM947xx nvram variable access 3 * 4 * Copyright (C) 2005 Broadcom Corporation 5 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 */ 12 13#include <linux/init.h> 14#include <linux/types.h> 15#include <linux/module.h> 16#include <linux/ssb/ssb.h> 17#include <linux/kernel.h> 18#include <linux/string.h> 19#include <asm/addrspace.h> 20#include <asm/mach-bcm47xx/nvram.h> 21#include <asm/mach-bcm47xx/bcm47xx.h> 22 23static char nvram_buf[NVRAM_SPACE]; 24 25/* Probe for NVRAM header */ 26static void __init early_nvram_init(void) 27{ 28 struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; 29 struct nvram_header *header; 30 int i; 31 u32 base, lim, off; 32 u32 *src, *dst; 33 34 base = mcore->flash_window; 35 lim = mcore->flash_window_size; 36 37 off = FLASH_MIN; 38 while (off <= lim) { 39 /* Windowed flash access */ 40 header = (struct nvram_header *) 41 KSEG1ADDR(base + off - NVRAM_SPACE); 42 if (header->magic == NVRAM_HEADER) 43 goto found; 44 off <<= 1; 45 } 46 47 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ 48 header = (struct nvram_header *) KSEG1ADDR(base + 4096); 49 if (header->magic == NVRAM_HEADER) 50 goto found; 51 52 header = (struct nvram_header *) KSEG1ADDR(base + 1024); 53 if (header->magic == NVRAM_HEADER) 54 goto found; 55 56 return; 57 58found: 59 src = (u32 *) header; 60 dst = (u32 *) nvram_buf; 61 for (i = 0; i < sizeof(struct nvram_header); i += 4) 62 *dst++ = *src++; 63 for (; i < header->len && i < NVRAM_SPACE; i += 4) 64 *dst++ = le32_to_cpu(*src++); 65} 66 67int nvram_getenv(char *name, char *val, size_t val_len) 68{ 69 char *var, *value, *end, *eq; 70 71 if (!name) 72 return NVRAM_ERR_INV_PARAM; 73 74 if (!nvram_buf[0]) 75 early_nvram_init(); 76 77 /* Look for name=value and return value */ 78 var = &nvram_buf[sizeof(struct nvram_header)]; 79 end = nvram_buf + sizeof(nvram_buf) - 2; 80 end[0] = end[1] = '\0'; 81 for (; *var; var = value + strlen(value) + 1) { 82 eq = strchr(var, '='); 83 if (!eq) 84 break; 85 value = eq + 1; 86 if ((eq - var) == strlen(name) && 87 strncmp(var, name, (eq - var)) == 0) { 88 snprintf(val, val_len, "%s", value); 89 return 0; 90 } 91 } 92 return NVRAM_ERR_ENVNOTFOUND; 93} 94EXPORT_SYMBOL(nvram_getenv); 95