#include #include #include #include #include #include #include #include #include #include #include #include #include /*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ #if IS_ENABLED(CONFIG_OF_AVM_DT_ENV) #include #include #include /* * Retrieves the AVM Environment Variables from the Device Tree */ char *__must_check prom_getenv_device_tree(char *envname) { /* Check if we have a device tree */ if (of_have_populated_dt()) { struct device_node *node; char *string = 0; /* Go to the chosen node where the environment is stored */ node = of_find_node_by_path("/chosen"); if (!node) { pr_err("Chosen node not found\n"); return 0; } /* check if the is a property with the name specified by * envname */ if (of_property_read_string(node, envname, (const char **) &string) == 0) { pr_debug("Found env %s\n", string); return string; } pr_err("Could not find Env '%s' in the device tree\n", envname); return 0; } pr_err("Device Tree not populated\n"); return NULL; } #else /* === Support for old urlader env mechanism used for scorpion et al. === */ #include char *dst_env[64 * 2] __attribute__ ((section(".init.data"))); char *dst_config[4] __attribute__ ((section(".init.data"))); char dst_env_buff[2048] __attribute__((section(".init.data"))); char *dst_cmdline[COMMAND_LINE_SIZE] __attribute__ ((section(".init.data"))); char dst_cmdline_buff[64 * 1024] __attribute__((section(".init.data"))); /* --- #define DEBUG_PROM_INIT --- */ #if defined(DEBUG_PROM_INIT) #define PROM_PRINTK(...) printk(__VA_ARGS__) #else #define PROM_PRINTK(...) #endif #define prom_envp(index) ((char *)(long)_prom_envp[(index)]) static char env_buffer[2048]; static char *_local_envp[64 * 2]; unsigned int fritz_box_hw_revision; int *_prom_envp; #if defined(DEBUG_PROM_INIT) void print_env(char **myenv) { int i = 0; PROM_PRINTK("myenvp=%p\n", myenv); while (myenv[i] && myenv[i+1]) { PROM_PRINTK("(%p)%s : (%p)%s\n", myenv[i], myenv[i], myenv[i+1], myenv[i+1]); i += 2; } } #if defined(CONFIG_MIPS) void print_cmdline(int argc, char **argv) { int i = 0; PROM_PRINTK("argc=%d argv=%p\n", argc, argv); for (i = 0; i < argc; i++) { PROM_PRINTK("[%d]: %s\n", i, argv[i]); } } #include #endif /*--- #if defined(CONFIG_MIPS) ---*/ #endif /*--- #if defined(DEBUG_PROM_INIT) ---*/ void __init env_init(int *fw_arg2, enum _env_location env_location) { unsigned int i; char *p; struct _avm_kernel_urlader_env *urlader_env; static unsigned int once; if (once) return; once = 1; if (env_location == ENV_LOCATION_AVM_CONF) { urlader_env = (struct _avm_kernel_urlader_env *) fw_arg2; for (i = 0; urlader_env[i].name[0] && i < 64; i++) { _local_envp[2 * i] = (urlader_env[i].name); _local_envp[2 * i + 1] = (urlader_env[i].value); } i *= 2; } else { _prom_envp = fw_arg2; #if defined(DEBUG_PROM_INIT) print_env((char **)_prom_envp); #if defined(CONFIG_MIPS) print_cmdline(fw_arg0, (char **)fw_arg1); #endif /*--- #if defined(CONFIG_MIPS) ---*/ #endif /*--- #if defined(DEBUG_PROM_INIT) ---*/ PROM_PRINTK("[prom_init] 0\n"); env_buffer[0] = '\0'; p = env_buffer; /* copy envp values from urlader memory to (non init) kernel * memory. */ for (i = 0 ; _prom_envp && _prom_envp[i] && _prom_envp[i + 1] ; i += 2) { #if defined(DEBUG_PROM_INIT) PROM_PRINTK("[prom_init] envp[%u]= \"%s\"=\"%s\"\n", i, (char *)_prom_envp[i], (char *)_prom_envp[i + 1]); #endif /*--- #if defined(DEBUG_PROM_INIT) ---*/ _local_envp[i] = p; strcat(p, (char *)(_prom_envp[i])); p += strlen((char *)(_prom_envp[i])) + 1; /*--- align auf naechstes wort ---*/ while ((unsigned int)p & 0x3) *p++ = '\0'; _local_envp[i + 1] = p; switch (env_location) { case ENV_LOCATION_FLASH: strcat(p, (char *)_prom_envp[i + 1]); p += strlen((char *)_prom_envp[i + 1]) + 1; break; case ENV_LOCATION_PHY_RAM: strcat(p, (char *)phys_to_virt(_prom_envp[i + 1])); p += strlen((char *)phys_to_virt(_prom_envp[i + 1])) + 1; break; case ENV_LOCATION_VIRT_RAM: strcat(p, (char *)(_prom_envp[i + 1])); p += strlen((char *)(_prom_envp[i + 1])) + 1; break; case ENV_LOCATION_AVM_CONF: /* Can not happen !! */ break; } /*--- align auf naechstes wort ---*/ while ((unsigned int)p & 0x3) *p++ = '\0'; } } _local_envp[i] = NULL; _local_envp[i + 1] = NULL; _prom_envp = (int *)_local_envp; fritz_box_hw_revision = simple_strtoul(prom_getenv("HWRevision"), NULL, 10); } #endif char *__must_check prom_getenv(char *envname) { /* * Return a pointer to the given environment variable. * In 64-bit mode: we're using 64-bit pointers, but all pointers * in the PROM structures are only 32-bit, so we need some * workarounds, if we are running in 64-bit mode. */ #if IS_ENABLED(CONFIG_OF_AVM_DT_ENV) pr_debug("Retrieving %s from device tree\n", envname); return prom_getenv_device_tree(envname); #else int i, index = 0; if (!_prom_envp) return NULL; i = strlen(envname); while (prom_envp(index)) { if (strncmp(envname, prom_envp(index), i) == 0) { return prom_envp(index+1); } index += 2; } return NULL; #endif } EXPORT_SYMBOL(prom_getenv);