4 Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
12 #include <IndustryStandard/DebugPort2Table.h>
13 #include <Library/AcpiLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/PL011UartLib.h>
16 #include <Protocol/AcpiTable.h>
17 #include <Protocol/SerialIo.h>
19 // Module specific include files.
20 #include <AcpiTableGenerator.h>
21 #include <ConfigurationManagerObject.h>
22 #include <ConfigurationManagerHelper.h>
23 #include <Library/TableHelperLib.h>
24 #include <Protocol/ConfigurationManagerProtocol.h>
26 /** ARM standard DBG2 Table Generator
28 Constructs the DBG2 table for PL011 or SBSA UART peripherals.
31 The following Configuration Manager Object(s) are required by
33 - EArmObjSerialDebugPortInfo
38 /** The number of debug ports represented by the Table.
40 #define DBG2_NUM_DEBUG_PORTS 1
42 /** The number of Generic Address Registers
43 presented in the debug device information.
45 #define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS 1
47 /** The index for the debug port 1 in the Debug port information list.
49 #define DBG_PORT_INDEX_PORT1 0
51 /** A string representing the name of the debug port 1.
53 #define NAME_STR_PORT1 "COM1"
55 /** The length of the namespace string.
57 #define DBG2_NAMESPACESTRING_FIELD_SIZE sizeof (NAME_STR_PORT1)
59 /** The PL011 UART address range length.
61 #define PL011_UART_LENGTH 0x1000
63 /** A structure that provides the OS with the required information
64 for initializing a debugger connection.
67 /// The debug device information for the platform
68 EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device
;
70 /// The base address register for the serial port
71 EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister
;
76 /// The debug port name string
77 UINT8 NameSpaceString
[DBG2_NAMESPACESTRING_FIELD_SIZE
];
78 } DBG2_DEBUG_DEVICE_INFORMATION
;
80 /** A structure representing the information about the debug port(s)
81 available on the platform.
84 /// The DBG2 table header
85 EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE Description
;
87 /// Debug port information list
88 DBG2_DEBUG_DEVICE_INFORMATION Dbg2DeviceInfo
[DBG2_NUM_DEBUG_PORTS
];
91 /** A helper macro used for initializing the debug port device
92 information structure.
94 @param [in] SubType The DBG Port SubType.
95 @param [in] UartBase The UART port base address.
96 @param [in] UartAddrLen The UART port address range length.
97 @param [in] UartNameStr The UART port name string.
99 #define DBG2_DEBUG_PORT_DDI( \
106 /* UINT8 Revision */ \
107 EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, \
108 /* UINT16 Length */ \
109 sizeof (DBG2_DEBUG_DEVICE_INFORMATION), \
110 /* UINT8 NumberofGenericAddressRegisters */ \
111 DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS, \
112 /* UINT16 NameSpaceStringLength */ \
113 DBG2_NAMESPACESTRING_FIELD_SIZE, \
114 /* UINT16 NameSpaceStringOffset */ \
115 OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString), \
116 /* UINT16 OemDataLength */ \
118 /* UINT16 OemDataOffset */ \
120 /* UINT16 Port Type */ \
121 EFI_ACPI_DBG2_PORT_TYPE_SERIAL, \
122 /* UINT16 Port Subtype */ \
124 /* UINT8 Reserved[2] */ \
125 {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}, \
126 /* UINT16 BaseAddressRegister Offset */ \
127 OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), \
128 /* UINT16 AddressSize Offset */ \
129 OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize) \
131 /* EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \
132 ARM_GAS32 (UartBase), \
133 /* UINT32 AddressSize */ \
135 /* UINT8 NameSpaceString[MAX_DBG2_NAME_LEN] */ \
139 /** The DBG2 Table template definition.
141 Note: fields marked with "{Template}" will be set dynamically
144 DBG2_TABLE AcpiDbg2
= {
147 EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE
,
149 EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
151 OFFSET_OF (DBG2_TABLE
, Dbg2DeviceInfo
),
158 DBG2_DEBUG_PORT_DDI (
159 0, // {Template}: Serial Port Subtype
160 0, // {Template}: Serial Port Base Address
169 /** This macro expands to a function that retrieves the Serial
170 debug port information from the Configuration Manager
174 EArmObjSerialDebugPortInfo
,
175 CM_ARM_SERIAL_PORT_INFO
178 /** Initialize the PL011 UART with the parameters obtained from
179 the Configuration Manager.
181 @param [in] SerialPortInfo Pointer to the Serial Port Information.
183 @retval EFI_SUCCESS Success.
184 @retval EFI_INVALID_PARAMETER The parameters for serial port initialization
190 IN CONST CM_ARM_SERIAL_PORT_INFO
* CONST SerialPortInfo
195 UINT32 ReceiveFifoDepth
;
196 EFI_PARITY_TYPE Parity
;
198 EFI_STOP_BITS_TYPE StopBits
;
200 ASSERT (SerialPortInfo
!= NULL
);
202 // Initialize the Serial Debug UART
203 DEBUG ((DEBUG_INFO
, "Initializing Serial Debug UART...\n"));
204 ReceiveFifoDepth
= 0; // Use the default value for FIFO depth
205 Parity
= (EFI_PARITY_TYPE
)FixedPcdGet8 (PcdUartDefaultParity
);
206 DataBits
= FixedPcdGet8 (PcdUartDefaultDataBits
);
207 StopBits
= (EFI_STOP_BITS_TYPE
)FixedPcdGet8 (PcdUartDefaultStopBits
);
209 BaudRate
= SerialPortInfo
->BaudRate
;
210 Status
= PL011UartInitializePort (
211 (UINTN
)SerialPortInfo
->BaseAddress
,
212 SerialPortInfo
->Clock
,
220 DEBUG ((DEBUG_INFO
, "Debug UART Configuration:\n"));
221 DEBUG ((DEBUG_INFO
, "UART Base = 0x%lx\n", SerialPortInfo
->BaseAddress
));
222 DEBUG ((DEBUG_INFO
, "Clock = %d\n", SerialPortInfo
->Clock
));
223 DEBUG ((DEBUG_INFO
, "Baudrate = %ld\n", BaudRate
));
224 DEBUG ((DEBUG_INFO
, "Configuring Debug UART. Status = %r\n", Status
));
226 ASSERT_EFI_ERROR (Status
);
230 /** Construct the DBG2 ACPI table
232 The BuildDbg2Table function is called by the Dynamic Table Manager
233 to construct the DBG2 ACPI table.
235 This function invokes the Configuration Manager protocol interface
236 to get the required hardware information for generating the ACPI
239 If this function allocates any resources then they must be freed
240 in the FreeXXXXTableResources function.
242 @param [in] This Pointer to the table generator.
243 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
244 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
246 @param [out] Table Pointer to the constructed ACPI Table.
248 @retval EFI_SUCCESS Table generated successfully.
249 @retval EFI_INVALID_PARAMETER A parameter is invalid.
250 @retval EFI_NOT_FOUND The required object was not found.
251 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
252 Manager is less than the Object size for the
259 IN CONST ACPI_TABLE_GENERATOR
* CONST This
,
260 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
261 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
262 OUT EFI_ACPI_DESCRIPTION_HEADER
** CONST Table
266 CM_ARM_SERIAL_PORT_INFO
* SerialPortInfo
;
268 ASSERT (This
!= NULL
);
269 ASSERT (AcpiTableInfo
!= NULL
);
270 ASSERT (CfgMgrProtocol
!= NULL
);
271 ASSERT (Table
!= NULL
);
272 ASSERT (AcpiTableInfo
->TableGeneratorId
== This
->GeneratorID
);
273 ASSERT (AcpiTableInfo
->AcpiTableSignature
== This
->AcpiTableSignature
);
275 if ((AcpiTableInfo
->AcpiTableRevision
< This
->MinAcpiTableRevision
) ||
276 (AcpiTableInfo
->AcpiTableRevision
> This
->AcpiTableRevision
)) {
279 "ERROR: DBG2: Requested table revision = %d, is not supported."
280 "Supported table revision: Minimum = %d, Maximum = %d\n",
281 AcpiTableInfo
->AcpiTableRevision
,
282 This
->MinAcpiTableRevision
,
283 This
->AcpiTableRevision
285 return EFI_INVALID_PARAMETER
;
290 Status
= GetEArmObjSerialDebugPortInfo (
296 if (EFI_ERROR (Status
)) {
299 "ERROR: DBG2: Failed to get serial port information. Status = %r\n",
305 if (SerialPortInfo
->BaseAddress
== 0) {
306 Status
= EFI_INVALID_PARAMETER
;
309 "ERROR: DBG2: Uart port base address is invalid. BaseAddress = 0x%lx\n",
310 SerialPortInfo
->BaseAddress
315 if ((SerialPortInfo
->PortSubtype
!=
316 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART
) &&
317 (SerialPortInfo
->PortSubtype
!=
318 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X
) &&
319 (SerialPortInfo
->PortSubtype
!=
320 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART
) &&
321 (SerialPortInfo
->PortSubtype
!=
322 EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC
)) {
323 Status
= EFI_INVALID_PARAMETER
;
326 "ERROR: DBG2: Uart port sybtype is invalid. PortSubtype = 0x%x\n",
327 SerialPortInfo
->PortSubtype
332 Status
= AddAcpiHeader (
335 (EFI_ACPI_DESCRIPTION_HEADER
*)&AcpiDbg2
,
339 if (EFI_ERROR (Status
)) {
342 "ERROR: DBG2: Failed to add ACPI header. Status = %r\n",
348 // Update the base address
349 AcpiDbg2
.Dbg2DeviceInfo
[DBG_PORT_INDEX_PORT1
].BaseAddressRegister
.Address
=
350 SerialPortInfo
->BaseAddress
;
352 // Update the serial port subtype
353 AcpiDbg2
.Dbg2DeviceInfo
[DBG_PORT_INDEX_PORT1
].Dbg2Device
.PortSubtype
=
354 SerialPortInfo
->PortSubtype
;
356 // Initialize the serial port
357 Status
= SetupDebugUart (SerialPortInfo
);
358 if (EFI_ERROR (Status
)) {
361 "ERROR: DBG2: Failed to configure debug serial port. Status = %r\n",
367 *Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)&AcpiDbg2
;
373 /** This macro defines the DBG2 Table Generator revision.
375 #define DBG2_GENERATOR_REVISION CREATE_REVISION (1, 0)
377 /** The interface for the DBG2 Table Generator.
381 ACPI_TABLE_GENERATOR Dbg2Generator
= {
383 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2
),
384 // Generator Description
385 L
"ACPI.STD.DBG2.GENERATOR",
386 // ACPI Table Signature
387 EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE
,
388 // ACPI Table Revision supported by this Generator
389 EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
,
390 // Minimum supported ACPI Table Revision
391 EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
,
393 TABLE_GENERATOR_CREATOR_ID_ARM
,
395 DBG2_GENERATOR_REVISION
,
396 // Build Table function
398 // No additional resources are allocated by the generator.
399 // Hence the Free Resource function is not required.
401 // Extended build function not needed
403 // Extended build function not implemented by the generator.
404 // Hence extended free resource function is not required.
408 /** Register the Generator with the ACPI Table Factory.
410 @param [in] ImageHandle The handle to the image.
411 @param [in] SystemTable Pointer to the System Table.
413 @retval EFI_SUCCESS The Generator is registered.
414 @retval EFI_INVALID_PARAMETER A parameter is invalid.
415 @retval EFI_ALREADY_STARTED The Generator for the Table ID
416 is already registered.
420 AcpiDbg2LibConstructor (
421 IN CONST EFI_HANDLE ImageHandle
,
422 IN EFI_SYSTEM_TABLE
* CONST SystemTable
426 Status
= RegisterAcpiTableGenerator (&Dbg2Generator
);
427 DEBUG ((DEBUG_INFO
, "DBG2: Register Generator. Status = %r\n", Status
));
428 ASSERT_EFI_ERROR (Status
);
433 /** Deregister the Generator from the ACPI Table Factory.
435 @param [in] ImageHandle The handle to the image.
436 @param [in] SystemTable Pointer to the System Table.
438 @retval EFI_SUCCESS The Generator is deregistered.
439 @retval EFI_INVALID_PARAMETER A parameter is invalid.
440 @retval EFI_NOT_FOUND The Generator is not registered.
444 AcpiDbg2LibDestructor (
445 IN CONST EFI_HANDLE ImageHandle
,
446 IN EFI_SYSTEM_TABLE
* CONST SystemTable
450 Status
= DeregisterAcpiTableGenerator (&Dbg2Generator
);
451 DEBUG ((DEBUG_INFO
, "DBG2: Deregister Generator. Status = %r\n", Status
));
452 ASSERT_EFI_ERROR (Status
);