added pci bios and irq router files

renamed io and configuration functions
implemented configuration mechanisms


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4727 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-09-17 15:57:53 +00:00
parent 4cc6d1c38b
commit 1626396b9d
6 changed files with 309 additions and 21 deletions
@@ -0,0 +1,8 @@
SubDir OBOS_TOP src add-ons kernel bus_managers pci arch x86 ;
KernelStaticLibrary pci_arch_x86_bus_manager :
bios.c
pci_config.c
pci_io.c
pci_irq.c
;
@@ -0,0 +1,27 @@
#include "pci_priv.h"
#include "bios.h"
void
pci_bios_init(void)
{
}
bool
pci_bios_available(void)
{
return false;
}
uint32
pci_bios_read_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size)
{
return 0;
}
void
pci_bios_write_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value)
{
}
@@ -0,0 +1,7 @@
void pci_bios_init(void);
bool pci_bios_available(void);
uint32 pci_bios_read_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size);
void pci_bios_write_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value);
@@ -1,20 +1,248 @@
#include <KernelExport.h>
#include "pci_priv.h" #include "pci_priv.h"
#include "bios.h"
#include "arch_cpu.h"
static uint32 (*gReadConfigFunc)(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size);
static void (*gWriteConfigFunc)(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value);
int gMaxBusDevices;
status_t detect_config_mechanism(void);
bool pci_config_access_ok(void);
uint32 pci_mech1_read_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size);
void pci_mech1_write_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value);
uint32 pci_mech2_read_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size);
void pci_mech2_write_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value);
#define PCI_MECH1_REQ_PORT 0xCF8
#define PCI_MECH1_DATA_PORT 0xCFC
#define PCI_MECH1_REQ_DATA(bus, device, func, offset) \
(0x80000000 | (bus << 16) | (device << 11) | (func << 8) | (offset & ~3))
#define PCI_MECH2_ENABLE_PORT 0x0cf8
#define PCI_MECH2_FORWARD_PORT 0x0cfa
#define PCI_MECH2_CONFIG_PORT(dev, offset) \
(uint16)(0xC00 | (dev << 8) | offset)
status_t status_t
pci_config_init() pci_config_init(void)
{ {
pci_bios_init();
if (B_OK != detect_config_mechanism()) {
dprintf("PCI: failed to detect configuration mechanism\n");
return B_ERROR;
}
return B_OK; return B_OK;
} }
uint32 status_t
read_pci_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size) detect_config_mechanism(void)
{ {
return 0; // PCI configuration mechanism 1 is the preferred one.
// If it doesn't work, try mechanism 2.
// Finally, try to fallback to PCI BIOS
if (1) {
// check for mechanism 1
out32(0x80000000, PCI_MECH1_REQ_PORT);
if (0x80000000 == in32(PCI_MECH1_REQ_PORT)) {
dprintf("PCI: mechanism 1 found\n");
gMaxBusDevices = 32;
gReadConfigFunc = pci_mech1_read_config;
gWriteConfigFunc = pci_mech1_write_config;
if (pci_config_access_ok()) {
dprintf("PCI: using mechanism 1\n");
return B_OK;
}
}
}
if (1) {
// check for mechanism 2
out8(0x00, 0xCFB);
out8(0x00, 0xCF8);
out8(0x00, 0xCFA);
if (in8(0xCF8) == 0x00 && in8(0xCFA) == 0x00) {
dprintf("PCI: mechanism 2 found\n");
gMaxBusDevices = 16;
gReadConfigFunc = pci_mech2_read_config;
gWriteConfigFunc = pci_mech2_write_config;
if (pci_config_access_ok()) {
dprintf("PCI: using mechanism 2\n");
return B_OK;
}
}
}
if (1) {
// check for PCI BIOS
if (pci_bios_available()) {
gReadConfigFunc = pci_bios_read_config;
gWriteConfigFunc = pci_bios_write_config;
gMaxBusDevices = 32;
if (pci_config_access_ok()) {
dprintf("PCI: using PCI BIOS\n");
return B_OK;
}
}
}
dprintf("PCI: no configuration mechanism found\n");
return B_ERROR;
}
bool
pci_config_access_ok(void)
{
return true;
}
uint32
pci_read_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size)
{
return gReadConfigFunc(bus, device, function, offset, size);
} }
void void
write_pci_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value) pci_write_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value)
{
gWriteConfigFunc(bus, device, function, offset, size, value);
}
uint8
pci_read_irq(uint8 bus, uint8 device, uint8 function, uint8 line)
{ {
} }
void
pci_write_irq(uint8 bus, uint8 device, uint8 function, uint8 line, uint8 irq)
{
}
uint32
pci_mech1_read_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size)
{
uint32 result;
if (device > 31 || function > 7 || (size != 1 && size != 2 && size != 4)
|| (size == 2 && (offset & 3) == 3) || (size == 4 && (offset & 3) != 0)) {
dprintf("PCI: mech1 can't read config for bus %u, device %u, function %u, offset %u, size %u\n",
bus, device, function, offset, size);
return 0xffffffff;
}
out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT);
switch (size) {
case 1:
result = in8(PCI_MECH1_DATA_PORT + (offset & 3));
break;
case 2:
result = in16(PCI_MECH1_DATA_PORT + (offset & 3));
break;
case 4:
result = in32(PCI_MECH1_DATA_PORT);
break;
default:
result = 0xffffffff;
}
return result;
}
void
pci_mech1_write_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value)
{
if (device > 31 || function > 7 || (size != 1 && size != 2 && size != 4)
|| (size == 2 && (offset & 3) == 3) || (size == 4 && (offset & 3) != 0)) {
dprintf("PCI: mech1 can't write config for bus %u, device %u, function %u, offset %u, size %u\n",
bus, device, function, offset, size);
return;
}
out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT);
switch (size) {
case 1:
out8(value, PCI_MECH1_DATA_PORT + (offset & 3));
break;
case 2:
out16(value, PCI_MECH1_DATA_PORT + (offset & 3));
break;
case 4:
out32(value, PCI_MECH1_DATA_PORT);
break;
}
}
uint32
pci_mech2_read_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size)
{
uint32 result;
if (device > 15 || function > 7 || (size != 1 && size != 2 && size != 4)) {
dprintf("PCI: mech2 can't read config for bus %u, device %u, function %u, offset %u, size %u\n",
bus, device, function, offset, size);
return 0xffffffff;
}
out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT);
out8(bus, PCI_MECH2_FORWARD_PORT);
switch (size) {
case 1:
result = in8(PCI_MECH2_CONFIG_PORT(device, offset));
break;
case 2:
result = in16(PCI_MECH2_CONFIG_PORT(device, offset));
break;
case 4:
result = in32(PCI_MECH2_CONFIG_PORT(device, offset));
break;
default:
result = 0xffffffff;
}
out8(0, PCI_MECH2_ENABLE_PORT);
return result;
}
void
pci_mech2_write_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value)
{
if (device > 15 || function > 7 || (size != 1 && size != 2 && size != 4)) {
dprintf("PCI: mech2 can't write config for bus %u, device %u, function %u, offset %u, size %u\n",
bus, device, function, offset, size);
return;
}
out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT);
out8(bus, PCI_MECH2_FORWARD_PORT);
switch (size) {
case 1:
out8(value, PCI_MECH2_CONFIG_PORT(device, offset));
break;
case 2:
out16(value, PCI_MECH2_CONFIG_PORT(device, offset));
break;
case 4:
out32(value, PCI_MECH2_CONFIG_PORT(device, offset));
break;
}
out8(0, PCI_MECH2_ENABLE_PORT);
}
void *
pci_ram_address(const void *physical_address_in_system_memory)
{
return 0;
}
@@ -1,53 +1,51 @@
#include "pci_priv.h" #include "pci_priv.h"
#include "arch_cpu.h"
status_t status_t
pci_io_init() pci_io_init()
{ {
// nothing to do on x86 hardware
return B_OK; return B_OK;
} }
uint8 uint8
read_io_8(int mapped_io_addr) pci_read_io_8(int mapped_io_addr)
{ {
return 0; return in8(mapped_io_addr);
} }
void void
write_io_8(int mapped_io_addr, uint8 value) pci_write_io_8(int mapped_io_addr, uint8 value)
{ {
out8(value, mapped_io_addr);
} }
uint16 uint16
read_io_16(int mapped_io_addr) pci_read_io_16(int mapped_io_addr)
{ {
return 0; return in16(mapped_io_addr);
} }
void void
write_io_16(int mapped_io_addr, uint16 value) pci_write_io_16(int mapped_io_addr, uint16 value)
{ {
out16(value, mapped_io_addr);
} }
uint32 uint32
read_io_32(int mapped_io_addr) pci_read_io_32(int mapped_io_addr)
{ {
return 0; return in32(mapped_io_addr);
} }
void void
write_io_32(int mapped_io_addr, uint32 value) pci_write_io_32(int mapped_io_addr, uint32 value)
{ {
} out32(value, mapped_io_addr);
void *
ram_address(const void *physical_address_in_system_memory)
{
return 0;
} }
@@ -0,0 +1,20 @@
#include "pci_priv.h"
status_t
pci_irq_init(void)
{
return B_ERROR;
}
uint8
pci_read_irq(uint8 bus, uint8 device, uint8 function, uint8 line)
{
return 0;
}
void
pci_write_irq(uint8 bus, uint8 device, uint8 function, uint8 line, uint8 irq)
{
}