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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [alpha/] [kernel/] [core_mcpcia.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *      linux/arch/alpha/kernel/core_mcpcia.c
3
 *
4
 * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
5
 *
6
 * Code common to all MCbus-PCI Adaptor core logic chipsets
7
 */
8
 
9
#define __EXTERN_INLINE inline
10
#include <asm/io.h>
11
#include <asm/core_mcpcia.h>
12
#undef __EXTERN_INLINE
13
 
14
#include <linux/types.h>
15
#include <linux/pci.h>
16
#include <linux/sched.h>
17
#include <linux/init.h>
18
#include <linux/delay.h>
19
 
20
#include <asm/ptrace.h>
21
 
22
#include "proto.h"
23
#include "pci_impl.h"
24
 
25
/*
26
 * NOTE: Herein lie back-to-back mb instructions.  They are magic.
27
 * One plausible explanation is that the i/o controller does not properly
28
 * handle the system transaction.  Another involves timing.  Ho hum.
29
 */
30
 
31
/*
32
 * BIOS32-style PCI interface:
33
 */
34
 
35
#define DEBUG_CFG 0
36
 
37
#if DEBUG_CFG
38
# define DBG_CFG(args)  printk args
39
#else
40
# define DBG_CFG(args)
41
#endif
42
 
43
/*
44
 * Given a bus, device, and function number, compute resulting
45
 * configuration space address and setup the MCPCIA_HAXR2 register
46
 * accordingly.  It is therefore not safe to have concurrent
47
 * invocations to configuration space access routines, but there
48
 * really shouldn't be any need for this.
49
 *
50
 * Type 0:
51
 *
52
 *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
53
 *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
54
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55
 * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
56
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
 *
58
 *      31:11   Device select bit.
59
 *      10:8    Function number
60
 *       7:2    Register number
61
 *
62
 * Type 1:
63
 *
64
 *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
65
 *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
66
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67
 * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
68
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69
 *
70
 *      31:24   reserved
71
 *      23:16   bus number (8 bits = 128 possible buses)
72
 *      15:11   Device number (5 bits)
73
 *      10:8    function number
74
 *       7:2    register number
75
 *
76
 * Notes:
77
 *      The function number selects which function of a multi-function device
78
 *      (e.g., SCSI and Ethernet).
79
 *
80
 *      The register selects a DWORD (32 bit) register offset.  Hence it
81
 *      doesn't get shifted by 2 bits as we want to "drop" the bottom two
82
 *      bits.
83
 */
84
 
85
static unsigned int
86
conf_read(unsigned long addr, unsigned char type1,
87
          struct pci_controller *hose)
88
{
89
        unsigned long flags;
90
        unsigned long mid = MCPCIA_HOSE2MID(hose->index);
91
        unsigned int stat0, value, temp, cpu;
92
 
93
        cpu = smp_processor_id();
94
 
95
        local_irq_save(flags);
96
 
97
        DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
98
                 addr, type1, mid));
99
 
100
        /* Reset status register to avoid losing errors.  */
101
        stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
102
        *(vuip)MCPCIA_CAP_ERR(mid) = stat0;
103
        mb();
104
        temp = *(vuip)MCPCIA_CAP_ERR(mid);
105
        DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0));
106
 
107
        mb();
108
        draina();
109
        mcheck_expected(cpu) = 1;
110
        mcheck_taken(cpu) = 0;
111
        mcheck_extra(cpu) = mid;
112
        mb();
113
 
114
        /* Access configuration space.  */
115
        value = *((vuip)addr);
116
        mb();
117
        mb();  /* magic */
118
 
119
        if (mcheck_taken(cpu)) {
120
                mcheck_taken(cpu) = 0;
121
                value = 0xffffffffU;
122
                mb();
123
        }
124
        mcheck_expected(cpu) = 0;
125
        mb();
126
 
127
        DBG_CFG(("conf_read(): finished\n"));
128
 
129
        local_irq_restore(flags);
130
        return value;
131
}
132
 
133
static void
134
conf_write(unsigned long addr, unsigned int value, unsigned char type1,
135
           struct pci_controller *hose)
136
{
137
        unsigned long flags;
138
        unsigned long mid = MCPCIA_HOSE2MID(hose->index);
139
        unsigned int stat0, temp, cpu;
140
 
141
        cpu = smp_processor_id();
142
 
143
        local_irq_save(flags);  /* avoid getting hit by machine check */
144
 
145
        /* Reset status register to avoid losing errors.  */
146
        stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
147
        *(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb();
148
        temp = *(vuip)MCPCIA_CAP_ERR(mid);
149
        DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0));
150
 
151
        draina();
152
        mcheck_expected(cpu) = 1;
153
        mcheck_extra(cpu) = mid;
154
        mb();
155
 
156
        /* Access configuration space.  */
157
        *((vuip)addr) = value;
158
        mb();
159
        mb();  /* magic */
160
        temp = *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */
161
        mcheck_expected(cpu) = 0;
162
        mb();
163
 
164
        DBG_CFG(("conf_write(): finished\n"));
165
        local_irq_restore(flags);
166
}
167
 
168
static int
169
mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where,
170
             struct pci_controller *hose, unsigned long *pci_addr,
171
             unsigned char *type1)
172
{
173
        u8 bus = pbus->number;
174
        unsigned long addr;
175
 
176
        DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x,"
177
                 " pci_addr=0x%p, type1=0x%p)\n",
178
                 bus, devfn, hose->index, where, pci_addr, type1));
179
 
180
        /* Type 1 configuration cycle for *ALL* busses.  */
181
        *type1 = 1;
182
 
183
        if (!pbus->parent) /* No parent means peer PCI bus. */
184
                bus = 0;
185
        addr = (bus << 16) | (devfn << 8) | (where);
186
        addr <<= 5; /* swizzle for SPARSE */
187
        addr |= hose->config_space_base;
188
 
189
        *pci_addr = addr;
190
        DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
191
        return 0;
192
}
193
 
194
static int
195
mcpcia_read_config(struct pci_bus *bus, unsigned int devfn, int where,
196
                   int size, u32 *value)
197
{
198
        struct pci_controller *hose = bus->sysdata;
199
        unsigned long addr, w;
200
        unsigned char type1;
201
 
202
        if (mk_conf_addr(bus, devfn, where, hose, &addr, &type1))
203
                return PCIBIOS_DEVICE_NOT_FOUND;
204
 
205
        addr |= (size - 1) * 8;
206
        w = conf_read(addr, type1, hose);
207
        switch (size) {
208
        case 1:
209
                *value = __kernel_extbl(w, where & 3);
210
                break;
211
        case 2:
212
                *value = __kernel_extwl(w, where & 3);
213
                break;
214
        case 4:
215
                *value = w;
216
                break;
217
        }
218
        return PCIBIOS_SUCCESSFUL;
219
}
220
 
221
static int
222
mcpcia_write_config(struct pci_bus *bus, unsigned int devfn, int where,
223
                    int size, u32 value)
224
{
225
        struct pci_controller *hose = bus->sysdata;
226
        unsigned long addr;
227
        unsigned char type1;
228
 
229
        if (mk_conf_addr(bus, devfn, where, hose, &addr, &type1))
230
                return PCIBIOS_DEVICE_NOT_FOUND;
231
 
232
        addr |= (size - 1) * 8;
233
        value = __kernel_insql(value, where & 3);
234
        conf_write(addr, value, type1, hose);
235
        return PCIBIOS_SUCCESSFUL;
236
}
237
 
238
struct pci_ops mcpcia_pci_ops =
239
{
240
        .read =         mcpcia_read_config,
241
        .write =        mcpcia_write_config,
242
};
243
 
244
void
245
mcpcia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
246
{
247
        wmb();
248
        *(vuip)MCPCIA_SG_TBIA(MCPCIA_HOSE2MID(hose->index)) = 0;
249
        mb();
250
}
251
 
252
static int __init
253
mcpcia_probe_hose(int h)
254
{
255
        int cpu = smp_processor_id();
256
        int mid = MCPCIA_HOSE2MID(h);
257
        unsigned int pci_rev;
258
 
259
        /* Gotta be REAL careful.  If hose is absent, we get an mcheck.  */
260
 
261
        mb();
262
        mb();
263
        draina();
264
        wrmces(7);
265
 
266
        mcheck_expected(cpu) = 2;       /* indicates probing */
267
        mcheck_taken(cpu) = 0;
268
        mcheck_extra(cpu) = mid;
269
        mb();
270
 
271
        /* Access the bus revision word. */
272
        pci_rev = *(vuip)MCPCIA_REV(mid);
273
 
274
        mb();
275
        mb();  /* magic */
276
        if (mcheck_taken(cpu)) {
277
                mcheck_taken(cpu) = 0;
278
                pci_rev = 0xffffffff;
279
                mb();
280
        }
281
        mcheck_expected(cpu) = 0;
282
        mb();
283
 
284
        return (pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST;
285
}
286
 
287
static void __init
288
mcpcia_new_hose(int h)
289
{
290
        struct pci_controller *hose;
291
        struct resource *io, *mem, *hae_mem;
292
        int mid = MCPCIA_HOSE2MID(h);
293
 
294
        hose = alloc_pci_controller();
295
        if (h == 0)
296
                pci_isa_hose = hose;
297
        io = alloc_resource();
298
        mem = alloc_resource();
299
        hae_mem = alloc_resource();
300
 
301
        hose->io_space = io;
302
        hose->mem_space = hae_mem;
303
        hose->sparse_mem_base = MCPCIA_SPARSE(mid) - IDENT_ADDR;
304
        hose->dense_mem_base = MCPCIA_DENSE(mid) - IDENT_ADDR;
305
        hose->sparse_io_base = MCPCIA_IO(mid) - IDENT_ADDR;
306
        hose->dense_io_base = 0;
307
        hose->config_space_base = MCPCIA_CONF(mid);
308
        hose->index = h;
309
 
310
        io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS;
311
        io->end = io->start + 0xffff;
312
        io->name = pci_io_names[h];
313
        io->flags = IORESOURCE_IO;
314
 
315
        mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS;
316
        mem->end = mem->start + 0xffffffff;
317
        mem->name = pci_mem_names[h];
318
        mem->flags = IORESOURCE_MEM;
319
 
320
        hae_mem->start = mem->start;
321
        hae_mem->end = mem->start + MCPCIA_MEM_MASK;
322
        hae_mem->name = pci_hae0_name;
323
        hae_mem->flags = IORESOURCE_MEM;
324
 
325
        if (request_resource(&ioport_resource, io) < 0)
326
                printk(KERN_ERR "Failed to request IO on hose %d\n", h);
327
        if (request_resource(&iomem_resource, mem) < 0)
328
                printk(KERN_ERR "Failed to request MEM on hose %d\n", h);
329
        if (request_resource(mem, hae_mem) < 0)
330
                printk(KERN_ERR "Failed to request HAE_MEM on hose %d\n", h);
331
}
332
 
333
static void
334
mcpcia_pci_clr_err(int mid)
335
{
336
        *(vuip)MCPCIA_CAP_ERR(mid);
337
        *(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff;   /* Clear them all.  */
338
        mb();
339
        *(vuip)MCPCIA_CAP_ERR(mid);  /* Re-read for force write.  */
340
}
341
 
342
static void __init
343
mcpcia_startup_hose(struct pci_controller *hose)
344
{
345
        int mid = MCPCIA_HOSE2MID(hose->index);
346
        unsigned int tmp;
347
 
348
        mcpcia_pci_clr_err(mid);
349
 
350
        /*
351
         * Set up error reporting.
352
         */
353
        tmp = *(vuip)MCPCIA_CAP_ERR(mid);
354
        tmp |= 0x0006;          /* master/target abort */
355
        *(vuip)MCPCIA_CAP_ERR(mid) = tmp;
356
        mb();
357
        tmp = *(vuip)MCPCIA_CAP_ERR(mid);
358
 
359
        /*
360
         * Set up the PCI->physical memory translation windows.
361
         *
362
         * Window 0 is scatter-gather 8MB at 8MB (for isa)
363
         * Window 1 is scatter-gather (up to) 1GB at 1GB (for pci)
364
         * Window 2 is direct access 2GB at 2GB
365
         */
366
        hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
367
        hose->sg_pci = iommu_arena_new(hose, 0x40000000,
368
                                       size_for_memory(0x40000000), 0);
369
 
370
        __direct_map_base = 0x80000000;
371
        __direct_map_size = 0x80000000;
372
 
373
        *(vuip)MCPCIA_W0_BASE(mid) = hose->sg_isa->dma_base | 3;
374
        *(vuip)MCPCIA_W0_MASK(mid) = (hose->sg_isa->size - 1) & 0xfff00000;
375
        *(vuip)MCPCIA_T0_BASE(mid) = virt_to_phys(hose->sg_isa->ptes) >> 8;
376
 
377
        *(vuip)MCPCIA_W1_BASE(mid) = hose->sg_pci->dma_base | 3;
378
        *(vuip)MCPCIA_W1_MASK(mid) = (hose->sg_pci->size - 1) & 0xfff00000;
379
        *(vuip)MCPCIA_T1_BASE(mid) = virt_to_phys(hose->sg_pci->ptes) >> 8;
380
 
381
        *(vuip)MCPCIA_W2_BASE(mid) = __direct_map_base | 1;
382
        *(vuip)MCPCIA_W2_MASK(mid) = (__direct_map_size - 1) & 0xfff00000;
383
        *(vuip)MCPCIA_T2_BASE(mid) = 0;
384
 
385
        *(vuip)MCPCIA_W3_BASE(mid) = 0x0;
386
 
387
        mcpcia_pci_tbi(hose, 0, -1);
388
 
389
        *(vuip)MCPCIA_HBASE(mid) = 0x0;
390
        mb();
391
 
392
        *(vuip)MCPCIA_HAE_MEM(mid) = 0U;
393
        mb();
394
        *(vuip)MCPCIA_HAE_MEM(mid); /* read it back. */
395
        *(vuip)MCPCIA_HAE_IO(mid) = 0;
396
        mb();
397
        *(vuip)MCPCIA_HAE_IO(mid);  /* read it back. */
398
}
399
 
400
void __init
401
mcpcia_init_arch(void)
402
{
403
        /* With multiple PCI busses, we play with I/O as physical addrs.  */
404
        ioport_resource.end = ~0UL;
405
 
406
        /* Allocate hose 0.  That's the one that all the ISA junk hangs
407
           off of, from which we'll be registering stuff here in a bit.
408
           Other hose detection is done in mcpcia_init_hoses, which is
409
           called from init_IRQ.  */
410
 
411
        mcpcia_new_hose(0);
412
}
413
 
414
/* This is called from init_IRQ, since we cannot take interrupts
415
   before then.  Which means we cannot do this in init_arch.  */
416
 
417
void __init
418
mcpcia_init_hoses(void)
419
{
420
        struct pci_controller *hose;
421
        int hose_count;
422
        int h;
423
 
424
        /* First, find how many hoses we have.  */
425
        hose_count = 0;
426
        for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
427
                if (mcpcia_probe_hose(h)) {
428
                        if (h != 0)
429
                                mcpcia_new_hose(h);
430
                        hose_count++;
431
                }
432
        }
433
 
434
        printk("mcpcia_init_hoses: found %d hoses\n", hose_count);
435
 
436
        /* Now do init for each hose.  */
437
        for (hose = hose_head; hose; hose = hose->next)
438
                mcpcia_startup_hose(hose);
439
}
440
 
441
static void
442
mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
443
{
444
        struct el_common_EV5_uncorrectable_mcheck *frame;
445
        int i;
446
 
447
        frame = &logout->procdata;
448
 
449
        /* Print PAL fields */
450
        for (i = 0; i < 24; i += 2) {
451
                printk("  paltmp[%d-%d] = %16lx %16lx\n",
452
                       i, i+1, frame->paltemp[i], frame->paltemp[i+1]);
453
        }
454
        for (i = 0; i < 8; i += 2) {
455
                printk("  shadow[%d-%d] = %16lx %16lx\n",
456
                       i, i+1, frame->shadow[i],
457
                       frame->shadow[i+1]);
458
        }
459
        printk("  Addr of excepting instruction  = %16lx\n",
460
               frame->exc_addr);
461
        printk("  Summary of arithmetic traps    = %16lx\n",
462
               frame->exc_sum);
463
        printk("  Exception mask                 = %16lx\n",
464
               frame->exc_mask);
465
        printk("  Base address for PALcode       = %16lx\n",
466
               frame->pal_base);
467
        printk("  Interrupt Status Reg           = %16lx\n",
468
               frame->isr);
469
        printk("  CURRENT SETUP OF EV5 IBOX      = %16lx\n",
470
               frame->icsr);
471
        printk("  I-CACHE Reg %s parity error   = %16lx\n",
472
               (frame->ic_perr_stat & 0x800L) ?
473
               "Data" : "Tag",
474
               frame->ic_perr_stat);
475
        printk("  D-CACHE error Reg              = %16lx\n",
476
               frame->dc_perr_stat);
477
        if (frame->dc_perr_stat & 0x2) {
478
                switch (frame->dc_perr_stat & 0x03c) {
479
                case 8:
480
                        printk("    Data error in bank 1\n");
481
                        break;
482
                case 4:
483
                        printk("    Data error in bank 0\n");
484
                        break;
485
                case 20:
486
                        printk("    Tag error in bank 1\n");
487
                        break;
488
                case 10:
489
                        printk("    Tag error in bank 0\n");
490
                        break;
491
                }
492
        }
493
        printk("  Effective VA                   = %16lx\n",
494
               frame->va);
495
        printk("  Reason for D-stream            = %16lx\n",
496
               frame->mm_stat);
497
        printk("  EV5 SCache address             = %16lx\n",
498
               frame->sc_addr);
499
        printk("  EV5 SCache TAG/Data parity     = %16lx\n",
500
               frame->sc_stat);
501
        printk("  EV5 BC_TAG_ADDR                = %16lx\n",
502
               frame->bc_tag_addr);
503
        printk("  EV5 EI_ADDR: Phys addr of Xfer = %16lx\n",
504
               frame->ei_addr);
505
        printk("  Fill Syndrome                  = %16lx\n",
506
               frame->fill_syndrome);
507
        printk("  EI_STAT reg                    = %16lx\n",
508
               frame->ei_stat);
509
        printk("  LD_LOCK                        = %16lx\n",
510
               frame->ld_lock);
511
}
512
 
513
static void
514
mcpcia_print_system_area(unsigned long la_ptr)
515
{
516
        struct el_common *frame;
517
        struct pci_controller *hose;
518
 
519
        struct IOD_subpacket {
520
          unsigned long base;
521
          unsigned int whoami;
522
          unsigned int rsvd1;
523
          unsigned int pci_rev;
524
          unsigned int cap_ctrl;
525
          unsigned int hae_mem;
526
          unsigned int hae_io;
527
          unsigned int int_ctl;
528
          unsigned int int_reg;
529
          unsigned int int_mask0;
530
          unsigned int int_mask1;
531
          unsigned int mc_err0;
532
          unsigned int mc_err1;
533
          unsigned int cap_err;
534
          unsigned int rsvd2;
535
          unsigned int pci_err1;
536
          unsigned int mdpa_stat;
537
          unsigned int mdpa_syn;
538
          unsigned int mdpb_stat;
539
          unsigned int mdpb_syn;
540
          unsigned int rsvd3;
541
          unsigned int rsvd4;
542
          unsigned int rsvd5;
543
        } *iodpp;
544
 
545
        frame = (struct el_common *)la_ptr;
546
        iodpp = (struct IOD_subpacket *) (la_ptr + frame->sys_offset);
547
 
548
        for (hose = hose_head; hose; hose = hose->next, iodpp++) {
549
 
550
          printk("IOD %d Register Subpacket - Bridge Base Address %16lx\n",
551
                 hose->index, iodpp->base);
552
          printk("  WHOAMI      = %8x\n", iodpp->whoami);
553
          printk("  PCI_REV     = %8x\n", iodpp->pci_rev);
554
          printk("  CAP_CTRL    = %8x\n", iodpp->cap_ctrl);
555
          printk("  HAE_MEM     = %8x\n", iodpp->hae_mem);
556
          printk("  HAE_IO      = %8x\n", iodpp->hae_io);
557
          printk("  INT_CTL     = %8x\n", iodpp->int_ctl);
558
          printk("  INT_REG     = %8x\n", iodpp->int_reg);
559
          printk("  INT_MASK0   = %8x\n", iodpp->int_mask0);
560
          printk("  INT_MASK1   = %8x\n", iodpp->int_mask1);
561
          printk("  MC_ERR0     = %8x\n", iodpp->mc_err0);
562
          printk("  MC_ERR1     = %8x\n", iodpp->mc_err1);
563
          printk("  CAP_ERR     = %8x\n", iodpp->cap_err);
564
          printk("  PCI_ERR1    = %8x\n", iodpp->pci_err1);
565
          printk("  MDPA_STAT   = %8x\n", iodpp->mdpa_stat);
566
          printk("  MDPA_SYN    = %8x\n", iodpp->mdpa_syn);
567
          printk("  MDPB_STAT   = %8x\n", iodpp->mdpb_stat);
568
          printk("  MDPB_SYN    = %8x\n", iodpp->mdpb_syn);
569
        }
570
}
571
 
572
void
573
mcpcia_machine_check(unsigned long vector, unsigned long la_ptr)
574
{
575
        struct el_common *mchk_header;
576
        struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout;
577
        unsigned int cpu = smp_processor_id();
578
        int expected;
579
 
580
        mchk_header = (struct el_common *)la_ptr;
581
        mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr;
582
        expected = mcheck_expected(cpu);
583
 
584
        mb();
585
        mb();  /* magic */
586
        draina();
587
 
588
        switch (expected) {
589
        case 0:
590
            {
591
                /* FIXME: how do we figure out which hose the
592
                   error was on?  */
593
                struct pci_controller *hose;
594
                for (hose = hose_head; hose; hose = hose->next)
595
                        mcpcia_pci_clr_err(MCPCIA_HOSE2MID(hose->index));
596
                break;
597
            }
598
        case 1:
599
                mcpcia_pci_clr_err(mcheck_extra(cpu));
600
                break;
601
        default:
602
                /* Otherwise, we're being called from mcpcia_probe_hose
603
                   and there's no hose clear an error from.  */
604
                break;
605
        }
606
 
607
        wrmces(0x7);
608
        mb();
609
 
610
        process_mcheck_info(vector, la_ptr, "MCPCIA", expected != 0);
611
        if (!expected && vector != 0x620 && vector != 0x630) {
612
                mcpcia_print_uncorrectable(mchk_logout);
613
                mcpcia_print_system_area(la_ptr);
614
        }
615
}

powered by: WebSVN 2.1.0

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