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/] [x86/] [pci/] [numa.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * numa.c - Low-level PCI access for NUMA-Q machines
3
 */
4
 
5
#include <linux/pci.h>
6
#include <linux/init.h>
7
#include <linux/nodemask.h>
8
#include "pci.h"
9
 
10
#define BUS2QUAD(global) (mp_bus_id_to_node[global])
11
#define BUS2LOCAL(global) (mp_bus_id_to_local[global])
12
#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
13
 
14
#define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \
15
        (0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3))
16
 
17
static int pci_conf1_mq_read(unsigned int seg, unsigned int bus,
18
                             unsigned int devfn, int reg, int len, u32 *value)
19
{
20
        unsigned long flags;
21
 
22
        if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
23
                return -EINVAL;
24
 
25
        spin_lock_irqsave(&pci_config_lock, flags);
26
 
27
        outl_quad(PCI_CONF1_MQ_ADDRESS(bus, devfn, reg), 0xCF8, BUS2QUAD(bus));
28
 
29
        switch (len) {
30
        case 1:
31
                *value = inb_quad(0xCFC + (reg & 3), BUS2QUAD(bus));
32
                break;
33
        case 2:
34
                *value = inw_quad(0xCFC + (reg & 2), BUS2QUAD(bus));
35
                break;
36
        case 4:
37
                *value = inl_quad(0xCFC, BUS2QUAD(bus));
38
                break;
39
        }
40
 
41
        spin_unlock_irqrestore(&pci_config_lock, flags);
42
 
43
        return 0;
44
}
45
 
46
static int pci_conf1_mq_write(unsigned int seg, unsigned int bus,
47
                              unsigned int devfn, int reg, int len, u32 value)
48
{
49
        unsigned long flags;
50
 
51
        if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
52
                return -EINVAL;
53
 
54
        spin_lock_irqsave(&pci_config_lock, flags);
55
 
56
        outl_quad(PCI_CONF1_MQ_ADDRESS(bus, devfn, reg), 0xCF8, BUS2QUAD(bus));
57
 
58
        switch (len) {
59
        case 1:
60
                outb_quad((u8)value, 0xCFC + (reg & 3), BUS2QUAD(bus));
61
                break;
62
        case 2:
63
                outw_quad((u16)value, 0xCFC + (reg & 2), BUS2QUAD(bus));
64
                break;
65
        case 4:
66
                outl_quad((u32)value, 0xCFC, BUS2QUAD(bus));
67
                break;
68
        }
69
 
70
        spin_unlock_irqrestore(&pci_config_lock, flags);
71
 
72
        return 0;
73
}
74
 
75
#undef PCI_CONF1_MQ_ADDRESS
76
 
77
static struct pci_raw_ops pci_direct_conf1_mq = {
78
        .read   = pci_conf1_mq_read,
79
        .write  = pci_conf1_mq_write
80
};
81
 
82
 
83
static void __devinit pci_fixup_i450nx(struct pci_dev *d)
84
{
85
        /*
86
         * i450NX -- Find and scan all secondary buses on all PXB's.
87
         */
88
        int pxb, reg;
89
        u8 busno, suba, subb;
90
        int quad = BUS2QUAD(d->bus->number);
91
 
92
        printk("PCI: Searching for i450NX host bridges on %s\n", pci_name(d));
93
        reg = 0xd0;
94
        for(pxb=0; pxb<2; pxb++) {
95
                pci_read_config_byte(d, reg++, &busno);
96
                pci_read_config_byte(d, reg++, &suba);
97
                pci_read_config_byte(d, reg++, &subb);
98
                DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
99
                if (busno) {
100
                        /* Bus A */
101
                        pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno));
102
                }
103
                if (suba < subb) {
104
                        /* Bus B */
105
                        pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1));
106
                }
107
        }
108
        pcibios_last_bus = -1;
109
}
110
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx);
111
 
112
static int __init pci_numa_init(void)
113
{
114
        int quad;
115
 
116
        raw_pci_ops = &pci_direct_conf1_mq;
117
 
118
        if (pcibios_scanned++)
119
                return 0;
120
 
121
        pci_root_bus = pcibios_scan_root(0);
122
        if (pci_root_bus)
123
                pci_bus_add_devices(pci_root_bus);
124
        if (num_online_nodes() > 1)
125
                for_each_online_node(quad) {
126
                        if (quad == 0)
127
                                continue;
128
                        printk("Scanning PCI bus %d for quad %d\n",
129
                                QUADLOCAL2BUS(quad,0), quad);
130
                        pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0));
131
                }
132
        return 0;
133
}
134
 
135
subsys_initcall(pci_numa_init);

powered by: WebSVN 2.1.0

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