Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4437 → Rev 4438

/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/pci_conf.h
7,4 → 7,4
uint16_t pci_conf_read_16(pci_dev_t *dev, int reg);
uint32_t pci_conf_read_32(pci_dev_t *dev, int reg);
 
#endif
#endif
/branches/dd/uspace/srv/pci/psycho.c
84,10 → 84,8
 
uint8_t pci_conf_read_8(pci_dev_t *dev, int reg)
{
uint8_t res;
futex_down(&pci_conf_futex);
uint8_t res;
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);
psycho_conf_read(dev, reg, (uint8_t *)(&res), sizeof(uint32_t));
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));
131,11 → 126,13
case 4:
*((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_bus.h
4,4 → 4,4
int pci_bus_init();
void pci_bus_clean();
 
#endif
#endif
/branches/dd/uspace/srv/pci/pci.c
26,16 → 26,18
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) {
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);
pci_device_register(dev);
dev = pci_alloc_dev(); // alloc new aux. dev. structure
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);
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;
}