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;
|
EFI_IDENTIFY_DATA *AtaIdentifyPointer;
|
||||||
UINT32 Capacity;
|
UINT32 Capacity;
|
||||||
UINT8 DeviceSelect;
|
UINT8 DeviceSelect;
|
||||||
|
UINTN Retry;
|
||||||
|
|
||||||
//
|
//
|
||||||
// AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
|
// AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
|
||||||
|
@ -68,6 +69,10 @@ ATAIdentify (
|
||||||
// and receive data from device
|
// and receive data from device
|
||||||
//
|
//
|
||||||
DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
|
DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
|
||||||
|
|
||||||
|
|
||||||
|
Retry = 3;
|
||||||
|
while (Retry > 0) {
|
||||||
Status = AtaPioDataIn (
|
Status = AtaPioDataIn (
|
||||||
IdeDev,
|
IdeDev,
|
||||||
(VOID *) AtaIdentifyPointer,
|
(VOID *) AtaIdentifyPointer,
|
||||||
|
@ -115,6 +120,20 @@ ATAIdentify (
|
||||||
// It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
|
// It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
|
||||||
//
|
//
|
||||||
return EFI_SUCCESS;
|
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
|
// This is a hard disk <= 120GB capacity, treat it as normal hard disk
|
||||||
|
@ -141,8 +160,10 @@ ATAIdentify (
|
||||||
IdeDev->BlkIo.Media->LastBlock = Capacity - 1;
|
IdeDev->BlkIo.Media->LastBlock = Capacity - 1;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gBS->FreePool (AtaIdentifyPointer);
|
gBS->FreePool (AtaIdentifyPointer);
|
||||||
|
@ -167,8 +188,9 @@ ATAIdentify (
|
||||||
and 48-bit addressing must be used
|
and 48-bit addressing must be used
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but
|
@retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but
|
||||||
the capacity is below 120G, 48bit addressing is not
|
the capacity is below 120G, 48bit addressing is not needed
|
||||||
needed
|
|
||||||
|
@retval EFI_DEVICE_ERROR The identify data in IdeDev is incorrect
|
||||||
|
|
||||||
@note
|
@note
|
||||||
This function must be called after DEVICE_IDENTITY command has been
|
This function must be called after DEVICE_IDENTITY command has been
|
||||||
|
@ -191,6 +213,13 @@ AtaAtapi6Identify (
|
||||||
|
|
||||||
Atapi6IdentifyStruct = IdeDev->pIdData;
|
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) {
|
if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) {
|
||||||
//
|
//
|
||||||
// The device dosn't support 48 bit addressing
|
// 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);
|
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;
|
DeviceControl = 0;
|
||||||
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
|
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
|
||||||
|
|
||||||
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
|
|
||||||
|
|
||||||
if (IdePrimary == IdeDev->Channel) {
|
if (IdePrimary == IdeDev->Channel) {
|
||||||
IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
|
IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
|
||||||
IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_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;
|
RemainBlockNum = NumberOfBlocks;
|
||||||
while (RemainBlockNum > 0) {
|
while (RemainBlockNum > 0) {
|
||||||
|
|
||||||
|
@ -2452,29 +2505,6 @@ DoAtaUdma (
|
||||||
&RegisterValue
|
&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) {
|
if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {
|
||||||
Status = AtaCommandIssueExt (
|
Status = AtaCommandIssueExt (
|
||||||
IdeDev,
|
IdeDev,
|
||||||
|
@ -2530,6 +2560,7 @@ DoAtaUdma (
|
||||||
// it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
|
// 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.
|
// So set the variable Count to 2000, for about 2 second timeout time.
|
||||||
//
|
//
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
Count = 2000;
|
Count = 2000;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
|
||||||
|
@ -2543,31 +2574,8 @@ DoAtaUdma (
|
||||||
);
|
);
|
||||||
if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {
|
if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {
|
||||||
if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {
|
if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {
|
||||||
//
|
Status = EFI_DEVICE_ERROR;
|
||||||
// Clear START bit of BMIC register before return EFI_DEVICE_ERROR
|
break;
|
||||||
//
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2579,6 +2587,28 @@ DoAtaUdma (
|
||||||
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
|
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
|
||||||
IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
|
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
|
// Read Status Register of IDE device to clear interrupt
|
||||||
//
|
//
|
||||||
RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);
|
RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);
|
||||||
|
@ -2609,6 +2639,9 @@ DoAtaUdma (
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
|
DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
|
||||||
StartLba += NumberOfBlocks;
|
StartLba += NumberOfBlocks;
|
||||||
}
|
}
|
||||||
|
@ -2620,5 +2653,6 @@ DoAtaUdma (
|
||||||
DeviceControl |= ATA_CTLREG_IEN_L;
|
DeviceControl |= ATA_CTLREG_IEN_L;
|
||||||
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
|
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -354,7 +354,7 @@ Returns:
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
CoreInitializeGcdServices (
|
CoreInitializeGcdServices (
|
||||||
IN VOID **HobStart,
|
IN OUT VOID **HobStart,
|
||||||
IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
|
IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
|
||||||
IN UINT64 MemoryLength
|
IN UINT64 MemoryLength
|
||||||
)
|
)
|
||||||
|
@ -367,7 +367,8 @@ Routine Description:
|
||||||
memory map, so memory allocations and resource allocations can be made. The first
|
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
|
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
|
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:
|
Arguments:
|
||||||
|
|
||||||
|
|
|
@ -299,6 +299,10 @@ Returns:
|
||||||
ASSERT_EFI_ERROR (Status);
|
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
|
// Install the DXE Services Table into the EFI System Tables's Configuration Table
|
||||||
//
|
//
|
||||||
Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);
|
Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);
|
||||||
|
@ -867,4 +871,3 @@ DxeMainUefiDecompress (
|
||||||
|
|
||||||
return UefiDecompress (Source, Destination, Scratch);
|
return UefiDecompress (Source, Destination, Scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2242,7 +2242,7 @@ Returns:
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
CoreInitializeGcdServices (
|
CoreInitializeGcdServices (
|
||||||
IN VOID **HobStart,
|
IN OUT VOID **HobStart,
|
||||||
IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
|
IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
|
||||||
IN UINT64 MemoryLength
|
IN UINT64 MemoryLength
|
||||||
)
|
)
|
||||||
|
@ -2255,7 +2255,8 @@ Routine Description:
|
||||||
memory map, so memory allocations and resource allocations can be made. The first
|
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
|
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
|
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:
|
Arguments:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue