Subversion Repositories HelenOS

Rev

Rev 4269 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4269 Rev 4295
Line 16... Line 16...
16
static void *conf_addr = 0;  
16
static void *conf_addr = 0;  
17
 
17
 
18
/*
18
/*
19
 * virtual address of specified PCI configuration register:
19
 * virtual address of specified PCI configuration register:
20
 * bus ... bus number (0 for top level PCI bus B, 1 for top level PCI bus A)
20
 * bus ... bus number (0 for top level PCI bus B, 1 for top level PCI bus A)
21
 * dev ... device number (0 - 15)
21
 * dev ... device number (0 - 31)
22
 * fn  ... function number (0 - 7)
22
 * fn  ... function number (0 - 7)
23
 * reg ... register number (register's position within PCI configuration header)
23
 * reg ... register number (register's position within PCI configuration header)
24
 **/
24
 **/
25
#define CONF_ADDR(bus, dev, fn, reg)   ((void *)(conf_addr + ((bus << 16) | (dev << 11) | (fn << 8) | (reg << 0))))
25
#define CONF_ADDR(bus, dev, fn, reg)   ((void *)(conf_addr + ((bus << 16) | (dev << 11) | (fn << 8) | reg)))
26
 
26
 
27
 
27
 
28
 
28
 
29
static void us2i_init(struct pci_access *a)
29
static void us2_init(struct pci_access *a)
30
{  
30
{  
31
}
31
}
32
 
32
 
33
static void us2i_cleanup(struct pci_access *a UNUSED)
33
static void us2_cleanup(struct pci_access *a UNUSED)
34
{
34
{
35
}
35
}
36
 
36
 
37
static inline uint64_t pio_read_64(uint64_t *port)
-
 
38
{
-
 
39
    uint64_t rv;
-
 
40
 
-
 
41
    rv = *port;
-
 
42
    memory_barrier();
-
 
43
 
-
 
44
    return rv;
-
 
45
}
-
 
46
 
-
 
47
static int us2i_detect(struct pci_access *a)
37
static int us2_detect(struct pci_access *a)
48
{  
38
{  
49
    /*
39
    /*
50
     * Gain control over PCI configuration ports.
40
     * Gain control over PCI configuration ports.
51
     */
41
     */
52
    if (pio_enable((void *)PCI_CONF_BASE, PCI_CONF_SIZE, &conf_addr)) {
42
    if (pio_enable((void *)PCI_CONF_BASE, PCI_CONF_SIZE, &conf_addr)) {
53
        return 0;
43
        return 0;
54
    }  
44
    }  
55
 
45
 
56
    int vendor_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID)));   
46
    unsigned int vendor_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID)));  
57
    int device_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID)));
47
    unsigned int device_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID)));
58
   
48
   
59
    printf("PCI: vendor id = %x\n", vendor_id);
49
    // printf("PCI: vendor id = %x\n", vendor_id);
60
    printf("PCI: device id = %x\n", device_id);
50
    // printf("PCI: device id = %x\n", device_id);
61
 
51
 
62
    return vendor_id == 0x108E && device_id == 0x8000; // should be Psycho from Sun Microsystems 
52
    return vendor_id == 0x108E && device_id == 0x8000; // should be Psycho from Sun Microsystems 
63
}
53
}
64
 
54
 
65
/** Compute new starting position of the operation if byte twisting is used.
-
 
66
 *
-
 
67
 * See chapter 10.2 of the UPA to PCI Interface User's Manual.
-
 
68
 * Note: byte twisting is used only for devices beyond the UPA
-
 
69
 * to PCI bridge, not for the device of the bridge itself.
-
 
70
 * Configuration registers of the bridge must be read in a different way.
-
 
71
 *
-
 
72
 * @param pos       The original starting position of the read/write operation.
-
 
73
 * @param len       The length of the read/write operation (<= 4).
-
 
74
 * @return      New starting position of the operation.
-
 
75
 */
-
 
76
static int byte_twist(int pos, int len)
-
 
77
{
-
 
78
    int end = (pos + len) % 4;
-
 
79
    if (end == 0) {
-
 
80
        end = 4;
-
 
81
    }
-
 
82
    int begin = 4 - end;   
-
 
83
    pos = pos - pos % 4 + begin;
-
 
84
    return pos;
-
 
85
}
-
 
86
 
-
 
87
/*
-
 
88
static int byte_twist(pos)
-
 
89
{
-
 
90
    return pos - pos % 4 + (3 - pos % 4);  
-
 
91
}*/
-
 
92
 
55
 
