]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/iq80310/v2_0/src/diag/interrupts.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / xscale / iq80310 / v2_0 / src / diag / interrupts.c
1 //=============================================================================
2 //
3 //      interrupts.c - Cyclone Diagnostics
4 //
5 //=============================================================================
6 //####ECOSGPLCOPYRIGHTBEGIN####
7 // -------------------------------------------
8 // This file is part of eCos, the Embedded Configurable Operating System.
9 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
10 //
11 // eCos is free software; you can redistribute it and/or modify it under
12 // the terms of the GNU General Public License as published by the Free
13 // Software Foundation; either version 2 or (at your option) any later version.
14 //
15 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
16 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 // for more details.
19 //
20 // You should have received a copy of the GNU General Public License along
21 // with eCos; if not, write to the Free Software Foundation, Inc.,
22 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 //
24 // As a special exception, if other files instantiate templates or use macros
25 // or inline functions from this file, or you compile this file and link it
26 // with other works to produce a work based on this file, this file does not
27 // by itself cause the resulting work to be covered by the GNU General Public
28 // License. However the source code for this file must still be made available
29 // in accordance with section (3) of the GNU General Public License.
30 //
31 // This exception does not invalidate any other reasons why a work based on
32 // this file might be covered by the GNU General Public License.
33 //
34 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
35 // at http://sources.redhat.com/ecos/ecos-license/
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //=============================================================================
39 //#####DESCRIPTIONBEGIN####
40 //
41 // Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
42 // Contributors:
43 // Date:        2001-01-25
44 // Purpose:     
45 // Description: 
46 //
47 //####DESCRIPTIONEND####
48 //
49 //===========================================================================*/
50
51 /******************************************************************************/
52 /* interrupts.c - Interrupt dispatcher routines for IQ80310 Board                         */
53 /*                                                                                                                                                        */
54 /* modification history                                                                                                           */
55 /* --------------------                                                                                                           */
56 /* 07sep00, ejb, Written for IQ80310 Cygmon diagnostics                                           */
57 /* 11oct00, ejb, Switched FIQ and IRQ interrupt handlers                                          */
58 /* 18dec00  snc and jwf                                                       */
59 /* 02feb01  jwf for snc                                                       */
60 /******************************************************************************/
61
62 #include "iq80310.h"
63 #include "pci_bios.h"
64 #include "7_segment_displays.h"
65
66 extern int(*board_fiq_handler)(void);
67 extern int(*board_irq_handler)(void);
68 extern long _cspr_enable_fiq_int(void);
69 extern long _cspr_enable_irq_int(void);
70 extern long _read_cpsr(void);
71 extern long _scrub_ecc(unsigned);
72 extern void _flushICache(void);
73
74
75 #define AND_WORD(addr,val)   *addr = *addr & val
76
77
78 void error_print(char *fmt, int arg0, int arg1, int arg2, int arg3);
79
80
81 extern int nmi_verbose; /* for NMI, only print NMI info if this is TRUE */
82 extern int pci_config_cycle; /* don't handle NMI if in a config cycle */
83 extern int pci_config_error;
84
85 typedef struct
86 {
87         INTFUNCPTR      handler;
88         int             arg;
89         int             bus;
90         int             device;
91 } INT_HANDLER;
92
93 extern UINT     secondary_busno;
94 extern UINT     primary_busno;
95
96 extern STATUS pci_to_xint(int device, int intpin, int *xint);
97 extern int isHost(void);
98 extern int off_ppci_bus (int busno);
99
100 #define MAX_SPURIOUS_CNT        5
101 #define NUM_PCI_XINTS           4               /* SINTA - SINTD */
102 #define MAX_PCI_HANDLERS        8               /* maximum handlers per PCI Xint */
103
104 /* 02/02/01 jwf */
105 int ecc_error_reported = FALSE;
106
107 static int isr_xint0_spurious = 0;
108 static int isr_xint1_spurious = 0;
109 static int isr_xint2_spurious = 0;
110 static int isr_xint3_spurious = 0;
111
112 /* Table where the interrupt handler addresses are stored. */
113 INT_HANDLER pci_int_handlers[4][MAX_PCI_HANDLERS];
114
115 /* Other User Interrupt Service Routines */
116
117 void (*usr_timer_isr)(int) = NULL;
118 int usr_timer_arg = 0;
119 void (*usr_enet_isr)(int) = NULL;
120 int usr_enet_arg = 0;
121 void (*usr_uart1_isr)(int) = NULL;
122 int usr_uart1_arg = 0;
123 void (*usr_uart2_isr)(int) = NULL;
124 int usr_uart2_arg = 0;
125 void (*usr_dma0_isr)(int) = NULL;
126 int usr_dma0_arg = 0;
127 void (*usr_dma1_isr)(int) = NULL;
128 int usr_dma1_arg = 0;
129 void (*usr_dma2_isr)(int) = NULL;
130 int usr_dma2_arg = 0;
131 void (*usr_pm_isr)(int) = NULL;
132 int usr_pm_arg = 0;
133 void (*usr_aa_isr)(int) = NULL;
134 int usr_aa_arg = 0;
135 void (*usr_i2c_isr)(int) = NULL;
136 int usr_i2c_arg = 0;
137 void (*usr_mu_isr)(int) = NULL;
138 int usr_mu_arg = 0;
139 void (*usr_patu_isr)(int) = NULL;
140 int usr_patu_arg = 0;
141
142 int ecc_int_handler(void);
143
144
145
146 /*********************************
147 * PCI interrupt wrappers 
148 */
149 int sinta_handler(void)
150 {
151     int x, serviced = 0;
152         /* cycle through connected interrupt handlers to determine which caused int */
153         for (x = 0; x < MAX_PCI_HANDLERS; x++) 
154         {
155                 if (pci_int_handlers[0][x].handler != NULL)     /* Is a routine installed */
156                         if ((*pci_int_handlers[0][x].handler)(pci_int_handlers[0][x].arg) == 1) 
157                         {
158                                 serviced = 1;
159                                 break;
160                         }
161         }
162         if (serviced == 0)
163         {
164                 isr_xint0_spurious++;
165
166                 if (isr_xint0_spurious > MAX_SPURIOUS_CNT)
167                         ; 
168         }
169         else
170                 isr_xint0_spurious = 0;
171
172         return (serviced);
173
174 }
175
176 int sintb_handler(void)
177 {
178     int x, serviced = 0;
179         
180         /* cycle through connected interrupt handlers to determine which caused int */
181         for (x = 0; x < MAX_PCI_HANDLERS; x++) 
182         {
183                 if (pci_int_handlers[1][x].handler != NULL)     /* Is a routine installed */
184                         if ((*pci_int_handlers[1][x].handler)(pci_int_handlers[1][x].arg) == 1) 
185                         {
186                                 serviced = 1;
187                                 break;
188                         }
189         }
190         if (serviced == 0)
191         {
192                 isr_xint1_spurious++;
193
194                 if (isr_xint1_spurious > MAX_SPURIOUS_CNT)
195                         ;
196         }
197         else
198                 isr_xint1_spurious = 0;
199
200         return (serviced);
201
202 }
203
204 int sintc_handler(void)
205 {
206
207     int x, serviced = 0;
208
209         /* cycle through connected interrupt handlers to determine which caused int */
210         for (x = 0; x < MAX_PCI_HANDLERS; x++) 
211         {
212                 if (pci_int_handlers[2][x].handler != NULL)     /* Is a routine installed */
213                         if ((*pci_int_handlers[2][x].handler)(pci_int_handlers[2][x].arg) == 1) 
214                         {
215                                 serviced = 1;
216                                 break;
217                         }
218         }
219         if (serviced == 0)
220         {
221                 isr_xint2_spurious++;
222
223                 if (isr_xint2_spurious > MAX_SPURIOUS_CNT)
224                         ;
225         }
226         else
227                 isr_xint2_spurious = 0;
228
229         return (serviced);
230
231 }
232
233 int sintd_handler(void)
234 {
235
236     int x, serviced = 0;
237
238         /* cycle through connected interrupt handlers to determine which caused int */
239         for (x = 0; x < MAX_PCI_HANDLERS; x++) 
240         {
241                 if (pci_int_handlers[3][x].handler != NULL)     /* Is a routine installed */
242                         if ((*pci_int_handlers[3][x].handler)(pci_int_handlers[3][x].arg) == 1) 
243                         {
244                                 serviced = 1;
245                                 break;
246                         }
247         }
248         if (serviced == 0)
249         {
250                 isr_xint3_spurious++;
251
252                 if (isr_xint3_spurious > MAX_SPURIOUS_CNT)
253                         ;
254         }
255         else
256                 isr_xint3_spurious = 0;
257
258         return (serviced);
259
260
261 }
262
263
264 /******************************************************************************
265 *
266 * Installs an interrupt handler in the PCI dispatch table, to be called
267 * by the appropriate PCI isr (above) when an interrupt occurs.
268 *
269 * Note: the intline parameter refers to which PCI interrupt INT A - INT D
270 *
271 *       device identifies the PCI device number
272 *
273 * Note: isrs connected with this function must return 1 if an interrupt is 
274 *       serviced in order to support the PCI interrupt sharing mechanism
275 *                                                   
276 */
277 STATUS pci_isr_connect (int intline, int bus, int device, int (*handler)(int), int arg)
278 {
279         int which_xint;
280         int handler_index;
281
282         /* check to see if we are attempting to connect to a PPCI interrupt and we are not
283            a host card */
284         if ((isHost() == FALSE) && (off_ppci_bus(bus) == TRUE))
285                 return (ERROR);
286
287         if ((intline < INTA) || (intline > INTD))
288                 return (ERROR);
289
290     (void)pci_to_xint(device, intline, &which_xint);
291
292         for (handler_index = 0; handler_index < MAX_PCI_HANDLERS; handler_index++)
293         {
294                 if (pci_int_handlers[which_xint][handler_index].handler == NULL)
295                 {
296                         pci_int_handlers[which_xint][handler_index].handler = handler;
297                         pci_int_handlers[which_xint][handler_index].arg         = arg;
298                         pci_int_handlers[which_xint][handler_index].bus         = bus;
299                         pci_int_handlers[which_xint][handler_index].device      = device;
300                         break;
301                 }
302         }
303
304         /* if there is no more room in the table return an error */
305         if (handler_index == MAX_PCI_HANDLERS)
306                 return (ERROR);
307
308     return (OK);
309 }
310
311
312 /******************************************************************************
313 *
314 * Uninstalls an interrupt handler in the PCI dispatch table
315 *
316 * Note: the intline parameter refers to which PCI interrupt INTA - INTD
317 *
318 *       the device parameter refers to which SPCI device number is sourcing the
319 *       interrupt
320 *
321 */
322 STATUS pci_isr_disconnect (int intline, int bus, int device)
323 {
324         int which_xint;
325         int handler_index;
326
327         /* check to see if we are attempting to disconnect a PPCI interrupt and we are not
328            a host card */
329         if ((isHost() == FALSE) && (off_ppci_bus(bus) == TRUE))
330                 return (ERROR);
331
332         if ((intline < INTA) || (intline > INTD))
333                 return (ERROR);
334
335     (void)pci_to_xint(device, intline, &which_xint);
336
337         for (handler_index = 0; handler_index < MAX_PCI_HANDLERS; handler_index++)
338         {
339                 if ((pci_int_handlers[which_xint][handler_index].bus == bus) &&
340                         (pci_int_handlers[which_xint][handler_index].device == device))
341                 {
342                         pci_int_handlers[which_xint][handler_index].handler = NULL;
343                         pci_int_handlers[which_xint][handler_index].arg         = (int)NULL;
344                         pci_int_handlers[which_xint][handler_index].bus         = (int)NULL;
345                         pci_int_handlers[which_xint][handler_index].device      = (int)NULL;
346                 }
347         }
348
349         /* if the handler was not found in the table return an error */
350         if (handler_index == MAX_PCI_HANDLERS)
351                 return (ERROR);
352
353     return (OK);
354 }
355
356
357 /**********************************************************************************
358 * iq80310_irq_handler - Interrupt dispatcher for IQ80310 IRQ Interrupts
359 *
360 * This function determines the source of the IRQ Interrupt, and calls the 
361 * corresponding interrupt service routine.  If multiple sources are interrupting
362 * the dispatcher will call all interrupt handles.  Users must clear the interrupt
363 * within the interrupt service routine before exiting.
364 *
365 * IRQ Interrupts are multiplexed from SPCI INTA - INTD, External Device Interrupts,
366 * and XINT6 and XINT7 Internal device interrupts.
367 */
368 int iq80310_irq_handler(void)
369 {
370 UINT8* int_status_reg;
371 UINT8  int_status;      
372 int num_sources = 0;
373
374
375 /* 12/18/00 jwf */
376 unsigned char ri_state;
377 unsigned char board_rev;
378 unsigned char sint_status;                                              /* holds interrupt status for SINTA-SINTC */
379         ri_state = *( unsigned char * ) 0xfe810006;     /* access uart u2 msr reg at addr fe810006 */
380         ri_state &= RI_MASK;
381         if(ri_state == RI_MASK)                                         /* RI# pin on UART2 is grounded */
382         {
383                 board_rev = *BOARD_REV_REG_ADDR;                /* read Board Revision register */
384                 board_rev &= BOARD_REV_MASK;                    /* isolate LSN */
385                 if (board_rev >= BOARD_REV_E)                   /* Board Rev is at E or higher */
386                 {
387                         sint_status = *SINT_REG_ADDR;           /* read current secondary pci interrupt status */
388                         sint_status &= SINT_MASK;                       /* isolate SINTA, SINTB, and SINTC */
389                         switch(sint_status)
390                         {
391                                 case SINTA_INT:
392                                         num_sources += sinta_handler(); /* IRQ0 = SINTA? */
393 /*                                      printf(" sinta status = %#x\n", sint_status); */
394                                         break;
395                                 case SINTB_INT:
396                                         num_sources += sintb_handler(); /* IRQ1 = SINTB? */
397 /*                                      printf(" sintb status = %#x\n", sint_status); */
398                                         break;                  
399                                 case SINTC_INT:
400                                         num_sources += sintc_handler(); /* IRQ2 = SINTC? */
401 /*                                      printf(" sintc status = %#x\n", sint_status); */
402                                         break;
403                                 default:
404 /*                                      printf(" sint? status = %#x\n", sint_status); */
405                                         break;                                          /* probably should test for more conditions: 011b, 101b, 110b, 111b */
406                         }
407                 }
408         }
409         else                                                                            /* RI# pin on UART2 is pulled up to 3.3V. Cannot read board revision register, not implemented */
410         {
411                 num_sources += sinta_handler();                 /* IRQ0 = SINTA? */
412                 num_sources += sintb_handler();                 /* IRQ1 = SINTB? */
413                 num_sources += sintc_handler();                 /* IRQ2 = SINTC? */
414         }
415
416
417         /* 12/18/00 jwf */
418         /* Original code */
419         /* No S_INTA - S_INTC status register, call handlers always */
420         /* This may change in next revision of board */
421         /*num_sources += sinta_handler();*/     /* IRQ0 = SINTA? */
422         /*num_sources += sintb_handler();*/     /* IRQ1 = SINTB? */
423         /*num_sources += sintc_handler();*/     /* IRQ2 = SINTC? */
424
425
426         /* Read IRQ3 Status Register, and if any of the multiple sources are 
427            interrupting, call corresponding handler */
428         int_status_reg = (UINT8 *)X3ISR_ADDR;
429         int_status = *int_status_reg;
430         { 
431                 if (int_status & TIMER_INT) /* timer interrupt? */
432                 {
433                         /* call user ISR, if connected */
434                         if (usr_timer_isr != NULL)
435                                 (*usr_timer_isr)(usr_timer_arg);
436                         else
437                                 printf ("\nUnhandled Timer Interrupt Detected!\n");
438                         
439                         num_sources++;
440                 }
441
442                 if (int_status & ENET_INT)      /* ethernet interrupt? */
443                 {
444                         /* call user ISR, if connected */
445                         if (usr_enet_isr != NULL)
446                                 (*usr_enet_isr)(usr_enet_arg);
447                         else
448                                 printf ("\nUnhandled Ethernet Interrupt Detected!\n");
449
450                         num_sources++;
451                 }
452
453                 if (int_status & UART1_INT) /* uart1 interrupt? */
454                 {
455                         /* call user ISR, if connected */
456                         if (usr_uart1_isr != NULL)
457                                 (*usr_uart1_isr)(usr_uart1_arg);
458                         else
459                                 printf ("\nUnhandled UART1 Interrupt Detected!\n");
460
461                         num_sources++;
462                 }
463
464                 if (int_status & UART2_INT) /* uart2 interrupt? */
465                 {
466                         /* call user ISR, if connected */
467                         if (usr_uart2_isr != NULL)
468                                 (*usr_uart2_isr)(usr_uart2_arg);
469                         else
470                                 printf ("\nUnhandled UART2 Interrupt Detected!\n");
471                         num_sources++;
472                 }
473
474                 if (int_status & SINTD_INT)     /* SPCI_INTD? */
475                 {
476                         num_sources += sintd_handler();
477                 }
478         }
479
480
481         /* Read XINT6 Status Register, and if any of the multiple sources are 
482            interrupting, call corresponding handler */
483         int_status_reg = (UINT8 *)X6ISR_ADDR;
484         int_status = *int_status_reg;
485         {
486                 if (int_status & DMA0_INT) /* dma0 interrupt? */
487                 {
488                         if (usr_dma0_isr != NULL)
489                                 (*usr_dma0_isr)(usr_dma0_arg);
490                         else
491                                 printf ("\nUnhandled DMA Channel 0 Interrupt Detected!\n");
492                         num_sources++;
493                 }
494
495                 if (int_status & DMA1_INT) /* dma1 interrupt? */
496                 {
497                         if (usr_dma1_isr != NULL)
498                                 (*usr_dma1_isr)(usr_dma1_arg);
499                         else
500                                 printf ("\nUnhandled DMA Channel 1 Interrupt Detected!\n");
501                         num_sources++;
502                 }
503
504                 if (int_status & DMA2_INT) /* dma2 interrupt? */
505                 {
506                         if (usr_dma2_isr != NULL)
507                                 (*usr_dma2_isr)(usr_dma2_arg);
508                         else
509                                 printf ("\nUnhandled DMA Channel 2 Interrupt Detected!\n");
510                         num_sources++;
511                 }
512
513                 if (int_status & PM_INT) /* performance monitoring interrupt? */
514                 {
515                         if (usr_pm_isr != NULL)
516                                 (*usr_pm_isr)(usr_pm_arg);
517                         else
518                                 printf ("\nUnhandled Performance Monitoring Unit Interrupt Detected!\n");
519                         num_sources++;
520                 }
521                 
522                 if (int_status & AA_INT) /* application accelerator interrupt? */
523                 {
524                         if (usr_aa_isr != NULL)
525                                 (*usr_aa_isr)(usr_aa_arg);
526                         else
527                                 printf ("\nUnhandled Application Accelerating Unit Interrupt Detected!\n");
528                         num_sources++;
529                 }
530         }
531
532
533         /* Read XINT7 Status Register, and if any of the multiple sources are 
534            interrupting, call corresponding handler */
535         int_status_reg = (UINT8 *)X7ISR_ADDR;
536         int_status = *int_status_reg;
537         {
538                 if (int_status & I2C_INT) /* i2c interrupt? */
539                 {
540                         if (usr_i2c_isr != NULL)
541                                 (*usr_i2c_isr)(usr_i2c_arg);
542                         else
543                                 printf ("\nUnhandled I2C Unit Interrupt Detected!\n");
544                         num_sources++;
545                 }
546
547                 if (int_status & MU_INT) /* messaging unit interrupt? */
548                 {       
549                         if (usr_mu_isr != NULL)
550                                 (*usr_mu_isr)(usr_mu_arg);
551                         else
552                                 printf ("\nUnhandled Messaging Unit Interrupt Detected!\n");
553                         num_sources++;
554                 }
555
556                 if (int_status & PATU_INT) /* primary ATU / BIST start interrupt? */
557                 {
558                         if (usr_patu_isr != NULL)
559                                 (*usr_patu_isr)(usr_patu_arg);
560                         else
561                                 printf ("\nUnhandled Primary ATU Interrupt Detected!\n");
562                         num_sources++;
563                 }
564         }
565
566         /* return the number of interrupt sources found */
567         return (num_sources);
568 }
569
570
571
572
573
574 /****************************************************************
575 *  nmi_ecc_isr - ECC NMI Interrupt Handler
576 *
577 *  This module handles the NMI caused by an ECC error.
578 *  For a Single-bit error it does a read-nodify-write
579 *  to correct the error in memory. For a multi-bit or
580 *  nibble error it does absolutely nothing.
581 */
582 void nmi_ecc_isr(void)
583 {
584         UINT32 eccr_register;
585         UINT32* reg32;
586
587         /* Read current state of ECC register */
588         eccr_register = *(UINT32 *)ECCR_ADDR;
589
590         /* Turn off all ecc error reporting */
591         *(UINT32 *)ECCR_ADDR = 0x4;
592
593         /* Check for ECC Error 0 */
594         if(*(UINT32 *)MCISR_ADDR & 0x1)
595         {
596         reg32 = (UINT32*)ELOG0_ADDR;
597                 error_print("ELOG0 = 0x%X\n",*reg32,0,0,0);
598                 
599                 reg32 = (UINT32*)ECAR0_ADDR;
600                 error_print("ECC Error Detected at Address 0x%X\n",*reg32,0,0,0);               
601         
602                 /* Check for single-bit error */
603         if(!(*(UINT32 *)ELOG0_ADDR & 0x00000100))
604         {
605                         /* call ECC restoration function */
606                         _scrub_ecc(*reg32);
607
608                         /* Clear the MCISR */
609                     *(UINT32 *)MCISR_ADDR = 0x1;
610         }
611         else
612             error_print("Multi-bit or nibble error\n",0,0,0,0);
613         }
614
615         /* Check for ECC Error 1 */
616         if(*(UINT32 *)MCISR_ADDR & 0x2)
617         {
618                 reg32 = (UINT32*)ELOG1_ADDR;
619                 error_print("ELOG0 = 0x%X\n",*reg32,0,0,0);
620                 
621                 reg32 = (UINT32*)ECAR1_ADDR;
622                 error_print("ECC Error Detected at Address 0x%X\n",*reg32,0,0,0);       
623         
624                 /* Check for single-bit error */
625         if(!(*(UINT32 *)ELOG1_ADDR & 0x00000100))
626         {
627                         /* call ECC restoration function */
628                         _scrub_ecc(*reg32);
629  
630                         /* Clear the MCISR */
631                         *(UINT32 *)MCISR_ADDR = 0x2;
632        }
633        else
634             error_print("Multi-bit or nibble error\n",0,0,0,0);
635         }
636
637         /* Check for ECC Error N */
638         if(*(UINT32 *)MCISR_ADDR & 0x4)
639         {
640                 /* Clear the MCISR */
641                 *(UINT32 *)MCISR_ADDR = 0x4;
642                 error_print("Uncorrectable error during RMW\n",0,0,0,0);
643         }
644     
645         /* Turn on  ecc error reporting */
646         *(UINT32 *)ECCR_ADDR = eccr_register;
647 }
648
649
650
651
652 /******************************************************************************
653 * iq80310_fiq_handler - Interrupt dispatcher for IQ80310 FIQ Interrupts
654 *
655 *
656 */
657 int iq80310_fiq_handler(void)
658 {
659         
660 unsigned long nmi_status = *(volatile unsigned long *)NISR_ADDR;
661 unsigned long status;
662 int srcs_found = 0;
663
664         if (nmi_status & MCU_ERROR)
665         {
666                 status = *(volatile unsigned long *)MCISR_ADDR;
667                 *MSB_DISPLAY_REG = LETTER_E;
668                 if (status & 0x001)
669                         *LSB_DISPLAY_REG = ONE;
670                 if (status & 0x002)
671                         *LSB_DISPLAY_REG = TWO;
672                 if (status & 0x004)
673                         *LSB_DISPLAY_REG = FOUR;
674                 srcs_found++;
675 #if 0
676                 error_print ("**** 80312 Memory Controller Error ****\n",0,0,0,0);
677                 if (status & 0x001) error_print ("One ECC Error Detected and Recorded in ELOG0\n",0,0,0,0);
678                 if (status & 0x002) error_print ("Second ECC Error Detected and Recorded in ELOG1\n",0,0,0,0);
679                 if (status & 0x004) error_print ("Multiple ECC Errors Detected\n",0,0,0,0);
680 #endif
681
682                 /* call ecc interrupt handler */
683                 nmi_ecc_isr(); 
684
685                 /* clear the interrupt condition*/
686                 AND_WORD((volatile unsigned long *)MCISR_ADDR, 0x07);
687
688 /* 02/02/01 jwf */
689                 ecc_error_reported = TRUE;
690
691         }
692
693
694         if (nmi_status & PATU_ERROR)
695         {
696                 srcs_found++;
697                 error_print ("**** Primary ATU Error ****\n",0,0,0,0);
698                 status = *(volatile unsigned long *)PATUISR_ADDR;
699                 if (status & 0x001) error_print ("PPCI Master Parity Error\n",0,0,0,0);
700                 if (status & 0x002) error_print ("PPCI Target Abort (target)\n",0,0,0,0);
701                 if (status & 0x004) error_print ("PPCI Target Abort (master)\n",0,0,0,0);
702                 if (status & 0x008) error_print ("PPCI Master Abort\n",0,0,0,0);
703                 if (status & 0x010) error_print ("Primary P_SERR# Detected\n",0,0,0,0);
704                 if (status & 0x080) error_print ("Internal Bus Master Abort\n",0,0,0,0);
705                 if (status & 0x100) error_print ("PATU BIST Interrupt\n",0,0,0,0);
706                 if (status & 0x200) error_print ("PPCI Parity Error Detected\n",0,0,0,0);
707                 if (status & 0x400) error_print ("Primary P_SERR# Asserted\n",0,0,0,0);
708
709                 /* clear the interrupt conditions */
710                 AND_WORD((volatile unsigned long *)PATUISR_ADDR, 0x79f);
711                 CLEAR_PATU_STATUS();
712
713                 /* tell the config cleanup code about error */
714                 if (pci_config_cycle == 1) 
715                         pci_config_error = TRUE;
716         }
717
718         if (nmi_status & SATU_ERROR)
719         {
720                 srcs_found++;
721                 error_print ("**** Secondary ATU Error ****\n",0,0,0,0);
722                 status = *(volatile unsigned long *)SATUISR_ADDR;
723                 if (status & 0x001) error_print ("SPCI Master Parity Error\n",0,0,0,0);
724                 if (status & 0x002) error_print ("SPCI Target Abort (target)\n",0,0,0,0);
725                 if (status & 0x004) error_print ("SPCI Target Abort (master)\n",0,0,0,0);
726                 if (status & 0x008) error_print ("SPCI Master Abort\n",0,0,0,0);
727                 if (status & 0x010) error_print ("Secondary P_SERR# Detected\n",0,0,0,0);
728                 if (status & 0x080) error_print ("Internal Bus Master Abort\n",0,0,0,0);
729                 if (status & 0x200) error_print ("SPCI Parity Error Detected\n",0,0,0,0);
730                 if (status & 0x400) error_print ("Secondary S_SERR# Asserted\n",0,0,0,0);
731
732                 /* clear the interrupt conditions */
733                 AND_WORD((volatile unsigned long *)SATUISR_ADDR, 0x69f);
734                 CLEAR_SATU_STATUS();
735
736                 /* tell the config cleanup code about error */
737                 if (pci_config_cycle == 1) 
738                         pci_config_error = TRUE;
739         }
740
741         if (nmi_status & PBRIDGE_ERROR)
742         {
743                 srcs_found++;
744                 error_print ("**** Primary Bridge Error ****\n",0,0,0,0);
745                 status = *(volatile unsigned long *)PBISR_ADDR;
746                 if (status & 0x001) error_print ("PPCI Master Parity Error\n",0,0,0,0);
747                 if (status & 0x002) error_print ("PPCI Target Abort (Target)\n",0,0,0,0);
748                 if (status & 0x004) error_print ("PPCI Target Abort (Master)\n",0,0,0,0);
749                 if (status & 0x008) error_print ("PPCI Master Abort\n",0,0,0,0);
750                 if (status & 0x010) error_print ("Primary P_SERR# Asserted\n",0,0,0,0);
751                 if (status & 0x020) error_print ("PPCI Parity Error Detected\n",0,0,0,0);
752
753                 /* clear the interrupt condition */
754                 AND_WORD((volatile unsigned long *)PBISR_ADDR, 0x3f);
755                 CLEAR_PBRIDGE_STATUS();
756
757                 /* tell the config cleanup code about error */
758                 if (pci_config_cycle == 1) 
759                         pci_config_error = TRUE;
760         }
761
762         if (nmi_status & SBRIDGE_ERROR)
763         {
764                 srcs_found++;
765
766                 /* don't print configuration secondary bridge errors */
767
768                 /* clear the interrupt condition */
769                 AND_WORD((volatile unsigned long *)SBISR_ADDR, 0x7f);
770                 CLEAR_SBRIDGE_STATUS();
771
772                 /* tell the config cleanup code about error */
773                 if (pci_config_cycle == 1) 
774                         pci_config_error = TRUE;
775         }
776
777         if (nmi_status & DMA_0_ERROR)
778         {
779                 srcs_found++;
780                 error_print ("**** DMA Channel 0 Error ****\n",0,0,0,0);
781                 status = *(volatile unsigned long *)CSR0_ADDR;
782                 if (status & 0x001) error_print ("DMA Channel 0 PCI Parity Error\n",0,0,0,0);
783                 if (status & 0x004) error_print ("DMA Channel 0 PCI Target Abort\n",0,0,0,0);
784                 if (status & 0x008) error_print ("DMA Channel 0 PCI Master Abort\n",0,0,0,0);
785                 if (status & 0x020) error_print ("Internal PCI Master Abort\n",0,0,0,0);    
786                 /* clear the interrupt condition */
787                 AND_WORD((volatile unsigned long *)CSR0_ADDR, 0x2D);
788         }
789
790         if (nmi_status & DMA_1_ERROR)
791         {
792                 srcs_found++;
793                 error_print ("**** DMA Channel 1 Error ****\n",0,0,0,0);
794                 status = *(volatile unsigned long *)CSR1_ADDR;
795                 if (status & 0x001) error_print ("DMA Channel 1 PCI Parity Error\n",0,0,0,0);
796                 if (status & 0x004) error_print ("DMA Channel 1 PCI Target Abort\n",0,0,0,0);
797                 if (status & 0x008) error_print ("DMA Channel 1 PCI Master Abort\n",0,0,0,0);
798                 if (status & 0x020) error_print ("Internal PCI Master Abort\n",0,0,0,0);  
799             
800                 /* clear the interrupt condition */
801                 AND_WORD((volatile unsigned long *)CSR1_ADDR, 0x2D);
802         }
803
804         if (nmi_status & DMA_2_ERROR)
805         {
806                 srcs_found++;
807                 error_print ("**** DMA Channel 2 Error ****\n",0,0,0,0);
808                 status = *(volatile unsigned long *)CSR2_ADDR;
809                 if (status & 0x001) error_print ("DMA Channel 2 PCI Parity Error\n",0,0,0,0);
810                 if (status & 0x004) error_print ("DMA Channel 2 PCI Target Abort\n",0,0,0,0);
811                 if (status & 0x008) error_print ("DMA Channel 2 PCI Master Abort\n",0,0,0,0);
812                 if (status & 0x020) error_print ("Internal PCI Master Abort\n",0,0,0,0);  
813                 
814                 /* clear the interrupt condition */
815                 AND_WORD((volatile unsigned long *)CSR2_ADDR, 0x2D);
816         }
817
818         if (nmi_status & MU_ERROR)
819         {       
820                 status = *(volatile unsigned long *)IISR_ADDR;
821                 if (status & 0x20)
822                 {
823                         srcs_found++;
824                         error_print ("Messaging Unit Outbound Free Queue Overflow\n",0,0,0,0);
825
826                         /* clear the interrupt condition; note that the clearing of the NMI doorbell
827                         is handled by the PCI comms code */
828                 }       AND_WORD((volatile unsigned long *)IISR_ADDR, 0x20);    
829         }
830
831         if (nmi_status & AAU_ERROR)
832         {
833                 srcs_found++;
834                 error_print ("**** Application Accelerator Unit Error ****\n",0,0,0,0);
835                 status = *(volatile unsigned long *)ASR_ADDR;
836                 if (status & 0x020) error_print ("Internal PCI Master Abort\n",0,0,0,0);
837
838                 /* clear the interrupt condition */
839                 AND_WORD((volatile unsigned long *)ASR_ADDR, 0x20);
840         }
841
842         if (nmi_status & BIU_ERROR)
843         {
844                 srcs_found++;
845                 error_print ("**** Bus Interface Unit Error ****\n",0,0,0,0);
846                 status = *(volatile unsigned long *)BIUISR_ADDR;
847                 if (status & 0x004) error_print ("Internal PCI Master Abort\n",0,0,0,0);
848
849                 /* clear the interrupt condition */
850                 AND_WORD((volatile unsigned long *)BIUISR_ADDR, 0x04);
851         }
852
853         return (srcs_found);
854
855 }
856
857
858 /**********************************************************************
859 * isr_connect - Disconnect a user Interrupt Service Routine
860 *
861 * NOT TO BE USED FOR SPCI INTERRUPTS! - use pci_isr_connect instead
862 *
863 */
864 int isr_connect(int int_num, void (*handler)(int), int arg)
865 {
866     switch (int_num)
867     {
868
869         case DMA0_INT_ID:
870             usr_dma0_isr = handler;
871             usr_dma0_arg = arg;
872             break;
873         case DMA1_INT_ID:
874             usr_dma1_isr = handler;
875             usr_dma1_arg = arg;
876             break;
877         case DMA2_INT_ID:
878             usr_dma2_isr = handler;
879             usr_dma2_arg = arg;
880             break;
881         case PM_INT_ID:
882                 usr_pm_isr = handler;
883                 usr_pm_arg = arg;
884                 break;
885         case AA_INT_ID:
886                 usr_aa_isr = handler;
887                 usr_aa_arg = arg;
888                 break;
889         case I2C_INT_ID: 
890                 usr_i2c_isr = handler;
891                 usr_i2c_arg = arg;
892                 break;
893         case MU_INT_ID:
894                 usr_mu_isr = handler;
895                 usr_mu_arg = arg;
896                 break;
897         case PATU_INT_ID:
898                 usr_patu_isr = handler;
899                 usr_patu_arg = arg;
900                 break;
901         case TIMER_INT_ID:
902                 usr_timer_isr = handler;
903                 usr_timer_arg = arg;
904                 break;
905         case ENET_INT_ID:
906                 usr_enet_isr = handler;
907                 usr_enet_arg = arg;
908                 break;
909         case UART1_INT_ID:
910                 usr_uart1_isr = handler;
911                 usr_uart1_arg = arg;
912                 break;
913         case UART2_INT_ID:
914                 usr_uart2_isr = handler;
915                 usr_uart2_arg = arg;
916                 break;
917         default:
918                 return (ERROR);
919                 break;
920         }
921
922         return (OK);
923 }
924
925 /**********************************************************************
926 * isr_disconnect - Disconnect a user Interrupt Service Routine
927 *
928 * NOT TO BE USED FOR SPCI INTERRUPTS! - use pci_isr_disconnect instead
929 *
930 */
931 int isr_disconnect(int int_num)
932 {
933     switch (int_num)
934     {
935
936         case DMA0_INT_ID:
937             usr_dma0_isr = NULL;
938             usr_dma0_arg = 0;
939             break;
940         case DMA1_INT_ID:
941             usr_dma1_isr = NULL;
942             usr_dma1_arg = 0;
943             break;
944         case DMA2_INT_ID:
945             usr_dma2_isr = NULL;
946             usr_dma2_arg = 0;
947             break;
948         case PM_INT_ID:
949                 usr_pm_isr = NULL;
950                 usr_pm_arg = 0;
951                 break;
952         case AA_INT_ID:
953                 usr_aa_isr = NULL;
954                 usr_aa_arg = 0;
955                 break;
956         case I2C_INT_ID: 
957                 usr_i2c_isr = NULL;
958                 usr_i2c_arg = 0;
959                 break;
960         case MU_INT_ID:
961                 usr_mu_isr = NULL;
962                 usr_mu_arg = 0;
963                 break;
964         case PATU_INT_ID:
965                 usr_patu_isr = NULL;
966                 usr_patu_arg = 0;
967                 break;
968         case TIMER_INT_ID:
969                 usr_timer_isr = NULL;
970                 usr_timer_arg = 0;
971                 break;
972         case ENET_INT_ID:
973                 usr_enet_isr = NULL;
974                 usr_enet_arg = 0;
975                 break;
976         case UART1_INT_ID:
977                 usr_uart1_isr = NULL;
978                 usr_uart1_arg = 0;
979                 break;
980         case UART2_INT_ID:
981                 usr_uart2_isr = NULL;
982                 usr_uart2_arg = 0;
983                 break;
984         default:
985                 return (ERROR);
986                 break;
987         }
988
989         /* i960 disabled interrupt here - should we? */
990
991         return (OK);
992 }
993
994 /********************************************************************
995 * disable_external_interrupt - Mask an external interrupt 
996 *
997 */
998 int disable_external_interrupt(int int_id)
999 {
1000
1001 unsigned char* ext_mask_reg = (unsigned char*) X3MASK_ADDR;
1002 unsigned char  new_mask_value;
1003
1004         /* make sure interrupt to enable is an external interrupt */
1005         if ((int_id < TIMER_INT_ID) || (int_id > SINTD_INT_ID))
1006                 return (ERROR);
1007
1008         new_mask_value = *ext_mask_reg; /* read current mask status */
1009         
1010         switch (int_id)
1011         {
1012         case TIMER_INT_ID:
1013                 new_mask_value |= TIMER_INT;
1014                 break;
1015         case ENET_INT_ID:
1016                 new_mask_value |= ENET_INT;
1017                 break;
1018         case UART1_INT_ID:
1019                 new_mask_value |= UART1_INT;
1020                 break;
1021         case UART2_INT_ID:
1022                 new_mask_value |= UART2_INT;
1023                 break;
1024         case SINTD_INT_ID:
1025                 new_mask_value |= SINTD_INT;
1026                 break;
1027         default:
1028                 break; /* leave mask register as it was */
1029         }
1030
1031         *ext_mask_reg = new_mask_value; /* set new mask value */
1032
1033         return (OK);
1034
1035 }
1036
1037
1038
1039 /********************************************************************
1040 * enable_external_interrupt - Unmask an external interrupt 
1041 *
1042 */
1043 int enable_external_interrupt(int int_id)
1044 {
1045
1046 unsigned char* ext_mask_reg = (unsigned char*) X3MASK_ADDR;
1047 unsigned char  new_mask_value;
1048
1049         /* make sure interrupt to enable is an external interrupt */
1050         if ((int_id < TIMER_INT_ID) || (int_id > SINTD_INT_ID))
1051                 return (ERROR);
1052
1053         
1054         new_mask_value = *ext_mask_reg; /* read current mask status */
1055         
1056         switch (int_id)
1057         {
1058         case TIMER_INT_ID:
1059                 new_mask_value &= ~(TIMER_INT);
1060                 break;
1061         case ENET_INT_ID:
1062                 new_mask_value &= ~(ENET_INT);
1063                 break;
1064         case UART1_INT_ID:
1065                 new_mask_value &= ~(UART1_INT);
1066                 break;
1067         case UART2_INT_ID:
1068                 new_mask_value &= ~(UART2_INT);
1069                 break;
1070         case SINTD_INT_ID:
1071                 new_mask_value &= ~(SINTD_INT);
1072                 break;
1073         default:
1074                 break; /* leave mask register as it was */
1075         }
1076
1077         *ext_mask_reg = new_mask_value; /* set new mask value */
1078
1079         return (OK);
1080 }
1081
1082
1083 void error_print (
1084                 char *fmt,
1085                 int arg0,
1086                 int arg1,
1087                 int arg2,
1088                 int arg3
1089                 )
1090 {
1091         /* Wait until host configures the boards to start printing NMI errors */
1092         UINT32* atu_reg = (UINT32*)PIABAR_ADDR;
1093         if ((*atu_reg & 0xfffffff0) == 0)
1094                 return;
1095         if (nmi_verbose) printf (fmt, arg0, arg1, arg2, arg3);
1096                 return;
1097 }
1098
1099 extern void __diag_IRQ(void);
1100 extern void __diag_FIQ(void);
1101
1102 void config_ints(void)
1103 {
1104 int xint, x;
1105         
1106         unsigned int* pirsr_ptr = (unsigned int*)PIRSR_ADDR;
1107         *pirsr_ptr = 0xf; /* this is an errata in the original Yavapai manual.
1108                                              The interrupt steering bits are reversed, so a '1'
1109                                                  routes XINT interrupts to FIQ
1110                                                 */
1111
1112         /* install diag IRQ handlers */
1113         ((volatile unsigned *)0x20)[6] = (unsigned)__diag_IRQ;
1114         ((volatile unsigned *)0x20)[7] = (unsigned)__diag_FIQ;
1115         _flushICache(); 
1116
1117         /* make sure interrupts are enabled in CSPR */
1118
1119         _cspr_enable_irq_int(); 
1120
1121         _cspr_enable_fiq_int(); 
1122
1123         /* initialize the PCI interrupt table */
1124         for (xint = 0; xint < NUM_PCI_XINTS; xint++)
1125         {
1126                 for (x = 0; x < MAX_PCI_HANDLERS; x++) 
1127                 {
1128                         pci_int_handlers[xint][x].handler       = NULL;
1129                         pci_int_handlers[xint][x].arg           = (int)NULL;
1130                         pci_int_handlers[xint][x].bus           = (int)NULL;
1131                         pci_int_handlers[xint][x].device        = (int)NULL;
1132                 }
1133         }
1134
1135
1136 }
1137
1138
1139