From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: david.y.wei@intel.com) Received: from mga17.intel.com (mga17.intel.com []) by groups.io with SMTP; Fri, 09 Aug 2019 15:46:57 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Aug 2019 15:46:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,367,1559545200"; d="scan'208";a="199536447" Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by fmsmga004.fm.intel.com with ESMTP; 09 Aug 2019 15:46:55 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules Date: Fri, 9 Aug 2019 15:46:49 -0700 Message-Id: <28fad95137c6aecfbf593a14191bdb4d0819951e.1565389186.git.david.y.wei@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: References: MIME-Version: 1.0 In-Reply-To: References: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add modules AcpiTables, Include, Library, PlatformDxe, PlatformPei, Policy, SmbiosPlatformDxe for Simics QSP platform support Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: David Wei --- .../Library/LoadLinuxLib/Linux.c | 662 ++++++++++++++++ .../Library/LoadLinuxLib/LinuxGdt.c | 175 +++++ .../Library/NvVarsFileLib/FsAccess.c | 507 ++++++++++++ .../Library/NvVarsFileLib/NvVarsFileLib.c | 77 ++ .../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++++++++++++ .../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865 ++++++++++++++++++++ .../PlatformDxe/PlatformConfig.c | 123 +++ .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 ++ .../PlatformPei/FeatureControl.c | 114 +++ Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 +++ .../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568 ++++++++++++++ .../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 +++++++++++++++ .../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 +++ .../SiliconPolicyUpdateLib.c | 70 ++ .../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++++ .../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 + .../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 +++++++++++++++++++ .../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 ++ .../Include/Guid/SimicsX58PlatformConfig.h | 17 + .../Include/IndustryStandard/X58Ich10.h | 106 +++ .../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 +++++++ .../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++++++ .../Include/Protocol/Legacy8259.h | 291 +++++++ .../Include/Register/X58SmramSaveStateMap.h | 178 +++++ .../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 ++ .../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 + .../Library/LoadLinuxLib/LoadLinuxLib.h | 52 ++ .../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 + .../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++ .../Library/NvVarsFileLib/NvVarsFileLib.h | 55 ++ .../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 ++ .../SerializeVariablesLib/SerializeVariablesLib.h | 33 + .../SerializeVariablesLib.inf | 36 + .../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 + .../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 ++ .../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 + .../PlatformDxe/PlatformConfig.h | 51 ++ .../PlatformDxe/PlatformForms.vfr | 67 ++ .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 ++ .../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 +++ .../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 +++ .../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 + .../SiliconPolicyUpdateLib.inf | 35 + .../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 ++++ .../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 + .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 ++ 46 files changed, 8531 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c new file mode 100644 index 0000000000..43a2dee9f6 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c @@ -0,0 +1,662 @@ +/** @file + Copyright (c) 2011 - 2014 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "LoadLinuxLib.h" + + +/** + A simple check of the kernel setup image + + An assumption is made that the size of the data is at least the + size of struct boot_params. + + @param[in] KernelSetup - The kernel setup image + + @retval EFI_SUCCESS - The kernel setup looks valid and supported + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL + @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported + +**/ +STATIC +EFI_STATUS +EFIAPI +BasicKernelSetupCheck ( + IN VOID *KernelSetup + ) +{ + return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params)); +} + + +EFI_STATUS +EFIAPI +LoadLinuxCheckKernelSetup ( + IN VOID *KernelSetup, + IN UINTN KernelSetupSize + ) +{ + struct boot_params *Bp; + + if (KernelSetup == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (KernelSetupSize < sizeof (*Bp)) { + return EFI_UNSUPPORTED; + } + + Bp = (struct boot_params*) KernelSetup; + + if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature + (Bp->hdr.header != SETUP_HDR) || + (Bp->hdr.version < 0x205) || // We only support relocatable kernels + (!Bp->hdr.relocatable_kernel) + ) { + return EFI_UNSUPPORTED; + } else { + return EFI_SUCCESS; + } +} + + +UINTN +EFIAPI +LoadLinuxGetKernelSize ( + IN VOID *KernelSetup, + IN UINTN KernelSize + ) +{ + struct boot_params *Bp; + + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) { + return 0; + } + + Bp = (struct boot_params*) KernelSetup; + + if (Bp->hdr.version > 0x20a) { + return Bp->hdr.init_size; + } else { + // + // Add extra size for kernel decompression + // + return 3 * KernelSize; + } +} + + +VOID* +EFIAPI +LoadLinuxAllocateKernelSetupPages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + + Address = BASE_1GB; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiLoaderData, + Pages, + &Address + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) Address; + } else { + return NULL; + } +} + +EFI_STATUS +EFIAPI +LoadLinuxInitializeKernelSetup ( + IN VOID *KernelSetup + ) +{ + EFI_STATUS Status; + UINTN SetupEnd; + struct boot_params *Bp; + + Status = BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp = (struct boot_params*) KernelSetup; + + SetupEnd = 0x202 + (Bp->hdr.jump & 0xff); + + // + // Clear all but the setup_header + // + ZeroMem (KernelSetup, 0x1f1); + ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd); + DEBUG ((EFI_D_INFO, "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n", + (UINT64)SetupEnd)); + + return EFI_SUCCESS; +} + +VOID* +EFIAPI +LoadLinuxAllocateKernelPages ( + IN VOID *KernelSetup, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS KernelAddress; + UINT32 Loop; + struct boot_params *Bp; + + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) { + return NULL; + } + + Bp = (struct boot_params*) KernelSetup; + + for (Loop = 1; Loop < 512; Loop++) { + KernelAddress = MultU64x32 ( + 2 * Bp->hdr.kernel_alignment, + Loop + ); + Status = gBS->AllocatePages ( + AllocateAddress, + EfiLoaderData, + Pages, + &KernelAddress + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) KernelAddress; + } + } + + return NULL; +} + + +VOID* +EFIAPI +LoadLinuxAllocateCommandLinePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + + Address = 0xa0000; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiLoaderData, + Pages, + &Address + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) Address; + } else { + return NULL; + } +} + + +VOID* +EFIAPI +LoadLinuxAllocateInitrdPages ( + IN VOID *KernelSetup, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + + struct boot_params *Bp; + + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) { + return NULL; + } + + Bp = (struct boot_params*) KernelSetup; + + Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Bp->hdr.ramdisk_max; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiLoaderData, + Pages, + &Address + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) Address; + } else { + return NULL; + } +} + + +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; + Status = gBS->AllocatePool ( + EfiLoaderData, + MemoryMapSize, + (VOID **) &MemoryMap + ); + ASSERT_EFI_ERROR (Status); + + // + // 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 ((UINTN) MemoryMap->NumberOfPages); + LastEndAddr += EFI_PAGES_TO_SIZE ((UINTN) 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 ((UINTN) 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 = (UINT32) (((UINT64)(UINTN) gST) >> 32); + Efi->efi_memmap_hi = (UINT32) (((UINT64)(UINTN) MemoryMapPtr) >> 32); + Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4'); +#endif + + gBS->ExitBootServices (gImageHandle, MapKey); +} + + +EFI_STATUS +EFIAPI +LoadLinuxSetCommandLine ( + IN OUT VOID *KernelSetup, + IN CHAR8 *CommandLine + ) +{ + EFI_STATUS Status; + struct boot_params *Bp; + + Status = BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp = (struct boot_params*) KernelSetup; + + Bp->hdr.cmd_line_ptr = (UINT32)(UINTN) CommandLine; + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +LoadLinuxSetInitrd ( + IN OUT VOID *KernelSetup, + IN VOID *Initrd, + IN UINTN InitrdSize + ) +{ + EFI_STATUS Status; + struct boot_params *Bp; + + Status = BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp = (struct boot_params*) KernelSetup; + + Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd; + Bp->hdr.ramdisk_len = (UINT32) InitrdSize; + + return EFI_SUCCESS; +} + + +STATIC VOID +FindBits ( + unsigned long Mask, + UINT8 *Pos, + UINT8 *Size + ) +{ + UINT8 First, Len; + + First = 0; + Len = 0; + + if (Mask) { + while (!(Mask & 0x1)) { + Mask = Mask >> 1; + First++; + } + + while (Mask & 0x1) { + Mask = Mask >> 1; + Len++; + } + } + *Pos = First; + *Size = Len; +} + + +STATIC +EFI_STATUS +SetupGraphicsFromGop ( + struct screen_info *Si, + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop + ) +{ + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + EFI_STATUS Status; + UINTN Size; + + Status = Gop->QueryMode(Gop, Gop->Mode->Mode, &Size, &Info); + if (EFI_ERROR (Status)) { + return Status; + } + + /* We found a GOP */ + + /* EFI framebuffer */ + Si->orig_video_isVGA = 0x70; + + Si->orig_x = 0; + Si->orig_y = 0; + Si->orig_video_page = 0; + Si->orig_video_mode = 0; + Si->orig_video_cols = 0; + Si->orig_video_lines = 0; + Si->orig_video_ega_bx = 0; + Si->orig_video_points = 0; + + Si->lfb_base = (UINT32) Gop->Mode->FrameBufferBase; + Si->lfb_size = (UINT32) Gop->Mode->FrameBufferSize; + Si->lfb_width = (UINT16) Info->HorizontalResolution; + Si->lfb_height = (UINT16) Info->VerticalResolution; + Si->pages = 1; + Si->vesapm_seg = 0; + Si->vesapm_off = 0; + + if (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) { + Si->lfb_depth = 32; + Si->red_size = 8; + Si->red_pos = 0; + Si->green_size = 8; + Si->green_pos = 8; + Si->blue_size = 8; + Si->blue_pos = 16; + Si->rsvd_size = 8; + Si->rsvd_pos = 24; + Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4); + + } else if (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { + Si->lfb_depth = 32; + Si->red_size = 8; + Si->red_pos = 16; + Si->green_size = 8; + Si->green_pos = 8; + Si->blue_size = 8; + Si->blue_pos = 0; + Si->rsvd_size = 8; + Si->rsvd_pos = 24; + Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4); + } else if (Info->PixelFormat == PixelBitMask) { + FindBits(Info->PixelInformation.RedMask, + &Si->red_pos, &Si->red_size); + FindBits(Info->PixelInformation.GreenMask, + &Si->green_pos, &Si->green_size); + FindBits(Info->PixelInformation.BlueMask, + &Si->blue_pos, &Si->blue_size); + FindBits(Info->PixelInformation.ReservedMask, + &Si->rsvd_pos, &Si->rsvd_size); + Si->lfb_depth = Si->red_size + Si->green_size + + Si->blue_size + Si->rsvd_size; + Si->lfb_linelength = (UINT16) ((Info->PixelsPerScanLine * Si->lfb_depth) / 8); + } else { + Si->lfb_depth = 4; + Si->red_size = 0; + Si->red_pos = 0; + Si->green_size = 0; + Si->green_pos = 0; + Si->blue_size = 0; + Si->blue_pos = 0; + Si->rsvd_size = 0; + Si->rsvd_pos = 0; + Si->lfb_linelength = Si->lfb_width / 2; + } + + return Status; +} + + +STATIC +EFI_STATUS +SetupGraphics ( + IN OUT struct boot_params *Bp + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + + ZeroMem ((VOID*)&Bp->screen_info, sizeof(Bp->screen_info)); + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiGraphicsOutputProtocolGuid, + (VOID*) &Gop + ); + if (EFI_ERROR (Status)) { + continue; + } + + Status = SetupGraphicsFromGop (&Bp->screen_info, Gop); + if (!EFI_ERROR (Status)) { + FreePool (HandleBuffer); + return EFI_SUCCESS; + } + } + + FreePool (HandleBuffer); + } + + return EFI_NOT_FOUND; +} + + +STATIC +EFI_STATUS +SetupLinuxBootParams ( + IN OUT struct boot_params *Bp + ) +{ + SetupGraphics (Bp); + + SetupLinuxMemmap (Bp); + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +LoadLinux ( + IN VOID *Kernel, + IN OUT VOID *KernelSetup + ) +{ + EFI_STATUS Status; + struct boot_params *Bp; + + Status = BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp = (struct boot_params *) KernelSetup; + + if (Bp->hdr.version < 0x205 || !Bp->hdr.relocatable_kernel) { + // + // We only support relocatable kernels + // + return EFI_UNSUPPORTED; + } + + InitLinuxDescriptorTables (); + + Bp->hdr.code32_start = (UINT32)(UINTN) Kernel; + if (Bp->hdr.version >= 0x20c && Bp->hdr.handover_offset && + (Bp->hdr.xloadflags & (sizeof (UINTN) == 4 ? BIT2 : BIT3))) { + DEBUG ((EFI_D_INFO, "Jumping to kernel EFI handover point at ofs %x\n", Bp->hdr.handover_offset)); + + DisableInterrupts (); + JumpToUefiKernel ((VOID*) gImageHandle, (VOID*) gST, KernelSetup, Kernel); + } + + // + // Old kernels without EFI handover protocol + // + SetupLinuxBootParams (KernelSetup); + + DEBUG ((EFI_D_INFO, "Jumping to kernel\n")); + DisableInterrupts (); + SetLinuxDescriptorTables (); + JumpToKernel (Kernel, (VOID*) KernelSetup); + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c new file mode 100644 index 0000000000..624fbc37cb --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c @@ -0,0 +1,175 @@ +/** @file + Initialize GDT for Linux. + + Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "LoadLinuxLib.h" + + +// +// Local structure definitions +// + +#pragma pack (1) + +// +// Global Descriptor Entry structures +// + +typedef struct _GDT_ENTRY { + UINT16 Limit15_0; + UINT16 Base15_0; + UINT8 Base23_16; + UINT8 Type; + UINT8 Limit19_16_and_flags; + UINT8 Base31_24; +} GDT_ENTRY; + +typedef +struct _GDT_ENTRIES { + GDT_ENTRY Null; + GDT_ENTRY Null2; + GDT_ENTRY Linear; + GDT_ENTRY LinearCode; + GDT_ENTRY TaskSegment; + GDT_ENTRY Spare4; + GDT_ENTRY Spare5; +} GDT_ENTRIES; + +#pragma pack () + +STATIC GDT_ENTRIES *mGdt = NULL; + +// +// Global descriptor table (GDT) Template +// +STATIC GDT_ENTRIES GdtTemplate = { + // + // Null + // + { + 0x0, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x0, // type + 0x0, // limit 19:16, flags + 0x0, // base 31:24 + }, + // + // Null2 + // + { + 0x0, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x0, // type + 0x0, // limit 19:16, flags + 0x0, // base 31:24 + }, + // + // Linear + // + { + 0x0FFFF, // limit 0xFFFFF + 0x0, // base 0 + 0x0, + 0x09A, // present, ring 0, data, expand-up, writable + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // LinearCode + // + { + 0x0FFFF, // limit 0xFFFFF + 0x0, // base 0 + 0x0, + 0x092, // present, ring 0, data, expand-up, writable + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // TaskSegment + // + { + 0x0, // limit 0 + 0x0, // base 0 + 0x0, + 0x089, // ? + 0x080, // ? + 0x0, + }, + // + // Spare4 + // + { + 0x0, // limit 0 + 0x0, // base 0 + 0x0, + 0x0, // present, ring 0, data, expand-up, writable + 0x0, // page-granular, 32-bit + 0x0, + }, + // + // Spare5 + // + { + 0x0, // limit 0 + 0x0, // base 0 + 0x0, + 0x0, // present, ring 0, data, expand-up, writable + 0x0, // page-granular, 32-bit + 0x0, + }, +}; + +/** + Initialize Global Descriptor Table. + +**/ +VOID +InitLinuxDescriptorTables ( + VOID + ) +{ + // + // Allocate Runtime Data for the GDT + // + mGdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8); + ASSERT (mGdt != NULL); + mGdt = ALIGN_POINTER (mGdt, 8); + + // + // Initialize all GDT entries + // + CopyMem (mGdt, &GdtTemplate, sizeof (GdtTemplate)); + +} + +/** + Initialize Global Descriptor Table. + +**/ +VOID +SetLinuxDescriptorTables ( + VOID + ) +{ + IA32_DESCRIPTOR GdtPtr; + IA32_DESCRIPTOR IdtPtr; + + // + // Write GDT register + // + GdtPtr.Base = (UINT32)(UINTN)(VOID*) mGdt; + GdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1); + AsmWriteGdtr (&GdtPtr); + + IdtPtr.Base = (UINT32) 0; + IdtPtr.Limit = (UINT16) 0; + AsmWriteIdtr (&IdtPtr); +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c new file mode 100644 index 0000000000..6ba8784cf3 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c @@ -0,0 +1,507 @@ +/** @file + File System Access for NvVarsFileLib + + Copyright (c) 2004 - 2014 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "NvVarsFileLib.h" + +#include +#include +#include + + +/** + Open the NvVars file for reading or writing + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance + @param[in] ReadingFile - TRUE: open the file for reading. FALSE: writing + @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated + with the opened NvVars file. + + @return EFI_SUCCESS if the file was opened + +**/ +EFI_STATUS +GetNvVarsFile ( + IN EFI_HANDLE FsHandle, + IN BOOLEAN ReadingFile, + OUT EFI_FILE_HANDLE *NvVarsFile + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; + EFI_FILE_HANDLE Root; + + // + // Get the FileSystem protocol on that handle + // + Status = gBS->HandleProtocol ( + FsHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID **)&Fs + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the volume (the root directory) + // + Status = Fs->OpenVolume (Fs, &Root); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Attempt to open the NvVars file in the root directory + // + Status = Root->Open ( + Root, + NvVarsFile, + L"NvVars", + ReadingFile ? + EFI_FILE_MODE_READ : + ( + EFI_FILE_MODE_CREATE | + EFI_FILE_MODE_READ | + EFI_FILE_MODE_WRITE + ), + 0 + ); + + return Status; +} + + +/** + Open the NvVars file for reading or writing + + @param[in] File - The file to inspect + @param[out] Exists - Returns whether the file exists + @param[out] Size - Returns the size of the file + (0 if the file does not exist) + +**/ +VOID +NvVarsFileReadCheckup ( + IN EFI_FILE_HANDLE File, + OUT BOOLEAN *Exists, + OUT UINTN *Size + ) +{ + EFI_FILE_INFO *FileInfo; + + *Exists = FALSE; + *Size = 0; + + FileInfo = FileHandleGetInfo (File); + if (FileInfo == NULL) { + return; + } + + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) { + FreePool (FileInfo); + return; + } + + *Exists = TRUE; + *Size = (UINTN) FileInfo->FileSize; + + FreePool (FileInfo); +} + + +/** + Open the NvVars file for reading or writing + + @param[in] File - The file to inspect + @param[out] Exists - Returns whether the file exists + @param[out] Size - Returns the size of the file + (0 if the file does not exist) + +**/ +EFI_STATUS +FileHandleEmpty ( + IN EFI_FILE_HANDLE File + ) +{ + EFI_STATUS Status; + EFI_FILE_INFO *FileInfo; + + // + // Retrieve the FileInfo structure + // + FileInfo = FileHandleGetInfo (File); + if (FileInfo == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // If the path is a directory, then return an error + // + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) { + FreePool (FileInfo); + return EFI_INVALID_PARAMETER; + } + + // + // If the file size is already 0, then it is empty, so + // we can return success. + // + if (FileInfo->FileSize == 0) { + FreePool (FileInfo); + return EFI_SUCCESS; + } + + // + // Set the file size to 0. + // + FileInfo->FileSize = 0; + Status = FileHandleSetInfo (File, FileInfo); + + FreePool (FileInfo); + + return Status; +} + + +/** + Reads a file to a newly allocated buffer + + @param[in] File - The file to read + @param[in] ReadSize - The size of data to read from the file + + @return Pointer to buffer allocated to hold the file + contents. NULL if an error occurred. + +**/ +VOID* +FileHandleReadToNewBuffer ( + IN EFI_FILE_HANDLE FileHandle, + IN UINTN ReadSize + ) +{ + EFI_STATUS Status; + UINTN ActualReadSize; + VOID *FileContents; + + ActualReadSize = ReadSize; + FileContents = AllocatePool (ReadSize); + if (FileContents != NULL) { + Status = FileHandleRead ( + FileHandle, + &ReadSize, + FileContents + ); + if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) { + FreePool (FileContents); + return NULL; + } + } + + return FileContents; +} + + +/** + Reads the contents of the NvVars file on the file system + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance + + @return EFI_STATUS based on the success or failure of the file read + +**/ +EFI_STATUS +ReadNvVarsFile ( + IN EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + EFI_FILE_HANDLE File; + UINTN FileSize; + BOOLEAN FileExists; + VOID *FileContents; + EFI_HANDLE SerializedVariables; + + Status = GetNvVarsFile (FsHandle, TRUE, &File); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this file system\n")); + return Status; + } + + NvVarsFileReadCheckup (File, &FileExists, &FileSize); + if (FileSize == 0) { + FileHandleClose (File); + return EFI_UNSUPPORTED; + } + + FileContents = FileHandleReadToNewBuffer (File, FileSize); + if (FileContents == NULL) { + FileHandleClose (File); + return EFI_UNSUPPORTED; + } + + DEBUG (( + EFI_D_INFO, + "FsAccess.c: Read %Lu bytes from NV Variables file\n", + (UINT64)FileSize + )); + + Status = SerializeVariablesNewInstanceFromBuffer ( + &SerializedVariables, + FileContents, + FileSize + ); + if (!RETURN_ERROR (Status)) { + Status = SerializeVariablesSetSerializedVariables (SerializedVariables); + } + + FreePool (FileContents); + FileHandleClose (File); + + return Status; +} + + +/** + Writes a variable to indicate that the NV variables + have been loaded from the file system. + +**/ +STATIC +VOID +SetNvVarsVariable ( + VOID + ) +{ + BOOLEAN VarData; + UINTN Size; + + // + // Write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading on + // subsequent attempts. + // + Size = sizeof (VarData); + VarData = TRUE; + gRT->SetVariable ( + L"NvVars", + &gEfiSimpleFileSystemProtocolGuid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + Size, + (VOID*) &VarData + ); +} + + +/** + Loads the non-volatile variables from the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +LoadNvVarsFromFs ( + EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + BOOLEAN VarData; + UINTN Size; + + DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n")); + + // + // We write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading. + // + // This is relevant if the non-volatile variable have been + // able to survive a reboot operation. In that case, we don't + // want to re-load the file as it would overwrite newer changes + // made to the variables. + // + Size = sizeof (VarData); + VarData = TRUE; + Status = gRT->GetVariable ( + L"NvVars", + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &Size, + (VOID*) &VarData + ); + if (Status == EFI_SUCCESS) { + DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n")); + return EFI_ALREADY_STARTED; + } + + // + // Attempt to restore the variables from the NvVars file. + // + Status = ReadNvVarsFile (FsHandle); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n")); + return Status; + } + + // + // Write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading on + // subsequent attempts. + // + SetNvVarsVariable(); + + DEBUG (( + EFI_D_INFO, + "FsAccess.c: Read NV Variables file (size=%Lu)\n", + (UINT64)Size + )); + + return Status; +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackAddAllNvVariables ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_HANDLE Instance; + + Instance = (EFI_HANDLE) Context; + + // + // Only save non-volatile variables + // + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { + return RETURN_SUCCESS; + } + + return SerializeVariablesAddVariable ( + Instance, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); +} + + +/** + Saves the non-volatile variables into the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +SaveNvVarsToFs ( + EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + EFI_FILE_HANDLE File; + UINTN WriteSize; + UINTN VariableDataSize; + VOID *VariableData; + EFI_HANDLE SerializedVariables; + + SerializedVariables = NULL; + + Status = SerializeVariablesNewInstance (&SerializedVariables); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = SerializeVariablesIterateSystemVariables ( + IterateVariablesCallbackAddAllNvVariables, + (VOID*) SerializedVariables + ); + if (EFI_ERROR (Status)) { + return Status; + } + + VariableData = NULL; + VariableDataSize = 0; + Status = SerializeVariablesToBuffer ( + SerializedVariables, + NULL, + &VariableDataSize + ); + if (Status == RETURN_BUFFER_TOO_SMALL) { + VariableData = AllocatePool (VariableDataSize); + if (VariableData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + Status = SerializeVariablesToBuffer ( + SerializedVariables, + VariableData, + &VariableDataSize + ); + } + } + + SerializeVariablesFreeInstance (SerializedVariables); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Open the NvVars file for writing. + // + Status = GetNvVarsFile (FsHandle, FALSE, &File); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n")); + return Status; + } + + // + // Empty the starting file contents. + // + Status = FileHandleEmpty (File); + if (EFI_ERROR (Status)) { + FileHandleClose (File); + return Status; + } + + WriteSize = VariableDataSize; + Status = FileHandleWrite (File, &WriteSize, VariableData); + if (EFI_ERROR (Status)) { + return Status; + } + + FileHandleClose (File); + + if (!EFI_ERROR (Status)) { + // + // Write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading on + // subsequent attempts. + // + SetNvVarsVariable(); + + DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n")); + } + + return Status; +} + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c new file mode 100644 index 0000000000..f60fbc6112 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c @@ -0,0 +1,77 @@ +/** @file + Save Non-Volatile Variables to a file system. + + Copyright (c) 2009 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "NvVarsFileLib.h" +#include +#include + +EFI_HANDLE mNvVarsFileLibFsHandle = NULL; + + +/** + Attempts to connect the NvVarsFileLib to the specified file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance + + @return The EFI_STATUS while attempting to connect the NvVarsFileLib + to the file system instance. + @retval EFI_SUCCESS - The given file system was connected successfully + +**/ +EFI_STATUS +EFIAPI +ConnectNvVarsToFileSystem ( + IN EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + + // + // We might fail to load the variable, since the file system initially + // will not have the NvVars file. + // + LoadNvVarsFromFs (FsHandle); + + // + // We must be able to save the variables successfully to the file system + // to have connected successfully. + // + Status = SaveNvVarsToFs (FsHandle); + if (!EFI_ERROR (Status)) { + mNvVarsFileLibFsHandle = FsHandle; + } + + return Status; +} + + +/** + Update non-volatile variables stored on the file system. + + @return The EFI_STATUS while attempting to update the variable on + the connected file system. + @retval EFI_SUCCESS - The non-volatile variables were saved to the disk + @retval EFI_NOT_STARTED - A file system has not been connected + +**/ +EFI_STATUS +EFIAPI +UpdateNvVarsOnFileSystem ( + ) +{ + if (mNvVarsFileLibFsHandle == NULL) { + // + // A file system had not been connected to the library. + // + return EFI_NOT_STARTED; + } else { + return SaveNvVarsToFs (mNvVarsFileLibFsHandle); + } +} + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c new file mode 100644 index 0000000000..c32a978550 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c @@ -0,0 +1,869 @@ +/** @file + Serialize Variables Library implementation + + Copyright (c) 2004 - 2011 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SerializeVariablesLib.h" + +/** + Serialization format: + + The SerializeVariablesLib interface does not specify a format + for the serialization of the variable data. This library uses + a packed array of a non-uniformly sized data structure elements. + + Each variable is stored (packed) as: + UINT32 VendorNameSize; // Name size in bytes + CHAR16 VendorName[?]; // The variable unicode name including the + // null terminating character. + EFI_GUID VendorGuid; // The variable GUID + UINT32 DataSize; // The size of variable data in bytes + UINT8 Data[?]; // The variable data + +**/ + + +/** + Unpacks the next variable from the buffer + + @param[in] Buffer - Buffer pointing to the next variable instance + On subsequent calls, the pointer should be incremented + by the returned SizeUsed value. + @param[in] MaxSize - Max allowable size for the variable data + On subsequent calls, this should be decremented + by the returned SizeUsed value. + @param[out] Name - Variable name string (address in Buffer) + @param[out] NameSize - Size of Name in bytes + @param[out] Guid - GUID of variable (address in Buffer) + @param[out] Attributes - Attributes of variable + @param[out] Data - Buffer containing Data for variable (address in Buffer) + @param[out] DataSize - Size of Data in bytes + @param[out] SizeUsed - Total size used for this variable instance in Buffer + + @return EFI_STATUS based on the success or failure of the operation + +**/ +STATIC +EFI_STATUS +UnpackVariableFromBuffer ( + IN VOID *Buffer, + IN UINTN MaxSize, + OUT CHAR16 **Name, + OUT UINT32 *NameSize, + OUT EFI_GUID **Guid, + OUT UINT32 *Attributes, + OUT UINT32 *DataSize, + OUT VOID **Data, + OUT UINTN *SizeUsed + ) +{ + UINT8 *BytePtr; + UINTN Offset; + + BytePtr = (UINT8*)Buffer; + Offset = 0; + + *NameSize = *(UINT32*) (BytePtr + Offset); + Offset = Offset + sizeof (UINT32); + + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Name = (CHAR16*) (BytePtr + Offset); + Offset = Offset + *(UINT32*)BytePtr; + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Guid = (EFI_GUID*) (BytePtr + Offset); + Offset = Offset + sizeof (EFI_GUID); + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Attributes = *(UINT32*) (BytePtr + Offset); + Offset = Offset + sizeof (UINT32); + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *DataSize = *(UINT32*) (BytePtr + Offset); + Offset = Offset + sizeof (UINT32); + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Data = (VOID*) (BytePtr + Offset); + Offset = Offset + *DataSize; + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *SizeUsed = Offset; + + return EFI_SUCCESS; +} + + +/** + Iterates through the variables in the buffer, and calls a callback + function for each variable found. + + @param[in] CallbackFunction - Function called for each variable instance + @param[in] Context - Passed to each call of CallbackFunction + @param[in] Buffer - Buffer containing serialized variables + @param[in] MaxSize - Size of Buffer in bytes + + @return EFI_STATUS based on the success or failure of the operation + +**/ +STATIC +EFI_STATUS +IterateVariablesInBuffer ( + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *CallbackContext, + IN VOID *Buffer, + IN UINTN MaxSize + ) +{ + RETURN_STATUS Status; + UINTN TotalSizeUsed; + UINTN SizeUsed; + + CHAR16 *Name; + UINT32 NameSize; + CHAR16 *AlignedName; + UINT32 AlignedNameMaxSize; + EFI_GUID *Guid; + UINT32 Attributes; + UINT32 DataSize; + VOID *Data; + + SizeUsed = 0; + AlignedName = NULL; + AlignedNameMaxSize = 0; + Name = NULL; + Guid = NULL; + Attributes = 0; + DataSize = 0; + Data = NULL; + + for ( + Status = EFI_SUCCESS, TotalSizeUsed = 0; + !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize); + ) { + Status = UnpackVariableFromBuffer ( + (VOID*) ((UINT8*) Buffer + TotalSizeUsed), + (MaxSize - TotalSizeUsed), + &Name, + &NameSize, + &Guid, + &Attributes, + &DataSize, + &Data, + &SizeUsed + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // We copy the name to a separately allocated buffer, + // to be sure it is 16-bit aligned. + // + if (NameSize > AlignedNameMaxSize) { + if (AlignedName != NULL) { + FreePool (AlignedName); + } + AlignedName = AllocatePool (NameSize); + } + if (AlignedName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (AlignedName, Name, NameSize); + + TotalSizeUsed = TotalSizeUsed + SizeUsed; + + // + // Run the callback function + // + Status = (*CallbackFunction) ( + CallbackContext, + AlignedName, + Guid, + Attributes, + DataSize, + Data + ); + + } + + if (AlignedName != NULL) { + FreePool (AlignedName); + } + + // + // Make sure the entire buffer was used, or else return an error + // + if (TotalSizeUsed != MaxSize) { + DEBUG (( + EFI_D_ERROR, + "Deserialize variables error: TotalSizeUsed(%Lu) != MaxSize(%Lu)\n", + (UINT64)TotalSizeUsed, + (UINT64)MaxSize + )); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackNop ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + return RETURN_SUCCESS; +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackSetInInstance ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_HANDLE Instance; + + Instance = (EFI_HANDLE) Context; + + return SerializeVariablesAddVariable ( + Instance, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackSetSystemVariable ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_STATUS Status; + STATIC CONST UINT32 AuthMask = + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + + Status = gRT->SetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); + + if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) { + DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" " + "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__, + VariableName)); + Status = EFI_SUCCESS; + } else if (Status == EFI_WRITE_PROTECTED) { + DEBUG ((DEBUG_WARN, "%a: setting ReadOnly variable \"%s\" " + "failed with EFI_WRITE_PROTECTED, ignoring\n", __FUNCTION__, + VariableName)); + Status = EFI_SUCCESS; + } + return Status; +} + + +STATIC +RETURN_STATUS +EnsureExtraBufferSpace ( + IN SV_INSTANCE *Instance, + IN UINTN Size + ) +{ + VOID *NewBuffer; + UINTN NewSize; + + NewSize = Instance->DataSize + Size; + if (NewSize <= Instance->BufferSize) { + return RETURN_SUCCESS; + } + + // + // Double the required size to lessen the need to re-allocate in the future + // + NewSize = 2 * NewSize; + + NewBuffer = AllocatePool (NewSize); + if (NewBuffer == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + if (Instance->BufferPtr != NULL) { + CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize); + FreePool (Instance->BufferPtr); + } + + Instance->BufferPtr = NewBuffer; + Instance->BufferSize = NewSize; + + return RETURN_SUCCESS; +} + + +STATIC +VOID +AppendToBuffer ( + IN SV_INSTANCE *Instance, + IN VOID *Data, + IN UINTN Size + ) +{ + UINTN NewSize; + + ASSERT (Instance != NULL); + ASSERT (Data != NULL); + + NewSize = Instance->DataSize + Size; + ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize); + + CopyMem ( + (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize), + Data, + Size + ); + + Instance->DataSize = NewSize; +} + + +/** + Creates a new variable serialization instance + + @param[out] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - The variable serialization instance was + successfully created. + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + create the variable serialization instance. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesNewInstance ( + OUT EFI_HANDLE *Handle + ) +{ + SV_INSTANCE *New; + + New = AllocateZeroPool (sizeof (*New)); + if (New == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + New->Signature = SV_SIGNATURE; + + *Handle = (EFI_HANDLE) New; + return RETURN_SUCCESS; +} + + +/** + Free memory associated with a variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - The variable serialization instance was + successfully freed. + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesFreeInstance ( + IN EFI_HANDLE Handle + ) +{ + SV_INSTANCE *Instance; + + Instance = SV_FROM_HANDLE (Handle); + + if (Instance->Signature != SV_SIGNATURE) { + return RETURN_INVALID_PARAMETER; + } + + Instance->Signature = 0; + + if (Instance->BufferPtr != NULL) { + FreePool (Instance->BufferPtr); + } + + FreePool (Instance); + + return RETURN_SUCCESS; +} + + +/** + Creates a new variable serialization instance using the given + binary representation of the variables to fill the new instance + + @param[out] Handle - Handle for a variable serialization instance + @param[in] Buffer - A buffer with the serialized representation + of the variables. Must be the same format as produced + by SerializeVariablesToBuffer. + @param[in] Size - This is the size of the binary representation + of the variables. + + @retval RETURN_SUCCESS - The binary representation was successfully + imported into a new variable serialization instance + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + create the new variable serialization instance + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesNewInstanceFromBuffer ( + OUT EFI_HANDLE *Handle, + IN VOID *Buffer, + IN UINTN Size + ) +{ + RETURN_STATUS Status; + + Status = SerializeVariablesNewInstance (Handle); + if (RETURN_ERROR (Status)) { + return Status; + } + + Status = IterateVariablesInBuffer ( + IterateVariablesCallbackNop, + NULL, + Buffer, + Size + ); + if (RETURN_ERROR (Status)) { + SerializeVariablesFreeInstance (*Handle); + return Status; + } + + Status = IterateVariablesInBuffer ( + IterateVariablesCallbackSetInInstance, + (VOID*) *Handle, + Buffer, + Size + ); + if (RETURN_ERROR (Status)) { + SerializeVariablesFreeInstance (*Handle); + return Status; + } + + return Status; +} + + +/** + Iterates all variables found with RuntimeServices GetNextVariableName + + @param[in] CallbackFunction - Function called for each variable instance + @param[in] Context - Passed to each call of CallbackFunction + + @retval RETURN_SUCCESS - All variables were iterated without the + CallbackFunction returning an error + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + iterate through the variables + @return Any of RETURN_ERROR indicates an error reading the variable + or an error was returned from CallbackFunction + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesIterateSystemVariables ( + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *Context + ) +{ + RETURN_STATUS Status; + UINTN VariableNameBufferSize; + UINTN VariableNameSize; + CHAR16 *VariableName; + EFI_GUID VendorGuid; + UINTN VariableDataBufferSize; + UINTN VariableDataSize; + VOID *VariableData; + UINT32 VariableAttributes; + VOID *NewBuffer; + + // + // Initialize the variable name and data buffer variables. + // + VariableNameBufferSize = sizeof (CHAR16); + VariableName = AllocateZeroPool (VariableNameBufferSize); + + VariableDataBufferSize = 0; + VariableData = NULL; + + for (;;) { + // + // Get the next variable name and guid + // + VariableNameSize = VariableNameBufferSize; + Status = gRT->GetNextVariableName ( + &VariableNameSize, + VariableName, + &VendorGuid + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // The currently allocated VariableName buffer is too small, + // so we allocate a larger buffer, and copy the old buffer + // to it. + // + NewBuffer = AllocatePool (VariableNameSize); + if (NewBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + break; + } + CopyMem (NewBuffer, VariableName, VariableNameBufferSize); + if (VariableName != NULL) { + FreePool (VariableName); + } + VariableName = NewBuffer; + VariableNameBufferSize = VariableNameSize; + + // + // Try to get the next variable name again with the larger buffer. + // + Status = gRT->GetNextVariableName ( + &VariableNameSize, + VariableName, + &VendorGuid + ); + } + + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + Status = EFI_SUCCESS; + } + break; + } + + // + // Get the variable data and attributes + // + VariableDataSize = VariableDataBufferSize; + Status = gRT->GetVariable ( + VariableName, + &VendorGuid, + &VariableAttributes, + &VariableDataSize, + VariableData + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // The currently allocated VariableData buffer is too small, + // so we allocate a larger buffer. + // + if (VariableDataBufferSize != 0) { + FreePool (VariableData); + VariableData = NULL; + VariableDataBufferSize = 0; + } + VariableData = AllocatePool (VariableDataSize); + if (VariableData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + break; + } + VariableDataBufferSize = VariableDataSize; + + // + // Try to read the variable again with the larger buffer. + // + Status = gRT->GetVariable ( + VariableName, + &VendorGuid, + &VariableAttributes, + &VariableDataSize, + VariableData + ); + } + if (EFI_ERROR (Status)) { + break; + } + + // + // Run the callback function + // + Status = (*CallbackFunction) ( + Context, + VariableName, + &VendorGuid, + VariableAttributes, + VariableDataSize, + VariableData + ); + if (EFI_ERROR (Status)) { + break; + } + + } + + if (VariableName != NULL) { + FreePool (VariableName); + } + + if (VariableData != NULL) { + FreePool (VariableData); + } + + return Status; +} + + +/** + Iterates all variables found in the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + @param[in] CallbackFunction - Function called for each variable instance + @param[in] Context - Passed to each call of CallbackFunction + + @retval RETURN_SUCCESS - All variables were iterated without the + CallbackFunction returning an error + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + iterate through the variables + @return Any of RETURN_ERROR indicates an error reading the variable + or an error was returned from CallbackFunction + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesIterateInstanceVariables ( + IN EFI_HANDLE Handle, + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *Context + ) +{ + SV_INSTANCE *Instance; + + Instance = SV_FROM_HANDLE (Handle); + + if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) { + return IterateVariablesInBuffer ( + CallbackFunction, + Context, + Instance->BufferPtr, + Instance->DataSize + ); + } else { + return RETURN_SUCCESS; + } +} + + +/** + Sets all variables found in the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - All variables were set successfully + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + set all the variables + @return Any of RETURN_ERROR indicates an error reading the variables + or in attempting to set a variable + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesSetSerializedVariables ( + IN EFI_HANDLE Handle + ) +{ + return SerializeVariablesIterateInstanceVariables ( + Handle, + IterateVariablesCallbackSetSystemVariable, + NULL + ); +} + + +/** + Adds a variable to the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + @param[in] VariableName - Refer to RuntimeServices GetVariable + @param[in] VendorGuid - Refer to RuntimeServices GetVariable + @param[in] Attributes - Refer to RuntimeServices GetVariable + @param[in] DataSize - Refer to RuntimeServices GetVariable + @param[in] Data - Refer to RuntimeServices GetVariable + + @retval RETURN_SUCCESS - All variables were set successfully + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + add the variable + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance or + VariableName, VariableGuid or Data are NULL. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesAddVariable ( + IN EFI_HANDLE Handle, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + RETURN_STATUS Status; + SV_INSTANCE *Instance; + UINT32 SerializedNameSize; + UINT32 SerializedDataSize; + UINTN SerializedSize; + + Instance = SV_FROM_HANDLE (Handle); + + if ((Instance->Signature != SV_SIGNATURE) || + (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) { + } + + SerializedNameSize = (UINT32) StrSize (VariableName); + + SerializedSize = + sizeof (SerializedNameSize) + + SerializedNameSize + + sizeof (*VendorGuid) + + sizeof (Attributes) + + sizeof (SerializedDataSize) + + DataSize; + + Status = EnsureExtraBufferSpace ( + Instance, + SerializedSize + ); + if (RETURN_ERROR (Status)) { + return Status; + } + + // + // Add name size (UINT32) + // + AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof (SerializedNameSize)); + + // + // Add variable unicode name string + // + AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize); + + // + // Add variable GUID + // + AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid)); + + // + // Add variable attributes + // + AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes)); + + // + // Add variable data size (UINT32) + // + SerializedDataSize = (UINT32) DataSize; + AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof (SerializedDataSize)); + + // + // Add variable data + // + AppendToBuffer (Instance, Data, DataSize); + + return RETURN_SUCCESS; +} + + +/** + Serializes the variables known to this instance into the + provided buffer. + + @param[in] Handle - Handle for a variable serialization instance + @param[out] Buffer - A buffer to store the binary representation + of the variables. + @param[in,out] Size - On input this is the size of the buffer. + On output this is the size of the binary representation + of the variables. + + @retval RETURN_SUCCESS - The binary representation was successfully + completed and returned in the buffer. + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + save the variables to the buffer. + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance or + Size or Buffer were NULL. + @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by + the Size parameter was too small for the serialized + variable data. Size is returned with the required size. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesToBuffer ( + IN EFI_HANDLE Handle, + OUT VOID *Buffer, + IN OUT UINTN *Size + ) +{ + SV_INSTANCE *Instance; + + Instance = SV_FROM_HANDLE (Handle); + + if (Size == NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (*Size < Instance->DataSize) { + *Size = Instance->DataSize; + return RETURN_BUFFER_TOO_SMALL; + } + + if (Buffer == NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Size = Instance->DataSize; + CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize); + + return RETURN_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c new file mode 100644 index 0000000000..7bede1496d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c @@ -0,0 +1,865 @@ +/** @file + This driver effectuates OVMF's platform configuration settings and exposes + them via HII. + + Copyright (C) 2014, Red Hat, Inc. + Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "PlatformConfig.h" +#include +// +// The HiiAddPackages() library function requires that any controller (or +// image) handle, to be associated with the HII packages under installation, be +// "decorated" with a device path. The tradition seems to be a vendor device +// path. +// +// We'd like to associate our HII packages with the driver's image handle. The +// first idea is to use the driver image's device path. Unfortunately, loaded +// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL (not the +// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even the +// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if the image +// has been loaded from an "unnamed" memory source buffer. +// +// Hence let's just stick with the tradition -- use a dedicated vendor device +// path, with the driver's FILE_GUID. +// +#pragma pack(1) +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} PKG_DEVICE_PATH; +#pragma pack() + +STATIC PKG_DEVICE_PATH mPkgDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH) ), + (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8) + } + }, + EFI_CALLER_ID_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH ), + (UINT8) (END_DEVICE_PATH_LENGTH >> 8) + } + } +}; + +// +// The configuration interface between the HII engine (form display etc) and +// this driver. +// +STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess; + +// +// The handle representing our list of packages after installation. +// +STATIC EFI_HII_HANDLE mInstalledPackages; + +// +// The arrays below constitute our HII package list. They are auto-generated by +// the VFR compiler and linked into the driver image during the build. +// +// - The strings package receives its C identifier from the driver's BASE_NAME, +// plus "Strings". +// +// - The forms package receives its C identifier from the VFR file's basename, +// plus "Bin". +// +// +extern UINT8 PlatformDxeStrings[]; +extern UINT8 PlatformFormsBin[]; + +// +// We want to be notified about GOP installations until we find one GOP +// interface that lets us populate the form. +// +STATIC EFI_EVENT mGopEvent; + +// +// The registration record underneath this pointer allows us to iterate through +// the GOP instances one by one. +// +STATIC VOID *mGopTracker; + +// +// Cache the resolutions we get from the GOP. +// +typedef struct { + UINT32 X; + UINT32 Y; +} GOP_MODE; + +STATIC UINTN mNumGopModes; +STATIC GOP_MODE *mGopModes; + + +/** + Load the persistent platform configuration and translate it to binary form + state. + + If the platform configuration is missing, then the function fills in a + default state. + + @param[out] MainFormState Binary form/widget state after translation. + + @retval EFI_SUCCESS Form/widget state ready. + @return Error codes from underlying functions. +**/ +STATIC +EFI_STATUS +EFIAPI +PlatformConfigToFormState ( + OUT MAIN_FORM_STATE *MainFormState + ) +{ + EFI_STATUS Status; + PLATFORM_CONFIG PlatformConfig; + UINT64 OptionalElements; + UINTN ModeNumber; + + ZeroMem (MainFormState, sizeof *MainFormState); + + Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements); + switch (Status) { + case EFI_SUCCESS: + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) { + // + // Format the preferred resolution as text. + // + UnicodeSPrintAsciiFormat ( + (CHAR16 *) MainFormState->CurrentPreferredResolution, + sizeof MainFormState->CurrentPreferredResolution, + "%Ldx%Ld", + (INT64) PlatformConfig.HorizontalResolution, + (INT64) PlatformConfig.VerticalResolution); + + // + // Try to locate it in the drop-down list too. This may not succeed, but + // that's fine. + // + for (ModeNumber = 0; ModeNumber < mNumGopModes; ++ModeNumber) { + if (mGopModes[ModeNumber].X == PlatformConfig.HorizontalResolution && + mGopModes[ModeNumber].Y == PlatformConfig.VerticalResolution) { + MainFormState->NextPreferredResolution = (UINT32) ModeNumber; + break; + } + } + + break; + } + // + // fall through otherwise + // + + case EFI_NOT_FOUND: + UnicodeSPrintAsciiFormat ( + (CHAR16 *) MainFormState->CurrentPreferredResolution, + sizeof MainFormState->CurrentPreferredResolution, + "Unset"); + break; + + default: + return Status; + } + + return EFI_SUCCESS; +} + + +/** + This function is called by the HII machinery when it fetches the form state. + + See the precise documentation in the UEFI spec. + + @param[in] This The Config Access Protocol instance. + + @param[in] Request A format UCS-2 string describing the + query. + + @param[out] Progress A pointer into Request on output, identifying the query + element where processing failed. + + @param[out] Results A format UCS-2 string that has + all values filled in for the names in the Request + string. + + @retval EFI_SUCCESS Extraction of form state in + encoding successful. + @return Status codes from underlying functions. + +**/ +STATIC +EFI_STATUS +EFIAPI +ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results +) +{ + MAIN_FORM_STATE MainFormState; + EFI_STATUS Status; + + DEBUG ((EFI_D_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request)); + + Status = PlatformConfigToFormState (&MainFormState); + if (EFI_ERROR (Status)) { + *Progress = Request; + return Status; + } + + // + // Answer the textual request keying off the binary form state. + // + Status = gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request, + (VOID *) &MainFormState, sizeof MainFormState, + Results, Progress); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n", + __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL : *Progress)); + } else { + DEBUG ((EFI_D_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results)); + } + return Status; +} + + +/** + Interpret the binary form state and save it as persistent platform + configuration. + + @param[in] MainFormState Binary form/widget state to verify and save. + + @retval EFI_SUCCESS Platform configuration saved. + @return Error codes from underlying functions. +**/ +STATIC +EFI_STATUS +EFIAPI +FormStateToPlatformConfig ( + IN CONST MAIN_FORM_STATE *MainFormState + ) +{ + EFI_STATUS Status; + PLATFORM_CONFIG PlatformConfig; + CONST GOP_MODE *GopMode; + + // + // There's nothing to do with the textual CurrentPreferredResolution field. + // We verify and translate the selection in the drop-down list. + // + if (MainFormState->NextPreferredResolution >= mNumGopModes) { + return EFI_INVALID_PARAMETER; + } + GopMode = mGopModes + MainFormState->NextPreferredResolution; + + ZeroMem (&PlatformConfig, sizeof PlatformConfig); + PlatformConfig.HorizontalResolution = GopMode->X; + PlatformConfig.VerticalResolution = GopMode->Y; + + Status = PlatformConfigSave (&PlatformConfig); + return Status; +} + + +/** + This function is called by the HII machinery when it wants the driver to + interpret and persist the form state. + + See the precise documentation in the UEFI spec. + + @param[in] This The Config Access Protocol instance. + + @param[in] Configuration A format UCS-2 string describing the + form state. + + @param[out] Progress A pointer into Configuration on output, + identifying the element where processing failed. + + @retval EFI_SUCCESS Configuration verified, state permanent. + + @return Status codes from underlying functions. +**/ +STATIC +EFI_STATUS +EFIAPI +RouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress +) +{ + MAIN_FORM_STATE MainFormState; + UINTN BlockSize; + EFI_STATUS Status; + + DEBUG ((EFI_D_VERBOSE, "%a: Configuration=\"%s\"\n", __FUNCTION__, + Configuration)); + + // + // the "read" step in RMW + // + Status = PlatformConfigToFormState (&MainFormState); + if (EFI_ERROR (Status)) { + *Progress = Configuration; + return Status; + } + + // + // the "modify" step in RMW + // + // (Update the binary form state. This update may be partial, which is why in + // general we must pre-load the form state from the platform config.) + // + BlockSize = sizeof MainFormState; + Status = gHiiConfigRouting->ConfigToBlock (gHiiConfigRouting, Configuration, + (VOID *) &MainFormState, &BlockSize, Progress); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=\"%s\"\n", + __FUNCTION__, Status, + (Status == EFI_BUFFER_TOO_SMALL) ? NULL : *Progress)); + return Status; + } + + // + // the "write" step in RMW + // + Status = FormStateToPlatformConfig (&MainFormState); + if (EFI_ERROR (Status)) { + *Progress = Configuration; + } + return Status; +} + + +STATIC +EFI_STATUS +EFIAPI +Callback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN OUT EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + DEBUG ((EFI_D_VERBOSE, "%a: Action=0x%Lx QuestionId=%d Type=%d\n", + __FUNCTION__, (UINT64) Action, QuestionId, Type)); + + if (Action != EFI_BROWSER_ACTION_CHANGED) { + return EFI_UNSUPPORTED; + } + + switch (QuestionId) { + case QUESTION_SAVE_EXIT: + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; + break; + + case QUESTION_DISCARD_EXIT: + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; + break; + + default: + break; + } + + return EFI_SUCCESS; +} + + +/** + Query and save all resolutions supported by the GOP. + + @param[in] Gop The Graphics Output Protocol instance to query. + + @param[out] NumGopModes The number of modes supported by the GOP. On output, + this parameter will be positive. + + @param[out] GopModes On output, a dynamically allocated array containing + the resolutions returned by the GOP. The caller is + responsible for freeing the array after use. + + @retval EFI_UNSUPPORTED No modes found. + @retval EFI_OUT_OF_RESOURCES Failed to allocate GopModes. + @return Error codes from Gop->QueryMode(). + +**/ +STATIC +EFI_STATUS +EFIAPI +QueryGopModes ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop, + OUT UINTN *NumGopModes, + OUT GOP_MODE **GopModes + ) +{ + EFI_STATUS Status; + UINT32 ModeNumber; + + if (Gop->Mode->MaxMode == 0) { + return EFI_UNSUPPORTED; + } + *NumGopModes = Gop->Mode->MaxMode; + + *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes); + if (*GopModes == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode; ++ModeNumber) { + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + + Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info); + if (EFI_ERROR (Status)) { + goto FreeGopModes; + } + + (*GopModes)[ModeNumber].X = Info->HorizontalResolution; + (*GopModes)[ModeNumber].Y = Info->VerticalResolution; + FreePool (Info); + } + + return EFI_SUCCESS; + +FreeGopModes: + FreePool (*GopModes); + + return Status; +} + + +/** + Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes, + based on available GOP resolutions, to be placed under a "one-of-many" (ie. + "drop down list") opcode. + + @param[in] PackageList The package list with the formset and form for + which the drop down options are produced. Option + names are added as new strings to PackageList. + + @param[out] OpCodeBuffer On output, a dynamically allocated opcode buffer + with drop down list options corresponding to GOP + resolutions. The caller is responsible for freeing + OpCodeBuffer with HiiFreeOpCodeHandle() after use. + + @param[in] NumGopModes Number of entries in GopModes. + + @param[in] GopModes Array of resolutions retrieved from the GOP. + + @retval EFI_SUCESS Opcodes have been successfully produced. + + @return Status codes from underlying functions. PackageList may + have been extended with new strings. OpCodeBuffer is + unchanged. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateResolutionOptions ( + IN EFI_HII_HANDLE *PackageList, + OUT VOID **OpCodeBuffer, + IN UINTN NumGopModes, + IN GOP_MODE *GopModes + ) +{ + EFI_STATUS Status; + VOID *OutputBuffer; + UINTN ModeNumber; + + OutputBuffer = HiiAllocateOpCodeHandle (); + if (OutputBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) { + CHAR16 Desc[MAXSIZE_RES_CUR]; + EFI_STRING_ID NewString; + VOID *OpCode; + + UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld", + (INT64) GopModes[ModeNumber].X, (INT64) GopModes[ModeNumber].Y); + NewString = HiiSetString (PackageList, 0 /* new string */, Desc, + NULL /* for all languages */); + if (NewString == 0) { + Status = EFI_OUT_OF_RESOURCES; + goto FreeOutputBuffer; + } + OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString, + 0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber); + if (OpCode == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto FreeOutputBuffer; + } + } + + *OpCodeBuffer = OutputBuffer; + return EFI_SUCCESS; + +FreeOutputBuffer: + HiiFreeOpCodeHandle (OutputBuffer); + + return Status; +} + + +/** + Populate the form identified by the (PackageList, FormSetGuid, FormId) + triplet. + + The drop down list of video resolutions is generated from (NumGopModes, + GopModes). + + @retval EFI_SUCESS Form successfully updated. + @return Status codes from underlying functions. + +**/ +STATIC +EFI_STATUS +EFIAPI +PopulateForm ( + IN EFI_HII_HANDLE *PackageList, + IN EFI_GUID *FormSetGuid, + IN EFI_FORM_ID FormId, + IN UINTN NumGopModes, + IN GOP_MODE *GopModes + ) +{ + EFI_STATUS Status; + VOID *OpCodeBuffer; + VOID *OpCode; + EFI_IFR_GUID_LABEL *Anchor; + VOID *OpCodeBuffer2; + + OpCodeBuffer2 = NULL; + + // + // 1. Allocate an empty opcode buffer. + // + OpCodeBuffer = HiiAllocateOpCodeHandle (); + if (OpCodeBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // 2. Create a label opcode (which is a Tiano extension) inside the buffer. + // The label's number must match the "anchor" label in the form. + // + OpCode = HiiCreateGuidOpCode (OpCodeBuffer, &gEfiIfrTianoGuid, + NULL /* optional copy origin */, sizeof *Anchor); + if (OpCode == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto FreeOpCodeBuffer; + } + Anchor = OpCode; + Anchor->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + Anchor->Number = LABEL_RES_NEXT; + + // + // 3. Create the opcodes inside the buffer that are to be inserted into the + // form. + // + // 3.1. Get a list of resolutions. + // + Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2, + NumGopModes, GopModes); + if (EFI_ERROR (Status)) { + goto FreeOpCodeBuffer; + } + + // + // 3.2. Create a one-of-many question with the above options. + // + OpCode = HiiCreateOneOfOpCode ( + OpCodeBuffer, // create opcode inside this + // opcode buffer, + QUESTION_RES_NEXT, // ID of question, + FORMSTATEID_MAIN_FORM, // identifies form state + // storage, + (UINT16) OFFSET_OF (MAIN_FORM_STATE, // value of question stored + NextPreferredResolution), // at this offset, + STRING_TOKEN (STR_RES_NEXT), // Prompt, + STRING_TOKEN (STR_RES_NEXT_HELP), // Help, + 0, // QuestionFlags, + EFI_IFR_NUMERIC_SIZE_4, // see sizeof + // NextPreferredResolution, + OpCodeBuffer2, // buffer with possible + // choices, + NULL // DEFAULT opcodes + ); + if (OpCode == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto FreeOpCodeBuffer2; + } + + // + // 4. Update the form with the opcode buffer. + // + Status = HiiUpdateForm (PackageList, FormSetGuid, FormId, + OpCodeBuffer, // buffer with head anchor, and new contents to be + // inserted at it + NULL // buffer with tail anchor, for deleting old + // contents up to it + ); + +FreeOpCodeBuffer2: + HiiFreeOpCodeHandle (OpCodeBuffer2); + +FreeOpCodeBuffer: + HiiFreeOpCodeHandle (OpCodeBuffer); + + return Status; +} + + +/** + Load and execute the platform configuration. + + @retval EFI_SUCCESS Configuration loaded and executed. + @return Status codes from PlatformConfigLoad(). +**/ +STATIC +EFI_STATUS +EFIAPI +ExecutePlatformConfig ( + VOID + ) +{ + EFI_STATUS Status; + PLATFORM_CONFIG PlatformConfig; + UINT64 OptionalElements; + + Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements); + if (EFI_ERROR (Status)) { + DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR, + "%a: failed to load platform config: %r\n", __FUNCTION__, Status)); + return Status; + } + + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) { + // + // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs. + // + PcdSet32 (PcdVideoHorizontalResolution, + PlatformConfig.HorizontalResolution); + PcdSet32 (PcdVideoVerticalResolution, + PlatformConfig.VerticalResolution); + } + + return EFI_SUCCESS; +} + + +/** + Notification callback for GOP interface installation. + + @param[in] Event Event whose notification function is being invoked. + + @param[in] Context The pointer to the notification function's context, which + is implementation-dependent. +**/ +STATIC +VOID +EFIAPI +GopInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + + ASSERT (Event == mGopEvent); + + // + // Check further GOPs. + // + for (;;) { + mNumGopModes = 0; + mGopModes = NULL; + + Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, mGopTracker, + (VOID **) &Gop); + if (EFI_ERROR (Status)) { + return; + } + + Status = QueryGopModes (Gop, &mNumGopModes, &mGopModes); + if (EFI_ERROR (Status)) { + continue; + } + + Status = PopulateForm (mInstalledPackages, &gSimicsX58PlatformConfigGuid, + FORMID_MAIN_FORM, mNumGopModes, mGopModes); + if (EFI_ERROR (Status)) { + FreePool (mGopModes); + continue; + } + + break; + } + + // + // Success -- so uninstall this callback. Closing the event removes all + // pending notifications and all protocol registrations. + // + Status = gBS->CloseEvent (mGopEvent); + ASSERT_EFI_ERROR (Status); + mGopEvent = NULL; + mGopTracker = NULL; +} + + +/** + Entry point for this driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Pointer to SystemTable. + + @retval EFI_SUCESS Driver has loaded successfully. + @retval EFI_OUT_OF_RESOURCES Failed to install HII packages. + @return Error codes from lower level functions. + +**/ +EFI_STATUS +EFIAPI +PlatformInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + ExecutePlatformConfig (); + + mConfigAccess.ExtractConfig = &ExtractConfig; + mConfigAccess.RouteConfig = &RouteConfig; + mConfigAccess.Callback = &Callback; + + // + // Declare ourselves suitable for HII communication. + // + Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gEfiDevicePathProtocolGuid, &mPkgDevicePath, + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess, + NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Publish the HII package list to HII Database. + // + mInstalledPackages = HiiAddPackages ( + &gEfiCallerIdGuid, // PackageListGuid + ImageHandle, // associated DeviceHandle + PlatformDxeStrings, // 1st package + PlatformFormsBin, // 2nd package + NULL // terminator + ); + if (mInstalledPackages == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto UninstallProtocols; + } + + Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, &GopInstalled, + NULL /* Context */, &mGopEvent); + if (EFI_ERROR (Status)) { + goto RemovePackages; + } + + Status = gBS->RegisterProtocolNotify (&gEfiGraphicsOutputProtocolGuid, + mGopEvent, &mGopTracker); + if (EFI_ERROR (Status)) { + goto CloseGopEvent; + } + + // + // Check already installed GOPs. + // + Status = gBS->SignalEvent (mGopEvent); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; + +CloseGopEvent: + gBS->CloseEvent (mGopEvent); + +RemovePackages: + HiiRemovePackages (mInstalledPackages); + +UninstallProtocols: + gBS->UninstallMultipleProtocolInterfaces (ImageHandle, + &gEfiDevicePathProtocolGuid, &mPkgDevicePath, + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess, + NULL); + return Status; +} + +/** + Unload the driver. + + @param[in] ImageHandle Handle that identifies the image to evict. + + @retval EFI_SUCCESS The image has been unloaded. +**/ +EFI_STATUS +EFIAPI +PlatformUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + if (mGopEvent == NULL) { + // + // The GOP callback ran successfully and unregistered itself. Release the + // resources allocated there. + // + ASSERT (mGopModes != NULL); + FreePool (mGopModes); + } else { + // + // Otherwise we need to unregister the callback. + // + ASSERT (mGopModes == NULL); + gBS->CloseEvent (mGopEvent); + } + + // + // Release resources allocated by the entry point. + // + HiiRemovePackages (mInstalledPackages); + gBS->UninstallMultipleProtocolInterfaces (ImageHandle, + &gEfiDevicePathProtocolGuid, &mPkgDevicePath, + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess, + NULL); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c new file mode 100644 index 0000000000..b3b2b34064 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c @@ -0,0 +1,123 @@ +/** @file + Utility functions for serializing (persistently storing) and deserializing + OVMF's platform configuration. + + Copyright (C) 2014, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +#include "PlatformConfig.h" + +// +// Name of the UEFI variable that we use for persistent storage. +// +STATIC CHAR16 mVariableName[] = L"PlatformConfig"; + + +/** + Serialize and persistently save platform configuration. + + @param[in] PlatformConfig The platform configuration to serialize and save. + + @return Status codes returned by gRT->SetVariable(). +**/ +EFI_STATUS +EFIAPI +PlatformConfigSave ( + IN PLATFORM_CONFIG *PlatformConfig + ) +{ + EFI_STATUS Status; + + // + // We could implement any kind of translation here, as part of serialization. + // For example, we could expose the platform configuration in separate + // variables with human-readable contents, allowing other tools to access + // them more easily. For now, just save a binary dump. + // + Status = gRT->SetVariable (mVariableName, &gSimicsX58PlatformConfigGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof *PlatformConfig, PlatformConfig); + return Status; +} + + +/** + Load and deserialize platform configuration. + + When the function fails, output parameters are indeterminate. + + @param[out] PlatformConfig The platform configuration to receive the + loaded data. + + @param[out] OptionalElements This bitmap describes the presence of optional + configuration elements that have been loaded. + PLATFORM_CONFIG_F_DOWNGRADE means that some + unknown elements, present in the wire format, + have been ignored. + + @retval EFI_SUCCESS Loading & deserialization successful. + @return Error codes returned by GetVariable2(). +**/ +EFI_STATUS +EFIAPI +PlatformConfigLoad ( + OUT PLATFORM_CONFIG *PlatformConfig, + OUT UINT64 *OptionalElements + ) +{ + VOID *Data; + UINTN DataSize; + EFI_STATUS Status; + + // + // Any translation done in PlatformConfigSave() would have to be mirrored + // here. For now, just load the binary dump. + // + // Versioning of the binary wire format is implemented based on size + // (only incremental changes, ie. new fields), and on GUID. + // (Incompatible changes require a GUID change.) + // + Status = GetVariable2 (mVariableName, &gSimicsX58PlatformConfigGuid, &Data, + &DataSize); + if (EFI_ERROR (Status)) { + return Status; + } + + *OptionalElements = 0; + if (DataSize > sizeof *PlatformConfig) { + // + // Handle firmware downgrade -- keep only leading part. + // + CopyMem (PlatformConfig, Data, sizeof *PlatformConfig); + *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE; + } else { + CopyMem (PlatformConfig, Data, DataSize); + + // + // Handle firmware upgrade -- zero out missing fields. + // + ZeroMem ((UINT8 *)PlatformConfig + DataSize, + sizeof *PlatformConfig - DataSize); + } + + // + // Based on DataSize, report the optional features that we recognize. + // + if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) + + sizeof PlatformConfig->VerticalResolution)) { + *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION; + } + + FreePool (Data); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c new file mode 100644 index 0000000000..fa2c22116c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c @@ -0,0 +1,57 @@ +/** @file + PC/AT CMOS access routines + + Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Cmos.h" +#include "Library/IoLib.h" + +/** + Reads 8-bits of CMOS data. + + Reads the 8-bits of CMOS data at the location specified by Index. + The 8-bit read value is returned. + + @param Index The CMOS location to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +CmosRead8 ( + IN UINTN Index + ) +{ + IoWrite8 (0x70, (UINT8) Index); + return IoRead8 (0x71); +} + + +/** + Writes 8-bits of CMOS data. + + Writes 8-bits of CMOS data to the location specified by Index + with the value specified by Value and returns Value. + + @param Index The CMOS location to write. + @param Value The value to write to CMOS. + + @return The value written to CMOS. + +**/ +UINT8 +EFIAPI +CmosWrite8 ( + IN UINTN Index, + IN UINT8 Value + ) +{ + IoWrite8 (0x70, (UINT8) Index); + IoWrite8 (0x71, Value); + return Value; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c new file mode 100644 index 0000000000..692405e417 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c @@ -0,0 +1,114 @@ +/** @file + Install a callback when necessary for setting the Feature Control MSR on all + processors. + + Copyright (C) 2016, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#include "Platform.h" + +// +// The value to be written to the Feature Control MSR, retrieved from fw_cfg. +// +STATIC UINT64 mFeatureControlValue = 0x00000005; + +/** + Write the Feature Control MSR on an Application Processor or the Boot + Processor. + + All APs execute this function in parallel. The BSP executes the function + separately. + + @param[in,out] WorkSpace Pointer to the input/output argument workspace + shared by all processors. +**/ +STATIC +VOID +EFIAPI +WriteFeatureControl ( + IN OUT VOID *WorkSpace + ) +{ + AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue); +} + +/** + Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available. + + @param[in] PeiServices Indirect reference to the PEI Services Table. + @param[in] NotifyDescriptor Address of the notification descriptor data + structure. + @param[in] Ppi Address of the PPI that was installed. + + @return Status of the notification. The status code returned from this + function is ignored. +**/ +STATIC +EFI_STATUS +EFIAPI +OnMpServicesAvailable ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_PEI_MP_SERVICES_PPI *MpServices; + EFI_STATUS Status; + + DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__)); + // + // Write the MSR on all the APs in parallel. + // + MpServices = Ppi; + Status = MpServices->StartupAllAPs ( + (CONST EFI_PEI_SERVICES **)PeiServices, + MpServices, + WriteFeatureControl, // Procedure + FALSE, // SingleThread + 0, // TimeoutInMicroSeconds: inf. + NULL // ProcedureArgument + ); + if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) { + DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status)); + return Status; + } + + // + // Now write the MSR on the BSP too. + // + WriteFeatureControl (NULL); + + return EFI_SUCCESS; +} + +// +// Notification object for registering the callback, for when +// EFI_PEI_MP_SERVICES_PPI becomes available. +// +STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiMpServicesPpiGuid, // Guid + OnMpServicesAvailable // Notify +}; + +VOID +InstallFeatureControlCallback ( + VOID + ) +{ + EFI_STATUS Status; + + Status = PeiServicesNotifyPpi (&mMpServicesNotify); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n", + __FUNCTION__, Status)); + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c new file mode 100644 index 0000000000..818d135c95 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c @@ -0,0 +1,100 @@ +/** @file + Build FV related hobs for platform. + + Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PiPei.h" +#include "Platform.h" +#include +#include +#include +#include + + +/** + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI + and DXE know about them. + + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. + +**/ +EFI_STATUS +PeiFvInitialization ( + VOID + ) +{ + BOOLEAN SecureS3Needed; + + DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n")); + + DEBUG ( + (EFI_D_ERROR, "Firmware Volume HOB: 0x%x 0x%x\n", + PcdGet32 (PcdSimicsPeiMemFvBase), + PcdGet32 (PcdSimicsPeiMemFvSize) + ) + ); + // + // Create a memory allocation HOB for the PEI FV. + // + // Allocate as ACPI NVS is S3 is supported + // + BuildMemoryAllocationHob ( + PcdGet32 (PcdSimicsPeiMemFvBase), + PcdGet32 (PcdSimicsPeiMemFvSize), + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData + ); + + // + // Let DXE know about the DXE FV + // + BuildFvHob (PcdGet32 (PcdSimicsDxeMemFvBase), PcdGet32 (PcdSimicsDxeMemFvSize)); + + SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire); + + // + // Create a memory allocation HOB for the DXE FV. + // + // If "secure" S3 is needed, then SEC will decompress both PEI and DXE + // firmware volumes at S3 resume too, hence we need to keep away the OS from + // DXEFV as well. Otherwise we only need to keep away DXE itself from the + // DXEFV area. + // + BuildMemoryAllocationHob ( + PcdGet32 (PcdSimicsDxeMemFvBase), + PcdGet32 (PcdSimicsDxeMemFvSize), + SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData + ); + + // + // Additionally, said decompression will use temporary memory above the end + // of DXEFV, so let's keep away the OS from there too. + // + if (SecureS3Needed) { + UINT32 DxeMemFvEnd; + + DxeMemFvEnd = PcdGet32 (PcdSimicsDxeMemFvBase) + + PcdGet32 (PcdSimicsDxeMemFvSize); + BuildMemoryAllocationHob ( + DxeMemFvEnd, + PcdGet32 (PcdSimicsDecompressionScratchEnd) - DxeMemFvEnd, + EfiACPIMemoryNVS + ); + } + + // + // Let PEI know about the DXE FV so it can find the DXE Core + // + PeiServicesInstallFvInfoPpi ( + NULL, + (VOID *)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase), + PcdGet32 (PcdSimicsDxeMemFvSize), + NULL, + NULL + ); + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c new file mode 100644 index 0000000000..4c527baef2 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c @@ -0,0 +1,568 @@ +/** @file + Memory Detection for Virtual Machines. + + Copyright (c) 2006 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Cmos.h" + +UINT8 mPhysMemAddressWidth; + +STATIC UINT32 mS3AcpiReservedMemoryBase; +STATIC UINT32 mS3AcpiReservedMemorySize; + +STATIC UINT16 mX58TsegMbytes; + +VOID +X58TsegMbytesInitialization( + VOID +) +{ + + if (mHostBridgeDevId != INTEL_ICH10_DEVICE_ID) { + DEBUG (( + DEBUG_ERROR, + "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; " + "only DID=0x%04x (X58) is supported\n", + __FUNCTION__, + mHostBridgeDevId, + INTEL_ICH10_DEVICE_ID + )); + ASSERT (FALSE); + CpuDeadLoop (); + } + + // + // Check if QEMU offers an extended TSEG. + // + // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the MCH_EXT_TSEG_MB + // register, and reading back the register. + // + // On a QEMU machine type that does not offer an extended TSEG, the initial + // write overwrites whatever value a malicious guest OS may have placed in + // the (unimplemented) register, before entering S3 or rebooting. + // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged. + // + // On a QEMU machine type that offers an extended TSEG, the initial write + // triggers an update to the register. Subsequently, the value read back + // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us the + // number of megabytes. + // + mX58TsegMbytes = FixedPcdGet8(PcdX58TsegMbytes); + return; +} + + +UINT32 +GetSystemMemorySizeBelow4gb ( + VOID + ) +{ + UINT8 Cmos0x34; + UINT8 Cmos0x35; + + // + // CMOS 0x34/0x35 specifies the system memory above 16 MB. + // * CMOS(0x35) is the high byte + // * CMOS(0x34) is the low byte + // * The size is specified in 64kb chunks + // * Since this is memory above 16MB, the 16MB must be added + // into the calculation to get the total memory size. + // + + Cmos0x34 = (UINT8) CmosRead8 (0x34); + Cmos0x35 = (UINT8) CmosRead8 (0x35); + + return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); +} + + +STATIC +UINT64 +GetSystemMemorySizeAbove4gb ( + ) +{ + UINT32 Size; + UINTN CmosIndex; + + // + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB. + // * CMOS(0x5d) is the most significant size byte + // * CMOS(0x5c) is the middle size byte + // * CMOS(0x5b) is the least significant size byte + // * The size is specified in 64kb chunks + // + + Size = 0; + for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) { + Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex); + } + + return LShiftU64 (Size, 16); +} + + +/** + Return the highest address that DXE could possibly use, plus one. +**/ +STATIC +UINT64 +GetFirstNonAddress ( + VOID + ) +{ + UINT64 FirstNonAddress; + UINT64 Pci64Base, Pci64Size; + + FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb (); + + // + // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO + // resources to 32-bit anyway. See DegradeResource() in + // "PciResourceSupport.c". + // +#ifdef MDE_CPU_IA32 + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + return FirstNonAddress; + } +#endif + + // + // Otherwise, in order to calculate the highest address plus one, we must + // consider the 64-bit PCI host aperture too. Fetch the default size. + // + Pci64Size = PcdGet64 (PcdPciMmio64Size); + + if (Pci64Size == 0) { + if (mBootMode != BOOT_ON_S3_RESUME) { + DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n", + __FUNCTION__)); + PcdSet64 (PcdPciMmio64Size, 0); + } + + // + // There's nothing more to do; the amount of memory above 4GB fully + // determines the highest address plus one. The memory hotplug area (see + // below) plays no role for the firmware in this case. + // + return FirstNonAddress; + } + + // + // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so + // that the host can map it with 1GB hugepages. Follow suit. + // + Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB); + Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB); + + // + // The 64-bit PCI host aperture should also be "naturally" aligned. The + // alignment is determined by rounding the size of the aperture down to the + // next smaller or equal power of two. That is, align the aperture by the + // largest BAR size that can fit into it. + // + Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size)); + + if (mBootMode != BOOT_ON_S3_RESUME) { + // + // The core PciHostBridgeDxe driver will automatically add this range to + // the GCD memory space map through our PciHostBridgeLib instance; here we + // only need to set the PCDs. + // + PcdSet64 (PcdPciMmio64Base, Pci64Base); + PcdSet64 (PcdPciMmio64Size, Pci64Size); + DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n", + __FUNCTION__, Pci64Base, Pci64Size)); + } + + // + // The useful address space ends with the 64-bit PCI host aperture. + // + FirstNonAddress = Pci64Base + Pci64Size; + return FirstNonAddress; +} + + +/** + Initialize the mPhysMemAddressWidth variable, based on guest RAM size. +**/ +VOID +AddressWidthInitialization ( + VOID + ) +{ + UINT64 FirstNonAddress; + + // + // As guest-physical memory size grows, the permanent PEI RAM requirements + // are dominated by the identity-mapping page tables built by the DXE IPL. + // The DXL IPL keys off of the physical address bits advertized in the CPU + // HOB. To conserve memory, we calculate the minimum address width here. + // + FirstNonAddress = GetFirstNonAddress (); + mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress); + + // + // If FirstNonAddress is not an integral power of two, then we need an + // additional bit. + // + if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) { + ++mPhysMemAddressWidth; + } + + // + // The minimum address width is 36 (covers up to and excluding 64 GB, which + // is the maximum for Ia32 + PAE). The theoretical architecture maximum for + // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We + // can simply assert that here, since 48 bits are good enough for 256 TB. + // + if (mPhysMemAddressWidth <= 36) { + mPhysMemAddressWidth = 36; + } + ASSERT (mPhysMemAddressWidth <= 48); +} + + +/** + Calculate the cap for the permanent PEI memory. +**/ +STATIC +UINT32 +GetPeiMemoryCap ( + VOID + ) +{ + BOOLEAN Page1GSupport; + UINT32 RegEax; + UINT32 RegEdx; + UINT32 Pml4Entries; + UINT32 PdpEntries; + UINTN TotalPages; + + // + // If DXE is 32-bit, then just return the traditional 64 MB cap. + // +#ifdef MDE_CPU_IA32 + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + return SIZE_64MB; + } +#endif + + // + // Dependent on physical address width, PEI memory allocations can be + // dominated by the page tables built for 64-bit DXE. So we key the cap off + // of those. The code below is based on CreateIdentityMappingPageTables() in + // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c". + // + Page1GSupport = FALSE; + if (PcdGetBool (PcdUse1GPageTable)) { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000001) { + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT26) != 0) { + Page1GSupport = TRUE; + } + } + } + + if (mPhysMemAddressWidth <= 39) { + Pml4Entries = 1; + PdpEntries = 1 << (mPhysMemAddressWidth - 30); + ASSERT (PdpEntries <= 0x200); + } else { + Pml4Entries = 1 << (mPhysMemAddressWidth - 39); + ASSERT (Pml4Entries <= 0x200); + PdpEntries = 512; + } + + TotalPages = Page1GSupport ? Pml4Entries + 1 : + (PdpEntries + 1) * Pml4Entries + 1; + ASSERT (TotalPages <= 0x40201); + + // + // Add 64 MB for miscellaneous allocations. Note that for + // mPhysMemAddressWidth values close to 36, the cap will actually be + // dominated by this increment. + // + return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB); +} + + +/** + Publish PEI core memory + + @return EFI_SUCCESS The PEIM initialized successfully. + +**/ +EFI_STATUS +PublishPeiMemory ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS MemoryBase; + UINT64 MemorySize; + UINT32 LowerMemorySize; + UINT32 PeiMemoryCap; + + LowerMemorySize = GetSystemMemorySizeBelow4gb (); + if (FeaturePcdGet (PcdSmmSmramRequire)) { + // + // TSEG is chipped from the end of low RAM + // + LowerMemorySize -= mX58TsegMbytes * SIZE_1MB; + } + + // + // If S3 is supported, then the S3 permanent PEI memory is placed next, + // downwards. Its size is primarily dictated by CpuMpPei. The formula below + // is an approximation. + // + if (mS3Supported) { + mS3AcpiReservedMemorySize = SIZE_512KB + + mMaxCpuCount * + PcdGet32 (PcdCpuApStackSize); + mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize; + LowerMemorySize = mS3AcpiReservedMemoryBase; + } + + if (mBootMode == BOOT_ON_S3_RESUME) { + MemoryBase = mS3AcpiReservedMemoryBase; + MemorySize = mS3AcpiReservedMemorySize; + } else { + PeiMemoryCap = GetPeiMemoryCap (); + DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n", + __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10)); + + // + // Determine the range of memory to use during PEI + // + // Technically we could lay the permanent PEI RAM over SEC's temporary + // decompression and scratch buffer even if "secure S3" is needed, since + // their lifetimes don't overlap. However, PeiFvInitialization() will cover + // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory + // allocation HOB, and other allocations served from the permanent PEI RAM + // shouldn't overlap with that HOB. + // + MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ? + PcdGet32 (PcdSimicsDecompressionScratchEnd) : + PcdGet32 (PcdSimicsDxeMemFvBase) + PcdGet32 (PcdSimicsDxeMemFvSize); + MemorySize = LowerMemorySize - MemoryBase; + } + DEBUG((EFI_D_INFO, "MemoryBase=0x%lx MemorySize=0x%lx\n", MemoryBase, MemorySize)); + // + // Publish this memory to the PEI Core + // + Status = PublishSystemMemory(MemoryBase, MemorySize); + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +/** + Peform Memory Detection for QEMU / KVM + +**/ +STATIC +VOID +QemuInitializeRam ( + VOID + ) +{ + UINT64 LowerMemorySize; + UINT64 UpperMemorySize; + UINTN BufferSize; + UINT8 SmramIndex; + UINT8 SmramRanges; + EFI_PEI_HOB_POINTERS Hob; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock; + UINT8 Index; + + DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__)); + + // + // Determine total memory size available + // + LowerMemorySize = GetSystemMemorySizeBelow4gb (); + UpperMemorySize = GetSystemMemorySizeAbove4gb (); + + if (mBootMode == BOOT_ON_S3_RESUME) { + // + // Create the following memory HOB as an exception on the S3 boot path. + // + // Normally we'd create memory HOBs only on the normal boot path. However, + // CpuMpPei specifically needs such a low-memory HOB on the S3 path as + // well, for "borrowing" a subset of it temporarily, for the AP startup + // vector. + // + // CpuMpPei saves the original contents of the borrowed area in permanent + // PEI RAM, in a backup buffer allocated with the normal PEI services. + // CpuMpPei restores the original contents ("returns" the borrowed area) at + // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before + // transferring control to the OS's wakeup vector in the FACS. + // + // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to + // restore the original contents. Furthermore, we expect all such PEIMs + // (CpuMpPei included) to claim the borrowed areas by producing memory + // allocation HOBs, and to honor preexistent memory allocation HOBs when + // looking for an area to borrow. + // + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB); + } else { + // + // Create memory HOBs + // + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB); + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + UINT32 TsegSize; + + TsegSize = mX58TsegMbytes * SIZE_1MB; + AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize); + AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize, + TRUE); + + BufferSize = sizeof(EFI_SMRAM_HOB_DESCRIPTOR_BLOCK); + SmramRanges = 1; + + Hob.Raw = BuildGuidHob( + &gEfiSmmPeiSmramMemoryReserveGuid, + BufferSize + ); + ASSERT(Hob.Raw); + + SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.Raw); + SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges; + + SmramIndex = 0; + for (Index = 0; Index < SmramRanges; Index++) { + // + // This is an SMRAM range, create an SMRAM descriptor + // + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart = LowerMemorySize - TsegSize; + SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart = LowerMemorySize - TsegSize; + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize = TsegSize; + SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE; + SmramIndex++; + } + + } else { + AddMemoryRangeHob (BASE_1MB, LowerMemorySize); + } + + // + // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM + // entries. Otherwise, create a single memory HOB with the flat >=4GB + // memory size read from the CMOS. + // + if (UpperMemorySize != 0) { + AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); + } + } +} + +/** + Publish system RAM and reserve memory regions + +**/ +VOID +InitializeRamRegions ( + VOID + ) +{ + QemuInitializeRam (); + + if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) { + // + // This is the memory range that will be used for PEI on S3 resume + // + BuildMemoryAllocationHob ( + mS3AcpiReservedMemoryBase, + mS3AcpiReservedMemorySize, + EfiACPIMemoryNVS + ); + + // + // Cover the initial RAM area used as stack and temporary PEI heap. + // + // This is reserved as ACPI NVS so it can be used on S3 resume. + // + BuildMemoryAllocationHob ( + PcdGet32 (PcdSimicsSecPeiTempRamBase), + PcdGet32 (PcdSimicsSecPeiTempRamSize), + EfiACPIMemoryNVS + ); + + // + // SEC stores its table of GUIDed section handlers here. + // + BuildMemoryAllocationHob ( + PcdGet64 (PcdGuidedExtractHandlerTableAddress), + PcdGet32 (PcdGuidedExtractHandlerTableSize), + EfiACPIMemoryNVS + ); + + } + + if (mBootMode != BOOT_ON_S3_RESUME) { + if (!FeaturePcdGet (PcdSmmSmramRequire)) { + // + // Reserve the lock box storage area + // + // Since this memory range will be used on S3 resume, it must be + // reserved as ACPI NVS. + // + // If S3 is unsupported, then various drivers might still write to the + // LockBox area. We ought to prevent DXE from serving allocation requests + // such that they would overlap the LockBox storage. + // + ZeroMem ( + (VOID*)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase), + (UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize) + ); + BuildMemoryAllocationHob ( + (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase), + (UINT64)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize), + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData + ); + } + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + UINT32 TsegSize; + + // + // Make sure the TSEG area that we reported as a reserved memory resource + // cannot be used for reserved memory allocations. + // + TsegSize = mX58TsegMbytes * SIZE_1MB; + BuildMemoryAllocationHob ( + GetSystemMemorySizeBelow4gb() - TsegSize, + TsegSize, + EfiReservedMemoryType + ); + } + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c new file mode 100644 index 0000000000..e64bdc7c56 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c @@ -0,0 +1,631 @@ +/** @file + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2011, Andrei Warkentin + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Cmos.h" + +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { + { EfiACPIMemoryNVS, 0x004 }, + { EfiACPIReclaimMemory, 0x008 }, + { EfiReservedMemoryType, 0x004 }, + { EfiRuntimeServicesData, 0x024 }, + { EfiRuntimeServicesCode, 0x030 }, + { EfiBootServicesCode, 0x180 }, + { EfiBootServicesData, 0xF00 }, + { EfiMaxMemoryType, 0x000 } +}; + + +EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiMasterBootModePpiGuid, + NULL + } +}; + + +UINT16 mHostBridgeDevId; + +EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION; + +BOOLEAN mS3Supported = FALSE; + +UINT32 mMaxCpuCount; + +VOID +AddIoMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + +VOID +AddReservedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize, + BOOLEAN Cacheable + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_RESERVED, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + (Cacheable ? + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE : + 0 + ) | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + +VOID +AddIoMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); +} + + +VOID +AddMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + + +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); +} + + +VOID +AddUntestedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE, + MemoryBase, + MemorySize + ); +} + + +VOID +AddUntestedMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); +} + +VOID +AddFlashDeviceRange ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_FIRMWARE_DEVICE, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + MemoryBase, + MemorySize + ); + + BuildMemoryAllocationHob ( + MemoryBase, + MemorySize, + EfiMemoryMappedIO + ); +} + +VOID +MemMapInitialization ( + VOID + ) +{ + UINT64 PciIoBase; + UINT64 PciIoSize; + + UINT32 TopOfLowRam; + UINT64 PciExBarBase; + UINT32 PciBase; + UINT32 PciSize; + + PciIoBase = 0xC000; + PciIoSize = 0x4000; + + // + // Create Memory Type Information HOB + // + BuildGuidDataHob ( + &gEfiMemoryTypeInformationGuid, + mDefaultMemoryTypeInformation, + sizeof(mDefaultMemoryTypeInformation) + ); + + // + // Video memory + Legacy BIOS region + // + AddIoMemoryRangeHob (0x0A0000, BASE_1MB); + + TopOfLowRam = GetSystemMemorySizeBelow4gb (); + PciExBarBase = 0; + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) { + // + // The MMCONFIG area is expected to fall between the top of low RAM and + // the base of the 32-bit PCI host aperture. + // + PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress); + ASSERT (TopOfLowRam <= PciExBarBase); + ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB); + PciBase = (UINT32)(PciExBarBase + SIZE_256MB); + } else { + PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam; + } + + // + // address purpose size + // ------------ -------- ------------------------- + // 0x00000000 TopOfLowRam 0xDF000000 + // 0xDF000000 Tseg+UMA 0x01000000 + // 0xE0000000 PciExBarBase 0x10000000 + // 0xF0000000 PciBase 0x0C000000 + // ------------------------------------------------- + // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g) + // 0xFC000000 gap 44 MB + // 0xFEC00000 IO-APIC 4 KB + // 0xFEC01000 gap 1020 KB + // 0xFED00000 HPET 1 KB + // 0xFED00400 gap 111 KB + // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB + // 0xFED20000 gap 896 KB + // 0xFEE00000 LAPIC 1 MB + // + PciSize = 0xFC000000 - PciBase; + AddIoMemoryBaseSizeHob (PciBase, PciSize); + PcdSet64 (PcdPciMmio32Base, PciBase); + PcdSet64 (PcdPciMmio32Size, PciSize); + AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); + AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB); + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) { + AddIoMemoryBaseSizeHob (ICH10_ROOT_COMPLEX_BASE, SIZE_16KB); + // + // Note: there should be an + // + // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB); + // BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB, EfiMemoryMappedIO); + // + // call below, just like the one above for RCBA. However, Linux insists + // that the MMCONFIG area be marked in the E820 or UEFI memory map as + // "reserved memory" -- Linux does not content itself with a simple gap + // in the memory map wherever the MCFG ACPI table points to. + // + // This appears to be a safety measure. The PCI Firmware Specification + // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can + // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory + // [...]". (Emphasis added here.) + // + // Normally we add memory resource descriptor HOBs in + // QemuInitializeRam(), and pre-allocate from those with memory + // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area + // is most definitely not RAM; so, as an exception, cover it with + // uncacheable reserved memory right here. + // + AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE); + BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB, + EfiReservedMemoryType); + } + AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB); + + // Add PCI IO Port space available for PCI resource allocations. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_IO, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED, + PciIoBase, + PciIoSize + ); + PcdSet64 (PcdPciIoBase, PciIoBase); + PcdSet64 (PcdPciIoSize, PciIoSize); + + // + // Add flash range. + // + AddFlashDeviceRange (PcdGet32(PcdFlashAreaBaseAddress), PcdGet32(PcdFlashAreaSize)); + // + // Video memory / ABSEG + // + AddIoMemoryBaseSizeHob (0x0A0000, 0x20000); + // + // Legacy BIOS region. + // + AddReservedMemoryBaseSizeHob (0xC0000, 0x40000, TRUE); +} + +VOID +MiscInitialization ( + VOID + ) +{ + UINTN PmCmd; + UINTN Pmba; + UINT32 PmbaAndVal; + UINT32 PmbaOrVal; + UINTN AcpiCtlReg; + UINT8 AcpiEnBit; + + // + // Disable A20 Mask + // + IoOr8 (0x92, BIT1); + + // + // Build the CPU HOB with guest RAM size dependent address width and 16-bits + // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during + // S3 resume as well, so we build it unconditionally.) + // + BuildCpuHob (mPhysMemAddressWidth, 16); + + // + // Determine platform type and save Host Bridge DID to PCD + // + switch (mHostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET); + Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA); + PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK; + PmbaOrVal = PIIX4_PMBA_VALUE; + AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC); + AcpiEnBit = PIIX4_PMREGMISC_PMIOSE; + break; + case INTEL_ICH10_DEVICE_ID: + PmCmd = POWER_MGMT_REGISTER_ICH10 (PCI_COMMAND_OFFSET); + Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE); + PmbaAndVal = ~(UINT32)ICH10_PMBASE_MASK; + PmbaOrVal = ICH10_PMBASE_VALUE; + AcpiCtlReg = POWER_MGMT_REGISTER_ICH10 (ICH10_ACPI_CNTL); + AcpiEnBit = ICH10_ACPI_CNTL_ACPI_EN; + break; + default: + DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n", + __FUNCTION__, mHostBridgeDevId)); + ASSERT (FALSE); + return; + } + PcdSet16 (PcdSimicsX58HostBridgePciDevId, mHostBridgeDevId); + + // + // If the appropriate IOspace enable bit is set, assume the ACPI PMBA + // has been configured and skip the setup here. + // This matches the logic in AcpiTimerLibConstructor (). + // + if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) { + // + // The PEI phase should be exited with fully accessibe ACPI PM IO space: + // 1. set PMBA + // + PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal); + + // + // 2. set PCICMD/IOSE + // + PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE); + + // + // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN) + // + PciOr8 (AcpiCtlReg, AcpiEnBit); + } + + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) { + // + // Set Root Complex Register Block BAR + // + PciWrite32 ( + POWER_MGMT_REGISTER_ICH10 (ICH10_RCBA), + ICH10_ROOT_COMPLEX_BASE | ICH10_RCBA_EN + ); + + } + // + // Set the PM I/O base address to 0x400 + // + PciAndThenOr32 ( + PCI_LIB_ADDRESS ( + 0, + 31, + 0, + 0x40 + ), + (UINT32) ~0xfc0, ICH10_PMBASE_VALUE + ); + // + // Enable AHCI and all ports on the SATA controller. + // + // Address MAP Reg, setting AHCI mode + // + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x90), 0x0060); + // + //Enabling Ports 0-5 + // + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x92), 0x003F); + // + //Disabling Sata Controller 2, bit 25 = 1, bit 0 = 1 + // + MmioWrite32(0xFED1F418, 0x02000001); + // + //Enable HPET at FED0_0000h – FED0_03FFh + // + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x3404, 0x80); + // + //Config and enable APIC + // + MmioWrite32(0xFEC00000 + 0X0, 0); + MmioWrite32(0xFEC00000 + 0X10, PcdGet8(PcdIoApicId)<<24); + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x31FF, 0x01); +} + + +VOID +BootModeInitialization ( + VOID + ) +{ + EFI_STATUS Status; + + DEBUG((EFI_D_INFO, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12))); + if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5) { + mBootMode = BOOT_ON_S3_RESUME; + } + + Status = PeiServicesSetBootMode (mBootMode); + ASSERT_EFI_ERROR (Status); + + Status = PeiServicesInstallPpi (mPpiBootMode); + ASSERT_EFI_ERROR (Status); +} + + +VOID +ReserveEmuVariableNvStore ( + ) +{ + EFI_PHYSICAL_ADDRESS VariableStore; + + // + // Allocate storage for NV variables early on so it will be + // at a consistent address. Since VM memory is preserved + // across reboots, this allows the NV variable storage to survive + // a VM reboot. + // + VariableStore = + (EFI_PHYSICAL_ADDRESS)(UINTN) + AllocateRuntimePages ( + EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) + ); + DEBUG ((EFI_D_INFO, + "Reserved variable store memory: 0x%lX; size: %dkb\n", + VariableStore, + (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024 + )); + PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore); +} + + +VOID +SimicsVersionCheck( + VOID + ) +{ + + UINTN PciAddrPtr; + UINT8 CapOffset; + STATIC CHAR8 SimicsStr[0x100]; + UINTN i; + UINT32 MajorVersion; + UINT32 MinorVersion; + UINT32 ModelNumber; + + PciAddrPtr = PCI_LIB_ADDRESS(0, SIMICS_SIDEBANDPCI_DEV, SIMICS_SIDEBANDPCI_FUNC, 0); + CapOffset = PciRead8(PciAddrPtr + PCI_CAPBILITY_POINTER_OFFSET); + if (CapOffset != 0xFF) { + ModelNumber = PciRead32(PciAddrPtr + CapOffset + 4); + MajorVersion = PciRead32(PciAddrPtr + CapOffset + 8); + MinorVersion = PciRead32(PciAddrPtr + CapOffset + 0xc); + for (i = 0; i < 0x80; i++) { + SimicsStr[i] = PciRead8(PciAddrPtr + CapOffset + 0x10 + i); + } + DEBUG((EFI_D_INFO, "=============SIMICS Version info=============\n")); + DEBUG((EFI_D_INFO, "Model number = %d\n", ModelNumber)); + DEBUG((EFI_D_INFO, "Major version = %d\n", MajorVersion)); + DEBUG((EFI_D_INFO, "Minor version = %d\n", MinorVersion)); + DEBUG((EFI_D_INFO, "%a\n", SimicsStr)); + DEBUG((EFI_D_INFO, "=============================================\n")); + } +} + +VOID +DebugDumpCmos ( + VOID + ) +{ + UINT32 Loop; + + DEBUG ((EFI_D_INFO, "CMOS:\n")); + + for (Loop = 0; Loop < 0x80; Loop++) { + if ((Loop % 0x10) == 0) { + DEBUG ((EFI_D_INFO, "%02x:", Loop)); + } + DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop))); + if ((Loop % 0x10) == 0xf) { + DEBUG ((EFI_D_INFO, "\n")); + } + } +} + + +/** + Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules. + Set the mMaxCpuCount variable. +**/ +VOID +MaxCpuCountInitialization ( + VOID + ) +{ + mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); + return; +} + +/** + Determine if S3 support is explicitly enabled. + + @retval TRUE If S3 support is explicitly enabled. Other functions in this + library may be called (subject to their individual + restrictions). + + FALSE Otherwise. This includes unavailability of the firmware + configuration interface. No other function in this library + must be called. +**/ +BOOLEAN +EFIAPI +QemuFwCfgS3Enabled( + VOID +) +{ + //TO DO IF NEEDED + return TRUE; +} + +/** + Perform Platform PEI initialization. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @return EFI_SUCCESS The PEIM initialized successfully. + +**/ +EFI_STATUS +EFIAPI +InitializePlatform ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n")); + + SimicsVersionCheck (); + DebugDumpCmos (); + + if (QemuFwCfgS3Enabled ()) { + DEBUG ((EFI_D_INFO, "S3 support was detected on SIMICS\n")); + mS3Supported = TRUE; + Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE); + ASSERT_EFI_ERROR (Status); + } + AddressWidthInitialization (); + MaxCpuCountInitialization (); + + mHostBridgeDevId = PciRead16(SIMICS_HOSTBRIDGE_DID); + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + X58TsegMbytesInitialization (); + } + + PublishPeiMemory (); + + InitializeRamRegions (); + + if (mBootMode != BOOT_ON_S3_RESUME) { + if (!FeaturePcdGet (PcdSmmSmramRequire)) { + ReserveEmuVariableNvStore (); + } + PeiFvInitialization (); + MemMapInitialization (); + } + + MiscInitialization (); + InstallFeatureControlCallback (); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c new file mode 100644 index 0000000000..01a9ed40d5 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c @@ -0,0 +1,108 @@ +/** @file + Copyright (c) 2018 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +/** + Performs silicon pre-mem policy initialization. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The returned data must be used as input data for SiliconPolicyDonePreMem(), + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem(). + + 1) In FSP path, the input Policy should be FspmUpd. + Value of FspmUpd has been initialized by FSP binary default value. + Only a subset of FspmUpd needs to be updated for different silicon sku. + The return data is same FspmUpd. + + 2) In non-FSP path, the input policy could be NULL. + The return data is the initialized policy. + + @param[in, out] Policy Pointer to policy. + + @return the initialized policy. +**/ +VOID * +EFIAPI +SiliconPolicyInitPreMem ( + IN OUT VOID *Policy OPTIONAL + ) +{ + return Policy; +} + +/* + The silicon pre-mem policy is finalized. + Silicon code can do initialization based upon the policy data. + + The input Policy must be returned by SiliconPolicyInitPreMem(). + + @param[in] Policy Pointer to policy. + + @retval RETURN_SUCCESS The policy is handled consumed by silicon code. +*/ +RETURN_STATUS +EFIAPI +SiliconPolicyDonePreMem ( + IN VOID *Policy + ) +{ + return RETURN_SUCCESS; +} + +/** + Performs silicon post-mem policy initialization. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The returned data must be used as input data for SiliconPolicyDonePostMem(), + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem(). + + 1) In FSP path, the input Policy should be FspsUpd. + Value of FspsUpd has been initialized by FSP binary default value. + Only a subset of FspsUpd needs to be updated for different silicon sku. + The return data is same FspsUpd. + + 2) In non-FSP path, the input policy could be NULL. + The return data is the initialized policy. + + @param[in, out] Policy Pointer to policy. + + @return the initialized policy. +**/ +VOID * +EFIAPI +SiliconPolicyInitPostMem ( + IN OUT VOID *Policy OPTIONAL + ) +{ + return Policy; +} + +/* + The silicon post-mem policy is finalized. + Silicon code can do initialization based upon the policy data. + + The input Policy must be returned by SiliconPolicyInitPostMem(). + + @param[in] Policy Pointer to policy. + + @retval RETURN_SUCCESS The policy is handled consumed by silicon code. +*/ +RETURN_STATUS +EFIAPI +SiliconPolicyDonePostMem ( + IN VOID *Policy + ) +{ + return RETURN_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c new file mode 100644 index 0000000000..6d9da67975 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c @@ -0,0 +1,70 @@ +/** @file + Copyright (c) 2018 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include +#include + +/** + Performs silicon pre-mem policy update. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The input Policy must be returned by SiliconPolicyDonePreMem(). + + 1) In FSP path, the input Policy should be FspmUpd. + A platform may use this API to update the FSPM UPD policy initialized + by the silicon module or the default UPD data. + The output of FSPM UPD data from this API is the final UPD data. + + 2) In non-FSP path, the board may use additional way to get + the silicon policy data field based upon the input Policy. + + @param[in, out] Policy Pointer to policy. + + @return the updated policy. +**/ +VOID * +EFIAPI +SiliconPolicyUpdatePreMem ( + IN OUT VOID *Policy + ) +{ + return Policy; +} + +/** + Performs silicon post-mem policy update. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The input Policy must be returned by SiliconPolicyDonePostMem(). + + 1) In FSP path, the input Policy should be FspsUpd. + A platform may use this API to update the FSPS UPD policy initialized + by the silicon module or the default UPD data. + The output of FSPS UPD data from this API is the final UPD data. + + 2) In non-FSP path, the board may use additional way to get + the silicon policy data field based upon the input Policy. + + @param[in, out] Policy Pointer to policy. + + @return the updated policy. +**/ +VOID * +EFIAPI +SiliconPolicyUpdatePostMem ( + IN OUT VOID *Policy + ) +{ + return Policy; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c new file mode 100644 index 0000000000..82a2d60959 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c @@ -0,0 +1,148 @@ +/** @file + This driver installs SMBIOS information for OVMF + + Copyright (c) 2011, Bei Guan + Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SmbiosPlatformDxe.h" + + +/** +Reads 8-bits of CMOS data. + +Reads the 8-bits of CMOS data at the location specified by Index. +The 8-bit read value is returned. + +@param Index The CMOS location to read. + +@return The value read. + +**/ +UINT8 +EFIAPI +CmosRead8( + IN UINTN Index + ) +{ + IoWrite8(0x70, (UINT8)Index); + return IoRead8(0x71); +} + +UINT32 +GetSystemMemorySizeBelow4gb( + VOID + ) +{ + UINT8 Cmos0x34; + UINT8 Cmos0x35; + + // + // CMOS 0x34/0x35 specifies the system memory above 16 MB. + // * CMOS(0x35) is the high byte + // * CMOS(0x34) is the low byte + // * The size is specified in 64kb chunks + // * Since this is memory above 16MB, the 16MB must be added + // into the calculation to get the total memory size. + // + + Cmos0x34 = (UINT8)CmosRead8(0x34); + Cmos0x35 = (UINT8)CmosRead8(0x35); + + return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); +} + +STATIC +UINT64 +GetSystemMemorySizeAbove4gb( + VOID +) +{ + UINT32 Size; + UINTN CmosIndex; + + // + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB. + // * CMOS(0x5d) is the most significant size byte + // * CMOS(0x5c) is the middle size byte + // * CMOS(0x5b) is the least significant size byte + // * The size is specified in 64kb chunks + // + + Size = 0; + for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) { + Size = (UINT32)(Size << 8) + (UINT32)CmosRead8(CmosIndex); + } + + return LShiftU64(Size, 16); +} + +/** + Installs SMBIOS information for OVMF + + @param ImageHandle Module's image handle + @param SystemTable Pointer of EFI_SYSTEM_TABLE + + @retval EFI_SUCCESS Smbios data successfully installed + @retval Other Smbios data was not installed + +**/ +EFI_STATUS +EFIAPI +SmbiosTablePublishEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_PROTOCOL *Smbios; + SMBIOS_TABLE_TYPE19 *Type19Record; + EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle; + UINT8 NumSlots; + UINT64 TotalMemorySize; + + // + // Find the SMBIOS protocol + // + Status = gBS->LocateProtocol ( + &gEfiSmbiosProtocolGuid, + NULL, + (VOID**)&Smbios + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Generate Memory Array Mapped Address info + // + NumSlots = 2; + TotalMemorySize = 0; + TotalMemorySize = GetSystemMemorySizeBelow4gb(); + Type19Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE19)); + ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19)); + Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS; + Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19); + Type19Record->Hdr.Handle = 0; + Type19Record->StartingAddress = 0; + Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1; + Type19Record->MemoryArrayHandle = SMBIOS_HANDLE_PI_RESERVED; + Type19Record->PartitionWidth = (UINT8)(NumSlots); + + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; + Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)Type19Record); + ASSERT_EFI_ERROR(Status); + + TotalMemorySize = GetSystemMemorySizeAbove4gb(); + Type19Record->StartingAddress = 0xFFFFFFFF; + Type19Record->ExtendedStartingAddress = 0xFFFFFFFF; + Type19Record->ExtendedEndingAddress = TotalMemorySize + 0xFFFFFFFF - 1; + + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; + Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)Type19Record); + FreePool(Type19Record); + ASSERT_EFI_ERROR(Status); + + return Status; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf new file mode 100644 index 0000000000..839626eb86 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf @@ -0,0 +1,31 @@ +## @file +# Component description file for PlatformAcpiTables module. +# +# ACPI table data and ASL sources required to boot the platform. +# +# Copyright (c) 2008 - 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformAcpiTables + FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD + MODULE_TYPE = USER_DEFINED + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Platform.h + Dsdt.asl + +[Packages] + MdePkg/MdePkg.dec + diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl new file mode 100644 index 0000000000..76a8fbc081 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl @@ -0,0 +1,821 @@ +/** @file + Contains root level name space objects for the platform + + Copyright (c) 2008 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 4) { + // + // System Sleep States + // + Name (\_S3, Package () {5, 5, 0, 0}) + Name (\_S4, Package () {6, 6, 0, 0}) + Name (\_S5, Package () {7, 7, 0, 0}) + + Name (GPIC, Zero) + Method (_PIC, 1, NotSerialized) // _PIC: Interrupt Model + { + GPIC = Arg0 + } + // + // System Bus + // + Scope (\_SB) { + // + // PCI Root Bridge + // + Device (PCI0) { + Name (_HID, EISAID ("PNP0A03")) + Name (_ADR, 0x00000000) + Name (_BBN, 0x00) + Name (_UID, 0x00) + + + // Current resource settings + Name (_CRS, ResourceTemplate () { + WORDBusNumber ( // Bus number resource (0); the bridge produces bus numbers for its subsequent buses + ResourceProducer, // bit 0 of general flags is 1 + MinFixed, // Range is fixed + MaxFixed, // Range is fixed + PosDecode, // PosDecode + 0x0000, // Granularity + 0x0000, // Min + 0x00FF, // Max + 0x0000, // Translation + 0x0100 // Range Length = Max-Min+1 + ) + + IO (Decode16, 0xCF8, 0xCF8, 0x01, 0x08) //Consumed resource (0xCF8-0xCFF) + + WORDIO ( // Consumed-and-produced resource (all I/O below CF8) + ResourceProducer, // bit 0 of general flags is 0 + MinFixed, // Range is fixed + MaxFixed, // Range is fixed + PosDecode, + EntireRange, + 0x0000, // Granularity + 0x0000, // Min + 0x0CF7, // Max + 0x0000, // Translation + 0x0CF8 // Range Length + ) + + WORDIO ( // Consumed-and-produced resource (all I/O above CFF) + ResourceProducer, // bit 0 of general flags is 0 + MinFixed, // Range is fixed + MaxFixed, // Range is fixed + PosDecode, + EntireRange, + 0x0000, // Granularity + 0x0D00, // Min + 0xFFFF, // Max + 0x0000, // Translation + 0xF300 // Range Length + ) + + DWORDMEMORY ( // Descriptor for legacy VGA video RAM + ResourceProducer, // bit 0 of general flags is 0 + PosDecode, + MinFixed, // Range is fixed + MaxFixed, // Range is Fixed + Cacheable, + ReadWrite, + 0x00000000, // Granularity + 0x000A0000, // Min + 0x000BFFFF, // Max + 0x00000000, // Translation + 0x00020000 // Range Length + ) + + DWORDMEMORY ( // Descriptor for 32-bit MMIO + ResourceProducer, // bit 0 of general flags is 0 + PosDecode, + MinFixed, // Range is fixed + MaxFixed, // Range is Fixed + NonCacheable, + ReadWrite, + 0x00000000, // Granularity + 0xF0000000, // Min + 0xFBFFFFFF, // Max + 0x00000000, // Translation + 0x0C000000, // Range Length + , // ResourceSourceIndex + , // ResourceSource + PW32 // DescriptorName + ) + }) + + // + // PCI Interrupt Routing Table - PIC Mode Only + // + // If you change the IRQ mapping here you also need + // to change the mapping in the south bridge + // (pci-conf.py) and in the BIOS. + // INTA -> 0xa (10) + // INTB -> 0xb (11) + // INTC -> 0xa (10) + // INTD -> 0xb (11) + + Method (_PRT, 0, NotSerialized) { + If (GPIC) { + Return (AR00) // APIC Mode + } + Return (PR00) // PIC Mode + } + + Name (PR00, Package(){ + Package () {0x000FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + // + // Bus 0, Device 1 + // + Package () {0x0001FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0002FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0002FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0002FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0002FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + // + // Bus 0, Device 3 + // + Package () {0x0003FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0003FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0003FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0003FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0004FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0004FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0004FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0004FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0005FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0005FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0005FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0005FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0006FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0006FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0006FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0006FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0007FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0007FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0007FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0007FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0008FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0008FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0008FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0008FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0009FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0009FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0009FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0009FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00010FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00010FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00010FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00010FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00011FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00011FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00011FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00011FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00012FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00012FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00012FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00012FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00013FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00013FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00013FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00013FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00014FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00014FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00014FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00014FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00015FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00015FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00015FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00015FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00016FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00016FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00016FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00016FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00017FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00017FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00017FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00017FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00018FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00018FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00018FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00018FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00019FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00019FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00019FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00019FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + } + ) + + Name(AR00, Package(){ + + Package () {0x000FFFF, 0x00, 0, 16}, + Package () {0x000FFFF, 0x01, 0, 17}, + Package () {0x000FFFF, 0x02, 0, 18}, + Package () {0x000FFFF, 0x03, 0, 19}, + + // + // Bus 0, Device 1 + // + Package () {0x0001FFFF, 0x00, 0, 16}, + Package () {0x0001FFFF, 0x01, 0, 17}, + Package () {0x0001FFFF, 0x02, 0, 18}, + Package () {0x0001FFFF, 0x03, 0, 19}, + + Package () {0x0002FFFF, 0x00, 0, 16}, + Package () {0x0002FFFF, 0x01, 0, 17}, + Package () {0x0002FFFF, 0x02, 0, 18}, + Package () {0x0002FFFF, 0x03, 0, 19}, + // + // Bus 0, Device 3 + // + Package () {0x0003FFFF, 0x00, 0, 16}, + Package () {0x0003FFFF, 0x01, 0, 17}, + Package () {0x0003FFFF, 0x02, 0, 18}, + Package () {0x0003FFFF, 0x03, 0, 19}, + + Package () {0x0004FFFF, 0x00, 0, 16}, + Package () {0x0004FFFF, 0x01, 0, 17}, + Package () {0x0004FFFF, 0x02, 0, 18}, + Package () {0x0004FFFF, 0x03, 0, 19}, + + Package () {0x0005FFFF, 0x00, 0, 16}, + Package () {0x0005FFFF, 0x01, 0, 17}, + Package () {0x0005FFFF, 0x02, 0, 18}, + Package () {0x0005FFFF, 0x03, 0, 19}, + + Package () {0x0006FFFF, 0x00, 0, 16}, + Package () {0x0006FFFF, 0x01, 0, 17}, + Package () {0x0006FFFF, 0x02, 0, 18}, + Package () {0x0006FFFF, 0x03, 0, 19}, + + Package () {0x0007FFFF, 0x00, 0, 16}, + Package () {0x0007FFFF, 0x01, 0, 17}, + Package () {0x0007FFFF, 0x02, 0, 18}, + Package () {0x0007FFFF, 0x03, 0, 19}, + + Package () {0x0008FFFF, 0x00, 0, 16}, + Package () {0x0008FFFF, 0x01, 0, 17}, + Package () {0x0008FFFF, 0x02, 0, 18}, + Package () {0x0008FFFF, 0x03, 0, 19}, + + Package () {0x0009FFFF, 0x00, 0, 16}, + Package () {0x0009FFFF, 0x01, 0, 17}, + Package () {0x0009FFFF, 0x02, 0, 18}, + Package () {0x0009FFFF, 0x03, 0, 19}, + + Package () {0x000AFFFF, 0x00, 0, 16}, + Package () {0x000AFFFF, 0x01, 0, 17}, + Package () {0x000AFFFF, 0x02, 0, 18}, + Package () {0x000AFFFF, 0x03, 0, 19}, + + Package () {0x000BFFFF, 0x00, 0, 16}, + Package () {0x000BFFFF, 0x01, 0, 17}, + Package () {0x000BFFFF, 0x02, 0, 18}, + Package () {0x000BFFFF, 0x03, 0, 19}, + + Package () {0x000CFFFF, 0x00, 0, 16}, + Package () {0x000CFFFF, 0x01, 0, 17}, + Package () {0x000CFFFF, 0x02, 0, 18}, + Package () {0x000CFFFF, 0x03, 0, 19}, + + Package () {0x000DFFFF, 0x00, 0, 16}, + Package () {0x000DFFFF, 0x01, 0, 17}, + Package () {0x000DFFFF, 0x02, 0, 18}, + Package () {0x000DFFFF, 0x03, 0, 19}, + + Package () {0x000EFFFF, 0x00, 0, 16}, + Package () {0x000EFFFF, 0x01, 0, 17}, + Package () {0x000EFFFF, 0x02, 0C, 18}, + Package () {0x000EFFFF, 0x03, 0, 19}, + + Package () {0x000FFFFF, 0x00, 0, 16}, + Package () {0x000FFFFF, 0x01, 0, 17}, + Package () {0x000FFFFF, 0x02, 0, 18}, + Package () {0x000FFFFF, 0x03, 0, 19}, + + Package () {0x00010FFFF, 0x00, 0, 16}, + Package () {0x00010FFFF, 0x01, 0, 17}, + Package () {0x00010FFFF, 0x02, 0, 18}, + Package () {0x00010FFFF, 0x03, 0, 19}, + + Package () {0x00011FFFF, 0x00, 0, 16}, + Package () {0x00011FFFF, 0x01, 0, 17}, + Package () {0x00011FFFF, 0x02, 0, 18}, + Package () {0x00011FFFF, 0x03, 0, 19}, + + Package () {0x00012FFFF, 0x00, 0, 16}, + Package () {0x00012FFFF, 0x01, 0, 17}, + Package () {0x00012FFFF, 0x02, 0, 18}, + Package () {0x00012FFFF, 0x03, 0, 19}, + + Package () {0x00013FFFF, 0x00, 0, 16}, + Package () {0x00013FFFF, 0x01, 0, 17}, + Package () {0x00013FFFF, 0x02, 0, 18}, + Package () {0x00013FFFF, 0x03, 0, 19}, + + Package () {0x00014FFFF, 0x00, 0, 16}, + Package () {0x00014FFFF, 0x01, 0, 17}, + Package () {0x00014FFFF, 0x02, 0, 18}, + Package () {0x00014FFFF, 0x03, 0, 19}, + + Package () {0x00015FFFF, 0x00, 0, 16}, + Package () {0x00015FFFF, 0x01, 0, 17}, + Package () {0x00015FFFF, 0x02, 0, 18}, + Package () {0x00015FFFF, 0x03, 0, 19}, + + Package () {0x00016FFFF, 0x00, 0, 16}, + Package () {0x00016FFFF, 0x01, 0, 17}, + Package () {0x00016FFFF, 0x02, 0, 18}, + Package () {0x00016FFFF, 0x03, 0, 19}, + + Package () {0x00017FFFF, 0x00, 0, 16}, + Package () {0x00017FFFF, 0x01, 0, 17}, + Package () {0x00017FFFF, 0x02, 0, 18}, + Package () {0x00017FFFF, 0x03, 0, 19}, + + Package () {0x00018FFFF, 0x00, 0, 16}, + Package () {0x00018FFFF, 0x01, 0, 17}, + Package () {0x00018FFFF, 0x02, 0, 18}, + Package () {0x00018FFFF, 0x03, 0, 19}, + + Package () {0x0001EFFFF, 0x00, 0, 16}, + Package () {0x0001EFFFF, 0x01, 0, 17}, + Package () {0x0001EFFFF, 0x02, 0, 18}, + Package () {0x0001EFFFF, 0x03, 0, 19}, + + Package () {0x00019FFFF, 0x00, 0, 16}, + Package () {0x00019FFFF, 0x01, 0, 17}, + Package () {0x00019FFFF, 0x02, 0, 18}, + Package () {0x00019FFFF, 0x03, 0, 19}, + + Package () {0x0001AFFFF, 0x00, 0, 16}, + Package () {0x0001AFFFF, 0x01, 0, 17}, + Package () {0x0001AFFFF, 0x02, 0, 18}, + Package () {0x0001AFFFF, 0x03, 0, 19}, + + Package () {0x0001BFFFF, 0x00, 0, 16}, + Package () {0x0001BFFFF, 0x01, 0, 17}, + Package () {0x0001BFFFF, 0x02, 0, 18}, + Package () {0x0001BFFFF, 0x03, 0, 19}, + + Package () {0x0001CFFFF, 0x00, 0, 16}, + Package () {0x0001CFFFF, 0x01, 0, 17}, + Package () {0x0001CFFFF, 0x02, 0, 18}, + Package () {0x0001CFFFF, 0x03, 0, 19}, + + Package () {0x0001DFFFF, 0x00, 0, 16}, + Package () {0x0001DFFFF, 0x01, 0, 17}, + Package () {0x0001DFFFF, 0x02, 0, 18}, + Package () {0x0001DFFFF, 0x03, 0, 19}, + + Package () {0x0001FFFFF, 0x00, 0, 16}, + Package () {0x0001FFFFF, 0x01, 0, 17}, + Package () {0x0001FFFFF, 0x02, 0, 18}, + Package () {0x0001FFFFF, 0x03, 0, 19}, + } + ) + + // + // PCI to ISA Bridge (Bus 0, Device 7, Function 0) + // + Device (LPC) { + Name (_ADR, 0x001F0000) + + // + // PCI Interrupt Routing Configuration Registers + // + OperationRegion (PRR0, PCI_Config, 0x60, 0x0C) + Field (PRR0, ANYACC, NOLOCK, PRESERVE) { + PIRA, 8, + PIRB, 8, + PIRC, 8, + PIRD, 8, + Offset (0x04), + PIRE, 8, + PIRF, 8, + PIRG, 8, + PIRH, 8 + } + + // + // _STA method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PSTA, 1, NotSerialized) { + If (And (Arg0, 0x80)) { + Return (0x9) + } Else { + Return (0xB) + } + } + + // + // _DIS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PDIS, 1, NotSerialized) { + Or (Arg0, 0x80, Arg0) + } + + // + // _CRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PCRS, 1, NotSerialized) { + Name (BUF0, ResourceTemplate () {IRQ (Level, ActiveLow, Shared){0}}) + // + // Define references to buffer elements + // + CreateWordField (BUF0, 0x01, IRQW) // IRQ low + // + // Write current settings into IRQ descriptor + // + If (And (Arg0, 0x80)) { + Store (Zero, Local0) + } Else { + Store (One, Local0) + } + // + // Shift 1 by value in register 70 + // + ShiftLeft (Local0, And (Arg0, 0x0F), IRQW) // Save in buffer + Return (BUF0) // Return Buf0 + } + + // + // _PRS resource for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Name (PPRS, ResourceTemplate () { + IRQ (Level, ActiveLow, Shared) {3, 4, 5, 7, 9, 10, 11, 12, 14, 15} + }) + + // + // _SRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PSRS, 2, NotSerialized) { + CreateWordField (Arg1, 0x01, IRQW) // IRQ low + FindSetRightBit (IRQW, Local0) // Set IRQ + If (LNotEqual (IRQW, Zero)) { + And (Local0, 0x7F, Local0) + Decrement (Local0) + } Else { + Or (Local0, 0x80, Local0) + } + Store (Local0, Arg0) + } + + // + // PCI IRQ Link A + // + Device (LNKA) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 1) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRA)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRA) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRA)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRA, Arg0) } + } + + // + // PCI IRQ Link B + // + Device (LNKB) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 2) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRB)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRB) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRB)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRB, Arg0) } + } + + // + // PCI IRQ Link C + // + Device (LNKC) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 3) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRC)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRC) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRC)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRC, Arg0) } + } + + // + // PCI IRQ Link D + // + Device (LNKD) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 4) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRD)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRD) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRD)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRD, Arg0) } + } + + // + // PCI IRQ Link E + // + Device (LNKE) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 5) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRE)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRE) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRE)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRE, Arg0) } + } + + // + // PCI IRQ Link F + // + Device (LNKF) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 6) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRF)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRF) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRF)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRF, Arg0) } + } + + // + // PCI IRQ Link G + // + Device (LNKG) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 7) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRG)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRG) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRG)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRG, Arg0) } + } + + // + // PCI IRQ Link H + // + Device (LNKH) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 8) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRH)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRH) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRH)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRH, Arg0) } + } + + // + // Programmable Interrupt Controller (PIC) + // + Device(PIC) { + Name (_HID, EISAID ("PNP0000")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x020, 0x020, 0x00, 0x02) + IO (Decode16, 0x0A0, 0x0A0, 0x00, 0x02) + IO (Decode16, 0x4D0, 0x4D0, 0x00, 0x02) + IRQNoFlags () {2} + }) + } + + // + // ISA DMA + // + Device (DMAC) { + Name (_HID, EISAID ("PNP0200")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x00, 0x00, 0, 0x10) + IO (Decode16, 0x81, 0x81, 0, 0x03) + IO (Decode16, 0x87, 0x87, 0, 0x01) + IO (Decode16, 0x89, 0x89, 0, 0x03) + IO (Decode16, 0x8f, 0x8f, 0, 0x01) + IO (Decode16, 0xc0, 0xc0, 0, 0x20) + DMA (Compatibility, NotBusMaster, Transfer8) {4} + }) + } + + // + // 8254 Timer + // + Device(TMR) { + Name(_HID,EISAID("PNP0100")) + Name(_CRS, ResourceTemplate () { + IO (Decode16, 0x40, 0x40, 0x00, 0x04) + IRQNoFlags () {0} + }) + } + + // + // Real Time Clock + // + Device (RTC) { + Name (_HID, EISAID ("PNP0B00")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x70, 0x70, 0x00, 0x02) + IRQNoFlags () {8} + }) + } + + // + // PCAT Speaker + // + Device(SPKR) { + Name (_HID, EISAID("PNP0800")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x61, 0x61, 0x01, 0x01) + }) + } + + // + // Floating Point Coprocessor + // + Device(FPU) { + Name (_HID, EISAID("PNP0C04")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0xF0, 0xF0, 0x00, 0x10) + IRQNoFlags () {13} + }) + } + + // + // Generic motherboard devices and pieces that don't fit anywhere else + // + Device(XTRA) { + Name (_HID, EISAID ("PNP0C02")) + Name (_UID, 0x01) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x010, 0x010, 0x00, 0x10) + IO (Decode16, 0x022, 0x022, 0x00, 0x1E) + IO (Decode16, 0x044, 0x044, 0x00, 0x1C) + IO (Decode16, 0x062, 0x062, 0x00, 0x02) + IO (Decode16, 0x065, 0x065, 0x00, 0x0B) + IO (Decode16, 0x072, 0x072, 0x00, 0x0E) + IO (Decode16, 0x080, 0x080, 0x00, 0x01) + IO (Decode16, 0x084, 0x084, 0x00, 0x03) + IO (Decode16, 0x088, 0x088, 0x00, 0x01) + IO (Decode16, 0x08c, 0x08c, 0x00, 0x03) + IO (Decode16, 0x090, 0x090, 0x00, 0x10) + IO (Decode16, 0x0A2, 0x0A2, 0x00, 0x1E) + IO (Decode16, 0x0E0, 0x0E0, 0x00, 0x10) + IO (Decode16, 0x1E0, 0x1E0, 0x00, 0x10) + IO (Decode16, 0x160, 0x160, 0x00, 0x10) + IO (Decode16, 0x278, 0x278, 0x00, 0x08) + IO (Decode16, 0x370, 0x370, 0x00, 0x02) + IO (Decode16, 0x378, 0x378, 0x00, 0x08) + IO (Decode16, 0x400, 0x400, 0x00, 0x40) // PMBLK1 + IO (Decode16, 0x440, 0x440, 0x00, 0x10) + IO (Decode16, 0x678, 0x678, 0x00, 0x08) + IO (Decode16, 0x778, 0x778, 0x00, 0x08) + Memory32Fixed (ReadOnly, 0xFEC00000, 0x1000) // IO APIC + Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000) // LAPIC + }) + } + + // + // PS/2 Keyboard and PC/AT Enhanced Keyboard 101/102 + // + Device (PS2K) { + Name (_HID, EISAID ("PNP0303")) + Name (_CID, EISAID ("PNP030B")) + Name(_CRS,ResourceTemplate() { + IO (Decode16, 0x60, 0x60, 0x00, 0x01) + IO (Decode16, 0x64, 0x64, 0x00, 0x01) + IRQNoFlags () {1} + }) + } + + // + // PS/2 Mouse and Microsoft Mouse + // + Device (PS2M) { // PS/2 stype mouse port + Name (_HID, EISAID ("PNP0F03")) + Name (_CID, EISAID ("PNP0F13")) + Name (_CRS, ResourceTemplate() { + IRQNoFlags () {12} + }) + } + + // + // UART Serial Port - COM1 + // + Device (UAR1) { + Name (_HID, EISAID ("PNP0501")) + Name (_DDN, "COM1") + Name (_UID, 0x01) + Name(_CRS,ResourceTemplate() { + IO (Decode16, 0x3F8, 0x3F8, 0x00, 0x08) + IRQ (Edge, ActiveHigh, Exclusive, ) {4} + }) + } + + // + // UART Serial Port - COM2 + // + Device (UAR2) { + Name (_HID, EISAID ("PNP0501")) + Name (_DDN, "COM2") + Name (_UID, 0x02) + Name(_CRS,ResourceTemplate() { + IO (Decode16, 0x2F8, 0x2F8, 0x00, 0x08) + IRQ (Edge, ActiveHigh, Exclusive, ) {3} + }) + } + } + } + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h new file mode 100644 index 0000000000..6395ec11e2 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h @@ -0,0 +1,75 @@ +/** @file + Platform specific defines for constructing ACPI tables + + Copyright (c) 2013 - 2008 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _Platform_h_INCLUDED_ +#define _Platform_h_INCLUDED_ + +#include +#include + +// +// ACPI table information used to initialize tables. +// +#define EFI_ACPI_OEM_ID 'O','V','M','F',' ',' ' // OEMID 6 bytes long +#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64('O','V','M','F','E','D','K','2') // OEM table id 8 bytes long +#define EFI_ACPI_OEM_REVISION 0x02000820 +#define EFI_ACPI_CREATOR_ID SIGNATURE_32('O','V','M','F') +#define EFI_ACPI_CREATOR_REVISION 0x00000097 + +#define INT_MODEL 0x01 +#define SCI_INT_VECTOR 0x0009 +#define SMI_CMD_IO_PORT 0xB2 +#define ACPI_ENABLE 0x0E1 +#define ACPI_DISABLE 0x01E +#define S4BIOS_REQ 0x00 +#define PM1a_EVT_BLK 0x00000400 +#define PM1b_EVT_BLK 0x00000000 +#define PM1a_CNT_BLK 0x00000404 +#define PM1b_CNT_BLK 0x00000000 +#define PM2_CNT_BLK 0x00000450 +#define PM_TMR_BLK 0x00000408 +#define GPE0_BLK 0x00000420 +#define GPE1_BLK 0x00000000 +#define PM1_EVT_LEN 0x04 +#define PM1_CNT_LEN 0x04 +#define PM2_CNT_LEN 0x01 +#define PM_TM_LEN 0x04 +#define GPE0_BLK_LEN 0x10 +#define GPE1_BLK_LEN 0x00 +#define GPE1_BASE 0x00 +#define RESERVED 0x00 +#define P_LVL2_LAT 0x0065 +#define P_LVL3_LAT 0x03E9 +#define FLUSH_SIZE 0x0400 +#define FLUSH_STRIDE 0x0010 +#define DUTY_OFFSET 0x00 +#define DUTY_WIDTH 0x00 +#define DAY_ALRM 0x0D +#define MON_ALRM 0x00 +#define CENTURY 0x00 +#define FLAG (EFI_ACPI_2_0_WBINVD | \ + EFI_ACPI_2_0_PROC_C1 | \ + EFI_ACPI_2_0_SLP_BUTTON | \ + EFI_ACPI_2_0_RTC_S4 | \ + EFI_ACPI_2_0_RESET_REG_SUP) +#define RESET_REG 0xCF9 +#define RESET_VALUE (BIT2 | BIT1) // PIIX3 Reset CPU + System Reset + +// +// Byte-aligned IO port register block initializer for +// EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE +// +#define GAS2_IO(Base, Size) { \ + EFI_ACPI_2_0_SYSTEM_IO, /* AddressSpaceId */ \ + (Size) * 8, /* RegisterBitWidth */ \ + 0, /* RegisterBitOffset */ \ + 0, /* Reserved */ \ + (Base) /* Address */ \ + } + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h new file mode 100644 index 0000000000..f65f61d74d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h @@ -0,0 +1,17 @@ +/** @file + GUID for UEFI variables that are specific to OVMF configuration. + + Copyright (C) 2014, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __SIMICSX58_PLATFORM_CONFIG_H__ +#define __SIMICSX58_PLATFORM_CONFIG_H__ + +#define SIMICSX58_PLATFORM_CONFIG_GUID \ +{0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}} + +extern EFI_GUID gSimicsX58PlatformConfigGuid; + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h new file mode 100644 index 0000000000..36c08176d1 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h @@ -0,0 +1,106 @@ +/** @file + Various register numbers and value bits based on the following publications: + - Intel(R) datasheet 319973-003 + - Intel(R) datasheet 319974-017US + + Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2014, Gabriel L. Somlo + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __X58_ICH10_H__ +#define __X58_ICH10_H__ + +#include + +// +// Host Bridge Device ID (DID) value for ICH10 +// +#define INTEL_ICH10_DEVICE_ID 0x3400 + +// +// B/D/F/Type: 0/0/0/PCI +// +#define DRAMC_REGISTER_Q35(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset)) +#define DRAMC_REGISTER_X58(Offset) PCI_LIB_ADDRESS (0, 20, 0, (Offset)) +#define MCH_GGC 0x52 +#define MCH_GGC_IVD BIT1 + +#define MCH_PCIEXBAR_LOW 0x10C +#define MCH_PCIEXBAR_LID 0x10E +#define MCH_PCIEXBAR_SHIFT 16 +#define MCH_PCIEXBAR_LOWMASK 0x0FFFFFFF +#define MCH_PCIEXBAR_BUS_FF 0 +#define MCH_PCIEXBAR_EN BIT0 + +#define MCH_PCIEXBAR_HIGH 0x64 +#define MCH_PCIEXBAR_HIGHMASK 0xFFFFFFF0 + +#define MCH_SMRAM 0x9D +#define MCH_SMRAM_D_LCK BIT4 +#define MCH_SMRAM_G_SMRAME BIT3 + +#define MCH_ESMRAMC 0x9E +#define MCH_ESMRAMC_H_SMRAME BIT7 +#define MCH_ESMRAMC_E_SMERR BIT6 +#define MCH_ESMRAMC_SM_CACHE BIT5 +#define MCH_ESMRAMC_SM_L1 BIT4 +#define MCH_ESMRAMC_SM_L2 BIT3 +#define MCH_ESMRAMC_TSEG_8MB BIT3 +#define MCH_ESMRAMC_TSEG_2MB BIT2 +#define MCH_ESMRAMC_TSEG_1MB BIT1 +#define MCH_ESMRAMC_TSEG_MASK (BIT3 | BIT2 | BIT1) +#define MCH_ESMRAMC_T_EN BIT0 + +#define MCH_GBSM 0xA4 +#define MCH_GBSM_MB_SHIFT 20 + +#define MCH_BGSM 0xA8 +#define MCH_BGSM_MB_SHIFT 20 + +#define MCH_TSEGMB 0xA8 +#define MCH_TSEGMB_MB_SHIFT 20 + +#define MCH_TOLUD 0xD0 + +// +// B/D/F/Type: 0/0x1f/0/PCI +// +#define POWER_MGMT_REGISTER_ICH10(Offset) \ + PCI_LIB_ADDRESS (0, 0x1f, 0, (Offset)) + +#define ICH10_PMBASE 0x40 +#define ICH10_PMBASE_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | \ + BIT10 | BIT9 | BIT8 | BIT7) + +#define ICH10_ACPI_CNTL 0x44 +#define ICH10_ACPI_CNTL_ACPI_EN BIT7 + +#define ICH10_GEN_PMCON_1 0xA0 +#define ICH10_GEN_PMCON_1_SMI_LOCK BIT4 + +#define ICH10_RCBA 0xF0 +#define ICH10_RCBA_EN BIT0 + +#define ICH10_PMBASE_IO 0x400 +// +// IO ports +// +#define ICH10_APM_CNT 0xB2 +#define ICH10_APM_STS 0xB3 + +// +// IO ports relative to PMBASE +// +#define ICH10_PMBASE_OFS_SMI_EN 0x30 +#define ICH10_SMI_EN_APMC_EN BIT5 +#define ICH10_SMI_EN_GBL_SMI_EN BIT0 +#define ICH10_SMI_EN_EOS BIT1 // End of SMI + +#define ICH10_PMBASE_OFS_SMI_STS 0x34 +#define ICH10_SMI_STS_APM BIT5 // APM Status + +#define ICH10_ROOT_COMPLEX_BASE 0xFED1C000 + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h new file mode 100644 index 0000000000..12aeb1227c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h @@ -0,0 +1,298 @@ +/** @file + EFI ISA ACPI Protocol is used to enumerate and manage all the ISA controllers on + the platform's ISA Bus. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ISA_ACPI_H_ +#define __ISA_ACPI_H_ + +/// +/// Global ID for the EFI ISA ACPI Protocol. +/// +#define EFI_ISA_ACPI_PROTOCOL_GUID \ + { \ + 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } \ + } + +/// +/// Forward declaration fo the EFI ISA ACPI Protocol +/// +typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL; + +/// +/// ISA ACPI Protocol interrupt resource attributes. +/// +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///< Edge triggered interrupt on a rising edge. +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///< Edge triggered interrupt on a falling edge. +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///< Level sensitive interrupt active high. +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///< Level sensitive interrupt active low. + +/// +/// ISA ACPI Protocol DMA resource attributes. +/// +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit mask of supported DMA speed attributes. +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///< ISA controller supports compatibility mode DMA transfers. +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA controller supports type A DMA transfers. +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA controller supports type B DMA transfers. +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA controller supports type F DMA transfers. +#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA controller increments DMA address by bytes (8-bit). +#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA controller increments DMA address by words (16-bit). +#define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA controller is a DMA bus master. +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA controller only supports 8-bit DMA transfers. +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40 ///< ISA controller both 8-bit and 16-bit DMA transfers. +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA controller only supports 16-bit DMA transfers. + +/// +/// ISA ACPI Protocol MMIO resource attributes +/// +#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit mask of supported ISA memory width attributes. +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA MMIO region only supports 8-bit access. +#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA MMIO region only supports 16-bit access. +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///< ISA MMIO region supports both 8-bit and 16-bit access. +#define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA MMIO region supports write transactions. +#define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA MMIO region supports being cached. +#define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA MMIO region may be shadowed. +#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA MMIO region is an expansion ROM. + +/// +/// ISA ACPI Protocol I/O resource attributes +/// +#define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA controllers uses a 10-bit address decoder for I/O cycles. +#define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA controllers uses a 16-bit address decoder for I/O cycles. + +/// +/// EFI ISA ACPI resource type +/// +typedef enum { + EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list. + EfiIsaAcpiResourceIo, ///< ISA I/O port resource range. + EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range. + EfiIsaAcpiResourceDma, ///< ISA DMA resource. + EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource. +} EFI_ISA_ACPI_RESOURCE_TYPE; + +/// +/// EFI ISA ACPI generic resource structure +/// +typedef struct { + EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O, MMIO, DMA, Interrupt). + UINT32 Attribute; ///< Bit mask of attributes associated with this resource. See EFI_ISA_ACPI_xxx macros for valid combinations. + UINT32 StartRange; ///< The start of the resource range. + UINT32 EndRange; ///< The end of the resource range. +} EFI_ISA_ACPI_RESOURCE; + +/// +/// EFI ISA ACPI resource device identifier +/// +typedef struct { + UINT32 HID; ///< The ACPI Hardware Identifier value associated with an ISA controller. Matchs ACPI DSDT contents. + UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA controller. Matches ACPI DSDT contents. +} EFI_ISA_ACPI_DEVICE_ID; + +/// +/// EFI ISA ACPI resource list +/// +typedef struct { + EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated with an ISA controller. + EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of resources associated with an ISA controller. +} EFI_ISA_ACPI_RESOURCE_LIST; + +/** + Enumerates the ISA controllers on an ISA bus. + + This service allows all the ISA controllers on an ISA bus to be enumerated. If + Device is a pointer to a NULL value, then the first ISA controller on the ISA + bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer + to a value that was returned on a prior call to DeviceEnumerate(), then the next + ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is returned. + If Device is a pointer to the last ISA controller on the ISA bus, then + EFI_NOT_FOUND is returned. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + @param[out] Device The pointer to an ISA controller named by ACPI HID/UID. + + @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned. + @retval EFI_NOT_FOUND No device found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)( + IN EFI_ISA_ACPI_PROTOCOL *This, + OUT EFI_ISA_ACPI_DEVICE_ID **Device + ); + +/** + Sets the power state of an ISA controller. + + This services sets the power state of the ISA controller specified by Device to + the power state specified by OnOff. TRUE denotes on, FALSE denotes off. + If the power state is sucessfully set on the ISA Controller, then + EFI_SUCCESS is returned. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. + @param[in] OnOff TRUE denotes on, FALSE denotes off. + + @retval EFI_SUCCESS Successfully set the power state of the ISA controller. + @retval Other The ISA controller could not be placed in the requested power state. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)( + IN EFI_ISA_ACPI_PROTOCOL *This, + IN EFI_ISA_ACPI_DEVICE_ID *Device, + IN BOOLEAN OnOff + ); + +/** + Retrieves the current set of resources associated with an ISA controller. + + Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently + assigned to the ISA controller specified by Device. These resources + are returned in ResourceList. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. + @param[out] ResourceList The pointer to the current resource list for Device. + + @retval EFI_SUCCESS Successfully retrieved the current resource list. + @retval EFI_NOT_FOUND The resource list could not be retrieved. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)( + IN EFI_ISA_ACPI_PROTOCOL *This, + IN EFI_ISA_ACPI_DEVICE_ID *Device, + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList + ); + +/** + Retrieves the set of possible resources that may be assigned to an ISA controller + with SetResource(). + + Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for the + ISA controller specified by Device. The sets are returned in ResourceList. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. + @param[out] ResourceList The pointer to the returned list of resource lists. + + @retval EFI_UNSUPPORTED This service is not supported. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)( + IN EFI_ISA_ACPI_PROTOCOL *This, + IN EFI_ISA_ACPI_DEVICE_ID *Device, + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList + ); + +/** + Assigns resources to an ISA controller. + + Assigns the I/O, MMIO, DMA, and interrupt resources specified by ResourceList + to the ISA controller specified by Device. ResourceList must match a resource list returned by GetPosResource() for the same ISA controller. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. + @param[in] ResourceList The pointer to a resources list that must be one of the + resource lists returned by GetPosResource() for the + ISA controller specified by Device. + + @retval EFI_SUCCESS Successfully set resources on the ISA controller. + @retval Other The resources could not be set for the ISA controller. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)( + IN EFI_ISA_ACPI_PROTOCOL *This, + IN EFI_ISA_ACPI_DEVICE_ID *Device, + IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList + ); + +/** + Enables or disables an ISA controller. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + @param[in] Device The pointer to the ISA controller to enable/disable. + @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the + ISA controller. + + @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller. + @retval Other The ISA controller could not be placed in the requested state. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)( + IN EFI_ISA_ACPI_PROTOCOL *This, + IN EFI_ISA_ACPI_DEVICE_ID *Device, + IN BOOLEAN Enable + ); + +/** + Initializes an ISA controller, so that it can be used. This service must be called + before SetResource(), EnableDevice(), or SetPower() will behave as expected. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. + + @retval EFI_SUCCESS Successfully initialized an ISA controller. + @retval Other The ISA controller could not be initialized. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)( + IN EFI_ISA_ACPI_PROTOCOL *This, + IN EFI_ISA_ACPI_DEVICE_ID *Device + ); + +/** + Initializes all the HW states required for the ISA controllers on the ISA bus + to be enumerated and managed by the rest of the services in this prorotol. + This service must be called before any of the other services in this + protocol will function as expected. + + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. + + @retval EFI_SUCCESS Successfully initialized all required hardware states. + @retval Other The ISA interface could not be initialized. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)( + IN EFI_ISA_ACPI_PROTOCOL *This + ); + +/// +/// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and manage +/// ISA controllers on an ISA bus. These services include the ability to initialize, +/// enable, disable, and manage the power state of ISA controllers. It also +/// includes services to query current resources, query possible resources, +/// and assign resources to an ISA controller. +/// +struct _EFI_ISA_ACPI_PROTOCOL { + EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate; + EFI_ISA_ACPI_SET_DEVICE_POWER SetPower; + EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource; + EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource; + EFI_ISA_ACPI_SET_RESOURCE SetResource; + EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice; + EFI_ISA_ACPI_INIT_DEVICE InitDevice; + EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit; +}; + +extern EFI_GUID gEfiIsaAcpiProtocolGuid; + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h new file mode 100644 index 0000000000..30000305fb --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h @@ -0,0 +1,356 @@ +/** @file + ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and DMA + operations on the ISA controllers they manage. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_ISA_IO_H_ +#define _EFI_ISA_IO_H_ + +#include + +/// +/// Global ID for the EFI_ISA_IO_PROTOCOL +/// +#define EFI_ISA_IO_PROTOCOL_GUID \ + { \ + 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +/// +/// Forward declaration for the EFI_ISA_IO_PROTOCOL. +/// +typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL; + +/// +/// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations. +/// +typedef enum { + EfiIsaIoWidthUint8 = 0, ///< 8-bit operation. + EfiIsaIoWidthUint16, ///< 16-bit operation. + EfiIsaIoWidthUint32, ///< 32-bit operation + EfiIsaIoWidthReserved, + EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation. + EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation. + EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation. + EfiIsaIoWidthFifoReserved, + EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation. + EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation. + EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation. + EfiIsaIoWidthFillReserved, + EfiIsaIoWidthMaximum +} EFI_ISA_IO_PROTOCOL_WIDTH; + +/// +/// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer allocations. +/// +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///< Map a memory range so write are combined. +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a memory range so all read and write accesses are cached. +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable a memory range. + +/// +/// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests +/// +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001 ///< Set the speed of the DMA transfer in compatible mode. +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///< Not supported. +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///< Not supported. +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///< Not supported. +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///< Request 8-bit DMA transfers. Only available on channels 0..3. +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///< Request 16-bit DMA transfers. Only available on channels 4..7. +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040 ///< Request a single DMA transfer. +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080 ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of Process). +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100 ///< Automatically reload base and count at the end of the DMA transfer. + +/// +/// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests. +/// +typedef enum { + /// + /// A read operation from system memory by a bus master. + /// + EfiIsaIoOperationBusMasterRead, + /// + /// A write operation to system memory by a bus master. + /// + EfiIsaIoOperationBusMasterWrite, + /// + /// Provides both read and write access to system memory by both the processor + /// and a bus master. The buffer is coherent from both the processor's and the + /// bus master's point of view. + /// + EfiIsaIoOperationBusMasterCommonBuffer, + /// + /// A read operation from system memory by a slave device. + /// + EfiIsaIoOperationSlaveRead, + /// + /// A write operation to system memory by a slave master. + /// + EfiIsaIoOperationSlaveWrite, + EfiIsaIoOperationMaximum +} EFI_ISA_IO_PROTOCOL_OPERATION; + +/** + Performs ISA I/O and MMIO Read/Write Cycles + + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. + @param[in] Width Specifies the width of the I/O or MMIO operation. + @param[in] Offset The offset into the ISA I/O or MMIO space to start the + operation. + @param[in] Count The number of I/O or MMIO operations to perform. + @param[in, out] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer to + write data from. + + @retval EFI_SUCCESS The data was successfully read from or written to the device. + @retval EFI_UNSUPPORTED The Offset is not valid for this device. + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)( + IN EFI_ISA_IO_PROTOCOL *This, + IN EFI_ISA_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +/// +/// Structure of functions for accessing ISA I/O and MMIO space. +/// +typedef struct { + /// + /// Read from ISA I/O or MMIO space. + /// + EFI_ISA_IO_PROTOCOL_IO_MEM Read; + /// + /// Write to ISA I/O or MMIO space. + /// + EFI_ISA_IO_PROTOCOL_IO_MEM Write; +} EFI_ISA_IO_PROTOCOL_ACCESS; + +/** + Copies data from one region of ISA MMIO space to another region of ISA + MMIO space. + + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. + @param[in] Width Specifies the width of the MMIO copy operation. + @param[in] DestOffset The offset of the destination in ISA MMIO space. + @param[in] SrcOffset The offset of the source in ISA MMIO space. + @param[in] Count The number tranfers to perform for this copy operation. + + @retval EFI_SUCCESS The data was copied sucessfully. + @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for this device. + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)( + IN EFI_ISA_IO_PROTOCOL *This, + IN EFI_ISA_IO_PROTOCOL_WIDTH Width, + IN UINT32 DestOffset, + IN UINT32 SrcOffset, + IN UINTN Count + ); + +/** + Maps a memory region for DMA. + + This function returns the device-specific addresses required to access system memory. + This function is used to map system memory for ISA DMA operations. All ISA DMA + operations must be performed through their mapped addresses, and such mappings must + be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is completed. + + If the DMA operation is a single read or write data transfer through an ISA bus + master, then EfiIsaIoOperationBusMasterRead or EfiIsaIoOperationBusMasterWrite + is used and the range is unmapped to complete the operation. If the DMA operation + is a single read or write data transfer through an ISA slave controller, then + EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the range + is unmapped to complete the operation. + + If performing a DMA read operation, all the data must be present in system memory before the Map() is performed. Similarly, + if performing a DMA write operation, the data must not be accessed in system + memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master operations that + require both read and write access or require multiple host device interactions + within the same mapped region must use EfiIsaIoOperationBusMasterCommonBuffer. + However, only memory allocated via the EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface + is guaranteed to be able to be mapped for this operation type. In all mapping + requests the NumberOfBytes returned may be less than originally requested. It is + the caller's responsibility to make additional requests to complete the entire + transfer. + + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. + @param[in] Operation Indicates the type of DMA (slave or bus master), + and if the DMA operation is going to read or + write to system memory. + @param[in] ChannelNumber The slave channel number to use for this DMA + operation. If Operation and ChannelAttributes + shows that this device performs bus mastering + DMA, then this field is ignored. The legal + range for this field is 0..7. + @param[in] ChannelAttributes A bitmask of the attributes used to configure + the slave DMA channel for this DMA operation. + See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the + legal bit combinations. + @param[in] HostAddress The system memory address to map to the device. + @param[in, out] NumberOfBytes On input the number of bytes to map. On + output the number of bytes that were mapped. + @param[out] DeviceAddress The resulting map address for the bus master + device to use to access the hosts HostAddress. + @param[out] Mapping A returned value that must be passed to into + EFI_ISA_IO_PROTOCOL.Unmap() to free all the the + resources associated with this map request. + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_INVALID_PARAMETER The Operation is undefined. + @retval EFI_INVALID_PARAMETER The HostAddress is undefined. + @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a common buffer. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)( + IN EFI_ISA_IO_PROTOCOL *This, + IN EFI_ISA_IO_PROTOCOL_OPERATION Operation, + IN UINT8 ChannelNumber OPTIONAL, + IN UINT32 ChannelAttributes, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +/** + Unmaps a memory region that was previously mapped with EFI_ISA_IO_PROTOCOL.Map(). + + The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any corresponding + resources are released. If the operation was EfiIsaIoOperationSlaveWrite + or EfiIsaIoOperationBusMasterWrite, the data is committed to system memory. + Any resources used for the mapping are freed. + + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. + @param[in] Mapping The mapping value returned from EFI_ISA_IO_PROTOCOL.Map(). + + @retval EFI_SUCCESS The memory region was unmapped. + @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)( + IN EFI_ISA_IO_PROTOCOL *This, + IN VOID *Mapping + ); + +/** + Allocates pages that are suitable for an EfiIsaIoOperationBusMasterCommonBuffer + mapping. + + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. + @param[in] Type The type allocation to perform. + @param[in] MemoryType The type of memory to allocate. + @param[in] Pages The number of pages to allocate. + @param[out] HostAddress A pointer to store the base address of the allocated range. + @param[in] Attributes The requested bit mask of attributes for the allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_INVALID_PARAMETER Type is invalid. + @retval EFI_INVALID_PARAMETER MemoryType is invalid. + @retval EFI_INVALID_PARAMETER HostAddress is NULL. + @retval EFI_UNSUPPORTED Attributes is unsupported. + @retval EFI_UNSUPPORTED The memory range specified by HostAddress, Pages, + and Type is not available for common buffer use. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)( + IN EFI_ISA_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ); + +/** + Frees a common buffer that was allocated with EFI_ISA_IO_PROTOCOL.AllocateBuffer(). + + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. + @param[in] Pages The number of pages to free from the previously allocated common buffer. + @param[in] HostAddress The base address of the previously allocated common buffer. + + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory was not allocated with EFI_ISA_IO.AllocateBufer(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)( + IN EFI_ISA_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ); + +/** + Flushes a DMA buffer, which forces all DMA posted write transactions to complete. + + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. + + @retval EFI_SUCCESS The DMA buffers were flushed. + @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)( + IN EFI_ISA_IO_PROTOCOL *This + ); + +/// +/// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA interfaces +/// used to abstract accesses to ISA controllers. There is one EFI_ISA_IO_PROTOCOL +/// instance for each ISA controller on a ISA bus. A device driver that wishes +/// to manage an ISA controller in a system will have to retrieve the +/// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller. +/// +struct _EFI_ISA_IO_PROTOCOL { + EFI_ISA_IO_PROTOCOL_ACCESS Mem; + EFI_ISA_IO_PROTOCOL_ACCESS Io; + EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem; + EFI_ISA_IO_PROTOCOL_MAP Map; + EFI_ISA_IO_PROTOCOL_UNMAP Unmap; + EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; + EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer; + EFI_ISA_IO_PROTOCOL_FLUSH Flush; + /// + /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the + /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL. + /// + EFI_ISA_ACPI_RESOURCE_LIST *ResourceList; + /// + /// The size, in bytes, of the ROM image. + /// + UINT32 RomSize; + /// + /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is responsible + /// for allocating memory for the ROM image, and copying the contents of the ROM to memory + /// during ISA Bus initialization. + /// + VOID *RomImage; +}; + +extern EFI_GUID gEfiIsaIoProtocolGuid; + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h new file mode 100644 index 0000000000..c38f2feba7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h @@ -0,0 +1,291 @@ +/** @file + This protocol abstracts the 8259 interrupt controller. This includes + PCI IRQ routing needed to program the PCI Interrupt Line register. + + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This protocol is defined in Framework for EFI Compatibility Support Module spec + Version 0.97. + +**/ + +#ifndef _EFI_LEGACY_8259_H_ +#define _EFI_LEGACY_8259_H_ + + +#define EFI_LEGACY_8259_PROTOCOL_GUID \ + { \ + 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1 } \ + } + +typedef struct _EFI_LEGACY_8259_PROTOCOL EFI_LEGACY_8259_PROTOCOL; + +typedef enum { + Efi8259Irq0, + Efi8259Irq1, + Efi8259Irq2, + Efi8259Irq3, + Efi8259Irq4, + Efi8259Irq5, + Efi8259Irq6, + Efi8259Irq7, + Efi8259Irq8, + Efi8259Irq9, + Efi8259Irq10, + Efi8259Irq11, + Efi8259Irq12, + Efi8259Irq13, + Efi8259Irq14, + Efi8259Irq15, + Efi8259IrqMax +} EFI_8259_IRQ; + +typedef enum { + Efi8259LegacyMode, + Efi8259ProtectedMode, + Efi8259MaxMode +} EFI_8259_MODE; + +/** + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for + the legacy mode mask and the protected mode mask. The base address for the 8259 + is different for legacy and protected mode, so two masks are required. + + @param This The protocol instance pointer. + @param MasterBase The base vector for the Master PIC in the 8259 controller. + @param SlaveBase The base vector for the Slave PIC in the 8259 controller. + + @retval EFI_SUCCESS The new bases were programmed. + @retval EFI_DEVICE_ERROR A device error occured programming the vector bases. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT8 MasterBase, + IN UINT8 SlaveBase + ); + +/** + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for + the legacy mode mask and the protected mode mask. The base address for the 8259 + is different for legacy and protected mode, so two masks are required. + + @param This The protocol instance pointer. + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15. + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15. + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. + + @retval EFI_SUCCESS 8259 status returned. + @retval EFI_DEVICE_ERROR Error reading 8259. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_GET_MASK)( + IN EFI_LEGACY_8259_PROTOCOL *This, + OUT UINT16 *LegacyMask, OPTIONAL + OUT UINT16 *LegacyEdgeLevel, OPTIONAL + OUT UINT16 *ProtectedMask, OPTIONAL + OUT UINT16 *ProtectedEdgeLevel OPTIONAL + ); + +/** + Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for + the legacy mode mask and the protected mode mask. The base address for the 8259 + is different for legacy and protected mode, so two masks are required. + Also set the edge/level masks. + + @param This The protocol instance pointer. + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15. + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15. + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. + + @retval EFI_SUCCESS 8259 status returned. + @retval EFI_DEVICE_ERROR Error writing 8259. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_SET_MASK)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT16 *LegacyMask, OPTIONAL + IN UINT16 *LegacyEdgeLevel, OPTIONAL + IN UINT16 *ProtectedMask, OPTIONAL + IN UINT16 *ProtectedEdgeLevel OPTIONAL + ); + +/** + Set the 8259 mode of operation. The base address for the 8259 is different for + legacy and protected mode. The legacy mode requires the master 8259 to have a + master base of 0x08 and the slave base of 0x70. The protected mode base locations + are not defined. Interrupts must be masked by the caller before this function + is called. The interrupt mask from the current mode is saved. The interrupt + mask for the new mode is Mask, or if Mask does not exist the previously saved + mask is used. + + @param This The protocol instance pointer. + @param Mode The mode of operation. i.e. the real mode or protected mode. + @param Mask Optional interupt mask for the new mode. + @param EdgeLevel Optional trigger mask for the new mode. + + @retval EFI_SUCCESS 8259 programmed. + @retval EFI_DEVICE_ERROR Error writing to 8259. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_SET_MODE)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_MODE Mode, + IN UINT16 *Mask, OPTIONAL + IN UINT16 *EdgeLevel OPTIONAL + ); + +/** + Convert from IRQ to processor interrupt vector number. + + @param This The protocol instance pointer. + @param Irq 8259 IRQ0 - IRQ15. + @param Vector The processor vector number that matches an Irq. + + @retval EFI_SUCCESS The Vector matching Irq is returned. + @retval EFI_INVALID_PARAMETER The Irq not valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_GET_VECTOR)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + OUT UINT8 *Vector + ); + +/** + Enable Irq by unmasking interrupt in 8259 + + @param This The protocol instance pointer. + @param Irq 8259 IRQ0 - IRQ15. + @param LevelTriggered TRUE if level triggered. FALSE if edge triggered. + + @retval EFI_SUCCESS The Irq was enabled on 8259. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + IN BOOLEAN LevelTriggered + ); + +/** + Disable Irq by masking interrupt in 8259 + + @param This The protocol instance pointer. + @param Irq 8259 IRQ0 - IRQ15. + + @retval EFI_SUCCESS The Irq was disabled on 8259. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq + ); + +/** + PciHandle represents a PCI config space of a PCI function. Vector + represents Interrupt Pin (from PCI config space) and it is the data + that is programmed into the Interrupt Line (from the PCI config space) + register. + + @param This The protocol instance pointer. + @param PciHandle The PCI function to return the vector for. + @param Vector The vector for the function it matches. + + @retval EFI_SUCCESS A valid Vector was returned. + @retval EFI_INVALID_PARAMETER PciHandle not valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_HANDLE PciHandle, + OUT UINT8 *Vector + ); + +/** + Send an EOI to 8259 + + @param This The protocol instance pointer. + @param Irq 8259 IRQ0 - IRQ15. + + @retval EFI_SUCCESS EOI was successfully sent to 8259. + @retval EFI_INVALID_PARAMETER The Irq isnot valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq + ); + +/** + @par Protocol Description: + Abstracts the 8259 and APIC hardware control between EFI usage and + Compatibility16 usage. + + @param SetVectorBase + Sets the vector bases for master and slave PICs. + + @param GetMask + Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected mode. + + @param SetMask + Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected mode. + + @param SetMode + Sets PIC mode to 16-bit real mode or 32-bit protected mode. + + @param GetVector + Gets the base vector assigned to an IRQ. + + @param EnableIrq + Enables an IRQ. + + @param DisableIrq + Disables an IRQ. + + @param GetInterruptLine + Gets an IRQ that is assigned to a PCI device. + + @param EndOfInterrupt + Issues the end of interrupt command. + +**/ +struct _EFI_LEGACY_8259_PROTOCOL { + EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase; + EFI_LEGACY_8259_GET_MASK GetMask; + EFI_LEGACY_8259_SET_MASK SetMask; + EFI_LEGACY_8259_SET_MODE SetMode; + EFI_LEGACY_8259_GET_VECTOR GetVector; + EFI_LEGACY_8259_ENABLE_IRQ EnableIrq; + EFI_LEGACY_8259_DISABLE_IRQ DisableIrq; + EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine; + EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt; +}; + +extern EFI_GUID gEfiLegacy8259ProtocolGuid; + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h new file mode 100644 index 0000000000..640ac4943d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h @@ -0,0 +1,178 @@ +/** @file +SMRAM Save State Map Definitions. + +SMRAM Save State Map definitions based on contents of the +Intel(R) 64 and IA-32 Architectures Software Developer's Manual + Volume 3C, Section 34.4 SMRAM + Volume 3C, Section 34.5 SMI Handler Execution Environment + Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs + +and the AMD64 Architecture Programmer's Manual + Volume 2, Section 10.2 SMM Resources + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2015, Red Hat, Inc.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__ +#define __X58_SMRAM_SAVE_STATE_MAP_H__ + +#pragma pack (1) + +/// +/// 32-bit SMRAM Save State Map +/// +typedef struct { + UINT8 Reserved0[0x200]; // 7c00h + UINT8 Reserved1[0xf8]; // 7e00h + UINT32 SMBASE; // 7ef8h + UINT32 SMMRevId; // 7efch + UINT16 IORestart; // 7f00h + UINT16 AutoHALTRestart; // 7f02h + UINT8 Reserved2[0x9C]; // 7f08h + UINT32 IOMemAddr; // 7fa0h + UINT32 IOMisc; // 7fa4h + UINT32 _ES; // 7fa8h + UINT32 _CS; // 7fach + UINT32 _SS; // 7fb0h + UINT32 _DS; // 7fb4h + UINT32 _FS; // 7fb8h + UINT32 _GS; // 7fbch + UINT32 Reserved3; // 7fc0h + UINT32 _TR; // 7fc4h + UINT32 _DR7; // 7fc8h + UINT32 _DR6; // 7fcch + UINT32 _EAX; // 7fd0h + UINT32 _ECX; // 7fd4h + UINT32 _EDX; // 7fd8h + UINT32 _EBX; // 7fdch + UINT32 _ESP; // 7fe0h + UINT32 _EBP; // 7fe4h + UINT32 _ESI; // 7fe8h + UINT32 _EDI; // 7fech + UINT32 _EIP; // 7ff0h + UINT32 _EFLAGS; // 7ff4h + UINT32 _CR3; // 7ff8h + UINT32 _CR0; // 7ffch +} X58_SMRAM_SAVE_STATE_MAP32; + +/// +/// 64-bit SMRAM Save State Map +/// +typedef struct { + UINT8 Reserved0[0x200]; // 7c00h + + UINT16 _ES; // 7e00h + UINT16 _ESAccessRights; // 7e02h + UINT32 _ESLimit; // 7e04h + UINT64 _ESBase; // 7e08h + + UINT16 _CS; // 7e10h + UINT16 _CSAccessRights; // 7e12h + UINT32 _CSLimit; // 7e14h + UINT64 _CSBase; // 7e18h + + UINT16 _SS; // 7e20h + UINT16 _SSAccessRights; // 7e22h + UINT32 _SSLimit; // 7e24h + UINT64 _SSBase; // 7e28h + + UINT16 _DS; // 7e30h + UINT16 _DSAccessRights; // 7e32h + UINT32 _DSLimit; // 7e34h + UINT64 _DSBase; // 7e38h + + UINT16 _FS; // 7e40h + UINT16 _FSAccessRights; // 7e42h + UINT32 _FSLimit; // 7e44h + UINT64 _FSBase; // 7e48h + + UINT16 _GS; // 7e50h + UINT16 _GSAccessRights; // 7e52h + UINT32 _GSLimit; // 7e54h + UINT64 _GSBase; // 7e58h + + UINT32 _GDTRReserved1; // 7e60h + UINT16 _GDTRLimit; // 7e64h + UINT16 _GDTRReserved2; // 7e66h + UINT64 _GDTRBase; // 7e68h + + UINT16 _LDTR; // 7e70h + UINT16 _LDTRAccessRights; // 7e72h + UINT32 _LDTRLimit; // 7e74h + UINT64 _LDTRBase; // 7e78h + + UINT32 _IDTRReserved1; // 7e80h + UINT16 _IDTRLimit; // 7e84h + UINT16 _IDTRReserved2; // 7e86h + UINT64 _IDTRBase; // 7e88h + + UINT16 _TR; // 7e90h + UINT16 _TRAccessRights; // 7e92h + UINT32 _TRLimit; // 7e94h + UINT64 _TRBase; // 7e98h + + UINT64 IO_RIP; // 7ea0h + UINT64 IO_RCX; // 7ea8h + UINT64 IO_RSI; // 7eb0h + UINT64 IO_RDI; // 7eb8h + UINT32 IO_DWord; // 7ec0h + UINT8 Reserved1[0x04]; // 7ec4h + UINT8 IORestart; // 7ec8h + UINT8 AutoHALTRestart; // 7ec9h + UINT8 Reserved2[0x06]; // 7ecah + + UINT64 IA32_EFER; // 7ed0h + UINT64 SVM_Guest; // 7ed8h + UINT64 SVM_GuestVMCB; // 7ee0h + UINT64 SVM_GuestVIntr; // 7ee8h + UINT8 Reserved3[0x0c]; // 7ef0h + + UINT32 SMMRevId; // 7efch + UINT32 SMBASE; // 7f00h + + UINT8 Reserved4[0x1c]; // 7f04h + UINT64 SVM_GuestPAT; // 7f20h + UINT64 SVM_HostIA32_EFER; // 7f28h + UINT64 SVM_HostCR4; // 7f30h + UINT64 SVM_HostCR3; // 7f38h + UINT64 SVM_HostCR0; // 7f40h + + UINT64 _CR4; // 7f48h + UINT64 _CR3; // 7f50h + UINT64 _CR0; // 7f58h + UINT64 _DR7; // 7f60h + UINT64 _DR6; // 7f68h + UINT64 _RFLAGS; // 7f70h + UINT64 _RIP; // 7f78h + UINT64 _R15; // 7f80h + UINT64 _R14; // 7f88h + UINT64 _R13; // 7f90h + UINT64 _R12; // 7f98h + UINT64 _R11; // 7fa0h + UINT64 _R10; // 7fa8h + UINT64 _R9; // 7fb0h + UINT64 _R8; // 7fb8h + UINT64 _RDI; // 7fc0h + UINT64 _RSI; // 7fc8h + UINT64 _RBP; // 7fd0h + UINT64 _RSP; // 7fd8h + UINT64 _RBX; // 7fe0h + UINT64 _RDX; // 7fe8h + UINT64 _RCX; // 7ff0h + UINT64 _RAX; // 7ff8h +} X58_SMRAM_SAVE_STATE_MAP64; + +/// +/// Union of 32-bit and 64-bit SMRAM Save State Maps +/// +typedef union { + X58_SMRAM_SAVE_STATE_MAP32 x86; + X58_SMRAM_SAVE_STATE_MAP64 x64; +} X58_SMRAM_SAVE_STATE_MAP; + +#pragma pack () + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h new file mode 100644 index 0000000000..c79111d811 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h @@ -0,0 +1,54 @@ +/** @file + OVMF Platform definitions + + Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2014, Gabriel L. Somlo + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __OVMF_PLATFORMS_H__ +#define __OVMF_PLATFORMS_H__ + +#include +#include +#include +#include // TODO: remove + +// +// Simics Host Bridge DID Address +// +#define SIMICS_HOSTBRIDGE_DID \ + PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET) + +// +// Simics SideBand PCI device registers +// +#define SIMICS_SIDEBANDPCI_DEV 0 +#define SIMICS_SIDEBANDPCI_FUNC 7 +#define SIMICS_SIDEBANDPCI_SVID \ + PCI_LIB_ADDRESS (0, 0, 7, PCI_SVID_OFFSET) +#define SIMICS_SIDEBANDPCI_SDID \ + PCI_LIB_ADDRESS (0, 0, 7, PCI_SID_OFFSET) +#define SIMICS_SIDEBANDPCI_CAP \ + PCI_LIB_ADDRESS (0, 0, 7, PCI_CAPBILITY_POINTER_OFFSET) +#define SIMICS_SIDEBANDPCI_CAP_Offset 0x40 +#define SIMICS_SIDEBANDPCI_CAP_ID 0xFF + +// +// Values we program into the PM base address registers +// +#define PIIX4_PMBA_VALUE 0xB000 +#define ICH10_PMBASE_VALUE 0x0400 + +// +// Common bits in same-purpose registers +// +#define PMBA_RTE BIT0 + +// +// Common IO ports relative to the Power Management Base Address +// +#define ACPI_TIMER_OFFSET 0x8 + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm new file mode 100644 index 0000000000..3f3cd33c8a --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm @@ -0,0 +1,41 @@ +; @file +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; + + SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; JumpToKernel ( +; VOID *KernelStart, +; VOID *KernelBootParams +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(JumpToKernel) +ASM_PFX(JumpToKernel): + + mov esi, [esp + 8] + call DWORD [esp + 4] + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; JumpToUefiKernel ( +; EFI_HANDLE ImageHandle, +; EFI_SYSTEM_TABLE *SystemTable, +; VOID *KernelBootParams, +; VOID *KernelStart +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(JumpToUefiKernel) +ASM_PFX(JumpToUefiKernel): + + mov eax, [esp + 12] + mov eax, [eax + 0x264] + add eax, [esp + 16] + jmp eax + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h new file mode 100644 index 0000000000..c4cc4dd8e7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h @@ -0,0 +1,52 @@ +/** @file + Boot UEFI Linux. + + Copyright (c) 2008 - 2013 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _LOAD_LINUX_LIB_INCLUDED_ +#define _LOAD_LINUX_LIB_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +VOID +EFIAPI +JumpToKernel ( + VOID *KernelStart, + VOID *KernelBootParams + ); + +VOID +EFIAPI +JumpToUefiKernel ( + EFI_HANDLE ImageHandle, + EFI_SYSTEM_TABLE *SystemTable, + VOID *KernelBootParams, + VOID *KernelStart + ); + +VOID +InitLinuxDescriptorTables ( + VOID + ); + +VOID +SetLinuxDescriptorTables ( + VOID + ); + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf new file mode 100644 index 0000000000..89664f4e42 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf @@ -0,0 +1,42 @@ +## @file +# +# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = LoadLinuxLib + FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = LoadLinuxLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + Linux.c + LinuxGdt.c + +[Sources.IA32] + Ia32/JumpToKernel.nasm + +[Sources.X64] + X64/JumpToKernel.nasm + +[Packages] + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + MemoryAllocationLib + BaseMemoryLib + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm new file mode 100644 index 0000000000..79e6b8e7ba --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm @@ -0,0 +1,85 @@ +; @file +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; JumpToKernel ( +; VOID *KernelStart, // rcx +; VOID *KernelBootParams // rdx +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(JumpToKernel) +ASM_PFX(JumpToKernel): + + ; Set up for executing kernel. BP in %esi, entry point on the stack + ; (64-bit when the 'ret' will use it as 32-bit, but we're little-endian) + mov rsi, rdx + push rcx + + ; Jump into the compatibility mode CS + push 0x10 + lea rax, [.0] + push rax + DB 0x48, 0xcb ; retfq + +.0: + ; Now in compatibility mode. + + DB 0xb8, 0x18, 0x0, 0x0, 0x0 ; movl $0x18, %eax + DB 0x8e, 0xd8 ; movl %eax, %ds + DB 0x8e, 0xc0 ; movl %eax, %es + DB 0x8e, 0xe0 ; movl %eax, %fs + DB 0x8e, 0xe8 ; movl %eax, %gs + DB 0x8e, 0xd0 ; movl %eax, %ss + + ; Disable paging + DB 0xf, 0x20, 0xc0 ; movl %cr0, %eax + DB 0xf, 0xba, 0xf8, 0x1f ; btcl $31, %eax + DB 0xf, 0x22, 0xc0 ; movl %eax, %cr0 + + ; Disable long mode in EFER + DB 0xb9, 0x80, 0x0, 0x0, 0xc0 ; movl $0x0c0000080, %ecx + DB 0xf, 0x32 ; rdmsr + DB 0xf, 0xba, 0xf8, 0x8 ; btcl $8, %eax + DB 0xf, 0x30 ; wrmsr + + ; Disable PAE + DB 0xf, 0x20, 0xe0 ; movl %cr4, %eax + DB 0xf, 0xba, 0xf8, 0x5 ; btcl $5, %eax + DB 0xf, 0x22, 0xe0 ; movl %eax, %cr4 + + DB 0x31, 0xed ; xor %ebp, %ebp + DB 0x31, 0xff ; xor %edi, %edi + DB 0x31, 0xdb ; xor %ebx, %ebx + DB 0xc3 ; ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; JumpToUefiKernel ( +; EFI_HANDLE ImageHandle, // rcx +; EFI_SYSTEM_TABLE *SystemTable, // rdx +; VOID *KernelBootParams // r8 +; VOID *KernelStart, // r9 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(JumpToUefiKernel) +ASM_PFX(JumpToUefiKernel): + + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + xor rax, rax + mov eax, [r8 + 0x264] + add r9, rax + add r9, 0x200 + call r9 + ret + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h new file mode 100644 index 0000000000..92aa038cdd --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h @@ -0,0 +1,55 @@ +/** @file + Save Non-Volatile Variables to a file system. + + Copyright (c) 2009 - 2011 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __NV_VARS_FILE_LIB_INSTANCE__ +#define __NV_VARS_FILE_LIB_INSTANCE__ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +/** + Loads the non-volatile variables from the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +LoadNvVarsFromFs ( + EFI_HANDLE FsHandle + ); + + +/** + Saves the non-volatile variables into the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +SaveNvVarsToFs ( + EFI_HANDLE FsHandle + ); + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf new file mode 100644 index 0000000000..e4c3b7ccff --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf @@ -0,0 +1,53 @@ +## @file +# NvVarsFileLib +# +# This library saves and restores non-volatile variables in a +# file within a file system. +# +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = NvVarsFileLib + FILE_GUID = 8ECD4CC0-1772-4583-8A74-83633A15FAA0 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NvVarsFileLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + FsAccess.c + NvVarsFileLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + FileHandleLib + MemoryAllocationLib + SerializeVariablesLib + +[Protocols] + gEfiSimpleFileSystemProtocolGuid ## CONSUMES + +[Guids] + gEfiFileInfoGuid + +[Depex] + gEfiVariableWriteArchProtocolGuid + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h new file mode 100644 index 0000000000..7e78cd4b21 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h @@ -0,0 +1,33 @@ +/** @file + Serialize Variables Library implementation + + Copyright (c) 2009 - 2011 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __SERIALIZE_VARIABLES_LIB_INSTANCE__ +#define __SERIALIZE_VARIABLES_LIB_INSTANCE__ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SV_FROM_HANDLE(a) CR (a, SV_INSTANCE, Signature, SV_SIGNATURE) +#define SV_SIGNATURE SIGNATURE_32 ('S', 'V', 'A', 'R') + +typedef struct { + UINT32 Signature; + VOID *BufferPtr; + UINTN BufferSize; + UINTN DataSize; +} SV_INSTANCE; + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf new file mode 100644 index 0000000000..25901192b2 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf @@ -0,0 +1,36 @@ +## @file +# Serialize Variables Library implementation +# +# This library serializes and deserializes UEFI variables +# +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeSerializeVariablesLib + FILE_GUID = 266A1434-6B22-441F-A8D2-D54AA8FDF95C + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerializeVariablesLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER + +[Sources] + SerializeVariablesLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h new file mode 100644 index 0000000000..63b5e52575 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h @@ -0,0 +1,37 @@ +/** @file + This driver effectuates OVMF's platform configuration settings and exposes + them via HII. + + Copyright (C) 2014, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +// +// Macro and type definitions that connect the form with the HII driver code. +// +#define FORMSTATEID_MAIN_FORM 1 +#define FORMID_MAIN_FORM 1 + +#define QUESTION_RES_CUR 1 +#define MAXSIZE_RES_CUR 16 + +#define LABEL_RES_NEXT 1 +#define QUESTION_RES_NEXT 2 + +#define QUESTION_SAVE_EXIT 3 +#define QUESTION_DISCARD_EXIT 4 + +// +// This structure describes the form state. Its fields relate strictly to the +// visual widgets on the form. +// +typedef struct { + UINT16 CurrentPreferredResolution[MAXSIZE_RES_CUR]; + UINT32 NextPreferredResolution; +} MAIN_FORM_STATE; + +#endif // _PLATFORM_H_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf new file mode 100644 index 0000000000..804ab59610 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf @@ -0,0 +1,65 @@ +## @file +# This driver effectuates Simics X58 platform configuration settings and exposes +# them via HII. +# +# Copyright (C) 2014, Red Hat, Inc. +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformDxe + FILE_GUID = 74B64DC1-B0B6-4853-A6BD-C6426059AB1E + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = PlatformInit + UNLOAD_IMAGE = PlatformUnload + +[Sources] + Platform.c + Platform.uni + PlatformConfig.c + PlatformForms.vfr + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + HiiLib + MemoryAllocationLib + PrintLib + UefiBootServicesTableLib + UefiHiiServicesLib + UefiLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + DxeServicesTableLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution + +[Protocols] + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiGraphicsOutputProtocolGuid ## CONSUMES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + +[Guids] + gEfiIfrTianoGuid + gSimicsX58PlatformConfigGuid + +[Depex] + gEfiHiiConfigRoutingProtocolGuid AND + gEfiHiiDatabaseProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni new file mode 100644 index 0000000000..6d68cbeb4f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni @@ -0,0 +1,31 @@ +// *++ +// +// Copyright (C) 2014, Red Hat, Inc. +// Copyright (c) 2009, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// Platform.uni +// +// Abstract: +// +// String definitions for PlatformForms.vfr +// +// --*/ + +/=# + +#langdef en-US "English" + +#string STR_FORMSET_TITLE #language en-US "QSP Platform Configuration" +#string STR_FORMSET_HELP #language en-US "Change various QSP platform settings." +#string STR_MAIN_FORM_TITLE #language en-US "QSP Settings" +#string STR_RES_CUR #language en-US "Preferred Resolution at Next Boot" +#string STR_RES_CUR_HELP #language en-US "The preferred resolution of the Graphics Console at next boot. It might be unset, or even invalid (hence ignored) wrt. the video RAM size." +#string STR_RES_NEXT #language en-US "Change Preferred Resolution for Next Boot" +#string STR_RES_NEXT_HELP #language en-US "You can specify a new preference for the Graphics Console here. The list is filtered against the video RAM size." +#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit" +#string STR_DISCARD_EXIT #language en-US "Discard Changes and Exit" + diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h new file mode 100644 index 0000000000..d3f041ddea --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h @@ -0,0 +1,51 @@ +/** @file + Utility functions for serializing (persistently storing) and deserializing + OVMF's platform configuration. + + Copyright (C) 2014, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_CONFIG_H_ +#define _PLATFORM_CONFIG_H_ + +#include + +// +// This structure participates in driver configuration. It does not +// (necessarily) reflect the wire format in the persistent store. +// +#pragma pack(1) +typedef struct { + // + // preferred graphics console resolution when booting + // + UINT32 HorizontalResolution; + UINT32 VerticalResolution; +} PLATFORM_CONFIG; +#pragma pack() + +// +// Please see the API documentation near the function definitions. +// +EFI_STATUS +EFIAPI +PlatformConfigSave ( + IN PLATFORM_CONFIG *PlatformConfig + ); + +EFI_STATUS +EFIAPI +PlatformConfigLoad ( + OUT PLATFORM_CONFIG *PlatformConfig, + OUT UINT64 *OptionalElements + ); + +// +// Feature flags for OptionalElements. +// +#define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0 +#define PLATFORM_CONFIG_F_DOWNGRADE BIT63 + +#endif // _PLATFORM_CONFIG_H_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr new file mode 100644 index 0000000000..1c02565ebb --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr @@ -0,0 +1,67 @@ +// *++ +// +// Copyright (C) 2014, Red Hat, Inc. +// Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// PlatformForms.vfr +// +// Abstract: +// +// Form definitions for exposing some of OVMF's platform knobs via HII. +// +// --*/ + +#include +#include "Platform.h" + +formset + guid = SIMICSX58_PLATFORM_CONFIG_GUID, + title = STRING_TOKEN(STR_FORMSET_TITLE), + help = STRING_TOKEN(STR_FORMSET_HELP), + + varstore MAIN_FORM_STATE, + varid = FORMSTATEID_MAIN_FORM, + name = MainFormState, + guid = SIMICSX58_PLATFORM_CONFIG_GUID; + + form + formid = FORMID_MAIN_FORM, + title = STRING_TOKEN(STR_MAIN_FORM_TITLE); + + // + // Display the current preference in a read-only string field. + // + string + varid = MainFormState.CurrentPreferredResolution, + questionid = QUESTION_RES_CUR, + prompt = STRING_TOKEN(STR_RES_CUR), + help = STRING_TOKEN(STR_RES_CUR_HELP), + flags = READ_ONLY, + minsize = 0, + maxsize = MAXSIZE_RES_CUR, + endstring; + + // + // We'll dynamically generate a one-of-many selection at this label. + // + label LABEL_RES_NEXT; + + text + help = STRING_TOKEN(STR_SAVE_EXIT), + text = STRING_TOKEN(STR_SAVE_EXIT), + flags = INTERACTIVE, + key = QUESTION_SAVE_EXIT; + + text + help = STRING_TOKEN(STR_DISCARD_EXIT), + text = STRING_TOKEN(STR_DISCARD_EXIT), + flags = INTERACTIVE, + key = QUESTION_DISCARD_EXIT; + + endform; + +endformset; diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h new file mode 100644 index 0000000000..616d2d74cb --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h @@ -0,0 +1,50 @@ +/** @file + PC/AT CMOS access routines + + Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __CMOS_H__ +#define __CMOS_H__ + +/** + Reads 8-bits of CMOS data. + + Reads the 8-bits of CMOS data at the location specified by Index. + The 8-bit read value is returned. + + @param Index The CMOS location to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +CmosRead8 ( + IN UINTN Index + ); + +/** + Writes 8-bits of CMOS data. + + Writes 8-bits of CMOS data to the location specified by Index + with the value specified by Value and returns Value. + + @param Index The CMOS location to write. + @param Value The value to write to CMOS. + + @return The value written to CMOS. + +**/ +UINT8 +EFIAPI +CmosWrite8 ( + IN UINTN Index, + IN UINT8 Value + ); + + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h new file mode 100644 index 0000000000..5b1a9b5f57 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h @@ -0,0 +1,93 @@ +/** @file + Platform PEI module include file. + + Copyright (c) 2006 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_PEI_H_INCLUDED_ +#define _PLATFORM_PEI_H_INCLUDED_ + +VOID +AddIoMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); + +VOID +AddIoMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ); + +VOID +AddMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); + +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ); + +VOID +AddUntestedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); + +VOID +AddReservedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize, + BOOLEAN Cacheable + ); + +VOID +AddressWidthInitialization ( + VOID + ); + +VOID +X58TsegMbytesInitialization ( + VOID + ); + +EFI_STATUS +PublishPeiMemory ( + VOID + ); + +UINT32 +GetSystemMemorySizeBelow4gb ( + VOID + ); + +VOID +InitializeRamRegions ( + VOID + ); + +EFI_STATUS +PeiFvInitialization ( + VOID + ); + +VOID +InstallFeatureControlCallback ( + VOID + ); + +extern EFI_BOOT_MODE mBootMode; + +extern BOOLEAN mS3Supported; + +extern UINT8 mPhysMemAddressWidth; + +extern UINT32 mMaxCpuCount; + +extern UINT16 mHostBridgeDevId; +#endif // _PLATFORM_PEI_H_INCLUDED_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf new file mode 100644 index 0000000000..eb8048c655 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf @@ -0,0 +1,109 @@ +## @file +# Platform PEI driver +# +# This module provides platform specific function to detect boot mode. +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformPei + FILE_GUID = 05116218-f9f1-41f8-8d17-c2207006ffff + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = InitializePlatform + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Cmos.c + FeatureControl.c + Fv.c + MemDetect.c + Platform.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + OvmfPkg/OvmfPkg.dec + +[Guids] + gEfiMemoryTypeInformationGuid + gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES + +[LibraryClasses] + BaseLib + DebugLib + HobLib + IoLib + PciLib + PeiResourcePublicationLib + PeiServicesLib + PeiServicesTablePointerLib + PeimEntryPoint + MtrrLib + PcdLib + +[Pcd] + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdIoApicId + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + + +[Ppis] + gEfiPeiMasterBootModePpiGuid + gEfiPeiMpServicesPpiGuid + +[Depex] + TRUE + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf new file mode 100644 index 0000000000..b9bcb5d2bd --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf @@ -0,0 +1,38 @@ +## @file +# +# Copyright (c) 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SiliconPolicyInitLib + FILE_GUID = B494DF39-A5F8-48A1-B2D0-EF523AD91C55 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SiliconPolicyInitLib + +[Sources] + SiliconPolicyInitLib.c + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseMemoryLib + BaseLib + DebugLib + DebugPrintErrorLevelLib + HobLib + IoLib + MemoryAllocationLib + PeiServicesLib + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf new file mode 100644 index 0000000000..da165ac947 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf @@ -0,0 +1,35 @@ +## @file +# +# Copyright (c) 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SiliconPolicyUpdateLib + FILE_GUID = 6EA9585C-3C15-47da-9FFC-25E9E4EA4D0C + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SiliconPolicyUpdateLib + +[Sources] + SiliconPolicyUpdateLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + HobLib + IoLib + PcdLib + +[Pcd] + +[FixedPcd] + +[Ppis] + +[Guids] diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec new file mode 100644 index 0000000000..17c87aca8c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec @@ -0,0 +1,168 @@ +## @file +# EFI/Framework Simics X58 platform +# +# Copyright (c) 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = SimicsX58Pkg + PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[Guids] + gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}} + gSimicsX58PlatformConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}} + +[Protocols] + gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}} + gEfiIsaAcpiProtocolGuid = {0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55}} + gEfiIsaIoProtocolGuid = {0x7ee2bd44, 0x3da0, 0x11d4, {0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}} + +[PcdsFixedAtBuild] + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16 + + #TODO: Remove these two when we integrate new PlatformPei + gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3 + + ## The following setting controls how many megabytes we configure as TSEG on + # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other values cause + # undefined behavior. + # + # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below). + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20 + + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UINT32|0x8 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UINT32|0x9 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UINT32|0xc + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UINT32|0xd + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x11 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x12 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0x13 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x14 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x18 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x19 + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT32|0x1f + +[PcdsDynamic, PcdsDynamicEx] + + # TODO: investigate whether next two Pcds are needed + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28 + gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0x1b + + ## The IO port aperture shared by all PCI root bridges. + # + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22 + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23 + + ## The 32-bit MMIO aperture shared by all PCI root bridges. + # + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24 + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25 + + ## The 64-bit MMIO aperture shared by all PCI root bridges. + # + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26 + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27 + +[PcdsFeatureFlag] + ## This feature flag enables SMM/SMRAM support. Note that it also requires + # such support from the underlying QEMU instance; if that support is not + # present, the firmware will reject continuing after a certain point. + # + # The flag also acts as a general "security switch"; when TRUE, many + # components will change behavior, with the goal of preventing a malicious + # runtime OS from tampering with firmware structures (special memory ranges + # used by OVMF, the varstore pflash chip, LockBox etc). + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e + + +[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule] + ## Pcd8259LegacyModeMask defines the default mask value for platform. This value is determined

