/branches/dd/uspace/srv/pci/pci.h |
---|
4,6 → 4,7 |
//#include <arch/types.h> |
#include <libadt/list.h> |
#include <stdio.h> |
#include <stdlib.h> |
struct pci_drv; |
struct pci_dev; |
/branches/dd/uspace/srv/pci/psycho.c |
---|
85,9 → 85,7 |
uint8_t pci_conf_read_8(pci_dev_t *dev, int reg) |
{ |
uint8_t res; |
futex_down(&pci_conf_futex); |
psycho_conf_read(dev, reg, &res, sizeof(uint8_t)); |
futex_up(&pci_conf_futex); |
return res; |
} |
94,9 → 92,7 |
uint16_t pci_conf_read_16(pci_dev_t *dev, int reg) |
{ |
uint16_t res; |
futex_down(&pci_conf_futex); |
psycho_conf_read(dev, reg, (uint8_t *)(&res), sizeof(uint16_t)); |
futex_up(&pci_conf_futex); |
return res; |
} |
103,9 → 99,7 |
uint32_t pci_conf_read_32(pci_dev_t *dev, int reg) |
{ |
uint32_t res; |
futex_down(&pci_conf_futex); |
psycho_conf_read(dev, reg, (uint8_t *)(&res), sizeof(uint32_t)); |
futex_up(&pci_conf_futex); |
return res; |
} |
121,6 → 115,7 |
static void psycho_conf_read(pci_dev_t *d, int reg, uint8_t *buf, int len) |
{ |
futex_down(&pci_conf_futex); |
switch (len) { |
case 1: |
buf[0] = pio_read_8(psycho_conf_addr(d, reg)); |
132,10 → 127,12 |
*((uint32_t *)buf) = invert_endianness_32(pio_read_32(psycho_conf_addr(d, reg))); |
break; |
} |
futex_up(&pci_conf_futex); |
} |
static void psycho_conf_write(pci_dev_t *d, int reg, uint8_t *buf, int len) |
{ |
futex_down(&pci_conf_futex); |
switch (len) { |
case 1: |
pio_write_8(psycho_conf_addr(d, reg), buf[0]); |
147,6 → 144,7 |
pio_write_32(psycho_conf_addr(d, reg), invert_endianness_32(*((uint32_t *)buf))); |
break; |
} |
futex_up(&pci_conf_futex); |
} |
/* pci bus structure initialization */ |
/branches/dd/uspace/srv/pci/pci.c |
---|
26,17 → 26,19 |
bool multi; |
uint8_t header_type; |
printf("PCI: scanning bus number %d\n", bus->num); |
for (dnum = 0; dnum < 256; dnum++) { |
for (dnum = 0; dnum < 32; dnum++) { |
multi = true; |
for (fnum = 0; multi && fnum < 8; fnum++) { |
pci_init_dev(dev, bus, dnum, fnum); |
dev->vendor_id = pci_conf_read_16(dev, PCI_VENDOR_ID); |
dev->device_id = pci_conf_read_16(dev, PCI_DEVICE_ID); |
if (dev->vendor_id == 0xFFFF) { |
continue; // device is not present, go on scanning the bus |
if (dev->vendor_id == 0xFFFF) { // device is not present, go on scanning the bus |
if (fnum == 0) { |
break; |
} else { |
continue; |
} |
} |
header_type = pci_conf_read_8(dev, PCI_HEADER_TYPE); |
if (fnum == 0) { |
multi = header_type >> 7; // is the device multifunction? |
43,14 → 45,14 |
} |
header_type = header_type & 0x7F; // clear the multifunction bit |
printf("PCI: adding new device %d : %d", dnum, fnum); |
printf(" - vendor = 0x%x, device = 0x%x.\n", dev->vendor_id, dev->device_id); |
printf("PCI: adding new device %d : %d : %d", dev->bus->num, dnum, fnum); |
printf(" - vendor = 0x%04X, device = 0x%04X.\n", dev->vendor_id, dev->device_id); |
pci_device_register(dev); |
dev = pci_alloc_dev(); // alloc new aux. dev. structure |
if (header_type == PCI_HEADER_TYPE_BRIDGE || header_type == PCI_HEADER_TYPE_CARDBUS ) { |
bus_num = pci_conf_read_8(dev, PCI_BRIDGE_SEC_BUS_NUM); |
if(bus_num != bus->num) { |
printf("PCI: device is pci-to-pci bridge, secondary bus number = %d.\n", bus_num); |
if(bus_num > bus->num) { |
child_bus = pci_alloc_bus(); |
pci_init_bus(child_bus, bus, bus_num); |
pci_bus_register(child_bus); |
57,6 → 59,8 |
pci_bus_scan(child_bus); |
} |
} |
dev = pci_alloc_dev(); // alloc new aux. dev. structure |
} |
} |
/branches/dd/uspace/srv/pci/Makefile |
---|
50,6 → 50,10 |
SOURCES += psycho.c |
endif |
ifeq ($(UARCH), ia32) |
SOURCES += intel_method1.c |
endif |
CFLAGS += -D$(UARCH) |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
/branches/dd/uspace/srv/pci/intel_method1.c |
---|
0,0 → 1,95 |
#include <ddi.h> |
#include <libarch/ddi.h> |
#include <futex.h> |
#include "pci.h" |
#include "pci_bus.h" |
#include "pci_conf.h" |
#define CONF_ADDR_PORT 0xCF8 |
#define CONF_DATA_PORT 0xCFC |
#define CONF_PORT_SIZE 4 |
static void *conf_addr_port = NULL; |
static void *conf_data_port = NULL; |
static atomic_t pci_conf_futex = FUTEX_INITIALIZER; |
static void method1_conf_read(pci_dev_t *d, int reg, uint8_t *buf, int len); |
#define CONF_ADDR(bus, dev, fn, reg) ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) |
uint8_t pci_conf_read_8(pci_dev_t *dev, int reg) |
{ |
uint8_t res; |
method1_conf_read(dev, reg, &res, 1); |
return res; |
} |
uint16_t pci_conf_read_16(pci_dev_t *dev, int reg) |
{ |
uint16_t res; |
method1_conf_read(dev, reg, (uint8_t *)&res, 2); |
return res; |
} |
uint32_t pci_conf_read_32(pci_dev_t *dev, int reg) |
{ |
uint32_t res; |
method1_conf_read(dev, reg, (uint8_t *)&res, 4); |
return res; |
} |
static void method1_conf_read(pci_dev_t *dev, int reg, uint8_t *buf, int len) |
{ |
futex_down(&pci_conf_futex); |
uint32_t conf_addr = CONF_ADDR(dev->bus->num, dev->dev, dev->fn, reg); |
void *addr = conf_data_port + (reg & 3); |
pio_write_32(conf_addr_port, conf_addr); |
switch (len) { |
case 1: |
buf[0] = pio_read_8(addr); |
break; |
case 2: |
((uint16_t *)buf)[0] = pio_read_16(addr); |
break; |
case 4: |
((uint32_t *)buf)[0] = pio_read_32(addr); |
break; |
} |
futex_up(&pci_conf_futex); |
} |
int pci_bus_init() |
{ |
int error; |
if (error = pio_enable((void *)CONF_ADDR_PORT, CONF_PORT_SIZE, &conf_addr_port)) { |
printf("PCI: failed to enable configuration address port (error %d)\n", error); |
return 0; |
} |
if (error = pio_enable((void *)CONF_DATA_PORT, CONF_PORT_SIZE, &conf_data_port)) { |
printf("PCI: failed to enable configuration data port (error %d)\n", error); |
return 0; |
} |
pci_bus_t *bus = pci_alloc_bus(); |
bus->data = NULL; |
bus->num = 0; |
pci_bus_register(bus); |
pci_bus_scan(bus); |
return 1; |
} |
void pci_bus_clean() |
{ |
} |
/* pci bus structure initialization */ |
void pci_init_bus_data(pci_bus_t *bus, pci_bus_t *parent) |
{ |
bus->data = NULL; |
} |