From 905dd497d2d481c50ff4856f06322309956fb068 Mon Sep 17 00:00:00 2001 From: jchen20 Date: Wed, 13 Sep 2006 02:22:42 +0000 Subject: Modify for enabling native VISTA git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1520 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c | 97 ++++++++++++++++++++++++++++++++ EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h | 15 +++++ EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c | 14 +++++ 3 files changed, 126 insertions(+) (limited to 'EdkModulePkg') diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c index 5a65995c26..80ee854e1d 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c @@ -1769,3 +1769,100 @@ EnableInterrupt ( return EFI_SUCCESS; } +/** + Clear pending IDE interrupt before OS loader/kernel take control of the IDE device. + + @param[in] Event Pointer to this event + @param[in] Context Event hanlder private data + + @retval EFI_SUCCESS - Interrupt cleared + +**/ +EFI_STATUS +ClearInterrupt ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINT64 IoPortForBmis; + UINT8 RegisterValue; + IDE_BLK_IO_DEV *IdeDev; + + // + // Get our context + // + IdeDev = (IDE_BLK_IO_DEV *) Context; + + // + // Obtain IDE IO port registers' base addresses + // + Status = ReassignIdeResources (IdeDev); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Check whether interrupt is pending + // + + // + // Reset IDE device to force it de-assert interrupt pin + // Note: this will reset all devices on this IDE channel + // + AtaSoftReset (IdeDev); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get base address of IDE Bus Master Status Regsiter + // + if (IdePrimary == IdeDev->Channel) { + IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET; + } else { + if (IdeSecondary == IdeDev->Channel) { + IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET; + } else { + return EFI_UNSUPPORTED; + } + } + // + // Read BMIS register and clear ERROR and INTR bit + // + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmis, + 1, + &RegisterValue + ); + + RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR); + + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmis, + 1, + &RegisterValue + ); + + // + // Select the other device on this channel to ensure this device to release the interrupt pin + // + if (IdeDev->Device == 0) { + RegisterValue = (1 << 4) | 0xe0; + } else { + RegisterValue = (0 << 4) | 0xe0; + } + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + RegisterValue + ); + + return EFI_SUCCESS; +} diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h index 177e842714..b3e54ef372 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h @@ -1304,5 +1304,20 @@ EnableInterrupt ( IN IDE_BLK_IO_DEV *IdeDev ) ; +/** + Clear pending IDE interrupt before OS loader/kernel take control of the IDE device. + + @param[in] Event Pointer to this event + @param[in] Context Event hanlder private data + + @retval EFI_SUCCESS - Interrupt cleared + +**/ +EFI_STATUS +ClearInterrupt ( + IN EFI_EVENT Event, + IN VOID *Context + ) +; #endif diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c index e5157dab70..45baa9ec87 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c @@ -183,6 +183,7 @@ IDEBusDriverBindingStart ( UINTN DataSize; UINT32 Attributes; IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; + EFI_EVENT Event; // // Local variables declaration for IdeControllerInit support @@ -696,6 +697,19 @@ IDEBusDriverBindingStart ( (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE), IdeBlkIoDevicePtr->DevicePath ); + + // + // Create event to clear pending IDE interrupt + // + Status = gBS->CreateEvent ( + EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES, + EFI_TPL_NOTIFY, + ClearInterrupt, + IdeBlkIoDevicePtr, + &Event + ); + + // // end of 2nd inner loop ---- // -- cgit v1.2.3