+ # 1) If platform only support pure UEFI, value should be set to 0xFFFF or 0xFFFE; + # Because only clock interrupt is allowed in legacy mode in pure UEFI platform.
+ # 2) If platform install CSM and use thunk module:
+ # a) If thunk call provided by CSM binary requires some legacy interrupt support, the corresponding bit + # should be opened as 0.
+ # For example, if keyboard interfaces provided CSM binary use legacy keyboard interrupt in 8259 bit 1, then + # the value should be set to 0xFFFC.
+ # b) If all thunk call provied by CSM binary do not require legacy interrupt support, value should be set + # to 0xFFFF or 0xFFFE.
+ # + # The default value of legacy mode mask could be changed by EFI_LEGACY_8259_PROTOCOL->SetMask(). But it is rarely + # need change it except some special cases such as when initializing the CSM binary, it should be set to 0xFFFF to + # mask all legacy interrupt. Please restore the original legacy mask value if changing is made for these special case.
+ # @Prompt 8259 Legacy Mode mask. + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16|0x00000001 + + ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy mode's interrrupt controller. + # For the corresponding bits, 0 = Edge triggered and 1 = Level triggered. + # @Prompt 8259 Legacy Mode edge level. + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UINT16|0x00000002 + + ## Indicates if we need enable IsaAcpiCom1 device.

