c-octeon.c (f9cd49033b349b8be3bb1f01b39eed837853d880) | c-octeon.c (f65aad41772f6a0022e9763fe06f47604449964c) |
---|---|
1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2005-2007 Cavium Networks 7 */ | 1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2005-2007 Cavium Networks 7 */ |
8#include <linux/export.h> |
|
8#include <linux/init.h> 9#include <linux/kernel.h> 10#include <linux/sched.h> 11#include <linux/smp.h> 12#include <linux/mm.h> 13#include <linux/bitops.h> 14#include <linux/cpu.h> 15#include <linux/io.h> --- 7 unchanged lines hidden (view full) --- 23#include <asm/r4kcache.h> 24#include <asm/traps.h> 25#include <asm/mmu_context.h> 26#include <asm/war.h> 27 28#include <asm/octeon/octeon.h> 29 30unsigned long long cache_err_dcache[NR_CPUS]; | 9#include <linux/init.h> 10#include <linux/kernel.h> 11#include <linux/sched.h> 12#include <linux/smp.h> 13#include <linux/mm.h> 14#include <linux/bitops.h> 15#include <linux/cpu.h> 16#include <linux/io.h> --- 7 unchanged lines hidden (view full) --- 24#include <asm/r4kcache.h> 25#include <asm/traps.h> 26#include <asm/mmu_context.h> 27#include <asm/war.h> 28 29#include <asm/octeon/octeon.h> 30 31unsigned long long cache_err_dcache[NR_CPUS]; |
32EXPORT_SYMBOL_GPL(cache_err_dcache); |
|
31 32/** 33 * Octeon automatically flushes the dcache on tlb changes, so 34 * from Linux's viewpoint it acts much like a physically 35 * tagged cache. No flushing is needed 36 * 37 */ 38static void octeon_flush_data_cache_page(unsigned long addr) --- 244 unchanged lines hidden (view full) --- 283 284 board_cache_error_setup = octeon_cache_error_setup; 285} 286 287/** 288 * Handle a cache error exception 289 */ 290 | 33 34/** 35 * Octeon automatically flushes the dcache on tlb changes, so 36 * from Linux's viewpoint it acts much like a physically 37 * tagged cache. No flushing is needed 38 * 39 */ 40static void octeon_flush_data_cache_page(unsigned long addr) --- 244 unchanged lines hidden (view full) --- 285 286 board_cache_error_setup = octeon_cache_error_setup; 287} 288 289/** 290 * Handle a cache error exception 291 */ 292 |
291static void cache_parity_error_octeon(int non_recoverable) | 293static RAW_NOTIFIER_HEAD(co_cache_error_chain); 294 295int register_co_cache_error_notifier(struct notifier_block *nb) |
292{ | 296{ |
293 unsigned long coreid = cvmx_get_core_num(); 294 uint64_t icache_err = read_octeon_c0_icacheerr(); | 297 return raw_notifier_chain_register(&co_cache_error_chain, nb); 298} 299EXPORT_SYMBOL_GPL(register_co_cache_error_notifier); |
295 | 300 |
296 pr_err("Cache error exception:\n"); 297 pr_err("cp0_errorepc == %lx\n", read_c0_errorepc()); 298 if (icache_err & 1) { 299 pr_err("CacheErr (Icache) == %llx\n", 300 (unsigned long long)icache_err); 301 write_octeon_c0_icacheerr(0); 302 } 303 if (cache_err_dcache[coreid] & 1) { 304 pr_err("CacheErr (Dcache) == %llx\n", 305 (unsigned long long)cache_err_dcache[coreid]); 306 cache_err_dcache[coreid] = 0; 307 } | 301int unregister_co_cache_error_notifier(struct notifier_block *nb) 302{ 303 return raw_notifier_chain_unregister(&co_cache_error_chain, nb); 304} 305EXPORT_SYMBOL_GPL(unregister_co_cache_error_notifier); |
308 | 306 |
309 if (non_recoverable) 310 panic("Can't handle cache error: nested exception"); | 307static inline int co_cache_error_call_notifiers(unsigned long val) 308{ 309 return raw_notifier_call_chain(&co_cache_error_chain, val, NULL); |
311} 312 313/** 314 * Called when the the exception is recoverable 315 */ | 310} 311 312/** 313 * Called when the the exception is recoverable 314 */ |
316 | |
317asmlinkage void cache_parity_error_octeon_recoverable(void) 318{ | 315asmlinkage void cache_parity_error_octeon_recoverable(void) 316{ |
319 cache_parity_error_octeon(0); | 317 co_cache_error_call_notifiers(0); |
320} 321 322/** 323 * Called when the the exception is not recoverable | 318} 319 320/** 321 * Called when the the exception is not recoverable |
322 * 323 * The issue not that the cache error exception itself was non-recoverable 324 * but that due to nesting of exception may have lost some state so can't 325 * continue. |
|
324 */ | 326 */ |
325 | |
326asmlinkage void cache_parity_error_octeon_non_recoverable(void) 327{ | 327asmlinkage void cache_parity_error_octeon_non_recoverable(void) 328{ |
328 cache_parity_error_octeon(1); | 329 co_cache_error_call_notifiers(1); 330 panic("Can't handle cache error: nested exception"); |
329} | 331} |