当前位置:网站首页>UEFI learning 3.6 - ACPI table on ARM QEMU
UEFI learning 3.6 - ACPI table on ARM QEMU
2022-06-23 09:21:00 【MyeDy】
If the ACPI Unfamiliar with concept , You can refer to this article first 【UEFI Basics 】ACPI Basics
Parsing code github Address :TestPkg
ACPI Table structure
ACPI The first picture of shows RSDP(Root System Description Pointer), It contains R(X)DST The address of .RDST yes 32 Bit address ,XDST yes 64 Bit address , Its function is the same . In the back is AARCH64 framework , So I used 64 Bit address XDST.
according to RSDP find XDST after , It can be based on XDST Find out each table item Entry, every last Entry The address of the corresponding table is recorded . There are many types of table items , Here you can refer to ACPI 6.3 SPEC. also Entry The type of will change with ACPI Version increase or change .
Be careful XDST first Entry It must be FADT.
It's just QEMU AARCH64 Examples of types used on .QEMU There are a total of 8 The table is as follows :
- FADT (Fixed ACPI Description Table) , Mainly put some hardware information and DSDT The address of .
- MADT(Multiple APIC Description Table ), Describes information about interrupt hardware .
- PPTT(Processor Properties Topology Table), It describes CPU Relevant information .
- MCFG(PCI Express memory mapped configuration space base address Description Table) PCIE Memory space first closed address .
- GTDT(Generic Timer Description Table), It describes timer Relevant information .
- SPCR(Serial Port Console Redirection Table), Describes the serial port related information .
- DBG2(Debug Port Table), It describes Debug Mouth related information .
- IORT(I/O Remapping Table), It describes IO Remap Related information .
therefore , stay QEMU On XSDT The layout is as follows .Header Here we put 8 Addresses of tables .
FADT Contains some hardware related information BLKs and DSDT The address of . and DSDT Contains many hardware definition blocks , The definition block describes the static and dynamic information of the hardware .
RSDP
First of all to see RSDP The definition of .
MdePkg/Include/IndustryStandard/Acpi63.h
typedef struct {
UINT64 Signature; --> The signature is "RSD PTR "
UINT8 Checksum; --> This checksum contains only the first... Of this table 20 Bytes , From 0~19, And include the field itself . front 20 The sum of bytes must be zero
UINT8 OemId[6]; --> OEM ID character string
UINT8 Revision; --> Version number
UINT32 RsdtAddress; --> 32 position RSDT Address
UINT32 Length; --> RSDP Table length
UINT64 XsdtAddress; --> 64 position XSDT Address
UINT8 ExtendedChecksum; --> This is the checksum of the entire table , Contains two checksum fields
UINT8 Reserved[3];
} EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER;
RSDP Store in UEFI Of configuration table in , its guid yes gEfiAcpi20TableGuid.
We can use the following code to find RSDP The address of , The principle is simple , It's traversal UEFI Of configuration table, If GUID yes ACPI surface , Just take it out . find configuration table Of VendorTable Field , It is RSDP Address
TestPkg/TestDxeAcpi.c
EFIAPI
EFI_STATUS
TestDxeDumpAcpi()
{
UINTN i, j = 0, EntryCount;
UINT8 Temp = 0;
EFI_CONFIGURATION_TABLE *configTab = NULL;
EFI_ACPI_DESCRIPTION_HEADER *XSDT, *Entry, *DSDT;
UINT64 *EntryPtr;
EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *FADT;
EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER *Root;
DEBUG((DEBUG_INFO, "Dump ACPI\n"));
configTab = gST->ConfigurationTable;
// Traverse the system configuration table
for(i=0; i<gST->NumberOfTableEntries;i++)
{
if ((CompareGuid(&configTab->VendorGuid, &gEfiAcpiTableGuid) == TRUE) ||
(CompareGuid(&configTab->VendorGuid, &gEfiAcpi20TableGuid) == TRUE))
{
// If it is ACPI The table takes out its address
DEBUG((DEBUG_INFO, "Found ACPI table\n"));
DEBUG((DEBUG_INFO, "Address: @[0x%p]\n",configTab));
Root = configTab->VendorTable; --> find RSDP
// Print RSDP Related fields
DEBUG((DEBUG_INFO, "RSDP @[0x%p]\n", Root));
DEBUG((DEBUG_INFO, " Signature:"));
for(j = 0; j < 8; j++) {
Temp = (Root->Signature >> (j * 8)) & 0xff;
DEBUG((DEBUG_INFO, "%c", Temp));
}
DEBUG((DEBUG_INFO, "\n"));
DEBUG((DEBUG_INFO, " Revision:%d\n", Root->Revision));
DEBUG((DEBUG_INFO, " OEM_ID:"));
for (j = 0; j < 6; j++) {
DEBUG((DEBUG_INFO, "%c", Root->OemId[j]));
}
DEBUG((DEBUG_INFO, "\n"));
DEBUG((DEBUG_INFO, " Length=[0x%x]\n", Root->Length));
DEBUG((DEBUG_INFO, " XSDT address=[0x%p]\n", Root->XsdtAddress));
DEBUG((DEBUG_INFO, " RSDT address=[0x%p]\n", Root->RsdtAddress));
...
}
Dump ACPI
Found ACPI table
Address: @[0x43FDFBD8]
RSDP @[0x405C0018]
Signature:RSD PTR --> Singautre accord with RSD PTR
Revision:2
OEM_ID:BOCHS
Length=[0x24] --> Length is EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER The length of
XSDT address=[0x405CFE98] --> It uses XSDT
RSDT address=[0x0] -->RSDT non-existent
XSDT

XSDT There is no proprietary structure definition , It's just APCI Header, Then there is a string Entry Address .XSDT Of Header The definition is as follows . This is also used for other tables Header, It's a ACPI Generic description header .
MdePkg/Include/IndustryStandard/Acpi10.h
typedef struct {
UINT32 Signature;
UINT32 Length;
UINT8 Revision;
UINT8 Checksum;
UINT8 OemId[6];
UINT64 OemTableId;
UINT32 OemRevision;
UINT32 CreatorId;
UINT32 CreatorRevision;
} EFI_ACPI_DESCRIPTION_HEADER;
When it finds XSDT after , You can traverse the following Entry Address , Then find the corresponding Entry
TestPkg/TestDxeAcpi.c
if (Root->Revision >= EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
// from RSDP Get in the XSDT The address of
XSDT = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Root->XsdtAddress;
// Count how many Entry, Here you are 8 individual Entry
EntryCount = (XSDT->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER))
/ sizeof(UINT64);
DEBUG((DEBUG_INFO, " XSDT @[0x%p]\n", XSDT));
// Print XSDT The signature of should be a string "XSDT"
DEBUG((DEBUG_INFO, " Signature:"));
for(j = 0; j < 4; j++) {
Temp = (XSDT->Signature >> (j * 8)) & 0xff;
DEBUG((DEBUG_INFO, "%c", Temp));
}
DEBUG((DEBUG_INFO, "\n"));
DEBUG((DEBUG_INFO, " Length=[%d]\n", XSDT->Length));
DEBUG((DEBUG_INFO, " Entry Count=[%d]\n", EntryCount));
DEBUG((DEBUG_INFO, " OEM_ID:"));
for (j = 0; j < 6; j++) {
DEBUG((DEBUG_INFO, "%c", Root->OemId[j]));
}
DEBUG((DEBUG_INFO, "\n"));
EntryPtr=(UINT64 *)(XSDT+1);
// Traverse XSDT Medium Entry, hold Entry Print out your signature
for (j = 0; j < EntryCount; j++, EntryPtr++) {
Entry = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr));
if (Entry == NULL) {
continue;
}
DEBUG((DEBUG_INFO, " Signature:"));
for(j = 0; j < 4; j++) {
Temp = (Entry->Signature >> (j * 8)) & 0xff;
DEBUG((DEBUG_INFO, "%c", Temp));
}
DEBUG((DEBUG_INFO, "\n"));
}
}
You can see the final print as follows
XSDT @[0x405CFE98]
Signature:XSDT --> Signature is "XSDT"
Length=[100] --> The length is 100 = Meter length 36 + Table item Entry length 64
Entry Count=[8] --> Entry Count = 8 = 64 / 8
OEM_ID:BOCHS --> OEM ID and RSDP The same is BOCHS
Signature:FACP --> The first table FADT The signature of the "FACP"
Signature:APIC --> Second sheet MADT The signature of the "APIC"
Signature:PPTT --> .
Signature:GTDT .
Signature:MCFG .
Signature:SPCR .
Signature:DBG2 --> .
Signature:IORT --> The signature of the last table "IORT"
FADT
FADT It's a long definition , as follows
MdePkg/Include/IndustryStandard/Acpi63.h
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header; --> Universal Header
UINT32 FirmwareCtrl; --> FACS The address of , OSPM And firmware use this field to exchange control information .
UINT32 Dsdt; --> DSDT The address of
UINT8 Reserved0;
----------------------
* Power management type
*0 - Unspecified
*1 - Desktp
*2 - Mobile
*3 - Wokrstation
*4 - Enterprise Server
*5 - SOHO Server
*6 - Applicance PC
*7 - Performance Server
*8 - Tablet
*>8 Reserved
-----------------------
UINT8 PreferredPmProfile;
--> stay 8259 In mode SCI Break the system vector of the binding . In the absence of 8269 In the system , This field contains SCI The global system interrupt number of the interrupt .
-->OSPM Need to put ACPI SCI Interrupts are considered sharable 、 Level trigger 、 Low effective interrupt .
UINT16 SciInt;
UINT32 SmiCmd; --> SMI The port where the command is located
UINT8 AcpiEnable; --> Write this value to SMI_CMD To re enable ACPI Hardware register SMI ownership . In systems that do not support legacy patterns , This field is reserved .
UINT8 AcpiDisable; --> Write this value to SMI_CMD To re shield ACPI Hardware register SMI ownership . In systems that do not support legacy patterns , This field is reserved .
UINT8 S4BiosReq; --> In order to enter S4BIOS The status needs to write this value to SM1_CMD in .
UINT8 PstateCnt; --> If this field value is non-zero , that OPSM Write this value to SM1_CMD Register will assume the responsibility of processor performance state control
UINT32 Pm1aEvtBlk; --> PM1a The system port address of the event register block
UINT32 Pm1bEvtBlk; --> PM1b The system port address of the event register block
UINT32 Pm1aCntBlk; --> PM1a The system port address of the control register block
UINT32 Pm1bCntBlk; --> PM1b The system port address of the control register block
UINT32 Pm2CntBlk; --> PM2 The system port address of the event register block
UINT32 PmTmrBlk; --> The system port address of the power management timer control register
UINT32 Gpe0Blk; --> General purpose events 0 The system port address of the register block
UINT32 Gpe1Blk; --> General purpose events 1 The system port address of the register block
UINT8 Pm1EvtLen; --> from PM1a_EVT_BLK and PM1b_EVT_BLK Number of bytes decoded
UINT8 Pm1CntLen; --> from PM1a_CNT_BLK and PM1b_CNT_BLK Number of bytes decoded
UINT8 Pm2CntLen; --> from PM2_CNT_BLK Number of bytes decoded
UINT8 PmTmrLen; --> from PM_TMR_BLK Number of bytes decoded
UINT8 Gpe0BlkLen; --> from GEP0_BLK Number of bytes decoded
UINT8 Gpe1BlkLen; --> from GPE1_BLK Number of bytes decoded
UINT8 Gpe1Base; --> stay ACPI Common event model GPE1 The offset at the beginning of the event
UINT8 CstCnt; --> OSPM Write this value to SMI_CMD Register to OS Show that you are right _CST Objects and C Support for state change notification
UINT16 PLvl2Lat; --> Enter and exit C2 The longest hardware delay of the state
UINT16 PLvl3Lat; --> Enter and exit C3 The longest hardware delay of the state
UINT16 FlushSize; --> Cache refresh step size
UINT16 FlushStride; --> The cache line width of the processor memory cache
UINT8 DutyOffset; --> On the processor's P_CNT In the register , Indicates the zero based index where the processor duty cycle is located
UINT8 DutyWidth;
UINT8 DayAlrm; --> Corresponding to the date warning value RTC_CMOS_RAM Indexes .
UINT8 MonAlrm; --> Corresponding to the month warning value RTC_CMOS_RAM Indexes .
UINT8 Century; --> Date century value corresponds to RTC_CMOS_RAM Indexes .
UINT16 IaPcBootArch; --> IA-PC Start schema flag
UINT8 Reserved1;
UINT32 Flags; --> Fixed feature mark
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResetReg; --> Reset the address of the register
UINT8 ResetValue; --> To restart the system , This value is written to RESET_REG port
UINT16 ArmBootArch; --> ARM Schema start flag
UINT8 MinorVersion; --> This version number
UINT64 XFirmwareCtrl; --> EACS Of 64 Bit physical address
UINT64 XDsdt; --> DSDT Of 64 Bit physical address
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; --> PM1a Extended address of the event register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; --> PM1b Extended address of the event register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; --> PM1a The extended address of the control register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; --> PM1b The extended address of the control register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; --> PM2 The extended address of the control register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; --> PM TMR Extended address of register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; --> GEP0 Extended address of register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; --> GEP1 Extended address of register block
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE SleepControlReg; --> Address of sleep control register
EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; --> Address of sleep status register
UINT64 HypervisorVendorIdentity; --> Hypevisor ID
} EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE;
analysis FADT Code , It is to parse the structure of a table and print it according to its definition
TestPkg/TestDxeAcpi.c
switch (Entry->Signature) {
case EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
FADT = (EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN) Entry;
DumpFADT(FADT);
DSDT = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(FADT->Dsdt);
VOID
DumpFADT(EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *FADT)
{
char *PMProfiles[] = {
"Unspecified",
"Desktop",
"Mobile",
"WorkStation",
"Enterprise Server",
"SOHO Server",
"Applicance PC",
"Performance Server",
"Tablet"
};
DEBUG((DEBUG_INFO, "\n#########Start Dump FADT##########\n"));
DumpACPIHeader(&FADT->Header);
DEBUG((DEBUG_INFO, "FACS:0x%x\n", FADT->FirmwareCtrl));
DEBUG((DEBUG_INFO, "Dsdt:0x%x\n", FADT->Dsdt));
DEBUG((DEBUG_INFO, "", FADT->PreferredPmProfile));
if (FADT->PreferredPmProfile > 8) {
DEBUG((DEBUG_INFO, "PreferredPmProfile: Reserved\n"));
} else {
DEBUG((DEBUG_INFO, "PreferredPmProfile: %a\n", PMProfiles[FADT->PreferredPmProfile]));
}
DEBUG((DEBUG_INFO, "SCI INT:0x%04x\n", FADT->SciInt));
DEBUG((DEBUG_INFO, "SMI CMD:0x%08x\n", FADT->SmiCmd));
DEBUG((DEBUG_INFO, "ACPI ENABLE:0x%02x\n", FADT->AcpiEnable));
DEBUG((DEBUG_INFO, "ACPI DISABLE:0x%02x\n", FADT->AcpiDisable));
DEBUG((DEBUG_INFO, "S4BIOS REQ:0x%02x\n", FADT->S4BiosReq));
DEBUG((DEBUG_INFO, "PSTATE CNT:0x%02x\n", FADT->PstateCnt));
DEBUG((DEBUG_INFO, "PM1a EVT BLK:0x%08x\n", FADT->Pm1aEvtBlk));
DEBUG((DEBUG_INFO, "PM1b EVT BLK:0x%08x\n", FADT->Pm1bEvtBlk));
DEBUG((DEBUG_INFO, "PM1a CNT BLK:0x%08x\n", FADT->Pm1aCntBlk));
DEBUG((DEBUG_INFO, "PM1b CNT BLK:0x%08x\n", FADT->Pm1bCntBlk));
DEBUG((DEBUG_INFO, "PM TMR BLK:0x%08x\n", FADT->PmTmrBlk));
DEBUG((DEBUG_INFO, "GPE0 BLK:0x%08x\n", FADT->Gpe0Blk));
DEBUG((DEBUG_INFO, "GPE1 BLK:0x%08x\n", FADT->Gpe1Blk));
DEBUG((DEBUG_INFO, "PM1 EVT LEN:0x%02x\n", FADT->Pm1EvtLen));
DEBUG((DEBUG_INFO, "PM1 CNT LEN:0x%02x\n", FADT->Pm1CntLen));
DEBUG((DEBUG_INFO, "PM2 CNT LEN:0x%02x\n", FADT->Pm2CntLen));
DEBUG((DEBUG_INFO, "PM TMR LEN:0x%02x\n", FADT->PmTmrLen));
DEBUG((DEBUG_INFO, "GPE0 BLK LEN:0x%02x\n", FADT->Gpe0BlkLen));
DEBUG((DEBUG_INFO, "GPE1 BLK LEN:0x%02x\n", FADT->Gpe1BlkLen));
DEBUG((DEBUG_INFO, "GPE1 BASE:0x%02x\n", FADT->Gpe1Base));
DEBUG((DEBUG_INFO, "CST CNT:0x%02x\n", FADT->CstCnt));
DEBUG((DEBUG_INFO, "P LVL2 LAT:0x%04x\n", FADT->PLvl2Lat));
DEBUG((DEBUG_INFO, "P LVL3 LAT:0x%04x\n", FADT->PLvl3Lat));
DEBUG((DEBUG_INFO, "Flush Size:0x%04x\n", FADT->FlushSize));
DEBUG((DEBUG_INFO, "FLUSH STRIDE:0x%04x\n", FADT->FlushStride));
DEBUG((DEBUG_INFO, "DUTY OFFSET:0x%02x\n", FADT->DutyOffset));
DEBUG((DEBUG_INFO, "DUTY WIDTH:0x%02x\n", FADT->DutyWidth));
DEBUG((DEBUG_INFO, "DAY ALARM:0x%02x\n", FADT->DayAlrm));
DEBUG((DEBUG_INFO, "MON ALARM:0x%02x\n", FADT->MonAlrm));
DEBUG((DEBUG_INFO, "CENTURY:0x%02x\n", FADT->Century));
DEBUG((DEBUG_INFO, "IAPC_BOOT_ARCH:0x%04x\n", FADT->IaPcBootArch));
DEBUG((DEBUG_INFO, "Flags:0x%08x\n", FADT->Flags));
DumpGenericAddress("Reset Reg", &FADT->ResetReg);
DEBUG((DEBUG_INFO, "Reset Value:0x%02x\n", FADT->ResetValue));
DEBUG((DEBUG_INFO, "ARM BOOT ARCH:0x%04x\n", FADT->ArmBootArch));
DEBUG((DEBUG_INFO, "FADT MINOR VERSION:0x%02x\n", FADT->MinorVersion));
DEBUG((DEBUG_INFO, "X FIRMWARE CTRL:0x%p", FADT->XFirmwareCtrl));
DEBUG((DEBUG_INFO, "X DSDT:0x%p\n", FADT->XDsdt));
DumpGenericAddress("X PM1a EVT BLK", &FADT->XPm1aEvtBlk);
DumpGenericAddress("X PM1b EVT BLK", &FADT->XPm1bEvtBlk);
DumpGenericAddress("X PM1a CNT BLK", &FADT->XPm1aCntBlk);
DumpGenericAddress("X PM1b CNT BLK", &FADT->XPm1bCntBlk);
DumpGenericAddress("X PM TMR BLK", &FADT->XPmTmrBlk);
DumpGenericAddress("GPE0 BLK", &FADT->XGpe0Blk);
DumpGenericAddress("GPE1 BLK", &FADT->XGpe1Blk);
DumpGenericAddress("SLEEP CONTROL", &FADT->SleepControlReg);
DumpGenericAddress("SLEEP STATUS", &FADT->SleepStatusReg);
DEBUG((DEBUG_INFO, "###########End Dump FADT###########\n\n"));
}
log analysis
#########Start Dump FADT##########
Signature:FACP --> The signature is "FACP"
Length:0x10C --> Length is FADT The length of the structure
Revision:0x05 --> Here are some version information
Checksum:0x03
OemID:BOCHS
OemTableId:0x2020202043505842 -
OemRevision:0x1
CreatorId:0x43505842
CreatorRevision:0x1
FACS:0x0 -->FACS The address is 0, It just doesn't exist
Dsdt:0x405C7518 -->DSDT The address of
PreferredPmProfile: Unspecified --> No power management is specified Profile
--> Because of the ARM AARCH64 Structure , The following hardware is in AARCH64 There is no architecture , So the following hardware information AARCH64 No need
--> So the following hardware information is 0, It just doesn't exist . about X86/X64 Architecture is needed .
SCI INT:0x0000
SMI CMD:0x00000000
ACPI ENABLE:0x00
ACPI DISABLE:0x00
S4BIOS REQ:0x00
PSTATE CNT:0x00
PM1a EVT BLK:0x00000000
PM1b EVT BLK:0x00000000
PM1a CNT BLK:0x00000000
PM1b CNT BLK:0x00000000
PM TMR BLK:0x00000000
GPE0 BLK:0x00000000
GPE1 BLK:0x00000000
PM1 EVT LEN:0x00
PM1 CNT LEN:0x00
PM2 CNT LEN:0x00
PM TMR LEN:0x00
GPE0 BLK LEN:0x00
GPE1 BLK LEN:0x00
GPE1 BASE:0x00
CST CNT:0x00
P LVL2 LAT:0x0000
P LVL3 LAT:0x0000
Flush Size:0x0000
FLUSH STRIDE:0x0000
DUTY OFFSET:0x00
DUTY WIDTH:0x00
DAY ALARM:0x00
MON ALARM:0x00
CENTURY:0x00
IAPC_BOOT_ARCH:0x0000
Flags:0x00100000
Reset Reg: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
Reset Value:0x00
ARM BOOT ARCH:0x0003 --> ARM BOOT framework
FADT MINOR VERSION:0x01 --> Sub version number
X FIRMWARE CTRL:0x0
X DSDT:0x405C7518 --> XDSDT The address of
X PM1a EVT BLK: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
X PM1b EVT BLK: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
X PM1a CNT BLK: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
X PM1b CNT BLK: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
X PM TMR BLK: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
GPE0 BLK: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
GPE1 BLK: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
SLEEP CONTROL: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
SLEEP STATUS: AddressSpaceId:0x00, RegisterBitWidth:0x00, RegisterBitOffset:0x00, AccessSize:0x00, Address:0x00000000000
###########End Dump FADT###########
DSDT
The above has been based on FADT eureka DSDT The address of . Then we can parse it out . Talked about before DSDT There is only one head , Then there are one by one AML Definition block . and AML Definition blocks exist as raw data , So we need to dump Out of this AML The data of , Then use tools to parse . The print code is as follows .
TestPkg/TestDxeAcpi.c
DSDT = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(FADT->Dsdt);
DEBUG((DEBUG_INFO, "\n#########Start Dump DSDT##########\n"));
UINT32 *temp = (UINT32 *)DSDT;
for (UINTN k = 0; k < DSDT->Length; k += 4) {
DEBUG((DEBUG_INFO, "0x%08x\n", *temp++));
}
DEBUG((DEBUG_INFO, "#########End Dump DSDT##########\n\n"));
break;
stay EDK2 I haven't found a ready-made one to put AML Code that parses into strings , So here I will DSDT and AML Define the data of the block to 16 I print it out , Then manually save to a file dsdt.txt in , Reuse scripts in ubuntu On the call iasl Parsing DSDT.
0x54445344 --> DSDT The raw data of is as follows
0x0000144C
0x4F429F02
0x20534843
...
0x00444955
Parsing script
import os
import sys
f = open('dsdt.txt')
out = open('dsdt.dat', 'wb+')
for line in f:
line = line.replace('\n', '')
val = int(line, 16)
print(val)
out.write(val.to_bytes(4, byteorder='little'))
f.close()
out.close()
os.system('iasl -d dsdt.dat')
Finally, it is resolved dsdt.dsl as follows .
/* * Intel ACPI Component Architecture * AML/ASL+ Disassembler version 20200925 (64-bit version) * Copyright (c) 2000 - 2020 Intel Corporation * * Disassembling to symbolic ASL+ operators * * Disassembly of dsdt.dat, Wed May 25 09:14:56 2022 */
--------------->DSDT Of Header
* Original Table Header:
* Signature "DSDT"
* Length 0x0000144C (5196)
* Revision 0x02
* Checksum 0x9F
* OEM ID "BOCHS "
* OEM Table ID "BXPC "
* OEM Revision 0x00000001 (1)
* Compiler ID "BXPC"
* Compiler Version 0x00000001 (1)
*
DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPC ", 0x00000001)
{
Scope (\_SB)
{
// CPU Device Information about
Device (C000)
{
Name (_HID, "ACPI0007" /* Processor Device */) // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
}
// Serial port information
Device (COM0)
{
Name (_HID, "ARMH0011") ARMH0011 representative ARM PL011 IP // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
Memory32Fixed (ReadWrite,
0x09000000, // Starting address of serial port register
0x00001000, // Length of serial port register
)
// Interrupt related information .
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
{
0x00000021,
}
})
}
// FW CFG Information about
Device (FWCF)
{
Name (_HID, "QEMU0002") QEMU0002 representative QMEU FW CFG equipment // _HID: Hardware ID
Name (_STA, 0x0B) // _STA: Status
Name (_CCA, One) // _CCA: Cache Coherency Attribute
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
Memory32Fixed (ReadWrite,
0x09020000, // FW CFG From
0x00000018, // FW CFG The length of
)
})
}
// There is a pile of VIRT IO Information about , Only the head and tail are left here , It's all the same thing
Device (VR00)
{
Name (_HID, "LNRO0005") // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Name (_CCA, One) // _CCA: Cache Coherency Attribute
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
Memory32Fixed (ReadWrite,
0x0A000000, // VIRT IO0 From
0x00000200, // VIRT IO0 The length of
)
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
{
0x00000030,
}
})
}
...
Device (VR31)
{
...
}
//PCI0 Information about Not very well understood QEMU On PCI Usage of , There is no explanation here
Device (PCI0)
{
Name (_HID, "PNP0A08" /* PCI Express Bus */) // _HID: Hardware ID
Name (_CID, "PNP0A03" /* PCI Bus */) // _CID: Compatible ID
Name (_SEG, Zero) // _SEG: PCI Segment
Name (_BBN, Zero) // _BBN: BIOS Bus Number
Name (_UID, Zero) // _UID: Unique ID
Name (_STR, Unicode ("PCIe 0 Device")) // _STR: Description String
Name (_CCA, One) // _CCA: Cache Coherency Attribute
Name (_PRT, Package (0x80) // _PRT: PCI Routing Table
{
Package (0x04)
{
0xFFFF,
Zero,
GSI0,
Zero
},
...
Package (0x04)
{
0x001FFFFF,
One,
GSI0,
Zero
},
Package (0x04)
{
0x001FFFFF,
0x02,
GSI1,
Zero
},
Package (0x04)
{
0x001FFFFF,
0x03,
GSI2,
Zero
}
})
...
}
// describe Generic Evenet Device Information about
Device (\_SB.GED)
{
Name (_HID, "ACPI0013" /* Generic Event Device */) // _HID: Hardware ID
Name (_UID, "GED") // _UID: Unique ID
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
// Interrupt message
Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
{
0x00000029,
}
})
// Register address and length
OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
//32 Bit register definition
Field (EREG, DWordAcc, NoLock, WriteAsZeros)
{
ESEL, 32
}
// How to operate
Method (_EVT, 1, Serialized) // _EVT: Event
{
Local0 = ESEL /* \_SB_.GED_.ESEL */
If (((Local0 & 0x02) == 0x02))
{
Notify (PWRB, 0x80) // Status Change
}
}
}
// Key information
Device (PWRB)
{
Name (_HID, "PNP0C0C" /* Power Button Device */) // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
}
}
}
MADT
MADT Used to describe interrupt hardware information .
MdePkg/Include/IndustryStandard/Acpi63.h
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header; --> ACPI Header
UINT32 LocalApicAddress; --> The address of the processor local interrupt processor
UINT32 Flags; --> Sign a .
} EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
stay MADT(EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER) Followed by a series of interrupt controller structures , Its size is not constant , It needs to be dynamically resolved . The following code can parse MADT Information about .
switch (Entry->Signature) {
...
case EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
DumpMADT((EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Entry);
break;
...
DumpMADT First of all, analyze out Header Information in , Then traverse the interrupt controller structure , Analyze the corresponding interrupt hardware information .AARCH64 There is only GIC,GICD and GIC MSI. So only dump These three interrupt controllers are designed .
TestPkg/TestDxeAcpi.c
VOID
DumpMADT(
IN EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MADT
)
{
UINT8 *TempPtr;
UINT8 Type, Length;
UINTN Len = 0;
DEBUG((DEBUG_INFO, "\n###########Start Dump MADT###########\n"));
DumpACPIHeader(&MADT->Header); // analysis ACPI head
DEBUG((DEBUG_INFO, "Local APIC Address:0x%08x\n", MADT->LocalApicAddress));
DEBUG((DEBUG_INFO, "Flags:0x%08x\n", MADT->Flags));
TempPtr = (UINT8 *)(MADT + 1);
Len = MADT->Header.Length - sizeof(EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
// Traverse the interrupt controller structure .
while (Len > 0) {
Type = *TempPtr; // The first byte of each interrupt controller structure is the type
Length = *(TempPtr + 1); // The second byte is the length
switch(Type)
{
// Resolve the corresponding interrupt structure information according to different types .
case EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC:
case EFI_ACPI_6_3_IO_APIC:
case EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE:
case EFI_ACPI_6_3_NON_MASKABLE_INTERRUPT_SOURCE:
case EFI_ACPI_6_3_LOCAL_APIC_NMI:
case EFI_ACPI_6_3_LOCAL_APIC_ADDRESS_OVERRIDE:
case EFI_ACPI_6_3_IO_SAPIC:
case EFI_ACPI_6_3_LOCAL_SAPIC:
case EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC:
case EFI_ACPI_6_3_LOCAL_X2APIC_NMI:
case EFI_ACPI_6_3_GICR:
case EFI_ACPI_6_3_GIC_ITS:
DEBUG((DEBUG_INFO, "Parser not implemented for Type:0x%02x\n", Type));
break;
case EFI_ACPI_6_3_GIC:
DumpMadtGIC((EFI_ACPI_6_3_GIC_STRUCTURE *)TempPtr);
break;
case EFI_ACPI_6_3_GICD:
DumpMadtGICD((EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE *)TempPtr);
break;
case EFI_ACPI_6_3_GIC_MSI_FRAME:
DumpMadtGICMSI((EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE *)TempPtr);
break;
default:
DEBUG((DEBUG_INFO, "Unknown Type:0x%02x\n", Type));
break;
}
Len = Len - Length;
TempPtr = TempPtr + Length;
}
DEBUG((DEBUG_INFO, "###########End Dump MADT###########\n\n"));
}


VOID
DumpMadtGIC(EFI_ACPI_6_3_GIC_STRUCTURE *GIC)
{
DEBUG((DEBUG_INFO, "GIC Information:\n"));
DEBUG((DEBUG_INFO, " CPU Interface Number:%d\n", GIC->CPUInterfaceNumber));
DEBUG((DEBUG_INFO, " Acpi Processor Uid:0x%08x\n", GIC->AcpiProcessorUid));
DEBUG((DEBUG_INFO, " Flags:0x%08x\n", GIC->Flags));
DEBUG((DEBUG_INFO, " Parking Protoco lVersion:0x%08x\n", GIC->ParkingProtocolVersion));
DEBUG((DEBUG_INFO, " Performance Interrupt Gsiv:0x%08x\n", GIC->PerformanceInterruptGsiv));
DEBUG((DEBUG_INFO, " Parked Address:0x%p\n", GIC->ParkedAddress));
DEBUG((DEBUG_INFO, " Physical Base Address:0x%p\n", GIC->PhysicalBaseAddress));
DEBUG((DEBUG_INFO, " GICV:0x%11p\n", GIC->GICV));
DEBUG((DEBUG_INFO, " GICH:0x%11p\n", GIC->GICH));
DEBUG((DEBUG_INFO, " VGIC Maintenance Interrupt:0x%x\n", GIC->VGICMaintenanceInterrupt));
DEBUG((DEBUG_INFO, " GICR Base Address:0x%11p\n", GIC->GICRBaseAddress));
DEBUG((DEBUG_INFO, " MPIDR:%11p\n", GIC->MPIDR));
DEBUG((DEBUG_INFO, " Processor Power Efficiency Class:0x%02x\n", GIC->ProcessorPowerEfficiencyClass));
DEBUG((DEBUG_INFO, " Spe Overflow Interrupt:0x%04x\n", GIC->SpeOverflowInterrupt));
}

VOID
DumpMadtGICD(
IN EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE *GICD
)
{
DEBUG((DEBUG_INFO, "GIC Distributor Information:\n"));
DEBUG((DEBUG_INFO, " Gic Id:0x%08x\n", GICD->GicId ));
DEBUG((DEBUG_INFO, " Physical Base Address:0x%11p\n", GICD->PhysicalBaseAddress));
DEBUG((DEBUG_INFO, " System Vector Base:0x%x\n", GICD->SystemVectorBase));
DEBUG((DEBUG_INFO, " Gic Version:0x%02x\n", GICD->GicVersion));
}

VOID
DumpMadtGICMSI(EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE *GICMSI)
{
DEBUG((DEBUG_INFO, "GIC MSI Information:\n"));
DEBUG((DEBUG_INFO, " Gic Msi Frame Id:0x%08x\n", GICMSI->GicMsiFrameId));
DEBUG((DEBUG_INFO, " Physical Base Address:0x%11p\n", GICMSI->PhysicalBaseAddress));
DEBUG((DEBUG_INFO, " Flags:0x%08x\n", GICMSI->Flags));
DEBUG((DEBUG_INFO, " SPI Count:0x%04x\n", GICMSI->SPICount));
DEBUG((DEBUG_INFO, " SPI Base:0x%04x\n", GICMSI->SPIBase));
}
Final dump Coming out log as follows
###########Start Dump MADT###########
Signature:APIC --> Header information
Length:0xA8
Revision:0x03
Checksum:0x50
OemID:BOCHS
OemTableId:0x2020202043505842
OemRevision:0x1
CreatorId:0x43505842
CreatorRevision:0x1
Local APIC Address:0x00000000 --> non-existent Local APIC
Flags:0x00000000
GIC Distributor Information:
Gic Id:0x00000000 --> GIC Distrubtor ID by 0
Physical Base Address:0x00008000000 --> GIC Distributor The physical address of
System Vector Base:0x0 --> It has to be for 0
Gic Version:0x02 --> GIC V2
GIC Information:
CPU Interface Number:0 --> CPU Interface does not exist , by 0
Acpi Processor Uid:0x00000000 --> non-existent
Flags:0x00000001 --> GIC You can make
Parking Protoco lVersion:0x00000000 --> ARM-Processor Parking Protocol Version number
Performance Interrupt Gsiv:0x00000017 --> Performance monitoring GIV Interrupt number
Parked Address:0x0
Physical Base Address:0x8010000 --> GIC The physical address of
GICV:0x00008040000 --> GIC virtual CPU interface Register address
GICH:0x00008030000 --> GIC virtual interface control block Register address
VGIC Maintenance Interrupt:0x0 --> non-existent
GICR Base Address:0x00000000000 --> Here is GIC V2, therefore GICR non-existent
MPIDR:00000000000
Processor Power Efficiency Class:0x0D --> Power consumption level
Spe Overflow Interrupt:0x0000 --> by 0, I won't support it Spe Overflow
GIC MSI Information:
Gic Msi Frame Id:0x00000000 --> ID by 0
Physical Base Address:0x00008020000 --> GIC MSI The physical address of
Flags:0x00000001 --> The SPI Count and Base values override the values specified in the MSI_TYPER register in the associated GIC MSI frame.
SPI Count:0x0040 --> SPI Number
SPI Base:0x0050
###########End Dump MADT###########
SPCR
SPCR(Serial Port Console Redirection) Provides information about serial ports or non legacy UART Interface configuration and usage information .. stay BIOS Use this serial port as console input / In the output system , You should use this table to pass information about these settings , Make sure BIOS Console output and Windows EMS(Emergency Management Serivces) Smooth transition between outputs .


MdePkg/Include/IndustryStandard/SerialPortConsoleRedirection.h
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 InterfaceType;
UINT8 Reserved1[3];
EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE BaseAddress;
UINT8 InterruptType;
UINT8 Irq;
UINT32 GlobalSystemInterrupt;
UINT8 BaudRate;
UINT8 Parity;
UINT8 StopBits;
UINT8 FlowControl;
UINT8 TerminalType;
UINT8 Reserved2;
UINT16 PciDeviceId;
UINT16 PciVendorId;
UINT8 PciBusNumber;
UINT8 PciDeviceNumber;
UINT8 PciFunctionNumber;
UINT32 PciFlags;
UINT8 PciSegment;
UINT32 Reserved3;
} EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE;
Dump SPCR The code for is as follows
switch (Entry->Signature) {
...
case EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
DumpSPCR((EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *)Entry);
break;
...
}
VOID
DumpSPCR(
IN EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *SPCR
)
{
char *TempStr;
DEBUG((DEBUG_INFO, "\n#########Start Dump SPCR##########\n"));
DumpACPIHeader(&SPCR->Header);
switch(SPCR->InterfaceType) {
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_16550:
TempStr = "16550";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_16450:
TempStr = "16450";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_PL011_UART:
TempStr = "ARM PL011 UART";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_NVIDIA_16550_UART:
TempStr = "NVIDIA 16550 UART";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_SBSA_GENERIC_UART_2X:
TempStr = "ARM SBSA Generic UART 2.x";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_SBSA_GENERIC_UART:
TempStr = "ARM SBSA Generic UART";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_DCC:
TempStr = "ARM DCC";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_BCM2835_UART:
TempStr = "BCM2835";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_16550_WITH_GAS:
TempStr = "16550-compatible";
break;
default:
TempStr = "Reserved";
break;
}
DEBUG((DEBUG_INFO, "Interface:%a\n", TempStr));
DumpGenericAddress("Base Address", (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *)&SPCR->BaseAddress);
switch (SPCR->InterruptType)
{
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_8259:
TempStr = "8259";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_APIC:
TempStr = "APIC";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_SAPIC:
TempStr = "SAPIC";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC:
TempStr = "GIC";
break;
default:
TempStr = "Not Supported";
break;
}
DEBUG((DEBUG_INFO, "Interrupt Type: %a\n", TempStr));
DEBUG((DEBUG_INFO, "IRQ:%d\n", SPCR->Irq));
DEBUG((DEBUG_INFO, "Global System Interrupt:0x%x\n", SPCR->GlobalSystemInterrupt));
switch (SPCR->BaudRate)
{
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600:
TempStr = "9600";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200:
TempStr = "19200";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600:
TempStr = "57600";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200:
TempStr = "115200";
break;
default:
TempStr = "Reserved";
break;
}
DEBUG((DEBUG_INFO, "Baud Rate:%a\n", TempStr));
switch (SPCR->Parity)
{
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY:
DEBUG((DEBUG_INFO, "Parity: No Parity\n"));
break;
default:
DEBUG((DEBUG_INFO, "Parity: Reserved\n"));
break;
}
switch (SPCR->StopBits)
{
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1:
DEBUG((DEBUG_INFO, "Stop Bits:%d\n", SPCR->StopBits));
break;
default:
DEBUG((DEBUG_INFO, "Stop Bits: No Stop Bits\n"));
break;
}
DEBUG((DEBUG_INFO, "Flow Control: \n"));
if (SPCR->FlowControl & EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_FLOW_CONTROL_DCD) {
DEBUG((DEBUG_INFO, " Support DCD\n"));
}
if (SPCR->FlowControl & EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_FLOW_CONTROL_RTS_CTS) {
DEBUG((DEBUG_INFO, " Support RTS/CTS\n"));
}
if (SPCR->FlowControl & EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_FLOW_CONTROL_XON_XOFF) {
DEBUG((DEBUG_INFO, " Support XON/XOFF\n"));
}
switch (SPCR->TerminalType)
{
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT100:
TempStr = "VT100";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT100_PLUS:
TempStr = "VT100+";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8:
TempStr = "VI-UTF8";
break;
case EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_ANSI:
TempStr = "ANSI";
break;
default:
TempStr = "Reserved";
break;
}
DEBUG((DEBUG_INFO, "Termial Type:%a\n", TempStr));
DEBUG((DEBUG_INFO, "PCI Device ID:0x%04x\n", SPCR->PciDeviceId));
DEBUG((DEBUG_INFO, "PCI Vendor ID:0x%04x\n", SPCR->PciVendorId));
DEBUG((DEBUG_INFO, "PCI Bus Number:0x%02x\n", SPCR->PciBusNumber));
DEBUG((DEBUG_INFO, "PCI Device Number:0x%02x\n", SPCR->PciDeviceNumber));
DEBUG((DEBUG_INFO, "PCI Function Number:0x%02x\n", SPCR->PciFunctionNumber));
DEBUG((DEBUG_INFO, "PCI Flags:0x%08x\n", SPCR->PciFlags));
DEBUG((DEBUG_INFO, "PCI Segment:0x%02x\n", SPCR->PciSegment));
DEBUG((DEBUG_INFO, "###########End Dump SPCR###########\n\n"));
}
dump Out of log
#########Start Dump SPCR##########
Signature:SPCR
Length:0x50
Revision:0x02
Checksum:0xCB
OemID:BOCHS
OemTableId:0x2020202043505842
OemRevision:0x1
CreatorId:0x43505842
CreatorRevision:0x1
Interface:ARM PL011 UART --> The type is ARM PL011 IP
--> The physical address of the serial port is 0x00009000000.
Base Address: AddressSpaceId:0x00, RegisterBitWidth:0x08, RegisterBitOffset:0x00, AccessSize:0x01, Address:0x00009000000
Interrupt Type: GIC --> The interrupt type is ARM GIC
IRQ:0
Global System Interrupt:0x21 --> The interrupt number is 0x21
Baud Rate:9600 --> The baud rate is 9600
Parity: No Parity --> No parity
Stop Bits:1 --> Stop bit is 1 position
Flow Control: --> Support RTS/CTS
Support RTS/CTS
Termial Type:VT100 --> Console The type is VT100
PCI Device ID:0xFFFF --> No PCI equipment , The following fields are all invalid
PCI Vendor ID:0xFFFF
PCI Bus Number:0x00
PCI Device Number:0x00
PCI Function Number:0x00
PCI Flags:0x00000000
PCI Segment:0x00
###########End Dump SPCR###########
边栏推荐
- [CISCN2019 华北赛区 Day2 Web1]Hack World
- ionic5表单输入框和单选按钮
- How to use matrix analysis to build your thinking scaffold in flowus, notation and other note taking software
- [event registration] sofastack × CSDN jointly held the open source series meetup, which was launched on June 24
- Redis学习笔记—单个键管理
- [GXYCTF2019]BabyUpload
- 设CPU有16根地址线,8根数据线,并用MREQ作为访存控制线号......存储器与CPU的连接
- 2022.6.22-----leetcode. five hundred and thirteen
- map的下标操作符
- 全局快门和卷帘快门的区别
猜你喜欢
随机推荐
Redis learning notes - redis and Lua
Redis learning notes RDB of persistence mechanism
Redis learning notes - detailed explanation of redis benchmark
'coach, I want to play basketball!'—— AI Learning Series booklet for system students
[極客大挑戰 2019]HardSQL
Basic process of code scanning login
[learning resources] understand and love mathematics
进入小公司的初级程序员要如何自我提高?
ionic5錶單輸入框和單選按鈕
Chain representation and implementation of linklist ---- linear structure
Redis learning notes - data type: hash
What is a closure function
Correspondence between three-tier architecture and SSM
[GXYCTF2019]BabySQli
ARM处理器与51单片机程序编写的区别
Basic use of lua
RBtree
Chain implementation of stack -- linear structure
自定义标签——jsp标签增强
Combination sum II of leetcode topic analysis








![[geek challenge 2019] hardsql](/img/73/ebfb410296b8e950c9ac0cf00adc17.png)