93
static int us2i_read(struct pci_dev *d, int pos, byte * buf, int len)
56
static int us2_read(struct pci_dev *d, int pos, byte * buf, int len)
94
{
57
{  
95
    /*void * addr = CONF_ADDR(d->bus, d->dev, d->func, pos);   
-
 
96
   
-
 
97
    if (pos >= 256)
58
    if (pos >= 256)
98
        return 0;      
59
        return 0;
99
 
-
 
100
    switch (len) {
-
 
101
    case 1:
-
 
102
        us2i_read_aligned(d->bus, d->dev, d->func, pos, buf, len);
-
 
103
        break;
-
 
104
    case 2:
-
 
105
        us2i_read_aligned(d->bus, d->dev, d->func, pos, buf, len);
-
 
106
        ((u16 *) buf)[0] = cpu_to_le16(*((u16 *) buf));
-
 
107
        break;
-
 
108
    case 4:
-
 
109
        us2i_read_aligned(d->bus, d->dev, d->func, pos, buf, len);
-
 
110
        ((u32 *) buf)[0] = cpu_to_le32(*((u32 *) buf));    
-
 
111
        break;
-
 
112
    default:
-
 
113
        return pci_generic_block_read(d, pos, buf, len);
-
 
114
    }
-
 
115
    return 1; */
-
 
116
   
-
 
117
   
60
   
118
    if (len <= 4) {
-
 
119
        int twist = d->dev != 0 || d->func != 0;
61
    /* The vendor ID and the device ID registers of the device number 0 (the bridge)
120
        if (twist) {       
-
 
121
            pos = byte_twist(pos, len);
62
     * work in simics in different way than the other config. registers. */
122
        }
-
 
123
        int i;
-
 
124
        for (i = 0; i < len; i++) {
63
    if (d->dev == 0 && d->func == 0 && pos == 0 && len == 4) {    
125
            void * addr = CONF_ADDR(d->bus, d->dev, d->func, pos + i);
64
        ((u32 *) buf)[0] = pio_read_32(CONF_ADDR(d->bus, d->dev, d->func, pos));
126
            if (byte_twist) {
-
 
127
                buf[i] = pio_read_8(addr);
-
 
128
            }
-
 
129
            else {
65
        return 1;
130
                buf[len-i-1] = pio_read_8(addr);
-
 
131
            }
-
 
132
        }
-
 
133
    } else {
-
 
134
        return pci_generic_block_read(d, pos, buf, len);
-
 
135
    }
66
    }
136
    return 1;
-
 
137
   
-
 
138
    /*void * addr = CONF_ADDR(d->bus, d->dev, d->func, pos);   
-
 
139
   
67
   
140
    if (pos >= 256)
-
 
141
        return 0;      
-
 
142
 
-
 
143
    switch (len) {
-
 
144
    case 1:
68
    int i;
145
        buf[0] = pio_read_8(addr);
69
    for (i = 0; i < len; i++) {
146
        break;
-
 
147
    case 2:
-
 
148
        ((u16 *) buf)[0] = cpu_to_le16(pio_read_16(addr));
-
 
149
        break;
-
 
150
    case 4:
-
 
151
        ((u32 *) buf)[0] = cpu_to_le32(pio_read_32(addr));     
-
 
152
        break;
-
 
153
    default:
-
 
154
        return pci_generic_block_read(d, pos, buf, len);
-
 
155
    }
-
 
156
    return 1; */
-
 
157
 
-
 
158
    /*
-
 
159
    switch (len) {
-
 
160
    case 1:
-
 
161
        buf[0] = pio_read_8(CONF_ADDR(d->bus, d->dev, d->func, pos));
70
        buf[i] = pio_read_8(CONF_ADDR(d->bus, d->dev, d->func, pos + i));
162
        break;
-
 
163
    case 2:
-
 
164
        us2i_read(d, pos + 1, buf, 1);   // unlike PCI, sparc uses big endian
-
 
165
        us2i_read(d, pos, buf + 1, 1);
-
 
166
        break;
-
 
167
    case 4:
-
 
168
        us2i_read(d, pos + 3, buf, 1);  // endians in an ugly way ... FIX ME
-
 
169
        us2i_read(d, pos + 2, buf + 1, 1);
-
 
170
        us2i_read(d, pos + 1, buf + 2, 1);
-
 
171
        us2i_read(d, pos, buf + 3, 1);     
-
 
172
        break;
-
 
173
    default:
-
 
174
        return pci_generic_block_read(d, pos, buf, len);
-
 
175
    }
71
    }
176
    return 1;
72
    return 1;
177
    */
-
 
178
}
73
}
179
 
74
 
180
static int us2i_write(struct pci_dev *d, int pos, byte * buf, int len)
75
static int us2_write(struct pci_dev *d, int pos, byte * buf, int len)
181
{
76
{
182
    void * addr = CONF_ADDR(d->bus, d->dev, d->func, pos);
-
 
183
 
-
 
184
    if (pos >= 256)
77
    if (pos >= 256)
185
        return 0;
78
        return 0;
186
 
79
 
187
    switch (len) {
80
    int i;
188
    case 1:
81
    for (i = 0; i < len; i++) {
189
        pio_write_8(CONF_ADDR(d->bus, d->dev, d->func, pos), buf[0]);
82
         pio_write_8(CONF_ADDR(d->bus, d->dev, d->func, pos + i), buf[i]);
190
        break;
-
 
191
    case 2:
-
 
192
        pio_write_16(addr, le16_to_cpu(((u16 *) buf)[0]));
-
 
193
        break;
-
 
194
    case 4:
-
 
195
        pio_write_32(addr, le32_to_cpu(((u32 *) buf)[0]));
-
 
196
        break;
-
 
197
    default:
-
 
198
        return pci_generic_block_write(d, pos, buf, len);
-
 
199
    }
83
    }
200
    return 1;
84
    return 1;
201
}
85
}
202
 
86
 
203
 
87
 
204
struct pci_methods pm_us2i = {
88
struct pci_methods pm_us2 = {
205
    "Ultra Sparc IIi",
89
    "Ultra Sparc IIi",
206
    NULL,           /* config */
90
    NULL,           /* config */
207
    us2i_detect,
91
    us2_detect,
208
    us2i_init,
92
    us2_init,
209
    us2i_cleanup,
93
    us2_cleanup,
210
    pci_generic_scan,
94
    pci_generic_scan,
211
    pci_generic_fill_info,
95
    pci_generic_fill_info,
212
    us2i_read,
96
    us2_read,
213
    us2i_write,
97
    us2_write,
214
    NULL,           /* init_dev */
98
    NULL,           /* init_dev */
215
    NULL            /* cleanup_dev */
99
    NULL            /* cleanup_dev */
216
};
100
};
217
101