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:
parent
4cc6d1c38b
commit
1626396b9d
8
src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile
Normal file
8
src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile
Normal file
@ -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
|
||||
;
|
27
src/add-ons/kernel/bus_managers/pci/arch/x86/bios.c
Normal file
27
src/add-ons/kernel/bus_managers/pci/arch/x86/bios.c
Normal file
@ -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)
|
||||
{
|
||||
}
|
7
src/add-ons/kernel/bus_managers/pci/arch/x86/bios.h
Normal file
7
src/add-ons/kernel/bus_managers/pci/arch/x86/bios.h
Normal file
@ -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 "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
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
read_pci_config(uint8 bus, uint8 device, uint8 function, uint8 offset, uint8 size)
|
||||
status_t
|
||||
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
|
||||
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 "arch_cpu.h"
|
||||
|
||||
status_t
|
||||
pci_io_init()
|
||||
{
|
||||
// nothing to do on x86 hardware
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
read_io_8(int mapped_io_addr)
|
||||
pci_read_io_8(int mapped_io_addr)
|
||||
{
|
||||
return 0;
|
||||
return in8(mapped_io_addr);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
read_io_16(int mapped_io_addr)
|
||||
pci_read_io_16(int mapped_io_addr)
|
||||
{
|
||||
return 0;
|
||||
return in16(mapped_io_addr);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
read_io_32(int mapped_io_addr)
|
||||
pci_read_io_32(int mapped_io_addr)
|
||||
{
|
||||
return 0;
|
||||
return in32(mapped_io_addr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
write_io_32(int mapped_io_addr, uint32 value)
|
||||
pci_write_io_32(int mapped_io_addr, uint32 value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ram_address(const void *physical_address_in_system_memory)
|
||||
{
|
||||
return 0;
|
||||
out32(value, mapped_io_addr);
|
||||
}
|
||||
|
20
src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.c
Normal file
20
src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.c
Normal file
@ -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)
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user