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:
eric_tian 2007-10-12 05:41:48 +00:00
parent cba02989d1
commit 6979fd9382
4 changed files with 163 additions and 124 deletions

View File

@ -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;
} }

View File

@ -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:

View File

@ -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);
} }

View File

@ -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: