OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [xscale/] [iq80310/] [v2_0/] [src/] [diag/] [interrupts.c] - Blame information for rev 565

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//=============================================================================
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.