38 EFI_PCI_IO_PROTOCOL *PciIo;
43 UINT32 HdaRingLowerBaseAddr;
44 UINT32 HdaRingUpperBaseAddr;
46 UINTN BufferSizeActual;
50 ASSERT (HdaRingBuffer != NULL);
60 return EFI_INVALID_PARAMETER;
63 HdaRingBuffer->HdaDev = HdaDev;
64 HdaRingBuffer->Type = Type;
65 PciIo = HdaDev->PciIo;
71 if (EFI_ERROR (Status)) {
79 HdaRingBuffer->BufferSize = 256 * EntrySize;
82 HdaRingBuffer->BufferSize = 16 * EntrySize;
85 HdaRingBuffer->BufferSize = 2 * EntrySize;
91 return EFI_UNSUPPORTED;
94 HdaRingBuffer->Buffer = NULL;
95 HdaRingBuffer->Mapping = NULL;
100 Status = PciIo->AllocateBuffer (
104 EFI_SIZE_TO_PAGES (HdaRingBuffer->BufferSize),
105 &HdaRingBuffer->Buffer,
108 if (EFI_ERROR (Status)) {
112 ZeroMem (HdaRingBuffer->Buffer, HdaRingBuffer->BufferSize);
117 BufferSizeActual = HdaRingBuffer->BufferSize;
118 Status = PciIo->Map (
120 EfiPciIoOperationBusMasterCommonBuffer,
121 HdaRingBuffer->Buffer,
123 &HdaRingBuffer->PhysAddr,
124 &HdaRingBuffer->Mapping
126 if (EFI_ERROR (Status)) {
130 if (BufferSizeActual != HdaRingBuffer->BufferSize) {
131 return EFI_NO_MAPPING;
138 if (EFI_ERROR (Status)) {
145 HdaRingLowerBaseAddr = (UINT32)HdaRingBuffer->PhysAddr;
147 if (EFI_ERROR (Status)) {
155 HdaRingUpperBaseAddr = (UINT32)(HdaRingBuffer->PhysAddr >> 32);
157 if (EFI_ERROR (Status)) {
166 if (EFI_ERROR (Status)) {
169 "HDA: Reset %a - %r\n",
179 if (EFI_ERROR (Status)) {
184 HdaRingBuffer->EntryCount = (UINT32)(HdaRingBuffer->BufferSize / EntrySize);
187 "HDA controller ring buffer allocated @ 0x%p (0x%p) (%u entries)\n",
188 HdaRingBuffer->Buffer,
189 HdaRingBuffer->PhysAddr,
190 HdaRingBuffer->EntryCount
202 EFI_PCI_IO_PROTOCOL *PciIo;
204 ASSERT (HdaRingBuffer != NULL);
209 if (HdaRingBuffer->HdaDev == NULL) {
213 PciIo = HdaRingBuffer->HdaDev->PciIo;
219 if (HdaRingBuffer->Mapping != NULL) {
220 PciIo->Unmap (PciIo, HdaRingBuffer->Mapping);
223 if (HdaRingBuffer->Buffer != NULL) {
224 PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (HdaRingBuffer->BufferSize), HdaRingBuffer->Buffer);
227 HdaRingBuffer->Buffer = NULL;
228 HdaRingBuffer->BufferSize = 0;
229 HdaRingBuffer->EntryCount = 0;
230 HdaRingBuffer->Mapping = NULL;
231 HdaRingBuffer->PhysAddr = 0;
232 HdaRingBuffer->Pointer = 0;
233 HdaRingBuffer->HdaDev = NULL;
244 EFI_PCI_IO_PROTOCOL *PciIo;
250 PciIo = HdaRingBuffer->HdaDev->PciIo;
257 return EFI_INVALID_PARAMETER;
264 if (EFI_ERROR (Status)) {
274 HdaRingCtl |= CtlFlags;
276 HdaRingCtl &= ~CtlFlags;
280 if (EFI_ERROR (Status)) {
287 Status = PciIo->PollMem (
297 if (EFI_ERROR (Status)) {
310 EFI_PCI_IO_PROTOCOL *PciIo;
311 UINT16 HdaRingPointer;
312 UINT64 HdaRingPointerPollResult;
314 PciIo = HdaRingBuffer->HdaDev->PciIo;
325 if (EFI_ERROR (Status)) {
334 if (EFI_ERROR (Status)) {
340 if (EFI_ERROR (Status)) {
350 if (EFI_ERROR (Status)) {
355 if (EFI_ERROR (Status)) {
363 if (EFI_ERROR (Status)) {
369 if (EFI_ERROR (Status)) {
373 return EFI_INVALID_PARAMETER;
385 EFI_PCI_IO_PROTOCOL *PciIo;
386 UINT32 LowerBaseAddr;
387 UINT32 UpperBaseAddr;
388 EFI_PHYSICAL_ADDRESS DataBlockAddr;
391 UINT8 InputStreamsCount;
392 UINT8 OutputStreamsCount;
393 UINT8 BidirStreamsCount;
394 UINT32 TotalStreamsCount;
395 UINT32 OutputStreamsOffset;
396 UINT32 BidirStreamsOffset;
400 UINTN PciLengthActual;
404 PciIo = HdaDev->PciIo;
409 HdaDev->StreamIdMapping = BIT0;
414 TotalStreamsCount = InputStreamsCount + OutputStreamsCount + BidirStreamsCount;
415 OutputStreamsOffset = InputStreamsCount;
416 BidirStreamsOffset = OutputStreamsOffset + OutputStreamsCount;
418 HdaDev->StreamsCount = OutputStreamsCount + BidirStreamsCount;
419 HdaDev->Streams = AllocateZeroPool (
sizeof (
HDA_STREAM) * HdaDev->StreamsCount);
420 if (HdaDev->Streams == NULL) {
421 return EFI_OUT_OF_RESOURCES;
424 DEBUG ((DEBUG_VERBOSE,
"AudioDxe: Total output-capable streams: %u\n", HdaDev->StreamsCount));
426 for (Index = 0; Index < HdaDev->StreamsCount; Index++) {
427 HdaStream = &HdaDev->Streams[Index];
428 HdaStream->
HdaDev = HdaDev;
429 HdaStream->
Index = (UINT8)(Index + OutputStreamsOffset);
430 HdaStream->
IsBidirectional = Index + OutputStreamsOffset >= BidirStreamsOffset;
440 Status =
gBS->CreateEvent (
441 EVT_TIMER | EVT_NOTIFY_SIGNAL,
447 if (EFI_ERROR (Status)) {
455 Status = PciIo->AllocateBuffer (
463 if (EFI_ERROR (Status)) {
473 Status = PciIo->Map (
475 EfiPciIoOperationBusMasterCommonBuffer,
481 if (EFI_ERROR (Status) || (PciLengthActual !=
HDA_BDL_SIZE)) {
486 return EFI_UNSUPPORTED;
492 Status = PciIo->AllocateBuffer (
500 if (EFI_ERROR (Status)) {
510 Status = PciIo->Map (
512 EfiPciIoOperationBusMasterCommonBuffer,
538 Status = PciIo->AllocateBuffer (
542 EFI_SIZE_TO_PAGES (HdaDev->DmaPositionsSize),
543 (VOID **)&HdaDev->DmaPositions,
546 if (EFI_ERROR (Status)) {
550 ZeroMem (HdaDev->DmaPositions, HdaDev->DmaPositionsSize);
553 PciLengthActual = HdaDev->DmaPositionsSize;
554 Status = PciIo->Map (
556 EfiPciIoOperationBusMasterCommonBuffer,
557 HdaDev->DmaPositions,
559 &HdaDev->DmaPositionsPhysAddr,
560 &HdaDev->DmaPositionsMapping
562 if (EFI_ERROR (Status) || (PciLengthActual != HdaDev->DmaPositionsSize)) {
571 if (EFI_ERROR (Status)) {
579 UpperBaseAddr = (UINT32)(HdaDev->DmaPositionsPhysAddr >> 32);
581 if (EFI_ERROR (Status)) {
595 EFI_PCI_IO_PROTOCOL *PciIo;
596 UINT32 LowerBaseAddr;
597 UINT32 UpperBaseAddr;
605 ASSERT (HdaStream != NULL);
607 PciIo = HdaStream->HdaDev->PciIo;
613 if (EFI_ERROR (Status)) {
622 if (EFI_ERROR (Status)) {
627 Status = PciIo->PollMem (
637 if (EFI_ERROR (Status)) {
643 if (EFI_ERROR (Status)) {
650 HdaStreamCtl1 &= ~HDA_REG_SDNCTL1_SRST;
652 if (EFI_ERROR (Status)) {
656 Status = PciIo->PollMem (
666 if (EFI_ERROR (Status)) {
674 if (HdaStream->IsBidirectional) {
679 if (EFI_ERROR (Status)) {
688 if (EFI_ERROR (Status)) {
696 LowerBaseAddr = (UINT32)HdaStream->BufferListPhysAddr;
698 if (EFI_ERROR (Status)) {
706 UpperBaseAddr = (UINT32)(HdaStream->BufferListPhysAddr >> 32);
708 if (EFI_ERROR (Status)) {
719 if (EFI_ERROR (Status)) {
724 if (EFI_ERROR (Status)) {
728 HdaStream->DmaPositionTotal = 0;
729 HdaStream->DmaPositionLast = 0;
730 HdaStream->DmaPositionChangedMax = 0;
731 HdaStream->UseLpib = FALSE;
732 HdaStream->DmaCheckCount = 0;
733 HdaStream->DmaCheckComplete = FALSE;
743 EFI_PCI_IO_PROTOCOL *PciIo;
751 PciIo = HdaDev->PciIo;
753 if ((HdaDev->Streams != NULL) && (HdaDev->StreamsCount > 0)) {
754 for (Index = 0; Index < HdaDev->StreamsCount; Index++) {
755 HdaStream = &HdaDev->Streams[Index];
811 if (HdaDev->DmaPositionsMapping != NULL) {
812 PciIo->Unmap (PciIo, HdaDev->DmaPositionsMapping);
815 if (HdaDev->DmaPositions != NULL) {
816 PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (HdaDev->DmaPositionsSize), HdaDev->DmaPositions);
819 if (HdaDev->Streams != NULL) {
820 FreePool (HdaDev->Streams);
823 HdaDev->DmaPositionsMapping = NULL;
824 HdaDev->DmaPositions = NULL;
825 HdaDev->DmaPositionsSize = 0;
826 HdaDev->DmaPositionsPhysAddr = 0;
827 HdaDev->Streams = NULL;
828 HdaDev->StreamsCount = 0;
838 EFI_PCI_IO_PROTOCOL *PciIo;
841 ASSERT (HdaStream != NULL);
844 PciIo = HdaStream->HdaDev->PciIo;
850 if (EFI_ERROR (Status)) {
865 EFI_PCI_IO_PROTOCOL *PciIo;
869 ASSERT (HdaStream != NULL);
871 PciIo = HdaStream->HdaDev->PciIo;
877 if (EFI_ERROR (Status)) {
884 HdaStreamCtl1 &= ~HDA_REG_SDNCTL1_RUN;
891 if (EFI_ERROR (Status)) {
895 Status = PciIo->PollMem (
905 return !EFI_ERROR (Status);
915 EFI_PCI_IO_PROTOCOL *PciIo;
917 ASSERT (HdaStream != NULL);
918 ASSERT (Position != NULL);
920 PciIo = HdaStream->HdaDev->PciIo;
926 return !EFI_ERROR (Status);
936 EFI_PCI_IO_PROTOCOL *PciIo;
939 ASSERT (HdaStream != NULL);
942 PciIo = HdaStream->HdaDev->PciIo;
948 if (EFI_ERROR (Status)) {
963 EFI_PCI_IO_PROTOCOL *PciIo;
966 ASSERT (HdaStream != NULL);
968 PciIo = HdaStream->HdaDev->PciIo;
981 if (EFI_ERROR (Status)) {
990 return !EFI_ERROR (Status);
998 ASSERT (HdaStream != NULL);
1003 HdaStream->BufferActive = FALSE;
1004 HdaStream->BufferSource = NULL;
1005 HdaStream->BufferSourcePosition = 0;
1006 HdaStream->BufferSourceLength = 0;
1007 HdaStream->DmaPositionTotal = 0;
1017 ASSERT (HdaStream != NULL);
1025 gBS->SetTimer (HdaStream->PollTimer, TimerCancel, 0);
VOID EFIAPI HdaControllerStreamOutputPollTimerHandler(IN EFI_EVENT Event, IN VOID *Context)
#define HDA_CORB_ENTRY_SIZE
#define HDA_STREAM_BUF_SIZE
#define HDA_BDL_BLOCKSIZE
#define HDA_CONTROLLER_QUIRK_QEMU_1
#define HDA_BDL_ENTRY_COUNT
#define HDA_CONTROLLER_QUIRK_CORB_NO_POLL_RESET
#define HDA_BDL_ENTRY_LAST
#define HDA_RIRB_ENTRY_SIZE
@ HDA_RING_BUFFER_TYPE_RIRB
@ HDA_RING_BUFFER_TYPE_CORB
#define HDA_CONTROLLER_QUIRK_QEMU_2
EFI_STATUS HdaControllerSetRingBufferState(IN HDA_RING_BUFFER *HdaRingBuffer, IN BOOLEAN Enable, IN HDA_RING_BUFFER_TYPE Type)
VOID HdaControllerStreamIdle(IN HDA_STREAM *HdaStream)
VOID HdaControllerStreamAbort(IN HDA_STREAM *HdaStream)
EFI_STATUS HdaControllerInitStreams(IN HDA_CONTROLLER_DEV *HdaDev)
BOOLEAN HdaControllerResetStream(IN HDA_STREAM *HdaStream)
BOOLEAN HdaControllerSetStreamId(IN HDA_STREAM *HdaStream, IN UINT8 Index)
BOOLEAN HdaControllerSetStreamState(IN HDA_STREAM *HdaStream, IN BOOLEAN Run)
BOOLEAN HdaControllerGetStreamLinkPos(IN HDA_STREAM *HdaStream, OUT UINT32 *Position)
VOID HdaControllerCleanupRingBuffer(IN HDA_RING_BUFFER *HdaRingBuffer, IN HDA_RING_BUFFER_TYPE Type)
EFI_STATUS HdaControllerResetRingBuffer(IN HDA_RING_BUFFER *HdaRingBuffer)
BOOLEAN HdaControllerGetStreamState(IN HDA_STREAM *HdaStream, OUT BOOLEAN *Run)
EFI_STATUS HdaControllerInitRingBuffer(IN HDA_RING_BUFFER *HdaRingBuffer, IN HDA_CONTROLLER_DEV *HdaDev, IN HDA_RING_BUFFER_TYPE Type)
VOID HdaControllerCleanupStreams(IN HDA_CONTROLLER_DEV *HdaDev)
BOOLEAN HdaControllerGetStreamId(IN HDA_STREAM *HdaStream, OUT UINT8 *Index)
#define HDA_REG_CORB_BASE
#define HDA_REG_SDNCTL3_STRM_GET(a)
#define HDA_REG_SDNCTL3_STRM_SET(a, s)
#define HDA_OFFSET_RING_SIZE_SZCAP_256
#define HDA_OFFSET_RING_UBASE
#define HDA_REG_SDNCTL3_DIR
#define HDA_REG_SDNLVI(n)
#define HDA_REG_CORBRP_RST
#define HDA_OFFSET_RING_SIZE_ENT256
#define HDA_REG_SDNCTL3(n)
#define HDA_OFFSET_RING_SIZE_SZCAP_16
#define HDA_OFFSET_RING_SIZE_ENT16
#define HDA_REG_SDNCTL1(n)
#define HDA_REG_SDNBDPL(n)
#define HDA_OFFSET_RING_SIZE_ENT2
#define HDA_REG_SDNBDPU(n)
#define HDA_OFFSET_RING_SIZE_SZCAP_2
#define HDA_REG_RIRBWP_RST
#define HDA_REG_GCAP_ISS(a)
#define HDA_OFFSET_RING_SIZE
#define HDA_REG_SDNCTL1_SRST
#define HDA_OFFSET_RING_BASE
#define HDA_REG_DPLBASE_EN
#define HDA_REG_SDNCBL(n)
#define HDA_OFFSET_RING_CTL
#define HDA_REG_SDNLPIB(n)
#define HDA_REG_SDNCTL1_RUN
#define HDA_OFFSET_RING_CTL_RUN
#define HDA_REG_GCAP_64OK
#define HDA_REG_RIRB_BASE
#define HDA_REG_RIRBCTL_RINTCTL
#define HDA_REG_GCAP_OSS(a)
#define HDA_REG_GCAP_BSS(a)
#define MS_TO_NANOSECONDS(x)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT32 InterruptOnCompletion
HDA_BDL_ENTRY * BufferList
EFI_PHYSICAL_ADDRESS BufferDataPhysAddr
HDA_CONTROLLER_DEV * HdaDev
EFI_PHYSICAL_ADDRESS BufferListPhysAddr