+ # TRUE - Enables IsaAcpiCom1 device.
+ # FALSE - Doesn't enable IsaAcpiCom1 device.
+ # @Prompt Enable IsaAcpiCom1 device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable|TRUE|BOOLEAN|0x00000003 + + ## Indicates if we need enable IsaAcpiCom2 device.

+ # TRUE - Enables IsaAcpiCom2 device.
+ # FALSE - Doesn't enable IsaAcpiCom2 device.
+ # @Prompt Enable IsaAcpiCom12 device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable|TRUE|BOOLEAN|0x00000004 + + ## Indicates if we need enable IsaAcpiPs2Keyboard device.

+ # TRUE - Enables IsaAcpiPs2Keyboard device.
+ # FALSE - Doesn't enable IsaAcpiPs2Keyboard device.
+ # @Prompt Enable IsaAcpiPs2Keyboard device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable|TRUE|BOOLEAN|0x00000005 + + ## Indicates if we need enable IsaAcpiPs2Mouse device.

+ # TRUE - Enables IsaAcpiPs2Mouse device.
+ # FALSE - Doesn't enable IsaAcpiPs2Mouse device.
+ # @Prompt Enable IsaAcpiPs2Mouse device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable|TRUE|BOOLEAN|0x00000006 + + ## Indicates if we need enable IsaAcpiFloppyA device.

