Subversion Repositories HelenOS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4300 trochtova 1
#include <unistd.h>
2
#include <ddi.h>
3
#include <libarch/ddi.h>
4
#include <stdio.h>
5
 
6
#include "internal.h"
7
 
8
/* physical addresses and offsets */
9
//#define U2P_BASE        0x1FE00000000
10
#define U2P_BASE        0x1c800000000
11
#define PCI_CONF_OFFSET   0x001000000
12
#define PCI_CONF_SIZE     0x001000000
13
#define PCI_CONF_BASE  (U2P_BASE + PCI_CONF_OFFSET)
14
 
15
/* virtual address of PCI configuration space */
16
static void *conf_addr = 0;  
17
 
18
/*
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)
21
 * dev ... device number (0 - 31)
22
 * fn  ... function number (0 - 7)
23
 * reg ... register number (register's position within PCI configuration header)
24
 **/
25
#define CONF_ADDR(bus, dev, fn, reg)   ((void *)(conf_addr + ((bus << 16) | (dev << 11) | (fn << 8) | reg)))
26
 
27
 
28
 
29
static void us2_init(struct pci_access *a)
30
{  
31
}
32
 
33
static void us2_cleanup(struct pci_access *a UNUSED)
34
{
35
}
36
 
37
static int us2_detect(struct pci_access *a)
38
{  
39
    /*
40
     * Gain control over PCI configuration ports.
41
     */
42
    if (pio_enable((void *)PCI_CONF_BASE, PCI_CONF_SIZE, &conf_addr)) {
43
        return 0;
44
    }  
45
 
46
    unsigned int vendor_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID)));  
47
    unsigned int device_id = le16_to_cpu(pio_read_16(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID)));
48
 
49
    // printf("PCI: vendor id = %x\n", vendor_id);
50
    // printf("PCI: device id = %x\n", device_id);
51
 
52
    return vendor_id == 0x108E && device_id == 0x8000; // should be Psycho from Sun Microsystems 
53
}
54
 
55
 
56
static int us2_read(struct pci_dev *d, int pos, byte * buf, int len)
57
{  
58
    if (pos >= 256)
59
        return 0;
60
 
61
    /* The vendor ID and the device ID registers of the device number 0 (the bridge)
62
     * work in simics in different way than the other config. registers. */
63
    if (d->dev == 0 && d->func == 0 && pos == 0 && len == 4) {    
64
        ((u32 *) buf)[0] = pio_read_32(CONF_ADDR(d->bus, d->dev, d->func, pos));
65
        return 1;
66
    }
67
 
68
    int i;
69
    for (i = 0; i < len; i++) {
70
        buf[i] = pio_read_8(CONF_ADDR(d->bus, d->dev, d->func, pos + i));
71
    }
72
    return 1;
73
}
74
 
75
static int us2_write(struct pci_dev *d, int pos, byte * buf, int len)
76
{
77
    if (pos >= 256)
78
        return 0;
79
 
80
    int i;
81
    for (i = 0; i < len; i++) {
82
         pio_write_8(CONF_ADDR(d->bus, d->dev, d->func, pos + i), buf[i]);
83
    }
84
    return 1;
85
}
86
 
87
 
88
struct pci_methods pm_us2 = {
89
    "Ultra Sparc IIi",
90
    NULL,           /* config */
91
    us2_detect,
92
    us2_init,
93
    us2_cleanup,
94
    pci_generic_scan,
95
    pci_generic_fill_info,
96
    us2_read,
97
    us2_write,
98
    NULL,           /* init_dev */
99
    NULL            /* cleanup_dev */
100
};