mirror of https://github.com/acidanthera/audk.git
fixed the following problems:
1) DMA interrupt don't been cleaning up after one UDMA operation 2) Global variable mHobStart is not updated after invoking CoreInitializeGcdServices() func in the dxemain. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4107 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
cba02989d1
commit
6979fd9382
|
@ -56,6 +56,7 @@ ATAIdentify (
|
|||
EFI_IDENTIFY_DATA *AtaIdentifyPointer;
|
||||
UINT32 Capacity;
|
||||
UINT8 DeviceSelect;
|
||||
UINTN Retry;
|
||||
|
||||
//
|
||||
// AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
|
||||
|
@ -68,6 +69,10 @@ ATAIdentify (
|
|||
// and receive data from device
|
||||
//
|
||||
DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
|
||||
|
||||
|
||||
Retry = 3;
|
||||
while (Retry > 0) {
|
||||
Status = AtaPioDataIn (
|
||||
IdeDev,
|
||||
(VOID *) AtaIdentifyPointer,
|
||||
|
@ -115,6 +120,20 @@ ATAIdentify (
|
|||
// It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
} else if (Status == EFI_DEVICE_ERROR) {
|
||||
//
|
||||
// Some disk with big capacity (>200GB) is slow when being identified
|
||||
// and will return all zero for word83.
|
||||
// We try twice at first. If it fails, we do a SoftRest and try again.
|
||||
//
|
||||
Retry--;
|
||||
if (Retry == 1) {
|
||||
//
|
||||
// Do a SoftRest before the third attempt.
|
||||
//
|
||||
AtaSoftReset (IdeDev);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// This is a hard disk <= 120GB capacity, treat it as normal hard disk
|
||||
|
@ -141,8 +160,10 @@ ATAIdentify (
|
|||
IdeDev->BlkIo.Media->LastBlock = Capacity - 1;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
gBS->FreePool (AtaIdentifyPointer);
|
||||
|
@ -167,8 +188,9 @@ ATAIdentify (
|
|||
and 48-bit addressing must be used
|
||||
|
||||
@retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but
|
||||
the capacity is below 120G, 48bit addressing is not
|
||||
needed
|
||||
the capacity is below 120G, 48bit addressing is not needed
|
||||
|
||||
@retval EFI_DEVICE_ERROR The identify data in IdeDev is incorrect
|
||||
|
||||
@note
|
||||
This function must be called after DEVICE_IDENTITY command has been
|
||||
|
@ -191,6 +213,13 @@ AtaAtapi6Identify (
|
|||
|
||||
Atapi6IdentifyStruct = IdeDev->pIdData;
|
||||
|
||||
if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & (BIT15 | BIT14)) != 0x4000) {
|
||||
//
|
||||
// Per ATA-6 spec, word83: bit15 is zero and bit14 is one
|
||||
//
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) {
|
||||
//
|
||||
// The device dosn't support 48 bit addressing
|
||||
|
@ -2298,18 +2327,17 @@ DoAtaUdma (
|
|||
}
|
||||
|
||||
//
|
||||
// Channel and device differential
|
||||
// Select device
|
||||
//
|
||||
Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
|
||||
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
|
||||
|
||||
//
|
||||
// Enable interrupt to support UDMA and Select device
|
||||
// Enable interrupt to support UDMA
|
||||
//
|
||||
DeviceControl = 0;
|
||||
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
|
||||
|
||||
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
|
||||
|
||||
if (IdePrimary == IdeDev->Channel) {
|
||||
IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
|
||||
IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
|
||||
|
@ -2324,6 +2352,31 @@ DoAtaUdma (
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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
|
||||
);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
RemainBlockNum = NumberOfBlocks;
|
||||
while (RemainBlockNum > 0) {
|
||||
|
||||
|
@ -2452,29 +2505,6 @@ DoAtaUdma (
|
|||
&RegisterValue
|
||||
);
|
||||
|
||||
//
|
||||
// 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
|
||||
);
|
||||
|
||||
if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {
|
||||
Status = AtaCommandIssueExt (
|
||||
IdeDev,
|
||||
|
@ -2530,6 +2560,7 @@ DoAtaUdma (
|
|||
// it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
|
||||
// So set the variable Count to 2000, for about 2 second timeout time.
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
Count = 2000;
|
||||
while (TRUE) {
|
||||
|
||||
|
@ -2543,31 +2574,8 @@ DoAtaUdma (
|
|||
);
|
||||
if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {
|
||||
if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {
|
||||
//
|
||||
// Clear START bit of BMIC register before return EFI_DEVICE_ERROR
|
||||
//
|
||||
IdeDev->PciIo->Io.Read (
|
||||
IdeDev->PciIo,
|
||||
EfiPciIoWidthUint8,
|
||||
EFI_PCI_IO_PASS_THROUGH_BAR,
|
||||
IoPortForBmic,
|
||||
1,
|
||||
&RegisterValue
|
||||
);
|
||||
|
||||
RegisterValue &= ~((UINT8)BMIC_START);
|
||||
|
||||
IdeDev->PciIo->Io.Write (
|
||||
IdeDev->PciIo,
|
||||
EfiPciIoWidthUint8,
|
||||
EFI_PCI_IO_PASS_THROUGH_BAR,
|
||||
IoPortForBmic,
|
||||
1,
|
||||
&RegisterValue
|
||||
);
|
||||
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
|
||||
IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
|
||||
return EFI_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2579,6 +2587,28 @@ DoAtaUdma (
|
|||
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
|
||||
IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
|
||||
//
|
||||
// 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
|
||||
);
|
||||
//
|
||||
// Read Status Register of IDE device to clear interrupt
|
||||
//
|
||||
RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);
|
||||
|
@ -2609,6 +2639,9 @@ DoAtaUdma (
|
|||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
|
||||
StartLba += NumberOfBlocks;
|
||||
}
|
||||
|
@ -2620,5 +2653,6 @@ DoAtaUdma (
|
|||
DeviceControl |= ATA_CTLREG_IEN_L;
|
||||
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ Returns:
|
|||
|
||||
EFI_STATUS
|
||||
CoreInitializeGcdServices (
|
||||
IN VOID **HobStart,
|
||||
IN OUT VOID **HobStart,
|
||||
IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
|
||||
IN UINT64 MemoryLength
|
||||
)
|
||||
|
@ -367,7 +367,8 @@ Routine Description:
|
|||
memory map, so memory allocations and resource allocations can be made. The first
|
||||
part of this function can not depend on any memory services until at least one
|
||||
memory descriptor is provided to the memory services. Then the memory services
|
||||
can be used to intialize the GCD map.
|
||||
can be used to intialize the GCD map. The HobStart will be relocated to a pool
|
||||
buffer.
|
||||
|
||||
Arguments:
|
||||
|
||||
|
|
|
@ -299,6 +299,10 @@ Returns:
|
|||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// The HobStart is relocated in gcd service init. Sync mHobStart varible.
|
||||
//
|
||||
mHobStart = HobStart;
|
||||
|
||||
// Install the DXE Services Table into the EFI System Tables's Configuration Table
|
||||
//
|
||||
Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);
|
||||
|
@ -867,4 +871,3 @@ DxeMainUefiDecompress (
|
|||
|
||||
return UefiDecompress (Source, Destination, Scratch);
|
||||
}
|
||||
|
||||
|
|
|
@ -2242,7 +2242,7 @@ Returns:
|
|||
|
||||
EFI_STATUS
|
||||
CoreInitializeGcdServices (
|
||||
IN VOID **HobStart,
|
||||
IN OUT VOID **HobStart,
|
||||
IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
|
||||
IN UINT64 MemoryLength
|
||||
)
|
||||
|
@ -2255,7 +2255,8 @@ Routine Description:
|
|||
memory map, so memory allocations and resource allocations can be made. The first
|
||||
part of this function can not depend on any memory services until at least one
|
||||
memory descriptor is provided to the memory services. Then the memory services
|
||||
can be used to intialize the GCD map.
|
||||
can be used to intialize the GCD map. The HobStart will be relocated to a pool
|
||||
buffer.
|
||||
|
||||
Arguments:
|
||||
|
||||
|
|
Loading…
Reference in New Issue