Subversion Repositories HelenOS

Rev

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

Rev 4221 Rev 4242
Line 2... Line 2...
2
#include <ddi.h>
2
#include <ddi.h>
3
#include <libarch/ddi.h>
3
#include <libarch/ddi.h>
4
#include <stdio.h>
4
#include <stdio.h>
5
 
5
 
6
#include "internal.h"
6
#include "internal.h"
7
#include "header.h"
-
 
8
 
7
 
9
/* physical addresses and offsets */
8
/* physical addresses and offsets */
10
#define U2P_BASE        0x1FE00000000
9
//#define U2P_BASE        0x1FE00000000
-
 
10
#define U2P_BASE        0x1ca00000000
11
#define PCI_CONF_OFFSET   0x001000000
11
#define PCI_CONF_OFFSET   0x001000000
12
#define PCI_CONF_SIZE     0x001000000
12
#define PCI_CONF_SIZE     0x001000000
13
#define PCI_CONF_BASE  (U2P_BASE + PCI_CONF_OFFSET)
13
#define PCI_CONF_BASE  (U2P_BASE + PCI_CONF_OFFSET)
14
 
14
 
15
/* virtual address of PCI configuration space */
15
/* virtual address of PCI configuration space */
Line 20... Line 20...
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 - 15)
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)   (conf_addr + ((bus << 16) | (dev << 11) | (fn << 8) | (reg << 2)))
25
#define CONF_ADDR(bus, dev, fn, reg)   ((void *)(conf_addr + ((bus << 16) | (dev << 11) | (fn << 8) | (reg << 0))))
-
 
26
 
26
 
27
 
27
 
28
 
28
static void us2i_init(struct pci_access *a)
29
static void us2i_init(struct pci_access *a)
29
{  
30
{  
30
}
31
}
31
 
32
 
32
static void us2i_cleanup(struct pci_access *a UNUSED)
33
static void us2i_cleanup(struct pci_access *a UNUSED)
33
{
34
{
34
}
35
}
35
 
36
 
36
static int us2i_detect(struct pci_access *a)
37
static inline uint64_t pio_read_64(uint64_t *port)
37
{
38
{
-
 
39
    uint64_t rv;
-
 
40
 
-
 
41
    rv = *port;
-
 
42
    memory_barrier();
-
 
43
 
-
 
44
    return rv;
-
 
45
}
-
 
46
 
-
 
47
 
-
 
48
// read whole 8-byte blocks 
-
 
49
static void us2i_read_aligned(int bus, int dev, int fn, int pos, byte * buf, int len)
-
 
50
{
38
    unsigned int tmp;
51
    uint64_t aux;
-
 
52
   
-
 
53
    int offset = pos % 8;
-
 
54
    int aligned_pos = pos - offset;
-
 
55
   
-
 
56
    if (len + offset > 8) {
-
 
57
        len = 8 - offset;
-
 
58
    }
-
 
59
   
-
 
60
    void *addr = CONF_ADDR(bus, dev, fn, aligned_pos);
-
 
61
    aux = pio_read_64(addr);
39
   
62
   
-
 
63
    int i;
-
 
64
    for (i = 0; i < len; i++) {
-
 
65
        buf[i] = ((byte *)(&aux))[offset + i];
-
 
66
    }  
-
 
67
}
-
 
68
 
-
 
69
static int us2i_detect(struct pci_access *a)
-
 
70
{  
40
    /*
71
    /*
41
     * Gain control over PCI configuration ports.
72
     * Gain control over PCI configuration ports.
42
     */
73
     */
43
    if (pio_enable((void *)PCI_CONF_BASE, PCI_CONF_SIZE, &conf_addr)) {
74
    if (pio_enable((void *)PCI_CONF_BASE, PCI_CONF_SIZE, &conf_addr)) {
44
        return 0;
75
        return 0;
45
    }
76
    }  
46
   
77
   
-
 
78
    u16 vendor_id, device_id;
-
 
79
    us2i_read_aligned(0, 0, 0, PCI_VENDOR_ID, &vendor_id, 2);
47
    printf("PCI: conf_addr = %lx", conf_addr);
80
    vendor_id = cpu_to_le16(vendor_id);
-
 
81
    us2i_read_aligned(0, 0, 0, PCI_DEVICE_ID, &device_id, 2);
-
 
82
    device_id = cpu_to_le16(device_id);
-
 
83
 
-
 
84
    //int vendor_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID)));  
-
 
85
    //int device_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID)));
48
    printf("PCI: vendor id address = %lx", CONF_ADDR(0, 0, 0, PCI_VENDOR_ID));
86
    //int vendor_id = pio_read_8(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID));
-
 
87
    //vendor_id = vendor_id + pio_read_8(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID + 1)) << 8;
-
 
88
    //int device_id = pio_read_8(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID));
-
 
89
    //device_id = device_id | pio_read_8(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID + 1)) << 8;
49
   
90
   
50
    asm volatile ("sethi 0x42224, %g0");
-
 
51
    int vendor_id = pio_read_16(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID));
-
 
52
    vendor_id = vendor_id | pio_read_8(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID + 1)) << 8;
-
 
53
    int device_id = pio_read_8(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID));
-
 
54
    device_id = device_id | pio_read_8(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID + 1)) << 8;
-
 
55
   
-
 
56
    printf("PCI: vendor id = %x", vendor_id);
91
    printf("PCI: vendor id = %x\n", vendor_id);
57
    printf("PCI: device id = %x", device_id);
92
    printf("PCI: device id = %x\n", device_id);
58
 
93
 
59
    return vendor_id == 0x108E && device_id == 0x8000; // should be Psycho from Sun Microsystems
