33#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
45#define MIN_UART_ADDRESS_LENGTH 0x1000U
59 IN UINT32 SerialPortCount
65 if ((SerialPortInfoTable ==
NULL) ||
66 (SerialPortCount == 0))
69 return EFI_INVALID_PARAMETER;
72 for (Index = 0; Index < SerialPortCount; Index++) {
73 SerialPortInfo = &SerialPortInfoTable[Index];
74 ASSERT (SerialPortInfo !=
NULL);
76 if ((SerialPortInfo ==
NULL) ||
77 (SerialPortInfo->BaseAddress == 0))
81 "ERROR: UART port base address is invalid. BaseAddress = 0x%llx\n",
82 SerialPortInfo->BaseAddress
84 return EFI_INVALID_PARAMETER;
87 if ((SerialPortInfo->PortSubtype !=
88 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) &&
89 (SerialPortInfo->PortSubtype !=
90 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) &&
91 (SerialPortInfo->PortSubtype !=
92 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) &&
93 (SerialPortInfo->PortSubtype !=
94 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC) &&
95 (SerialPortInfo->PortSubtype !=
96 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_FULL_16550) &&
97 (SerialPortInfo->PortSubtype !=
98 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS))
102 "ERROR: UART port subtype is invalid."
103 " UART Base = 0x%llx, PortSubtype = 0x%x\n",
104 SerialPortInfo->BaseAddress,
105 SerialPortInfo->PortSubtype
107 return EFI_INVALID_PARAMETER;
110 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
114 if ((SerialPortInfo->Interrupt != 0) &&
115 !(((SerialPortInfo->Interrupt >= ARM_GIC_ARCH_SPI_MIN) &&
116 (SerialPortInfo->Interrupt <= ARM_GIC_ARCH_SPI_MAX)) ||
117 ((SerialPortInfo->Interrupt >= ARM_GIC_ARCH_EXT_SPI_MIN) &&
118 (SerialPortInfo->Interrupt <= ARM_GIC_ARCH_EXT_SPI_MAX))))
122 "ERROR: Invalid UART port interrupt ID. Interrupt = %lu\n",
123 SerialPortInfo->Interrupt
125 return EFI_INVALID_PARAMETER;
130 DEBUG ((DEBUG_INFO,
"UART Configuration:\n"));
133 " UART Base = 0x%llx\n",
134 SerialPortInfo->BaseAddress
138 " Length = 0x%llx\n",
139 SerialPortInfo->BaseAddressLength
141 DEBUG ((DEBUG_INFO,
" Clock = %lu\n", SerialPortInfo->Clock));
142 DEBUG ((DEBUG_INFO,
" BaudRate = %llu\n", SerialPortInfo->BaudRate));
143 DEBUG ((DEBUG_INFO,
" Interrupt = %lu\n", SerialPortInfo->Interrupt));
173 CONST CHAR8 *HidString;
174 CONST CHAR8 *CidString;
175 CONST CHAR8 *NonBsaHid;
178 switch (SerialPortInfo->PortSubtype) {
179 case EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_FULL_16550:
180 case EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS:
183 NonBsaHid = (
CONST CHAR8 *)
PcdGetPtr (PcdNonBsaCompliant16550SerialHid);
186 return EFI_INVALID_PARAMETER;
189 HidString = NonBsaHid;
192 HidString =
"PNP0501";
193 CidString =
"PNP0500";
198 case EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART:
200 HidString =
"ARMH0011";
201 CidString =
"ARMHB000";
204 case EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART:
205 case EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X:
207 HidString =
"ARMHB000";
213 return EFI_INVALID_PARAMETER;
224 if (EFI_ERROR (Status)) {
229 if (EFI_ERROR (Status)) {
240 if (EFI_ERROR (Status)) {
245 if (EFI_ERROR (Status)) {
256 if (EFI_ERROR (Status)) {
266 if (EFI_ERROR (Status)) {
307 if (EFI_ERROR (Status)) {
313 if (EFI_ERROR (Status)) {
317 if (QWordRdNode ==
NULL) {
318 return EFI_INVALID_PARAMETER;
324 SerialPortInfo->BaseAddress,
328 if (EFI_ERROR (Status)) {
340 (UINT32 *)&SerialPortInfo->Interrupt,
378 Status =
AmlFindNode (RootNodeHandle,
"\\_SB_.COM0", &DeviceNode);
379 if (EFI_ERROR (Status)) {
422 ASSERT (RootNodeHandle !=
NULL);
423 ASSERT (SerialPortInfo !=
NULL);
424 ASSERT (Name !=
NULL);
425 ASSERT (Table !=
NULL);
428 Status =
FixupIds (RootNodeHandle, Uid, SerialPortInfo);
429 if (EFI_ERROR (Status)) {
434 Status =
FixupCrs (RootNodeHandle, SerialPortInfo);
435 if (EFI_ERROR (Status)) {
441 return FixupName (RootNodeHandle, SerialPortInfo, Name);
458 ASSERT (Table !=
NULL);
494 ASSERT (AcpiTableInfo !=
NULL);
495 ASSERT (SerialPortInfo !=
NULL);
496 ASSERT (Name !=
NULL);
497 ASSERT (Table !=
NULL);
501 if (EFI_ERROR (Status)) {
510 if (EFI_ERROR (Status)) {
513 "ERROR: SSDT-SERIAL-PORT-FIXUP:"
514 " Failed to parse SSDT Serial Port Template. Status = %r\n",
528 if (EFI_ERROR (Status)) {
531 "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to fixup SSDT Serial Port Table."
543 if (EFI_ERROR (Status)) {
546 "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to Serialize SSDT Table Data."
554 if (RootNodeHandle !=
NULL) {
556 if (EFI_ERROR (Status1)) {
559 "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to cleanup AML tree."
565 if (!EFI_ERROR (Status)) {
BOOLEAN IsValidAcpiId(IN CONST CHAR8 *Hid)
BOOLEAN IsValidPnpId(IN CONST CHAR8 *Hid)
void * AML_ROOT_NODE_HANDLE
void * AML_DATA_NODE_HANDLE
EFI_STATUS EFIAPI AmlCodeGenRdInterrupt(IN BOOLEAN ResourceConsumer, IN BOOLEAN EdgeTriggered, IN BOOLEAN ActiveLow, IN BOOLEAN Shared, IN UINT32 *IrqList, IN UINT8 IrqCount, IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL, OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL)
void * AML_OBJECT_NODE_HANDLE
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define PcdGetPtr(TokenName)
STATIC EFI_STATUS EFIAPI FixupIds(IN AML_ROOT_NODE_HANDLE RootNodeHandle, IN CONST UINT64 Uid, IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo)
CHAR8 ssdtserialporttemplate_aml_code[]
EFI_STATUS EFIAPI ValidateSerialPortInfo(IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable, IN UINT32 SerialPortCount)
STATIC EFI_STATUS EFIAPI FixupName(IN AML_ROOT_NODE_HANDLE RootNodeHandle, IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, IN CONST CHAR8 *Name)
STATIC EFI_STATUS EFIAPI FixupSerialPortInfo(IN AML_ROOT_NODE_HANDLE RootNodeHandle, IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, IN CONST CHAR8 *Name, IN CONST UINT64 Uid, OUT EFI_ACPI_DESCRIPTION_HEADER **Table)
STATIC EFI_STATUS EFIAPI FixupCrs(IN AML_ROOT_NODE_HANDLE RootNodeHandle, IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo)
#define MIN_UART_ADDRESS_LENGTH
EFI_STATUS EFIAPI FreeSsdtSerialPortTable(IN EFI_ACPI_DESCRIPTION_HEADER *Table)
EFI_STATUS EFIAPI BuildSsdtSerialPortTable(IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo, IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, IN CONST CHAR8 *Name, IN CONST UINT64 Uid, OUT EFI_ACPI_DESCRIPTION_HEADER **Table)
EFI_STATUS EFIAPI AmlFindNode(IN AML_NODE_HANDLE ReferenceNode, IN CONST CHAR8 *AslPath, OUT AML_NODE_HANDLE *OutNode)
EFI_STATUS EFIAPI AmlDeleteTree(IN AML_NODE_HANDLE Node)
EFI_STATUS EFIAPI AmlUpdateRdQWord(IN AML_DATA_NODE_HANDLE QWordRdNode, IN UINT64 BaseAddress, IN UINT64 BaseAddressLength)
EFI_STATUS EFIAPI AmlParseDefinitionBlock(IN CONST EFI_ACPI_DESCRIPTION_HEADER *DefinitionBlock, OUT AML_ROOT_NODE_HANDLE *RootPtr)
EFI_STATUS EFIAPI AmlNameOpGetFirstRdNode(IN AML_OBJECT_NODE_HANDLE NameOpNode, OUT AML_DATA_NODE_HANDLE *OutRdNode)
EFI_STATUS EFIAPI AmlDeviceOpUpdateName(IN AML_OBJECT_NODE_HANDLE DeviceOpNode, IN CONST CHAR8 *NewNameString)
EFI_STATUS EFIAPI AmlNameOpUpdateInteger(IN AML_OBJECT_NODE_HANDLE NameOpNode, IN UINT64 NewInt)
EFI_STATUS EFIAPI AmlNameOpUpdateString(IN AML_OBJECT_NODE_HANDLE NameOpNode, IN CONST CHAR8 *NewName)
EFI_STATUS EFIAPI AmlDetachNode(IN AML_NODE_HANDLE Node)
EFI_STATUS EFIAPI AmlSerializeDefinitionBlock(IN AML_ROOT_NODE_HANDLE RootNode, OUT EFI_ACPI_DESCRIPTION_HEADER **Table)