AHCI: MSI updates

Disable MSIs on device initialzation. Add ACPI-driver to run script
This commit is contained in:
Sebastian Sumpf 2012-02-25 21:29:30 +01:00 committed by Norman Feske
parent b6e355b841
commit c2c87c8833
2 changed files with 41 additions and 10 deletions

View File

@ -3,7 +3,7 @@
#
set build_components {
core init drivers/timer drivers/pci
core init drivers/timer drivers/pci drivers/acpi
drivers/ahci test/ahci
}
build $build_components
@ -32,10 +32,14 @@ set config {
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="pci">
<start name="acpi">
<resource name="RAM" quantum="2M"/>
<binary name="pci_drv"/>
<binary name="acpi_drv"/>
<provides><service name="PCI"/></provides>
<route>
<service name="ROM"> <parent/> </service>
<any-service> <any-child/> <parent/> </any-service>
</route>
</start>
<start name="timer">
<resource name="RAM" quantum="1M"/>
@ -63,7 +67,7 @@ install_config $config
#
set boot_modules {
core init timer pci_drv ahci_drv test-ahci
core init timer pci_drv ahci_drv test-ahci acpi_drv
}
build_boot_image $boot_modules

View File

@ -563,10 +563,10 @@ class Ahci_device
/* check for error */
enum {
INT_SETUP_FIS_DMA = 0x4,
INT_SETUP_FIS_PIO = 0x2,
INT_HOST_RIGSTER_FIS = 0x1,
INT_OK = INT_SETUP_FIS_DMA | INT_SETUP_FIS_PIO | INT_HOST_RIGSTER_FIS
INT_SETUP_FIS_DMA = 0x4,
INT_SETUP_FIS_PIO = 0x2,
INT_HOST_REGISTER_FIS = 0x1,
INT_OK = INT_SETUP_FIS_DMA | INT_SETUP_FIS_PIO | INT_HOST_REGISTER_FIS
};
if (!(status & INT_OK)) {
@ -581,6 +581,26 @@ class Ahci_device
_port->hba_disable();
}
static void _disable_msi(::Pci::Device_client &pci)
{
enum { PM_CAP_OFF = 0x34, MSI_CAP = 0x5, MSI_ENABLED = 0x1 };
uint8_t cap = pci.config_read(PM_CAP_OFF, ::Pci::Device::ACCESS_8BIT);
/* iterate through cap pointers */
for (uint16_t val = 0; cap; cap = val >> 8) {
val = pci.config_read(cap, ::Pci::Device::ACCESS_16BIT);
if ((val & 0xff) != MSI_CAP)
continue;
uint16_t msi = pci.config_read(cap + 2, ::Pci::Device::ACCESS_16BIT);
if (msi & MSI_ENABLED) {
pci.config_write(cap + 2, msi ^ MSI_CAP, ::Pci::Device::ACCESS_8BIT);
PINF("Disabled MSIs %x", msi);
}
}
}
public:
Ahci_device(addr_t base, Io_mem_session_capability io_cap)
@ -638,11 +658,18 @@ class Ahci_device
unsigned long intr = pci_device.config_read(AHCI_INTR_OFF,
::Pci::Device::ACCESS_32BIT);
if (verbose)
if (verbose) {
PDBG("Interrupt pin: %lu line: %lu", (intr >> 8) & 0xff, intr & 0xff);
device->_irq = new(env()->heap()) Irq_connection(intr & 0xff);
unsigned char bus, dev, func;
pci_device.bus_address(&bus, &dev, &func);
PDBG("Bus address: %x:%02x.%u (0x%x)", bus, dev, func, (bus << 8) | ((dev & 0x1f) << 3) | (func & 0x7));
}
/* disable message signaled interrupts */
_disable_msi(pci_device);
device->_irq = new(env()->heap()) Irq_connection(intr & 0xff);
pci.release_device(device_cap);
/* get device ready */