cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ip27-berr.c (3042B)


      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) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
      7 * Copyright (C) 1999, 2000 by Silicon Graphics
      8 * Copyright (C) 2002  Maciej W. Rozycki
      9 */
     10#include <linux/init.h>
     11#include <linux/kernel.h>
     12#include <linux/signal.h>	/* for SIGBUS */
     13#include <linux/sched.h>	/* schow_regs(), force_sig() */
     14#include <linux/sched/debug.h>
     15#include <linux/sched/signal.h>
     16
     17#include <asm/ptrace.h>
     18#include <asm/sn/addrs.h>
     19#include <asm/sn/agent.h>
     20#include <asm/sn/arch.h>
     21#include <asm/tlbdebug.h>
     22#include <asm/traps.h>
     23#include <linux/uaccess.h>
     24
     25static void dump_hub_information(unsigned long errst0, unsigned long errst1)
     26{
     27	static char *err_type[2][8] = {
     28		{ NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
     29		  NULL, NULL, NULL, NULL },
     30		{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
     31		  NULL, NULL, NULL, NULL }
     32	};
     33	union pi_err_stat0 st0;
     34	union pi_err_stat1 st1;
     35
     36	st0.pi_stat0_word = errst0;
     37	st1.pi_stat1_word = errst1;
     38
     39	if (!st0.pi_stat0_fmt.s0_valid) {
     40		pr_info("Hub does not contain valid error information\n");
     41		return;
     42	}
     43
     44	pr_info("Hub has valid error information:\n");
     45	if (st0.pi_stat0_fmt.s0_ovr_run)
     46		pr_info("Overrun is set. Error stack may contain additional "
     47		       "information.\n");
     48	pr_info("Hub error address is %08lx\n",
     49		(unsigned long)st0.pi_stat0_fmt.s0_addr);
     50	pr_info("Incoming message command 0x%lx\n",
     51		(unsigned long)st0.pi_stat0_fmt.s0_cmd);
     52	pr_info("Supplemental field of incoming message is 0x%lx\n",
     53		(unsigned long)st0.pi_stat0_fmt.s0_supl);
     54	pr_info("T5 Rn (for RRB only) is 0x%lx\n",
     55		(unsigned long)st0.pi_stat0_fmt.s0_t5_req);
     56	pr_info("Error type is %s\n", err_type[st1.pi_stat1_fmt.s1_rw_rb]
     57	       [st0.pi_stat0_fmt.s0_err_type] ? : "invalid");
     58}
     59
     60int ip27_be_handler(struct pt_regs *regs, int is_fixup)
     61{
     62	unsigned long errst0, errst1;
     63	int data = regs->cp0_cause & 4;
     64	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
     65
     66	if (is_fixup)
     67		return MIPS_BE_FIXUP;
     68
     69	printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
     70	       regs->cp0_epc);
     71	printk("Hub information:\n");
     72	printk("ERR_INT_PEND = 0x%06llx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
     73	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
     74	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
     75	dump_hub_information(errst0, errst1);
     76	show_regs(regs);
     77	dump_tlb_all();
     78	while(1);
     79	force_sig(SIGBUS);
     80}
     81
     82void __init ip27_be_init(void)
     83{
     84	/* XXX Initialize all the Hub & Bridge error handling here.  */
     85	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
     86	int cpuoff = cpu << 8;
     87
     88	mips_set_be_handler(ip27_be_handler);
     89
     90	LOCAL_HUB_S(PI_ERR_INT_PEND,
     91		    cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
     92	LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
     93	LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
     94	LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0);	/* Disable error stack */
     95	LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
     96}