traps.c
来自「linux 内核源代码」· C语言 代码 · 共 2,231 行 · 第 1/5 页
C
2,231 行
0, tt, SIGTRAP); if (regs->tstate & TSTATE_PRIV) { if (tl1) dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("UE", regs); } /* XXX need more intelligent processing here, such as is implemented * XXX for cheetah errors, in fact if the E-cache still holds the * XXX line with bad parity this will loop */ spitfire_clean_and_reenable_l1_caches(); spitfire_enable_estate_errors(); if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_OBJERR; info.si_addr = (void *)0; info.si_trapno = 0; force_sig_info(SIGBUS, &info, current);}void spitfire_access_error(struct pt_regs *regs, unsigned long status_encoded, unsigned long afar){ unsigned long afsr, tt, udbh, udbl; int tl1; afsr = (status_encoded & SFSTAT_AFSR_MASK) >> SFSTAT_AFSR_SHIFT; tt = (status_encoded & SFSTAT_TRAP_TYPE) >> SFSTAT_TRAP_TYPE_SHIFT; tl1 = (status_encoded & SFSTAT_TL_GT_ONE) ? 1 : 0; udbl = (status_encoded & SFSTAT_UDBL_MASK) >> SFSTAT_UDBL_SHIFT; udbh = (status_encoded & SFSTAT_UDBH_MASK) >> SFSTAT_UDBH_SHIFT;#ifdef CONFIG_PCI if (tt == TRAP_TYPE_DAE && pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) { spitfire_clean_and_reenable_l1_caches(); spitfire_enable_estate_errors(); pci_poke_faulted = 1; regs->tnpc = regs->tpc + 4; return; }#endif if (afsr & SFAFSR_UE) spitfire_ue_log(afsr, afar, udbh, udbl, tt, tl1, regs); if (tt == TRAP_TYPE_CEE) { /* Handle the case where we took a CEE trap, but ACK'd * only the UE state in the UDB error registers. */ if (afsr & SFAFSR_UE) { if (udbh & UDBE_CE) { __asm__ __volatile__( "stxa %0, [%1] %2\n\t" "membar #Sync" : /* no outputs */ : "r" (udbh & UDBE_CE), "r" (0x0), "i" (ASI_UDB_ERROR_W)); } if (udbl & UDBE_CE) { __asm__ __volatile__( "stxa %0, [%1] %2\n\t" "membar #Sync" : /* no outputs */ : "r" (udbl & UDBE_CE), "r" (0x18), "i" (ASI_UDB_ERROR_W)); } } spitfire_cee_log(afsr, afar, udbh, udbl, tl1, regs); }}int cheetah_pcache_forced_on;void cheetah_enable_pcache(void){ unsigned long dcr; printk("CHEETAH: Enabling P-Cache on cpu %d.\n", smp_processor_id()); __asm__ __volatile__("ldxa [%%g0] %1, %0" : "=r" (dcr) : "i" (ASI_DCU_CONTROL_REG)); dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL); __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" "membar #Sync" : /* no outputs */ : "r" (dcr), "i" (ASI_DCU_CONTROL_REG));}/* Cheetah error trap handling. */static unsigned long ecache_flush_physbase;static unsigned long ecache_flush_linesize;static unsigned long ecache_flush_size;/* WARNING: The error trap handlers in assembly know the precise * layout of the following structure. * * C-level handlers below use this information to log the error * and then determine how to recover (if possible). */struct cheetah_err_info {/*0x00*/u64 afsr;/*0x08*/u64 afar; /* D-cache state *//*0x10*/u64 dcache_data[4]; /* The actual data *//*0x30*/u64 dcache_index; /* D-cache index *//*0x38*/u64 dcache_tag; /* D-cache tag/valid *//*0x40*/u64 dcache_utag; /* D-cache microtag *//*0x48*/u64 dcache_stag; /* D-cache snooptag */ /* I-cache state *//*0x50*/u64 icache_data[8]; /* The actual insns + predecode *//*0x90*/u64 icache_index; /* I-cache index *//*0x98*/u64 icache_tag; /* I-cache phys tag *//*0xa0*/u64 icache_utag; /* I-cache microtag *//*0xa8*/u64 icache_stag; /* I-cache snooptag *//*0xb0*/u64 icache_upper; /* I-cache upper-tag *//*0xb8*/u64 icache_lower; /* I-cache lower-tag */ /* E-cache state *//*0xc0*/u64 ecache_data[4]; /* 32 bytes from staging registers *//*0xe0*/u64 ecache_index; /* E-cache index *//*0xe8*/u64 ecache_tag; /* E-cache tag/state *//*0xf0*/u64 __pad[32 - 30];};#define CHAFSR_INVALID ((u64)-1L)/* This table is ordered in priority of errors and matches the * AFAR overwrite policy as well. */struct afsr_error_table { unsigned long mask; const char *name;};static const char CHAFSR_PERR_msg[] = "System interface protocol error";static const char CHAFSR_IERR_msg[] = "Internal processor error";static const char CHAFSR_ISAP_msg[] = "System request parity error on incoming addresss";static const char CHAFSR_UCU_msg[] = "Uncorrectable E-cache ECC error for ifetch/data";static const char CHAFSR_UCC_msg[] = "SW Correctable E-cache ECC error for ifetch/data";static const char CHAFSR_UE_msg[] = "Uncorrectable system bus data ECC error for read";static const char CHAFSR_EDU_msg[] = "Uncorrectable E-cache ECC error for stmerge/blkld";static const char CHAFSR_EMU_msg[] = "Uncorrectable system bus MTAG error";static const char CHAFSR_WDU_msg[] = "Uncorrectable E-cache ECC error for writeback";static const char CHAFSR_CPU_msg[] = "Uncorrectable ECC error for copyout";static const char CHAFSR_CE_msg[] = "HW corrected system bus data ECC error for read";static const char CHAFSR_EDC_msg[] = "HW corrected E-cache ECC error for stmerge/blkld";static const char CHAFSR_EMC_msg[] = "HW corrected system bus MTAG ECC error";static const char CHAFSR_WDC_msg[] = "HW corrected E-cache ECC error for writeback";static const char CHAFSR_CPC_msg[] = "HW corrected ECC error for copyout";static const char CHAFSR_TO_msg[] = "Unmapped error from system bus";static const char CHAFSR_BERR_msg[] = "Bus error response from system bus";static const char CHAFSR_IVC_msg[] = "HW corrected system bus data ECC error for ivec read";static const char CHAFSR_IVU_msg[] = "Uncorrectable system bus data ECC error for ivec read";static struct afsr_error_table __cheetah_error_table[] = { { CHAFSR_PERR, CHAFSR_PERR_msg }, { CHAFSR_IERR, CHAFSR_IERR_msg }, { CHAFSR_ISAP, CHAFSR_ISAP_msg }, { CHAFSR_UCU, CHAFSR_UCU_msg }, { CHAFSR_UCC, CHAFSR_UCC_msg }, { CHAFSR_UE, CHAFSR_UE_msg }, { CHAFSR_EDU, CHAFSR_EDU_msg }, { CHAFSR_EMU, CHAFSR_EMU_msg }, { CHAFSR_WDU, CHAFSR_WDU_msg }, { CHAFSR_CPU, CHAFSR_CPU_msg }, { CHAFSR_CE, CHAFSR_CE_msg }, { CHAFSR_EDC, CHAFSR_EDC_msg }, { CHAFSR_EMC, CHAFSR_EMC_msg }, { CHAFSR_WDC, CHAFSR_WDC_msg }, { CHAFSR_CPC, CHAFSR_CPC_msg }, { CHAFSR_TO, CHAFSR_TO_msg }, { CHAFSR_BERR, CHAFSR_BERR_msg }, /* These two do not update the AFAR. */ { CHAFSR_IVC, CHAFSR_IVC_msg }, { CHAFSR_IVU, CHAFSR_IVU_msg }, { 0, NULL },};static const char CHPAFSR_DTO_msg[] = "System bus unmapped error for prefetch/storequeue-read";static const char CHPAFSR_DBERR_msg[] = "System bus error for prefetch/storequeue-read";static const char CHPAFSR_THCE_msg[] = "Hardware corrected E-cache Tag ECC error";static const char CHPAFSR_TSCE_msg[] = "SW handled correctable E-cache Tag ECC error";static const char CHPAFSR_TUE_msg[] = "Uncorrectable E-cache Tag ECC error";static const char CHPAFSR_DUE_msg[] = "System bus uncorrectable data ECC error due to prefetch/store-fill";static struct afsr_error_table __cheetah_plus_error_table[] = { { CHAFSR_PERR, CHAFSR_PERR_msg }, { CHAFSR_IERR, CHAFSR_IERR_msg }, { CHAFSR_ISAP, CHAFSR_ISAP_msg }, { CHAFSR_UCU, CHAFSR_UCU_msg }, { CHAFSR_UCC, CHAFSR_UCC_msg }, { CHAFSR_UE, CHAFSR_UE_msg }, { CHAFSR_EDU, CHAFSR_EDU_msg }, { CHAFSR_EMU, CHAFSR_EMU_msg }, { CHAFSR_WDU, CHAFSR_WDU_msg }, { CHAFSR_CPU, CHAFSR_CPU_msg }, { CHAFSR_CE, CHAFSR_CE_msg }, { CHAFSR_EDC, CHAFSR_EDC_msg }, { CHAFSR_EMC, CHAFSR_EMC_msg }, { CHAFSR_WDC, CHAFSR_WDC_msg }, { CHAFSR_CPC, CHAFSR_CPC_msg }, { CHAFSR_TO, CHAFSR_TO_msg }, { CHAFSR_BERR, CHAFSR_BERR_msg }, { CHPAFSR_DTO, CHPAFSR_DTO_msg }, { CHPAFSR_DBERR, CHPAFSR_DBERR_msg }, { CHPAFSR_THCE, CHPAFSR_THCE_msg }, { CHPAFSR_TSCE, CHPAFSR_TSCE_msg }, { CHPAFSR_TUE, CHPAFSR_TUE_msg }, { CHPAFSR_DUE, CHPAFSR_DUE_msg }, /* These two do not update the AFAR. */ { CHAFSR_IVC, CHAFSR_IVC_msg }, { CHAFSR_IVU, CHAFSR_IVU_msg }, { 0, NULL },};static const char JPAFSR_JETO_msg[] = "System interface protocol error, hw timeout caused";static const char JPAFSR_SCE_msg[] = "Parity error on system snoop results";static const char JPAFSR_JEIC_msg[] = "System interface protocol error, illegal command detected";static const char JPAFSR_JEIT_msg[] = "System interface protocol error, illegal ADTYPE detected";static const char JPAFSR_OM_msg[] = "Out of range memory error has occurred";static const char JPAFSR_ETP_msg[] = "Parity error on L2 cache tag SRAM";static const char JPAFSR_UMS_msg[] = "Error due to unsupported store";static const char JPAFSR_RUE_msg[] = "Uncorrectable ECC error from remote cache/memory";static const char JPAFSR_RCE_msg[] = "Correctable ECC error from remote cache/memory";static const char JPAFSR_BP_msg[] = "JBUS parity error on returned read data";static const char JPAFSR_WBP_msg[] = "JBUS parity error on data for writeback or block store";static const char JPAFSR_FRC_msg[] = "Foreign read to DRAM incurring correctable ECC error";static const char JPAFSR_FRU_msg[] = "Foreign read to DRAM incurring uncorrectable ECC error";static struct afsr_error_table __jalapeno_error_table[] = { { JPAFSR_JETO, JPAFSR_JETO_msg }, { JPAFSR_SCE, JPAFSR_SCE_msg }, { JPAFSR_JEIC, JPAFSR_JEIC_msg }, { JPAFSR_JEIT, JPAFSR_JEIT_msg }, { CHAFSR_PERR, CHAFSR_PERR_msg }, { CHAFSR_IERR, CHAFSR_IERR_msg }, { CHAFSR_ISAP, CHAFSR_ISAP_msg }, { CHAFSR_UCU, CHAFSR_UCU_msg }, { CHAFSR_UCC, CHAFSR_UCC_msg }, { CHAFSR_UE, CHAFSR_UE_msg }, { CHAFSR_EDU, CHAFSR_EDU_msg }, { JPAFSR_OM, JPAFSR_OM_msg }, { CHAFSR_WDU, CHAFSR_WDU_msg }, { CHAFSR_CPU, CHAFSR_CPU_msg }, { CHAFSR_CE, CHAFSR_CE_msg }, { CHAFSR_EDC, CHAFSR_EDC_msg }, { JPAFSR_ETP, JPAFSR_ETP_msg }, { CHAFSR_WDC, CHAFSR_WDC_msg }, { CHAFSR_CPC, CHAFSR_CPC_msg }, { CHAFSR_TO, CHAFSR_TO_msg }, { CHAFSR_BERR, CHAFSR_BERR_msg }, { JPAFSR_UMS, JPAFSR_UMS_msg }, { JPAFSR_RUE, JPAFSR_RUE_msg }, { JPAFSR_RCE, JPAFSR_RCE_msg }, { JPAFSR_BP, JPAFSR_BP_msg }, { JPAFSR_WBP, JPAFSR_WBP_msg }, { JPAFSR_FRC, JPAFSR_FRC_msg }, { JPAFSR_FRU, JPAFSR_FRU_msg }, /* These two do not update the AFAR. */ { CHAFSR_IVU, CHAFSR_IVU_msg }, { 0, NULL },};static struct afsr_error_table *cheetah_error_table;static unsigned long cheetah_afsr_errors;/* This is allocated at boot time based upon the largest hardware * cpu ID in the system. We allocate two entries per cpu, one for * TL==0 logging and one for TL >= 1 logging. */struct cheetah_err_info *cheetah_error_log;static inline struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr){ struct cheetah_err_info *p; int cpu = smp_processor_id(); if (!cheetah_error_log) return NULL; p = cheetah_error_log + (cpu * 2); if ((afsr & CHAFSR_TL1) != 0UL) p++; return p;}extern unsigned int tl0_icpe[], tl1_icpe[];extern unsigned int tl0_dcpe[], tl1_dcpe[];extern unsigned int tl0_fecc[], tl1_fecc[];extern unsigned int tl0_cee[], tl1_cee[];extern unsigned int tl0_iae[], tl1_iae[];extern unsigned int tl0_dae[], tl1_dae[];extern unsigned int cheetah_plus_icpe_trap_vector[], cheetah_plus_icpe_trap_vector_tl1[];extern unsigned int cheetah_plus_dcpe_trap_vector[], cheetah_plus_dcpe_trap_vector_tl1[];extern unsigned int cheetah_fecc_trap_vector[], cheetah_fecc_trap_vector_tl1[];extern unsigned int cheetah_cee_trap_vector[], cheetah_cee_trap_vector_tl1[];extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector_tl1[];void __init cheetah_ecache_flush_init(void){ unsigned long largest_size, smallest_linesize, order, ver; int i, sz; /* Scan all cpu device tree nodes, note two values: * 1) largest E-cache size * 2) smallest E-cache line size */ largest_size = 0UL; smallest_linesize = ~0UL; for (i = 0; i < NR_CPUS; i++) { unsigned long val; val = cpu_data(i).ecache_size; if (!val) continue; if (val > largest_size) largest_size = val; val = cpu_data(i).ecache_line_size; if (val < smallest_linesize) smallest_linesize = val; } if (largest_size == 0UL || smallest_linesize == ~0UL) { prom_printf("cheetah_ecache_flush_init: Cannot probe cpu E-cache " "parameters.\n"); prom_halt(); } ecache_flush_size = (2 * largest_size); ecache_flush_linesize = smallest_linesize; ecache_flush_physbase = find_ecache_flush_span(ecache_flush_size); if (ecache_flush_physbase == ~0UL) { prom_printf("cheetah_ecache_flush_init: Cannot find %d byte " "contiguous physical memory.\n", ecache_flush_size); prom_halt(); } /* Now allocate error trap reporting scoreboard. */ sz = NR_CPUS * (2 * sizeof(struct cheetah_err_info)); for (order = 0; order < MAX_ORDER; order++) { if ((PAGE_SIZE << order) >= sz) break; } cheetah_error_log = (struct cheetah_err_info *) __get_free_pages(GFP_KERNEL, order); if (!cheetah_error_log) { prom_printf("cheetah_ecache_flush_init: Failed to allocate " "error logging scoreboard (%d bytes).\n", sz); prom_halt(); } memset(cheetah_error_log, 0, PAGE_SIZE << order); /* Mark all AFSRs as invalid so that the trap handler will * log new new information there. */ for (i = 0; i < 2 * NR_CPUS; i++) cheetah_error_log[i].afsr = CHAFSR_INVALID; __asm__ ("rdpr %%ver, %0" : "=r" (ver)); if ((ver >> 32) == __JALAPENO_ID || (ver >> 32) == __SERRANO_ID) { cheetah_error_table = &__jalapeno_error_table[0]; cheetah_afsr_errors = JPAFSR_ERRORS; } else if ((ver >> 32) == 0x003e0015) { cheetah_error_table = &__cheetah_plus_error_table[0]; cheetah_afsr_errors = CHPAFSR_ERRORS; } else { cheetah_error_table = &__cheetah_error_table[0]; cheetah_afsr_errors = CHAFSR_ERRORS; } /* Now patch trap tables. */ memcpy(tl0_fecc, cheetah_fecc_trap_vector, (8 * 4)); memcpy(tl1_fecc, cheetah_fecc_trap_vector_tl1, (8 * 4)); memcpy(tl0_cee, cheetah_cee_trap_vector, (8 * 4)); memcpy(tl1_cee, cheetah_cee_trap_vector_tl1, (8 * 4)); memcpy(tl0_iae, cheetah_deferred_trap_vector, (8 * 4)); memcpy(tl1_iae, cheetah_deferred_trap_vector_tl1, (8 * 4)); memcpy(tl0_dae, cheetah_deferred_trap_vector, (8 * 4)); memcpy(tl1_dae, cheetah_deferred_trap_vector_tl1, (8 * 4)); if (tlb_type == cheetah_plus) { memcpy(tl0_dcpe, cheetah_plus_dcpe_trap_vector, (8 * 4)); memcpy(tl1_dcpe, cheetah_plus_dcpe_trap_vector_tl1, (8 * 4)); memcpy(tl0_icpe, cheetah_plus_icpe_trap_vector, (8 * 4)); memcpy(tl1_icpe, cheetah_plus_icpe_trap_vector_tl1, (8 * 4)); } flushi(PAGE_OFFSET);}static void cheetah_flush_ecache(void){ unsigned long flush_base = ecache_flush_physbase;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?