~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/sgi-ip22/ip28-berr.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/mips/sgi-ip22/ip28-berr.c (Version linux-6.12-rc7) and /arch/m68k/sgi-ip22/ip28-berr.c (Version linux-5.15.171)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*                                                
  3  * ip28-berr.c: Bus error handling.               
  4  *                                                
  5  * Copyright (C) 2002, 2003 Ladislav Michl (la    
  6  * Copyright (C) 2005 Peter Fuerst (pf@net.alp    
  7  */                                               
  8                                                   
  9 #include <linux/init.h>                           
 10 #include <linux/kernel.h>                         
 11 #include <linux/mm.h>                             
 12 #include <linux/sched.h>                          
 13 #include <linux/sched/debug.h>                    
 14 #include <linux/sched/signal.h>                   
 15 #include <linux/seq_file.h>                       
 16                                                   
 17 #include <asm/addrspace.h>                        
 18 #include <asm/traps.h>                            
 19 #include <asm/branch.h>                           
 20 #include <asm/irq_regs.h>                         
 21 #include <asm/sgi/mc.h>                           
 22 #include <asm/sgi/hpc3.h>                         
 23 #include <asm/sgi/ioc.h>                          
 24 #include <asm/sgi/ip22.h>                         
 25 #include <asm/r4kcache.h>                         
 26 #include <linux/uaccess.h>                        
 27 #include <asm/bootinfo.h>                         
 28                                                   
 29 static unsigned int count_be_is_fixup;            
 30 static unsigned int count_be_handler;             
 31 static unsigned int count_be_interrupt;           
 32 static int debug_be_interrupt;                    
 33                                                   
 34 static unsigned int cpu_err_stat;       /* Sta    
 35 static unsigned int gio_err_stat;       /* Sta    
 36 static unsigned int cpu_err_addr;       /* Err    
 37 static unsigned int gio_err_addr;       /* Err    
 38 static unsigned int extio_stat;                   
 39 static unsigned int hpc3_berr_stat;     /* Bus    
 40                                                   
 41 struct hpc3_stat {                                
 42         unsigned long addr;                       
 43         unsigned int ctrl;                        
 44         unsigned int cbp;                         
 45         unsigned int ndptr;                       
 46 };                                                
 47                                                   
 48 static struct {                                   
 49         struct hpc3_stat pbdma[8];                
 50         struct hpc3_stat scsi[2];                 
 51         struct hpc3_stat ethrx, ethtx;            
 52 } hpc3;                                           
 53                                                   
 54 static struct {                                   
 55         unsigned long err_addr;                   
 56         struct {                                  
 57                 u32 lo;                           
 58                 u32 hi;                           
 59         } tags[1][2], tagd[4][2], tagi[4][2];     
 60 } cache_tags;                                     
 61                                                   
 62 static inline void save_cache_tags(unsigned bu    
 63 {                                                 
 64         unsigned long addr = CAC_BASE | busadd    
 65         int i;                                    
 66         cache_tags.err_addr = addr;               
 67                                                   
 68         /*                                        
 69          * Starting with a bus-address, save s    
 70          * PA[23..18:7..6]) tags first.           
 71          */                                       
 72         addr &= ~1L;                              
 73 #define tag cache_tags.tags[0]                    
 74         cache_op(Index_Load_Tag_S, addr);         
 75         tag[0].lo = read_c0_taglo();    /* PA[    
 76         tag[0].hi = read_c0_taghi();    /* PA[    
 77         cache_op(Index_Load_Tag_S, addr | 1L);    
 78         tag[1].lo = read_c0_taglo();    /* PA[    
 79         tag[1].hi = read_c0_taghi();    /* PA[    
 80 #undef tag                                        
 81                                                   
 82         /*                                        
 83          * Save all primary data cache (indexe    
 84          * might fit to this bus-address, know    
 85          * Saving all tags and evaluating them    
 86          * than relying on VA[13:12] from the     
 87          * matching primary tags here already.    
 88          */                                       
 89         addr &= (0xffL << 56) | ((1 << 12) - 1    
 90 #define tag cache_tags.tagd[i]                    
 91         for (i = 0; i < 4; ++i, addr += (1 <<     
 92                 cache_op(Index_Load_Tag_D, add    
 93                 tag[0].lo = read_c0_taglo();      
 94                 tag[0].hi = read_c0_taghi();      
 95                 cache_op(Index_Load_Tag_D, add    
 96                 tag[1].lo = read_c0_taglo();      
 97                 tag[1].hi = read_c0_taghi();      
 98         }                                         
 99 #undef tag                                        
100                                                   
101         /*                                        
102          * Save primary instruction cache (ind    
103          * the same way.                          
104          */                                       
105         addr &= (0xffL << 56) | ((1 << 12) - 1    
106 #define tag cache_tags.tagi[i]                    
107         for (i = 0; i < 4; ++i, addr += (1 <<     
108                 cache_op(Index_Load_Tag_I, add    
109                 tag[0].lo = read_c0_taglo();      
110                 tag[0].hi = read_c0_taghi();      
111                 cache_op(Index_Load_Tag_I, add    
112                 tag[1].lo = read_c0_taglo();      
113                 tag[1].hi = read_c0_taghi();      
114         }                                         
115 #undef tag                                        
116 }                                                 
117                                                   
118 #define GIO_ERRMASK     0xff00                    
119 #define CPU_ERRMASK     0x3f00                    
120                                                   
121 static void save_and_clear_buserr(void)           
122 {                                                 
123         int i;                                    
124                                                   
125         /* save status registers */               
126         cpu_err_addr = sgimc->cerr;               
127         cpu_err_stat = sgimc->cstat;              
128         gio_err_addr = sgimc->gerr;               
129         gio_err_stat = sgimc->gstat;              
130         extio_stat = sgioc->extio;                
131         hpc3_berr_stat = hpc3c0->bestat;          
132                                                   
133         hpc3.scsi[0].addr  = (unsigned long)&h    
134         hpc3.scsi[0].ctrl  = hpc3c0->scsi_chan    
135         hpc3.scsi[0].cbp   = hpc3c0->scsi_chan    
136         hpc3.scsi[0].ndptr = hpc3c0->scsi_chan    
137                                                   
138         hpc3.scsi[1].addr  = (unsigned long)&h    
139         hpc3.scsi[1].ctrl  = hpc3c0->scsi_chan    
140         hpc3.scsi[1].cbp   = hpc3c0->scsi_chan    
141         hpc3.scsi[1].ndptr = hpc3c0->scsi_chan    
142                                                   
143         hpc3.ethrx.addr  = (unsigned long)&hpc    
144         hpc3.ethrx.ctrl  = hpc3c0->ethregs.rx_    
145         hpc3.ethrx.cbp   = hpc3c0->ethregs.rx_    
146         hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_    
147                                                   
148         hpc3.ethtx.addr  = (unsigned long)&hpc    
149         hpc3.ethtx.ctrl  = hpc3c0->ethregs.tx_    
150         hpc3.ethtx.cbp   = hpc3c0->ethregs.tx_    
151         hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_    
152                                                   
153         for (i = 0; i < 8; ++i) {                 
154                 /* HPC3_PDMACTRL_ISACT ? */       
155                 hpc3.pbdma[i].addr  = (unsigne    
156                 hpc3.pbdma[i].ctrl  = hpc3c0->    
157                 hpc3.pbdma[i].cbp   = hpc3c0->    
158                 hpc3.pbdma[i].ndptr = hpc3c0->    
159         }                                         
160         i = 0;                                    
161         if (gio_err_stat & CPU_ERRMASK)           
162                 i = gio_err_addr;                 
163         if (cpu_err_stat & CPU_ERRMASK)           
164                 i = cpu_err_addr;                 
165         save_cache_tags(i);                       
166                                                   
167         sgimc->cstat = sgimc->gstat = 0;          
168 }                                                 
169                                                   
170 static void print_cache_tags(void)                
171 {                                                 
172         u32 scb, scw;                             
173         int i;                                    
174                                                   
175         printk(KERN_ERR "Cache tags @ %08x:\n"    
176                                                   
177         /* PA[31:12] shifted to PTag0 (PA[35:1    
178         scw = (cache_tags.err_addr >> 4) & 0x0    
179                                                   
180         scb = cache_tags.err_addr & ((1 << 12)    
181         for (i = 0; i < 4; ++i) { /* for each     
182                 if ((cache_tags.tagd[i][0].lo     
183                     (cache_tags.tagd[i][1].lo     
184                     continue;                     
185                 printk(KERN_ERR                   
186                        "D: 0: %08x %08x, 1: %0    
187                         cache_tags.tagd[i][0].    
188                         cache_tags.tagd[i][1].    
189                         scb | (1 << 12)*i);       
190         }                                         
191         scb = cache_tags.err_addr & ((1 << 12)    
192         for (i = 0; i < 4; ++i) { /* for each     
193                 if ((cache_tags.tagi[i][0].lo     
194                     (cache_tags.tagi[i][1].lo     
195                     continue;                     
196                 printk(KERN_ERR                   
197                        "I: 0: %08x %08x, 1: %0    
198                         cache_tags.tagi[i][0].    
199                         cache_tags.tagi[i][1].    
200                         scb | (1 << 12)*i);       
201         }                                         
202         i = read_c0_config();                     
203         scb = i & (1 << 13) ? 7:6;      /* scb    
204         scw = ((i >> 16) & 7) + 19 - 1; /* scw    
205                                                   
206         i = ((1 << scw) - 1) & ~((1 << scb) -     
207         printk(KERN_ERR "S: 0: %08x %08x, 1: %    
208                 cache_tags.tags[0][0].hi, cach    
209                 cache_tags.tags[0][1].hi, cach    
210                 scw-1, scb, i & (unsigned)cach    
211 }                                                 
212                                                   
213 static inline const char *cause_excode_text(in    
214 {                                                 
215         static const char *txt[32] =              
216         {       "Interrupt",                      
217                 "TLB modification",               
218                 "TLB (load or instruction fetc    
219                 "TLB (store)",                    
220                 "Address error (load or instru    
221                 "Address error (store)",          
222                 "Bus error (instruction fetch)    
223                 "Bus error (data: load or stor    
224                 "Syscall",                        
225                 "Breakpoint",                     
226                 "Reserved instruction",           
227                 "Coprocessor unusable",           
228                 "Arithmetic Overflow",            
229                 "Trap",                           
230                 "14",                             
231                 "Floating-Point",                 
232                 "16", "17", "18", "19", "20",     
233                 "Watch Hi/Lo",                    
234                 "24", "25", "26", "27", "28",     
235         };                                        
236         return txt[(cause & 0x7c) >> 2];          
237 }                                                 
238                                                   
239 static void print_buserr(const struct pt_regs     
240 {                                                 
241         const int field = 2 * sizeof(unsigned     
242         int error = 0;                            
243                                                   
244         if (extio_stat & EXTIO_MC_BUSERR) {       
245                 printk(KERN_ERR "MC Bus Error\    
246                 error |= 1;                       
247         }                                         
248         if (extio_stat & EXTIO_HPC3_BUSERR) {     
249                 printk(KERN_ERR "HPC3 Bus Erro    
250                         hpc3_berr_stat,           
251                         (hpc3_berr_stat & HPC3    
252                                           HPC3    
253                         (hpc3_berr_stat & HPC3    
254                         hpc3_berr_stat & HPC3_    
255                 error |= 2;                       
256         }                                         
257         if (extio_stat & EXTIO_EISA_BUSERR) {     
258                 printk(KERN_ERR "EISA Bus Erro    
259                 error |= 4;                       
260         }                                         
261         if (cpu_err_stat & CPU_ERRMASK) {         
262                 printk(KERN_ERR "CPU error 0x%    
263                         cpu_err_stat,             
264                         cpu_err_stat & SGIMC_C    
265                         cpu_err_stat & SGIMC_C    
266                         cpu_err_stat & SGIMC_C    
267                         cpu_err_stat & SGIMC_C    
268                         cpu_err_stat & SGIMC_C    
269                         cpu_err_stat & SGIMC_C    
270                         cpu_err_addr);            
271                 error |= 8;                       
272         }                                         
273         if (gio_err_stat & GIO_ERRMASK) {         
274                 printk(KERN_ERR "GIO error 0x%    
275                         gio_err_stat,             
276                         gio_err_stat & SGIMC_G    
277                         gio_err_stat & SGIMC_G    
278                         gio_err_stat & SGIMC_G    
279                         gio_err_stat & SGIMC_G    
280                         gio_err_stat & SGIMC_G    
281                         gio_err_stat & SGIMC_G    
282                         gio_err_stat & SGIMC_G    
283                         gio_err_stat & SGIMC_G    
284                         gio_err_addr);            
285                 error |= 16;                      
286         }                                         
287         if (!error)                               
288                 printk(KERN_ERR "MC: Hmm, didn    
289         else {                                    
290                 printk(KERN_ERR "CP0: config %    
291                         "MC: cpuctrl0/1: %08x/    
292                         "MC: cpu/gio_memacc: %    
293                         read_c0_config(),         
294                         sgimc->cpuctrl0, sgimc    
295                         sgimc->cmacc, sgimc->g    
296                         sgimc->mconfig0, sgimc    
297                 print_cache_tags();               
298         }                                         
299         printk(KERN_ALERT "%s, epc == %0*lx, r    
300                cause_excode_text(regs->cp0_cau    
301                field, regs->cp0_epc, field, re    
302 }                                                 
303                                                   
304 static int check_microtlb(u32 hi, u32 lo, unsi    
305 {                                                 
306         /* This is likely rather similar to co    
307                                                   
308         vaddr &= 0x7fffffff; /* Doc. states th    
309                                                   
310         /* If tlb-entry is valid and VPN-high     
311         if ((lo & 2) && (vaddr >> 21) == ((hi<    
312                 u32 ctl = sgimc->dma_ctrl;        
313                 if (ctl & 1) {                    
314                         unsigned int pgsz = (c    
315                         /* PTEIndex is VPN-low    
316                         unsigned long pte = (l    
317                         pte += 8*((vaddr >> pg    
318                         if (page_is_ram(PFN_DO    
319                                 /*                
320                                  * Note: Since    
321                                  * translation    
322                                  * match the T    
323                                  */               
324                                 unsigned long     
325                                                   
326                                 a = (a & 0x3f)    
327                                 a += vaddr & (    
328                                 return cpu_err    
329                         }                         
330                 }                                 
331         }                                         
332         return 0;                                 
333 }                                                 
334                                                   
335 static int check_vdma_memaddr(void)               
336 {                                                 
337         if (cpu_err_stat & CPU_ERRMASK) {         
338                 u32 a = sgimc->maddronly;         
339                                                   
340                 if (!(sgimc->dma_ctrl & 0x100)    
341                         return cpu_err_addr ==    
342                                                   
343                 if (check_microtlb(sgimc->dtlb    
344                     check_microtlb(sgimc->dtlb    
345                     check_microtlb(sgimc->dtlb    
346                     check_microtlb(sgimc->dtlb    
347                         return 1;                 
348         }                                         
349         return 0;                                 
350 }                                                 
351                                                   
352 static int check_vdma_gioaddr(void)               
353 {                                                 
354         if (gio_err_stat & GIO_ERRMASK) {         
355                 u32 a = sgimc->gio_dma_trans;     
356                 a = (sgimc->gmaddronly & ~a) |    
357                 return gio_err_addr == a;         
358         }                                         
359         return 0;                                 
360 }                                                 
361                                                   
362 /*                                                
363  * MC sends an interrupt whenever bus or parit    
364  * if the error happened during a CPU read, it    
365  * pin on the R4K. Code in bus error handler s    
366  * and then clear the interrupt when this happ    
367  */                                               
368                                                   
369 static int ip28_be_interrupt(const struct pt_r    
370 {                                                 
371         int i;                                    
372                                                   
373         save_and_clear_buserr();                  
374         /*                                        
375          * Try to find out, whether we got her    
376          * load/store operation.  If so, it's     
377          */                                       
378         /* Any cause other than "Interrupt" (E    
379         if (regs->cp0_cause & CAUSEF_EXCCODE)     
380                 goto mips_be_fatal;               
381                                                   
382         /* Any cause other than "Bus error int    
383         if ((regs->cp0_cause & CAUSEF_IP6) !=     
384                 goto mips_be_fatal;               
385                                                   
386         if (extio_stat & (EXTIO_HPC3_BUSERR |     
387                 goto mips_be_fatal;               
388                                                   
389         /* Any state other than "Memory bus er    
390         if (cpu_err_stat & CPU_ERRMASK & ~SGIM    
391                 goto mips_be_fatal;               
392                                                   
393         /* GIO errors other than timeouts are     
394         if (gio_err_stat & GIO_ERRMASK & ~SGIM    
395                 goto mips_be_fatal;               
396                                                   
397         /*                                        
398          * Now we have an asynchronous bus err    
399          * Need to search all DMA descriptors     
400          */                                       
401         for (i = 0; i < sizeof(hpc3)/sizeof(st    
402                 struct hpc3_stat *hp = (struct    
403                 if ((cpu_err_stat & CPU_ERRMAS    
404                     (cpu_err_addr == hp->ndptr    
405                         break;                    
406                 if ((gio_err_stat & GIO_ERRMAS    
407                     (gio_err_addr == hp->ndptr    
408                         break;                    
409         }                                         
410         if (i < sizeof(hpc3)/sizeof(struct hpc    
411                 struct hpc3_stat *hp = (struct    
412                 printk(KERN_ERR "at DMA addres    
413                        " ctl %08x, ndp %08x, c    
414                        CPHYSADDR(hp->addr), hp    
415                 goto mips_be_fatal;               
416         }                                         
417         /* Check MC's virtual DMA stuff. */       
418         if (check_vdma_memaddr()) {               
419                 printk(KERN_ERR "at GIO DMA: m    
420                         sgimc->maddronly);        
421                 goto mips_be_fatal;               
422         }                                         
423         if (check_vdma_gioaddr()) {               
424                 printk(KERN_ERR "at GIO DMA: g    
425                         sgimc->gmaddronly);       
426                 goto mips_be_fatal;               
427         }                                         
428         /* A speculative bus error... */          
429         if (debug_be_interrupt) {                 
430                 print_buserr(regs);               
431                 printk(KERN_ERR "discarded!\n"    
432         }                                         
433         return MIPS_BE_DISCARD;                   
434                                                   
435 mips_be_fatal:                                    
436         print_buserr(regs);                       
437         return MIPS_BE_FATAL;                     
438 }                                                 
439                                                   
440 void ip22_be_interrupt(int irq)                   
441 {                                                 
442         struct pt_regs *regs = get_irq_regs();    
443                                                   
444         count_be_interrupt++;                     
445                                                   
446         if (ip28_be_interrupt(regs) != MIPS_BE    
447                 /* Assume it would be too dang    
448                 die_if_kernel("Oops", regs);      
449                 force_sig(SIGBUS);                
450         } else if (debug_be_interrupt)            
451                 show_regs(regs);                  
452 }                                                 
453                                                   
454 static int ip28_be_handler(struct pt_regs *reg    
455 {                                                 
456         /*                                        
457          * We arrive here only in the unusual     
458          * i.e. by a bus error exception witho    
459          */                                       
460         if (is_fixup) {                           
461                 count_be_is_fixup++;              
462                 save_and_clear_buserr();          
463                 return MIPS_BE_FIXUP;             
464         }                                         
465         count_be_handler++;                       
466         return ip28_be_interrupt(regs);           
467 }                                                 
468                                                   
469 void __init ip22_be_init(void)                    
470 {                                                 
471         mips_set_be_handler(ip28_be_handler);     
472 }                                                 
473                                                   
474 int ip28_show_be_info(struct seq_file *m)         
475 {                                                 
476         seq_printf(m, "IP28 be fixups\t\t: %u\    
477         seq_printf(m, "IP28 be interrupts\t: %    
478         seq_printf(m, "IP28 be handler\t\t: %u    
479                                                   
480         return 0;                                 
481 }                                                 
482                                                   
483 static int __init debug_be_setup(char *str)       
484 {                                                 
485         debug_be_interrupt++;                     
486         return 1;                                 
487 }                                                 
488 __setup("ip28_debug_be", debug_be_setup);         
489                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php