# DpcDxe

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **DpcInternalIsListValid** |  |
|  | **DpcInternalIsListEmpty** |  |
|  | **DpcGetDebugOutputProtocol** |  |
|  | **DpcDebugAssert** |  |
|  | **DpcReportAssertError** |  |
|  | **DpcReadUnaligned64** |  |
|  | **DpcCompareGuid** |  |
|  | **DpcHobInit** |  |
|  | **DpcQueueDpc** |  |
|  | **DpcDispatchDpc** |  |
|  | **DpcDriverEntry** |  |
|  | **ModuleEntryPoint** |  |
| Global | **data** |  |
| Protocol | **interface instance** | EFI_DPC_PROTOCOL |
| EFI_DPC_PROTOCOL | **gDpcProtocolInterface;** |  |
| Head | **of the free DPC_ENTRY pool (at 0x1140)** |  |
| LIST_ENTRY | **gDpcFreeListHead;** |  |
| DPC | **queue heads** | one LIST_ENTRY per priority level (0..31) |
| Array | **at 0x11C0 .. 0x13AF (32 entries * 16 bytes each)** |  |
| LIST_ENTRY | **gDpcQueue[DPC_NUM_QUEUES];** |  |
| Statistics | **(at 0x1160, 0x1170)** |  |
| UINT64 | **gDpcQueueDepth     = 0;** |  |
| Protocol | **registration handle (at 0x1168)** |  |
| EFI_HANDLE | **gDpcProtocolHandle = NULL;** |  |
| Debug | **output protocol (at 0x1198)** |  |
| EFI_DEBUG_OUTPUT_PROTOCOL | ***gDpcDebugProtocol = NULL;** |  |
| HOB | **list pointer (at 0x11A0)** |  |
| VOID | ***gDpcHobList = NULL;** |  |
| Memory | **management** |  |
| Debug | **output support** |  |
| Read | **CMOS status** | check error reporting level. |
| Port | **0x70 index, port 0x71 data.** |  |
| CmosIndex | **= __inbyte (0x70);** |  |
| Map | **CMOS value to EFI error severity.** |  |
| if | **(CmosValue == 1) {** |  |
| 0x80000004 | **} else {** |  |
| 0x80000006 | **}** |  |
| GUID | **comparison and HOB list initialization** |  |
| Validate | **DpcToken (must be in range 4..0x1F).** |  |
| if | **((DpcToken < 4) || (DpcToken > 0x1F)) {** |  |
| Raise | **TPL to serialize access to the DPC free list and queues.** |  |
| Tpl | **= gBS->RaiseTPL (TPL_DPC_PROCESSING);** |  |
| Check | **if the free list has an entry.** |  |
| if | **(DpcInternalIsListEmpty (&gDpcFreeListHead)) {** |  |
| Free | **list is empty** | try to allocate more entries. |
| if | **(Tpl <= 16) {** |  |
| TPL | **is high but still low enough for AllocatePool.** |  |
| Loop | **up to DPC_ALLOCATE_BATCH (64) times, dropping and** |  |
| raising | **TPL each iteration.** |  |
| for | **(RetryCount = 0; RetryCount < DPC_ALLOCATE_BATCH; RetryCount++) {** |  |
| Restore | **TPL so AllocatePool can work.** |  |
| Allocate | **a new DPC entry.** |  |
| Entry | **= DpcAllocatePool ();** |  |
| Raise | **TPL back.** |  |
| Check | **again if free list is still empty (another thread** |  |
| may | **have freed entries while TPL was lowered).** |  |
| Free | **list is still empty** | add this entry to it. |
| DpcInternalInsertTailList | **(&gDpcFreeListHead, &Entry->List);** |  |
| After | **the loop, check if we now have an entry.** |  |
| TPL | **is too high for pool allocation.** |  |
| Status | **= EFI_OUT_OF_RESOURCES;** |  |
| Take | **an entry from the free list.** |  |
| Entry | **= BASE_CR (gDpcFreeListHead.ForwardLink, DPC_ENTRY, List);** |  |
| Populate | **the DPC entry.** |  |
| Queue | **to the correct priority-level list.** |  |
| DpcInternalInsertTailList | **(&gDpcQueue[DpcToken], &Entry->List);** |  |
| Update | **statistics.** |  |
| Raise | **TPL to DPC_PROCESSING to serialize.** |  |
| Process | **priorities from the raised TPL (31) downwards.** |  |
| if | **(Priority <= 31) {** |  |
| If | **this priority queue has entries, drain it.** |  |
| if | **(!DpcInternalIsListEmpty (&gDpcQueue[Priority])) {** |  |
| Take | **the first entry from the queue.** |  |
| Entry | **= BASE_CR (gDpcQueue[Priority].ForwardLink** |  |
| Decrement | **the queue depth counter.** |  |
| Drop | **TPL to the priority level so the callback** |  |
| can | **execute at its intended TPL.** |  |
| Execute | **the deferred procedure.** |  |
| Raise | **TPL back, and return the entry to the free list.** |  |
| Move | **to the next lower priority level.** |  |
| if | **(Priority == 0) {** |  |
| Driver | **initialization** |  |
| Check | **if DPC protocol is already installed.** |  |
| Status | **= gBS->LocateProtocol (** |  |
| Protocol | **already registered** | this is a bug in the calling driver. |
| DpcDebugAssert | **(** |  |
| Initialize | **all 32 DPC queue heads.** |  |
| for | **(QueueIndex = 0; QueueIndex < DPC_NUM_QUEUES; QueueIndex++) {** |  |
| Install | **the DPC protocol.** |  |
| Status | **= gBS->InstallProtocolInterface (** |  |
| Initialize | **UEFI globals.** |  |
| gImageHandle | **= ImageHandle;** |  |
| Initialize | **HOB list for DXE phase services.** |  |
| DpcHobInit | **();** |  |
| return | **DpcDriverEntry (ImageHandle, SystemTable);** |  |

---
*Generated by HR650X BIOS Decompilation Project*