+ # TRUE - Enables IsaAcpiFloppyA device.
+ # FALSE - Doesn't enable IsaAcpiFloppyA device.
+ # @Prompt Enable IsaAcpiFloppyA device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable|TRUE|BOOLEAN|0x00000007 + + ## Indicates if we need enable IsaAcpiFloppyB device.

+ # TRUE - Enables IsaAcpiFloppyB device.
+ # FALSE - Doesn't enable IsaAcpiFloppyB device.
+ # @Prompt Enable IsaAcpiFloppyB device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN|0x00000008 + +[PcdsFixedAtBuild, PcdsPatchableInModule] + ## FFS filename to find the shell application. + # @Prompt FFS Name of Shell Application + gSimicsX58PkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }|VOID*|0x40000004 + + ## ISA Bus features to support DMA, SlaveDMA and ISA Memory.

+ # BIT0 indicates if DMA is supported
+ # BIT1 indicates if only slave DMA is supported
+ # BIT2 indicates if ISA memory is supported
+ # Other BITs are reseved and must be zero. + # If more than one features are supported, the different BIT will be enabled at the same time. + # @Prompt ISA Bus Features + # @Expression 0x80000002 | (gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0 + gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010040 \ No newline at end of file diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h new file mode 100644 index 0000000000..38a71a3527 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h @@ -0,0 +1,38 @@ +/** @file + This driver installs SMBIOS information for OVMF + + Copyright (c) 2011, Bei Guan + Copyright (c) 2011, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SMBIOS_PLATFORM_DXE_H_ +#define _SMBIOS_PLATFORM_DXE_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Validates the SMBIOS entry point structure + + @param EntryPointStructure SMBIOS entry point structure + + @retval TRUE The entry point structure is valid + @retval FALSE The entry point structure is not valid + +**/ +BOOLEAN +IsEntryPointStructureValid ( + IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure + ); + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf new file mode 100644 index 0000000000..6adaf0beb7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf @@ -0,0 +1,51 @@ +## @file +# This driver installs SMBIOS information for OVMF +# +# Copyright (c) 2011, Bei Guan +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmbiosPlatformDxe + FILE_GUID = 4b18323d-2d42-4afa-b9e5-91516a6fe505 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = SmbiosTablePublishEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 +# + +[Sources] + SmbiosPlatformDxe.h + SmbiosPlatformDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec + AdvancedFeaturePkg/AdvancedFeaturePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + BaseMemoryLib + BaseLib + UefiDriverEntryPoint + DebugLib + HobLib + MemoryAllocationLib + IoLib + +[Protocols] + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[Depex] + gEfiSmbiosProtocolGuid + -- 2.16.2.windows.1