First version of reading IRQ's that returns proper results.

There are TODO's in here, because the ACPI module needs restructuring and which I will take care of.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38289 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Fredrik Holmqvist 2010-08-20 19:48:49 +00:00
parent d7b1a83fc3
commit 59ada82f26
2 changed files with 49 additions and 89 deletions

View File

@ -11,7 +11,7 @@
#include <int.h>
//#define TRACE_PRT
#define TRACE_PRT
#ifdef TRACE_PRT
# define TRACE(x...) dprintf("IRQRoutingTable: "x)
#else
@ -49,8 +49,8 @@ print_irq_descriptor(irq_descriptor* descriptor)
const char* levelTriggeredString = "level triggered";
const char* edgeTriggeredString = " edge triggered";
dprintf("shareable: %i, polarity: %s, interrupt_mode: %s\n",
descriptor->shareable, descriptor->polarity == B_HIGH_ACTIVE_POLARITY
dprintf("irq: %i, shareable: %i, polarity: %s, interrupt_mode: %s\n",
descriptor->irq, descriptor->shareable, descriptor->polarity == B_HIGH_ACTIVE_POLARITY
? activeHighString : activeLowString,
descriptor->interrupt_mode == B_LEVEL_TRIGGERED ? levelTriggeredString
: edgeTriggeredString);
@ -67,34 +67,10 @@ print_irq_routing_table(IRQRoutingTable* table)
dprintf("pin: %i\n", entry.pin);
dprintf("source: %x\n", int(entry.source));
dprintf("source index: %i\n", entry.source_index);
dprintf("pci_bus: %i\n", entry.pci_bus);
dprintf("pci_device: %i\n", entry.pci_device);
}
}
static status_t
find_pci_device(pci_module_info *pci, irq_routing_entry* entry)
{
pci_info info;
int pciN = 0;
while ((*pci->get_nth_pci_info)(pciN, &info) == B_OK) {
pciN ++;
int16 deviceAddress = entry->device_address >> 16 & 0xFFFF;
if (info.device == deviceAddress
&& info.u.h0.interrupt_pin == entry->pin + 1) {
entry->pci_bus = info.bus;
entry->pci_device = info.device;
return B_OK;
}
}
return B_ERROR;
}
static status_t
read_device_irq_routing_table(pci_module_info *pci, acpi_module_info* acpi,
acpi_handle device, IRQRoutingTable* table)
@ -107,27 +83,16 @@ read_device_irq_routing_table(pci_module_info *pci, acpi_module_info* acpi,
return status;
irq_routing_entry irqEntry;
acpi_pci_routing_table* acpiTable
= (acpi_pci_routing_table*)buffer.pointer;
acpi_pci_routing_table* acpiTable = (acpi_pci_routing_table*)buffer.pointer;
while (acpiTable->length) {
irqEntry.device_address = acpiTable->address;
irqEntry.pin = acpiTable->pin;
acpi_handle source;
if (acpi->get_handle(device, acpiTable->source, &source) != B_OK)
continue;
irqEntry.source = source;
irqEntry.source_index = acpiTable->sourceIndex;
// connect to pci device
if (find_pci_device(pci, &irqEntry) != B_OK) {
TRACE("no pci dev found, device %x, pin %i\n",
irqEntry.device_address, irqEntry.pin);
acpiTable = (acpi_pci_routing_table*)((uint8*)acpiTable
+ acpiTable->length);
continue;
if (acpi->get_handle(NULL, acpiTable->source, &source) == B_OK) {
irqEntry.device_address = acpiTable->address;
irqEntry.pin = acpiTable->pin;
irqEntry.source = source;
irqEntry.source_index = acpiTable->sourceIndex;
table->PushBack(irqEntry);
}
table->PushBack(irqEntry);
acpiTable = (acpi_pci_routing_table*)((uint8*)acpiTable
+ acpiTable->length);
}
@ -156,24 +121,24 @@ read_irq_routing_table(pci_module_info *pci, acpi_module_info* acpi,
if (status != B_OK)
return status;
TRACE("find p2p \n");
TRACE("find routing tables \n");
char result[255];
result[0] = 0;
char name[255];
name[0] = 0;
void *counter = NULL;
while (acpi->get_next_entry(ACPI_TYPE_DEVICE, rootPciName, result, 255,
while (acpi->get_next_entry(ACPI_TYPE_DEVICE, rootPciName, name, 255,
&counter) == B_OK) {
acpi_handle brigde;
status = acpi->get_handle(NULL, result, &brigde);
status = acpi->get_handle(NULL, name, &brigde);
if (status != B_OK)
continue;
status = read_device_irq_routing_table(pci, acpi, brigde, table);
if (status == B_OK)
TRACE("p2p found %s\n", result);
TRACE("routing table found %s\n", name);
}
return status;
return table->Count() > 0 ? B_OK : B_ERROR;
}
@ -184,50 +149,31 @@ read_irq_descriptor(acpi_module_info* acpi, acpi_handle device,
acpi_data buffer;
buffer.pointer = NULL;
buffer.length = ACPI_ALLOCATE_BUFFER;
status_t status = acpi->evaluate_method(device, method, NULL,
&buffer);
status_t status = acpi->get_current_resources(device, &buffer);
if (status != B_OK) {
free(buffer.pointer);
return status;
}
acpi_object_type* resourceBuffer = (acpi_object_type*)buffer.pointer;
if (resourceBuffer[0].object_type != ACPI_TYPE_BUFFER)
return B_ERROR;
acpi_resource* resource = (acpi_resource*)buffer.pointer;
//TODO Don't hardcode END TAG
while (resource->type != 7) {
//TODO: Don't hardcode IRQ or Extended IRQ
if (resource->type == 0 || resource->type == 15) {
descriptor->irq = resource->interrupts[0];
descriptor->shareable = resource->sharable != 0;
descriptor->interrupt_mode = resource->triggering == 0 ?
B_LEVEL_TRIGGERED : B_EDGE_TRIGGERED;
descriptor->polarity = resource->polarity == 0 ?
B_HIGH_ACTIVE_POLARITY : B_LOW_ACTIVE_POLARITY;
int8* resourcePointer = (int8*)resourceBuffer[0].data.buffer.buffer;
int8 integer = resourcePointer[0];
if (integer >> 3 != kIRQDescriptor) {
TRACE("resource is not a irq descriptor\n");
return B_ERROR;
free(buffer.pointer);
return B_OK;
}
resource = (acpi_resource*)((uint8*)resource + resource->length);
}
int8 size = resourcePointer[0] & 0x07;
if (size < 2) {
TRACE("invalid resource size\n");
return B_ERROR;
}
descriptor->irq = resourcePointer[2];
descriptor->irq = descriptor->irq << 8;
descriptor->irq |= resourcePointer[1];
// if size equal 2 we are don't else read the third entry
if (size == 2)
return B_OK;
int irqInfo = resourcePointer[3];
int bit;
bit = irqInfo & 0x01;
descriptor->interrupt_mode = (bit == 0) ? B_LEVEL_TRIGGERED
: B_EDGE_TRIGGERED;
bit = irqInfo >> 3 & 0x01;
descriptor->polarity = (bit == 0) ? B_HIGH_ACTIVE_POLARITY
: B_LOW_ACTIVE_POLARITY;
descriptor->shareable = irqInfo >> 4 & 0x01;
return B_OK;
free(buffer.pointer);
return B_ERROR;
}

View File

@ -51,6 +51,20 @@ typedef struct acpi_prt {
// all cases
} acpi_pci_routing_table;
//TODO: Hack until we expose ACPI structs better, currently hardcoded to
// ACPI_RESOURCE_IRQ
struct acpi_resource {
uint32 type;
uint32 length;
uint8 descriptorLength;
uint8 triggering;
uint8 polarity;
uint8 sharable;
uint8 interruptCount;
uint8 interrupts[];
};
void print_irq_descriptor(irq_descriptor* descriptor);
void print_irq_routing_table(IRQRoutingTable* table);