/** Returns a boolean indicating if the firmware configuration interface is available or not. This function may change fw_cfg state. @retval TRUE The interface is available @retval FALSE The interface is not available **/ BOOLEAN EFIAPI QemuFwCfgIsAvailable ( VOID ) { UINT32 Signature; UINT32 Revision; QemuFwCfgSelectItem (QemuFwCfgItemSignature); Signature = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature)); QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); Revision = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision)); if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) || (Revision < 1) ) { DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n")); return FALSE; } DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n")); return TRUE; }
RETURN_STATUS EFIAPI QemuFwCfgInitialize ( VOID ) { UINT32 Signature; UINT32 Revision; // // Enable the access routines while probing to see if it is supported. // mQemuFwCfgSupported = TRUE; QemuFwCfgSelectItem (QemuFwCfgItemSignature); Signature = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature)); QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); Revision = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision)); if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) || (Revision < 1) ) { DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n")); mQemuFwCfgSupported = FALSE; return RETURN_SUCCESS; } DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n")); return RETURN_SUCCESS; }
RETURN_STATUS EFIAPI QemuFwCfgInitialize ( VOID ) { UINT32 Signature; UINT32 Revision; // // Enable the access routines while probing to see if it is supported. // For probing we always use the IO Port (IoReadFifo8()) access method. // mQemuFwCfgSupported = TRUE; mQemuFwCfgDmaSupported = FALSE; QemuFwCfgSelectItem (QemuFwCfgItemSignature); Signature = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature)); QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); Revision = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision)); if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) || (Revision < 1) ) { DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n")); mQemuFwCfgSupported = FALSE; return RETURN_SUCCESS; } if ((Revision & FW_CFG_F_DMA) == 0) { DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n")); } else { mQemuFwCfgDmaSupported = TRUE; DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n")); } if (mQemuFwCfgDmaSupported && MemEncryptSevIsEnabled ()) { EFI_STATUS Status; // // IoMmuDxe driver must have installed the IOMMU protocol. If we are not // able to locate the protocol then something must have gone wrong. // Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmuProtocol); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "QemuFwCfgSevDma %a:%a Failed to locate IOMMU protocol.\n", gEfiCallerBaseName, __FUNCTION__)); ASSERT (FALSE); CpuDeadLoop (); } } return RETURN_SUCCESS; }
/** Initialize and publish TPM items in ACPI table. @retval EFI_SUCCESS The TCG ACPI table is published successfully. @retval Others The TCG ACPI table is not published. **/ EFI_STATUS PublishAcpiTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; EFI_ACPI_DESCRIPTION_HEADER *Table; UINTN TableSize; Status = GetSectionFromFv ( &gEfiCallerIdGuid, EFI_SECTION_RAW, 0, (VOID **) &Table, &TableSize ); ASSERT_EFI_ERROR (Status); // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, Table, TableSize ); ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l')); CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) ); mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS)); ASSERT (mTcgNvs != NULL); // // Publish the TPM ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); TableKey = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
RETURN_STATUS EFIAPI QemuFwCfgInitialize ( VOID ) { UINT32 Signature; UINT32 Revision; // // Enable the access routines while probing to see if it is supported. // For probing we always use the IO Port (IoReadFifo8()) access method. // mQemuFwCfgSupported = TRUE; mQemuFwCfgDmaSupported = FALSE; QemuFwCfgSelectItem (QemuFwCfgItemSignature); Signature = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature)); QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); Revision = QemuFwCfgRead32 (); DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision)); if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) || (Revision < 1) ) { DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n")); mQemuFwCfgSupported = FALSE; return RETURN_SUCCESS; } if ((Revision & FW_CFG_F_DMA) == 0) { DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n")); } else { // // If SEV is enabled then we do not support DMA operations in PEI phase. // This is mainly because DMA in SEV guest requires using bounce buffer // (which need to allocate dynamic memory and allocating a PAGE size'd // buffer can be challenge in PEI phase) // if (MemEncryptSevIsEnabled ()) { DEBUG ((DEBUG_INFO, "SEV: QemuFwCfg fallback to IO Port interface.\n")); } else { mQemuFwCfgDmaSupported = TRUE; DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n")); } } return RETURN_SUCCESS; }
/** Initialize and publish TPM items in ACPI table. @retval EFI_SUCCESS The TCG ACPI table is published successfully. @retval Others The TCG ACPI table is not published. **/ EFI_STATUS PublishAcpiTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; EFI_ACPI_DESCRIPTION_HEADER *Table; UINTN TableSize; Status = GetSectionFromFv ( &gEfiCallerIdGuid, EFI_SECTION_RAW, 0, (VOID **) &Table, &TableSize ); ASSERT_EFI_ERROR (Status); ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'c', 'g', 'T', 'a', 'b', 'l', 'e')); mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS)); ASSERT (mTcgNvs != NULL); // // Publish the TPM ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); TableKey = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
//fTPM ACPI Object (AML code binary) #include "fTPMAmlData.h" #include "fTPMAcpi.h" #include <Guid/EventGroup.h> #include <Library/PspBaseLib.h> #include <Library/PspfTpmLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Protocol/AcpiSupport.h> #include <Protocol/AcpiSystemDescriptionTable.h> EFI_EVENT mfTPMAcpiEventHandle; STATIC TPM2_ACPI_TABLE Tpm2AcpiTable = { { SIGNATURE_32 ('T','P','M','2'), sizeof (TPM2_ACPI_TABLE), 0x03, // ACPI Revision. 0x00, TPM2_ACPI_OEM_ID, // OEM ID (filled in below). TPM2_ACPI_TABLE_OEM_ID, // OEM Table ID (filled in below). TPM2_ACPI_OEM_REVISION , // ACPI OEM Revision (filled in below). 1, // OEM Creator ID (filled in below). 1 // OEM Creator Revision (filled in below). }, 0, // Flags 0, // ControlArea 0x02 // StartMethod }; VOID
EFI_STATUS QemuVideoBochsModeSetup ( QEMU_VIDEO_PRIVATE_DATA *Private, BOOLEAN IsQxl ) { UINT32 AvailableFbSize; UINT32 Index; QEMU_VIDEO_MODE_DATA *ModeData; QEMU_VIDEO_BOCHS_MODES *VideoMode; // // Fetch the available framebuffer size. // // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the // drawable framebuffer. Up to and including qemu-2.1 however it used to // return the size of PCI BAR 0 (ie. the full video RAM size). // // On stdvga the two concepts coincide with each other; the full memory size // is usable for drawing. // // On QXL however, only a leading segment, "surface 0", can be used for // drawing; the rest of the video memory is used for the QXL guest-host // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of // "surface 0", but since it doesn't (up to and including qemu-2.1), we // retrieve the size of the drawable portion from a field in the QXL ROM BAR, // where it is also available. // if (IsQxl) { UINT32 Signature; UINT32 DrawStart; Signature = 0; DrawStart = 0xFFFFFFFF; AvailableFbSize = 0; if (EFI_ERROR ( Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, PCI_BAR_IDX2, 0, 1, &Signature)) || Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O') || EFI_ERROR ( Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, PCI_BAR_IDX2, 36, 1, &DrawStart)) || DrawStart != 0 || EFI_ERROR ( Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, PCI_BAR_IDX2, 40, 1, &AvailableFbSize))) { DEBUG ((EFI_D_ERROR, "%a: can't read size of drawable buffer from QXL " "ROM\n", __FUNCTION__)); return EFI_NOT_FOUND; } } else { AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); AvailableFbSize *= SIZE_64KB; } DEBUG ((EFI_D_VERBOSE, "%a: AvailableFbSize=0x%x\n", __FUNCTION__, AvailableFbSize)); // // Setup Video Modes // Private->ModeData = AllocatePool ( sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT ); if (Private->ModeData == NULL) { return EFI_OUT_OF_RESOURCES; } ModeData = Private->ModeData; VideoMode = &QemuVideoBochsModes[0]; for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) { UINTN RequiredFbSize; ASSERT (VideoMode->ColorDepth % 8 == 0); RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height * (VideoMode->ColorDepth / 8); if (RequiredFbSize <= AvailableFbSize) { ModeData->InternalModeIndex = Index; ModeData->HorizontalResolution = VideoMode->Width; ModeData->VerticalResolution = VideoMode->Height; ModeData->ColorDepth = VideoMode->ColorDepth; ModeData->RefreshRate = 60; DEBUG ((EFI_D_INFO, "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit, %d Hz\n", (INT32) (ModeData - Private->ModeData), ModeData->InternalModeIndex, ModeData->HorizontalResolution, ModeData->VerticalResolution, ModeData->ColorDepth, ModeData->RefreshRate )); ModeData ++ ; } VideoMode ++; } Private->MaxMode = ModeData - Private->ModeData; return EFI_SUCCESS; }
VOID DsdtTableUpdate ( IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, IN OUT EFI_ACPI_TABLE_VERSION *Version ) /*++ Routine Description: Update the DSDT table Arguments: Table - The table to be set Version - Version to publish Returns: None --*/ { UINT8 *CurrPtr; UINT8 *DsdtPointer; UINT32 *Signature; UINT8 *Operation; UINT32 *Address; UINT16 *Size; // // Loop through the ASL looking for values that we must fix up. // CurrPtr = (UINT8 *) TableHeader; for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++ ) { Signature = (UINT32 *) DsdtPointer; switch (*Signature) { // // MNVS operation region // case (SIGNATURE_32 ('M', 'N', 'V', 'S')): // // Conditional match. For Region Objects, the Operator will always be the // byte immediately before the specific name. Therefore, subtract 1 to check // the Operator. // Operation = DsdtPointer - 1; if (*Operation == AML_OPREGION_OP) { Address = (UINT32 *) (DsdtPointer + 6); *Address = (UINT32) (UINTN) mGlobalNvsArea.Area; Size = (UINT16 *) (DsdtPointer + 11); *Size = sizeof (EFI_GLOBAL_NVS_AREA); } break; // // Update processor PBLK register I/O base address // case (SIGNATURE_32 ('P', 'R', 'I', 'O')): // // Conditional match. Update the following ASL code: // Processor (CPU0, 0x01, 0x4F495250, 0x06) {} // The 3rd parameter will be updated to the actual PBLK I/O base address. // the Operator. // Operation = DsdtPointer - 8; if ((*Operation == AML_EXT_OP) && (*(Operation + 1) == AML_EXT_PROCESSOR_OP)) { *(UINT32 *)DsdtPointer = PcdGet16(PcdPmbaIoBaseAddress); } break; default: break; } } }
RETURN_STATUS EFIAPI QemuFwCfgInitialize ( VOID ) { EFI_STATUS Status; FDT_CLIENT_PROTOCOL *FdtClient; CONST UINT64 *Reg; UINT32 RegSize; UINTN AddressCells, SizeCells; UINT64 FwCfgSelectorAddress; UINT64 FwCfgSelectorSize; UINT64 FwCfgDataAddress; UINT64 FwCfgDataSize; UINT64 FwCfgDmaAddress; UINT64 FwCfgDmaSize; Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient); ASSERT_EFI_ERROR (Status); Status = FdtClient->FindCompatibleNodeReg (FdtClient, "qemu,fw-cfg-mmio", (CONST VOID **)&Reg, &AddressCells, &SizeCells, &RegSize); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "%a: No 'qemu,fw-cfg-mmio' compatible DT node found (Status == %r)\n", __FUNCTION__, Status)); return EFI_SUCCESS; } ASSERT (AddressCells == 2); ASSERT (SizeCells == 2); ASSERT (RegSize == 2 * sizeof (UINT64)); FwCfgDataAddress = SwapBytes64 (Reg[0]); FwCfgDataSize = 8; FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize; FwCfgSelectorSize = 2; // // The following ASSERT()s express // // Address + Size - 1 <= MAX_UINTN // // for both registers, that is, that the last byte in each MMIO range is // expressible as a MAX_UINTN. The form below is mathematically // equivalent, and it also prevents any unsigned overflow before the // comparison. // ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1); ASSERT (FwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1); mFwCfgSelectorAddress = FwCfgSelectorAddress; mFwCfgDataAddress = FwCfgDataAddress; DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", FwCfgSelectorAddress, FwCfgDataAddress)); if (SwapBytes64 (Reg[1]) >= 0x18) { FwCfgDmaAddress = FwCfgDataAddress + 0x10; FwCfgDmaSize = 0x08; // // See explanation above. // ASSERT (FwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1); DEBUG ((EFI_D_INFO, "Found FwCfg DMA @ 0x%Lx\n", FwCfgDmaAddress)); } else { FwCfgDmaAddress = 0; } if (InternalQemuFwCfgIsAvailable ()) { UINT32 Signature; QemuFwCfgSelectItem (QemuFwCfgItemSignature); Signature = QemuFwCfgRead32 (); if (Signature == SIGNATURE_32 ('Q', 'E', 'M', 'U')) { // // For DMA support, we require the DTB to advertise the register, and the // feature bitmap (which we read without DMA) to confirm the feature. // if (FwCfgDmaAddress != 0) { UINT32 Features; QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); Features = QemuFwCfgRead32 (); if ((Features & BIT1) != 0) { mFwCfgDmaAddress = FwCfgDmaAddress; InternalQemuFwCfgReadBytes = DmaReadBytes; } } } else { mFwCfgSelectorAddress = 0; mFwCfgDataAddress = 0; } } return RETURN_SUCCESS; }
STATIC VOID SetupLinuxMemmap ( IN OUT struct boot_params *Bp ) { EFI_STATUS Status; UINT8 TmpMemoryMap[1]; UINTN MapKey; UINTN DescriptorSize; UINT32 DescriptorVersion; UINTN MemoryMapSize; EFI_MEMORY_DESCRIPTOR *MemoryMap; EFI_MEMORY_DESCRIPTOR *MemoryMapPtr; UINTN Index; struct efi_info *Efi; struct e820_entry *LastE820; struct e820_entry *E820; UINTN E820EntryCount; EFI_PHYSICAL_ADDRESS LastEndAddr; // // Get System MemoryMapSize // MemoryMapSize = sizeof (TmpMemoryMap); Status = gBS->GetMemoryMap ( &MemoryMapSize, (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion ); ASSERT (Status == EFI_BUFFER_TOO_SMALL); // // Enlarge space here, because we will allocate pool now. // MemoryMapSize += EFI_PAGE_SIZE; MemoryMap = AllocatePool (MemoryMapSize); ASSERT (MemoryMap != NULL); // // Get System MemoryMap // Status = gBS->GetMemoryMap ( &MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion ); ASSERT_EFI_ERROR (Status); LastE820 = NULL; E820 = &Bp->e820_map[0]; E820EntryCount = 0; LastEndAddr = 0; MemoryMapPtr = MemoryMap; for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) { UINTN E820Type = 0; if (MemoryMap->NumberOfPages == 0) { continue; } switch(MemoryMap->Type) { case EfiReservedMemoryType: case EfiRuntimeServicesCode: case EfiRuntimeServicesData: case EfiMemoryMappedIO: case EfiMemoryMappedIOPortSpace: case EfiPalCode: E820Type = E820_RESERVED; break; case EfiUnusableMemory: E820Type = E820_UNUSABLE; break; case EfiACPIReclaimMemory: E820Type = E820_ACPI; break; case EfiLoaderCode: case EfiLoaderData: case EfiBootServicesCode: case EfiBootServicesData: case EfiConventionalMemory: E820Type = E820_RAM; break; case EfiACPIMemoryNVS: E820Type = E820_NVS; break; default: DEBUG (( EFI_D_ERROR, "Invalid EFI memory descriptor type (0x%x)!\n", MemoryMap->Type )); continue; } if ((LastE820 != NULL) && (LastE820->type == (UINT32) E820Type) && (MemoryMap->PhysicalStart == LastEndAddr)) { LastE820->size += EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages); LastEndAddr += EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages); } else { if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof (Bp->e820_map[0]))) { break; } E820->type = (UINT32) E820Type; E820->addr = MemoryMap->PhysicalStart; E820->size = EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages); LastE820 = E820; LastEndAddr = E820->addr + E820->size; E820++; E820EntryCount++; } // // Get next item // MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize); } Bp->e820_entries = (UINT8) E820EntryCount; Efi = &Bp->efi_info; Efi->efi_systab = (UINT32)(UINTN) gST; Efi->efi_memdesc_size = (UINT32) DescriptorSize; Efi->efi_memdesc_version = DescriptorVersion; Efi->efi_memmap = (UINT32)(UINTN) MemoryMapPtr; Efi->efi_memmap_size = (UINT32) MemoryMapSize; #ifdef MDE_CPU_IA32 Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2'); #else Efi->efi_systab_hi = ((UINT64)(UINTN) gST) >> 32; Efi->efi_memmap_hi = ((UINT64)(UINTN) MemoryMapPtr) >> 32; Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4'); #endif gBS->ExitBootServices (gImageHandle, MapKey); }
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "MMCHS.h" EFI_BLOCK_IO_MEDIA gMMCHSMedia = { SIGNATURE_32('s','d','i','o'), // MediaId TRUE, // RemovableMedia FALSE, // MediaPresent FALSE, // LogicalPartition FALSE, // ReadOnly FALSE, // WriteCaching 512, // BlockSize 4, // IoAlign 0, // Pad 0 // LastBlock }; typedef struct { VENDOR_DEVICE_PATH Mmc; EFI_DEVICE_PATH End; } MMCHS_DEVICE_PATH;
VOID FillSysTablesInfo(VOID **Tables, UINT32 TablesSize) { UINT32 Table = 0; EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdPtr; VOID *TablesPage; #define FLAG_OPTIONAL 1<<0 #define FLAG_NO_CHECKSUM 1<<1 static struct { UINT32 Signature; UINT32 Flags; CHAR8* Name; } TableInfo[] = { // MADT, optional { SIGNATURE_32('A', 'P', 'I', 'C'), FLAG_OPTIONAL, "MADT"}, // FACP (also called FADT) { SIGNATURE_32('F', 'A', 'C', 'P'), 0, "FADT"}, // FACS, according 5.2.9 of ACPI v2. spec FACS doesn't have checksum field { SIGNATURE_32('F', 'A', 'C', 'S'), FLAG_NO_CHECKSUM, "FACS"}, // DSDT { SIGNATURE_32('D', 'S', 'D', 'T'), 0, "DSDT"}, // SSDT { SIGNATURE_32('S', 'S', 'D', 'T'), FLAG_OPTIONAL, "SSDT"}, // HPET { SIGNATURE_32('H', 'P', 'E', 'T'), FLAG_OPTIONAL, "HPET"}, // MCFG { SIGNATURE_32('M', 'C', 'F', 'G'), FLAG_OPTIONAL, "MCFG"} }; UINT32 Index; RsdPtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER*)FindAcpiRsdPtr(); ASSERT(RsdPtr != NULL); TablesPage = (VOID*)(UINTN)((RsdPtr->RsdtAddress) & ~0xfff); DEBUG((DEBUG_INFO, "TablesPage:%p\n", TablesPage)); for (Index = 0; Index < sizeof TableInfo / sizeof TableInfo[0]; Index++) { VOID *Ptr = FindSignature(TablesPage, TableInfo[Index].Signature, (BOOLEAN)((TableInfo[Index].Flags & FLAG_NO_CHECKSUM) != 0)); if (TableInfo[Index].Signature == SIGNATURE_32('F', 'A', 'C', 'P')) { // we actually have 2 FADTs, see https://xtracker.innotek.de/index.php?bug=4082 Ptr = FindSignature((UINT8*)Ptr+32, SIGNATURE_32('F', 'A', 'C', 'P'), FALSE); } if (!(TableInfo[Index].Flags & FLAG_OPTIONAL)) { if (!Ptr) DEBUG((EFI_D_ERROR, "%a: isn't optional %p\n", TableInfo[Index].Name, Ptr)); ASSERT(Ptr != NULL); } DEBUG((EFI_D_ERROR, "%a: %p\n", TableInfo[Index].Name, Ptr)); if (Ptr) Tables[Table++] = Ptr; } #if 0 // RSDT ASSERT(Table < TablesSize); Tables[Table] = FindSignature(TablesPage, SIGNATURE_32('R', 'S', 'D', 'T')); DEBUG ((EFI_D_ERROR, "RSDT: %p\n", Tables[Table])); ASSERT(Tables[Table] != NULL); Table++; // XSDT ASSERT(Table < TablesSize); Tables[Table] = FindSignature(TablesPage, SIGNATURE_32('X', 'S', 'D', 'T')); DEBUG ((EFI_D_ERROR, "XSDT: %p\n", Tables[Table])); ASSERT(Tables[Table] != NULL); Table++; #endif DEBUG((DEBUG_INFO, "We found %d tables from %d\n", Table, TablesSize)); Tables[Table] = NULL; }
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include <Protocol/DevicePath.h> #include <Library/BaseLib.h> #include <Library/BaseMemoryLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/DevicePathLib.h> #include "Mmc.h" EFI_BLOCK_IO_MEDIA mMmcMediaTemplate = { SIGNATURE_32('m','m','c','o'), // MediaId TRUE, // RemovableMedia FALSE, // MediaPresent FALSE, // LogicalPartition FALSE, // ReadOnly FALSE, // WriteCaching 512, // BlockSize 4, // IoAlign 0, // Pad 0 // LastBlock }; // // This device structure is serviced as a header. // Its next field points to the first root bridge device node. //