94
    // return vendor_id == 0x108E && device_id == 0x8000; // should be Psycho from Sun Microsystems ???
-
 
95
    //return vendor_id == 0x108E /*&& device_id == 0x1000*/; // should be Psycho from Sun Microsystems
-
 
96
    return 1;
60
}
97
}
61
 
98
 
62
static int us2i_read(struct pci_dev *d, int pos, byte * buf, int len)
99
static int us2i_read(struct pci_dev *d, int pos, byte * buf, int len)
63
{
100
{
-
 
101
    void * addr = CONF_ADDR(d->bus, d->dev, d->func, pos); 
-
 
102
   
64
    if (pos >= 256)
103
    if (pos >= 256)
65
        return 0;      
104
        return 0;      
66
 
105
 
67
    switch (len) {
106
    switch (len) {
68
    case 1:
107
    case 1:
-
 
108
        us2i_read_aligned(d->bus, d->dev, d->func, pos, buf, len);
-
 
109
        break;
-
 
110
    case 2:
-
 
111
        us2i_read_aligned(d->bus, d->dev, d->func, pos, buf, len);
-
 
112
        ((u16 *) buf)[0] = cpu_to_le16(*((u16 *) buf));
-
 
113
        break;
-
 
114
    case 4:
-
 
115
        us2i_read_aligned(d->bus, d->dev, d->func, pos, buf, len);
-
 
116
        ((u32 *) buf)[0] = cpu_to_le32(*((u32 *) buf));    
-
 
117
        break;
-
 
118
    default:
-
 
119
        return pci_generic_block_read(d, pos, buf, len);
-
 
120
    }
-
 
121
    return 1;
-
 
122
   
-
 
123
    /*
-
 
124
    void * addr = CONF_ADDR(d->bus, d->dev, d->func, pos); 
-
 
125
   
-
 
126
    if (pos >= 256)
-
 
127
        return 0;      
-
 
128
 
-
 
129
    switch (len) {
-
 
130
    case 1:
-
 
131
        buf[0] = pio_read_8(addr);
-
 
132
        break;
-
 
133
    case 2:
-
 
134
        ((u16 *) buf)[0] = cpu_to_le16(pio_read_16(addr));
-
 
135
        break;
-
 
136
    case 4:
-
 
137
        ((u32 *) buf)[0] = cpu_to_le32(pio_read_32(addr));     
-
 
138
        break;
-
 
139
    default:
-
 
140
        return pci_generic_block_read(d, pos, buf, len);
-
 
141
    }
-
 
142
    return 1; */
-
 
143
   
-
 
144
    /*if (pos >= 256)
-
 
145
        return 0;      
-
 
146
 
-
 
147
    switch (len) {
-
 
148
    case 1:
69
        buf[0] = pio_read_8(CONF_ADDR(d->bus, d->dev, d->func, pos));
149
        buf[0] = pio_read_8(CONF_ADDR(d->bus, d->dev, d->func, pos));
70
        break;
150
        break;
71
    case 2:
151
    case 2:
72
        us2i_read(d, pos + 1, buf, 1);   // unlike PCI, sparc uses big endian
152
        us2i_read(d, pos + 1, buf, 1);   // unlike PCI, sparc uses big endian
73
        us2i_read(d, pos, buf + 1, 1);
153
        us2i_read(d, pos, buf + 1, 1);
Line 79... Line 159...
79
        us2i_read(d, pos, buf + 3, 1);     
159
        us2i_read(d, pos, buf + 3, 1);     
80
        break;
160
        break;
81
    default:
161
    default:
82
        return pci_generic_block_read(d, pos, buf, len);
162
        return pci_generic_block_read(d, pos, buf, len);
83
    }
163
    }
84
    return 1;
164
    return 1;*/
85
}
165
}
86
 
166
 
87
static int us2i_write(struct pci_dev *d, int pos, byte * buf, int len)
167
static int us2i_write(struct pci_dev *d, int pos, byte * buf, int len)
88
{
168
{
-
 
169
    void * addr = CONF_ADDR(d->bus, d->dev, d->func, pos);
-
 
170
 
89
    if (pos >= 256)
171
    if (pos >= 256)
90
        return 0;
172
        return 0;
91
 
173
 
92
    switch (len) {
174
    switch (len) {
93
    case 1:
175
    case 1:
94
        pio_write_8(CONF_ADDR(d->bus, d->dev, d->func, pos), buf[0]);
176
        pio_write_8(CONF_ADDR(d->bus, d->dev, d->func, pos), buf[0]);
95
        break;
177
        break;
96
    case 2:
178
    case 2:
97
        us2i_write(d, pos + 1, buf, 1);   // unlike PCI, sparc uses big endian
-
 
98
        us2i_write(d, pos, buf + 1, 1);
179
        pio_write_16(addr, le16_to_cpu(((u16 *) buf)[0]));
99
        break;
180
        break;
100
    case 4:
181
    case 4:
101
        us2i_write(d, pos + 3, buf, 1);  // endians in an ugly way ... FIX ME 
-
 
102
        us2i_write(d, pos + 2, buf + 1, 1);
-
 
103
        us2i_write(d, pos + 1, buf + 2, 1);
182
        pio_write_32(addr, le32_to_cpu(((u32 *) buf)[0]));
104
        us2i_write(d, pos, buf + 3, 1);
-
 
105
        break;
183
        break;
106
    default:
184
    default:
107
        return pci_generic_block_write(d, pos, buf, len);
185
        return pci_generic_block_write(d, pos, buf, len);
108
    }
186
    }
109
    return 1;
187
    return 1;