root/arch/mips/sgi-ip27/ip27-nmi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nmi_dump
  2. install_cpu_nmi_handler
  3. nmi_cpu_eframe_save
  4. nmi_dump_hub_irq
  5. nmi_node_eframe_save
  6. nmi_eframes_save
  7. cont_nmi_dump

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/kernel.h>
   3 #include <linux/mmzone.h>
   4 #include <linux/nodemask.h>
   5 #include <linux/spinlock.h>
   6 #include <linux/smp.h>
   7 #include <linux/atomic.h>
   8 #include <asm/sn/types.h>
   9 #include <asm/sn/addrs.h>
  10 #include <asm/sn/nmi.h>
  11 #include <asm/sn/arch.h>
  12 #include <asm/sn/sn0/hub.h>
  13 
  14 #if 0
  15 #define NODE_NUM_CPUS(n)        CNODE_NUM_CPUS(n)
  16 #else
  17 #define NODE_NUM_CPUS(n)        CPUS_PER_NODE
  18 #endif
  19 
  20 #define CNODEID_NONE (cnodeid_t)-1
  21 
  22 typedef unsigned long machreg_t;
  23 
  24 static arch_spinlock_t nmi_lock = __ARCH_SPIN_LOCK_UNLOCKED;
  25 
  26 /*
  27  * Let's see what else we need to do here. Set up sp, gp?
  28  */
  29 void nmi_dump(void)
  30 {
  31         void cont_nmi_dump(void);
  32 
  33         cont_nmi_dump();
  34 }
  35 
  36 void install_cpu_nmi_handler(int slice)
  37 {
  38         nmi_t *nmi_addr;
  39 
  40         nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
  41         if (nmi_addr->call_addr)
  42                 return;
  43         nmi_addr->magic = NMI_MAGIC;
  44         nmi_addr->call_addr = (void *)nmi_dump;
  45         nmi_addr->call_addr_c =
  46                 (void *)(~((unsigned long)(nmi_addr->call_addr)));
  47         nmi_addr->call_parm = 0;
  48 }
  49 
  50 /*
  51  * Copy the cpu registers which have been saved in the IP27prom format
  52  * into the eframe format for the node under consideration.
  53  */
  54 
  55 void nmi_cpu_eframe_save(nasid_t nasid, int slice)
  56 {
  57         struct reg_struct *nr;
  58         int             i;
  59 
  60         /* Get the pointer to the current cpu's register set. */
  61         nr = (struct reg_struct *)
  62                 (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
  63                 slice * IP27_NMI_KREGS_CPU_SIZE);
  64 
  65         pr_emerg("NMI nasid %d: slice %d\n", nasid, slice);
  66 
  67         /*
  68          * Saved main processor registers
  69          */
  70         for (i = 0; i < 32; ) {
  71                 if ((i % 4) == 0)
  72                         pr_emerg("$%2d   :", i);
  73                 pr_cont(" %016lx", nr->gpr[i]);
  74 
  75                 i++;
  76                 if ((i % 4) == 0)
  77                         pr_cont("\n");
  78         }
  79 
  80         pr_emerg("Hi    : (value lost)\n");
  81         pr_emerg("Lo    : (value lost)\n");
  82 
  83         /*
  84          * Saved cp0 registers
  85          */
  86         pr_emerg("epc   : %016lx %pS\n", nr->epc, (void *)nr->epc);
  87         pr_emerg("%s\n", print_tainted());
  88         pr_emerg("ErrEPC: %016lx %pS\n", nr->error_epc, (void *)nr->error_epc);
  89         pr_emerg("ra    : %016lx %pS\n", nr->gpr[31], (void *)nr->gpr[31]);
  90         pr_emerg("Status: %08lx       ", nr->sr);
  91 
  92         if (nr->sr & ST0_KX)
  93                 pr_cont("KX ");
  94         if (nr->sr & ST0_SX)
  95                 pr_cont("SX ");
  96         if (nr->sr & ST0_UX)
  97                 pr_cont("UX ");
  98 
  99         switch (nr->sr & ST0_KSU) {
 100         case KSU_USER:
 101                 pr_cont("USER ");
 102                 break;
 103         case KSU_SUPERVISOR:
 104                 pr_cont("SUPERVISOR ");
 105                 break;
 106         case KSU_KERNEL:
 107                 pr_cont("KERNEL ");
 108                 break;
 109         default:
 110                 pr_cont("BAD_MODE ");
 111                 break;
 112         }
 113 
 114         if (nr->sr & ST0_ERL)
 115                 pr_cont("ERL ");
 116         if (nr->sr & ST0_EXL)
 117                 pr_cont("EXL ");
 118         if (nr->sr & ST0_IE)
 119                 pr_cont("IE ");
 120         pr_cont("\n");
 121 
 122         pr_emerg("Cause : %08lx\n", nr->cause);
 123         pr_emerg("PrId  : %08x\n", read_c0_prid());
 124         pr_emerg("BadVA : %016lx\n", nr->badva);
 125         pr_emerg("CErr  : %016lx\n", nr->cache_err);
 126         pr_emerg("NMI_SR: %016lx\n", nr->nmi_sr);
 127 
 128         pr_emerg("\n");
 129 }
 130 
 131 void nmi_dump_hub_irq(nasid_t nasid, int slice)
 132 {
 133         u64 mask0, mask1, pend0, pend1;
 134 
 135         if (slice == 0) {                               /* Slice A */
 136                 mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A);
 137                 mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_A);
 138         } else {                                        /* Slice B */
 139                 mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_B);
 140                 mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_B);
 141         }
 142 
 143         pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
 144         pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
 145 
 146         pr_emerg("PI_INT_MASK0: %16llx PI_INT_MASK1: %16llx\n", mask0, mask1);
 147         pr_emerg("PI_INT_PEND0: %16llx PI_INT_PEND1: %16llx\n", pend0, pend1);
 148         pr_emerg("\n\n");
 149 }
 150 
 151 /*
 152  * Copy the cpu registers which have been saved in the IP27prom format
 153  * into the eframe format for the node under consideration.
 154  */
 155 void nmi_node_eframe_save(cnodeid_t  cnode)
 156 {
 157         nasid_t nasid;
 158         int slice;
 159 
 160         /* Make sure that we have a valid node */
 161         if (cnode == CNODEID_NONE)
 162                 return;
 163 
 164         nasid = COMPACT_TO_NASID_NODEID(cnode);
 165         if (nasid == INVALID_NASID)
 166                 return;
 167 
 168         /* Save the registers into eframe for each cpu */
 169         for (slice = 0; slice < NODE_NUM_CPUS(slice); slice++) {
 170                 nmi_cpu_eframe_save(nasid, slice);
 171                 nmi_dump_hub_irq(nasid, slice);
 172         }
 173 }
 174 
 175 /*
 176  * Save the nmi cpu registers for all cpus in the system.
 177  */
 178 void
 179 nmi_eframes_save(void)
 180 {
 181         cnodeid_t       cnode;
 182 
 183         for_each_online_node(cnode)
 184                 nmi_node_eframe_save(cnode);
 185 }
 186 
 187 void
 188 cont_nmi_dump(void)
 189 {
 190 #ifndef REAL_NMI_SIGNAL
 191         static atomic_t nmied_cpus = ATOMIC_INIT(0);
 192 
 193         atomic_inc(&nmied_cpus);
 194 #endif
 195         /*
 196          * Only allow 1 cpu to proceed
 197          */
 198         arch_spin_lock(&nmi_lock);
 199 
 200 #ifdef REAL_NMI_SIGNAL
 201         /*
 202          * Wait up to 15 seconds for the other cpus to respond to the NMI.
 203          * If a cpu has not responded after 10 sec, send it 1 additional NMI.
 204          * This is for 2 reasons:
 205          *      - sometimes a MMSC fail to NMI all cpus.
 206          *      - on 512p SN0 system, the MMSC will only send NMIs to
 207          *        half the cpus. Unfortunately, we don't know which cpus may be
 208          *        NMIed - it depends on how the site chooses to configure.
 209          *
 210          * Note: it has been measure that it takes the MMSC up to 2.3 secs to
 211          * send NMIs to all cpus on a 256p system.
 212          */
 213         for (i=0; i < 1500; i++) {
 214                 for_each_online_node(node)
 215                         if (NODEPDA(node)->dump_count == 0)
 216                                 break;
 217                 if (node == MAX_NUMNODES)
 218                         break;
 219                 if (i == 1000) {
 220                         for_each_online_node(node)
 221                                 if (NODEPDA(node)->dump_count == 0) {
 222                                         cpu = cpumask_first(cpumask_of_node(node));
 223                                         for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
 224                                                 CPUMASK_SETB(nmied_cpus, cpu);
 225                                                 /*
 226                                                  * cputonasid, cputoslice
 227                                                  * needs kernel cpuid
 228                                                  */
 229                                                 SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
 230                                         }
 231                                 }
 232 
 233                 }
 234                 udelay(10000);
 235         }
 236 #else
 237         while (atomic_read(&nmied_cpus) != num_online_cpus());
 238 #endif
 239 
 240         /*
 241          * Save the nmi cpu registers for all cpu in the eframe format.
 242          */
 243         nmi_eframes_save();
 244         LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
 245 }

/* [<][>][^][v][top][bottom][index][help] */