/* * Atheros AR71XX/AR724X/AR913X specific prom routines * * Copyright (C) 2008-2010 Gabor Juhos * Copyright (C) 2008 Imre Kaloz * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "machtypes.h" #include "common.h" #include /* --- #define DEBUG_ATH_PROM --- */ #if defined(DEBUG_ATH_PROM) #define ath_prom_print(arg...) printk(arg) #else #define ath_prom_print(arg...) #endif static unsigned int fw3_save[8]; void prom_printf (const char *fmt, ...) { va_list args; va_start (args, fmt); ath_prom_print (fmt, args); va_end (args); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static __init void ath79_prom_init_cmdline(int argc, char **argv) { int i; ath_prom_print("\n"); /*--- damit es schön aussieht ---*/ ath_prom_print("[%s]:\n", __func__); ath_prom_print("[%s]: argv[0] = '%s'\n", __func__, argv[0]); ath_prom_print("[%s]: argv[1] = '%s'\n", __func__, argv[1]); ath_prom_print("[%s]: argv[2] = '%s'\n", __func__, argv[2]); #if 0 if (!is_valid_ram_addr(argv)) return; #endif for (i = 0; i < argc; i++) { #if 0 if (is_valid_ram_addr(argv[i])) { #endif strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); #if 0 } #endif } ath_prom_print("[%s]:commandline = '%s'\n", __FUNCTION__, arcs_cmdline); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void __init mips_nmi_setup(void) { void *base; extern char except_vec_nmi; base = cpu_has_veic ? (void *)(CAC_BASE + 0xa80) : (void *)(CAC_BASE + 0x380); memcpy(base, &except_vec_nmi, 0x80); printk(KERN_ERR "[%s] setup NMI vector to base 0x%p\n", __FUNCTION__, base); flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void __init prom_init(void) { /* No Env from Urlader, load from AVM Config space */ if(avm_fw_urlader_env()) { /* === Search for kernel_args_tmp in urlader_env === */ struct _avm_kernel_urlader_env * env_var = avm_fw_urlader_env(); while(env_var->name[0]){ if(strncmp(env_var->name, "kernel_args_tmp", 64) == 0){ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); strlcat(arcs_cmdline, env_var->value, sizeof(arcs_cmdline)); break; } env_var++; } /* == Init Env with config content == */ ath_prom_print("[%s]: call env_init\n", __func__); env_init((int *)avm_fw_urlader_env(), ENV_LOCATION_AVM_CONF); board_nmi_handler_setup = NULL; } else { ath_prom_print("[%s]:\n", __func__); ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); ath_prom_print("[%s]: call env_init\n", __func__); env_init((int *)fw_arg2, ENV_LOCATION_FLASH); memcpy(fw3_save, (const void *)fw_arg3, sizeof(fw3_save)); board_nmi_handler_setup = mips_nmi_setup; } ath_prom_print("[%s]: done\n", __func__); } void __init prom_free_prom_memory(void) { /* We do not have to prom memory to free */ } static int __init prom_init_config(void) { unsigned int *config = (unsigned int *)fw3_save; int i; if (avm_fw_urlader_env()) return 0; for (i = 0; i < 8; i++) { unsigned int c = config[i] & ((128 << 10) - 1); avm_prom_load_config_entry(c); } return 0; } late_initcall(prom_init_config);